Merge from mozilla-central.
authorDavid Anderson <danderson@mozilla.com>
Wed, 29 Aug 2012 17:57:37 -0700
changeset 105829 7bf95bb092331b1db96ba9d561400fcdfb9f09d6
parent 105678 6cd206b371761294125cb98fe9d0c11e2383795f (current diff)
parent 105828 706174d31a02090effd97222dd174dbf2a2954c5 (diff)
child 105830 003feda8a0b3914c625acc784a1a441a3eeffaec
push id55
push usershu@rfrn.org
push dateThu, 30 Aug 2012 01:33:09 +0000
milestone18.0a1
Merge from mozilla-central.
accessible/src/base/AccIterator.cpp
accessible/src/base/AccIterator.h
accessible/src/base/Makefile.in
accessible/src/base/filters.cpp
accessible/src/base/filters.h
accessible/src/base/nsAccessNode.h
accessible/src/generic/ARIAGridAccessible.cpp
accessible/src/generic/ARIAGridAccessible.h
accessible/src/generic/Accessible.cpp
accessible/src/generic/Accessible.h
accessible/src/generic/DocAccessible.h
b2g/installer/package-manifest.in
browser/app/profile/firefox.js
browser/components/nsBrowserGlue.js
caps/src/nsPrincipal.cpp
config/makefiles/test/check-xpidl.mk
config/makefiles/xpidl.mk
config/system-headers
configure.in
content/base/public/nsIDocument.h
content/base/src/nsBlobProtocolHandler.cpp
content/base/src/nsContentSink.cpp
content/base/src/nsContentSink.h
content/base/src/nsDOMFileReader.cpp
content/base/src/nsDocument.cpp
content/base/src/nsDocument.h
content/base/src/nsFrameMessageManager.cpp
content/base/src/nsFrameMessageManager.h
content/base/src/nsObjectLoadingContent.cpp
content/base/src/nsStyleLinkElement.cpp
content/base/src/nsStyleLinkElement.h
content/base/src/nsTreeSanitizer.cpp
content/base/src/nsXMLHttpRequest.cpp
content/canvas/src/CanvasUtils.cpp
content/canvas/test/test_canvas.html
content/events/public/nsEventNameList.h
content/events/src/nsDOMEvent.cpp
content/events/src/nsDOMEvent.h
content/events/src/nsDOMNotifyPaintEvent.cpp
content/events/src/nsDOMScrollAreaEvent.cpp
content/events/src/nsDOMUIEvent.cpp
content/html/content/src/nsHTMLLinkElement.cpp
content/media/MediaResource.cpp
content/media/wave/nsWaveReader.cpp
content/smil/nsSMILAnimationController.cpp
content/smil/nsSMILInstanceTime.cpp
content/smil/nsSMILInstanceTime.h
content/svg/content/src/nsSVGStyleElement.cpp
docshell/base/nsDSURIContentListener.cpp
dom/Makefile.in
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfoClasses.h
dom/bindings/Codegen.py
dom/dom-config.mk
dom/indexedDB/IDBFactory.cpp
dom/indexedDB/IndexedDatabaseManager.cpp
dom/ipc/ContentChild.cpp
dom/ipc/ContentChild.h
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/Makefile.in
dom/ipc/PContent.ipdl
dom/ipc/TabChild.cpp
dom/ipc/TabChild.h
dom/ipc/TabMessageUtils.h
dom/ipc/TabParent.cpp
dom/plugins/ipc/PluginMessageUtils.h
dom/plugins/ipc/PluginModuleChild.cpp
dom/plugins/ipc/PluginModuleChild.h
dom/wifi/WifiWorker.js
dom/workers/RuntimeService.cpp
embedding/browser/webBrowser/nsWebBrowserContentPolicy.cpp
gfx/layers/Layers.h
gfx/layers/basic/BasicCanvasLayer.cpp
gfx/layers/basic/BasicContainerLayer.cpp
gfx/layers/basic/BasicContainerLayer.h
gfx/layers/d3d10/ContainerLayerD3D10.cpp
gfx/layers/d3d10/LayerManagerD3D10.cpp
gfx/layers/d3d10/LayerManagerD3D10.h
gfx/layers/d3d9/ContainerLayerD3D9.cpp
gfx/layers/d3d9/ContainerLayerD3D9.h
gfx/layers/ipc/PLayers.ipdl
gfx/layers/ipc/ShadowLayers.cpp
gfx/layers/ipc/ShadowLayers.h
gfx/layers/ipc/ShadowLayersParent.cpp
gfx/layers/opengl/ContainerLayerOGL.cpp
ipc/chromium/src/base/process_util_linux.cc
ipc/chromium/src/build/build_config.h
ipc/chromium/src/chrome/common/ipc_message_utils.h
ipc/glue/GeckoChildProcessHost.cpp
ipc/ipdl/ipdl/builtin.py
js/src/ETWProvider.man
js/src/Makefile.in
js/src/MemoryMetrics.cpp
js/src/config/makefiles/xpidl.mk
js/src/config/system-headers
js/src/devtools/sharkctl.cpp
js/src/devtools/sharkctl.h
js/src/frontend/BytecodeCompiler.cpp
js/src/gnuplot/gcTimer.gnu
js/src/javascript-trace.d
js/src/jit-test/tests/parallelarray/element-4.js
js/src/jsapi.h
js/src/jscntxt.cpp
js/src/jsdbgapi.cpp
js/src/jsfriendapi.cpp
js/src/jsfriendapi.h
js/src/jsfun.h
js/src/jsgc.h
js/src/jsinfer.cpp
js/src/jsiter.cpp
js/src/jsmemorymetrics.cpp
js/src/jsnum.cpp
js/src/metrics/gc/README.txt
js/src/metrics/gc/gc-test.py
js/src/metrics/gc/tests/clock.js
js/src/metrics/gc/tests/dslots.js
js/src/metrics/gc/tests/loops.js
js/src/metrics/gc/tests/objGraph.js
js/src/metrics/jint/sunspider/3d-cube.js
js/src/metrics/jint/sunspider/3d-morph.js
js/src/metrics/jint/sunspider/3d-raytrace.js
js/src/metrics/jint/sunspider/access-binary-trees.js
js/src/metrics/jint/sunspider/access-fannkuch.js
js/src/metrics/jint/sunspider/access-nbody.js
js/src/metrics/jint/sunspider/access-nsieve.js
js/src/metrics/jint/sunspider/bitops-3bit-bits-in-byte.js
js/src/metrics/jint/sunspider/bitops-bits-in-byte.js
js/src/metrics/jint/sunspider/bitops-bitwise-and.js
js/src/metrics/jint/sunspider/bitops-nsieve-bits.js
js/src/metrics/jint/sunspider/controlflow-recursive.js
js/src/metrics/jint/sunspider/crypto-aes.js
js/src/metrics/jint/sunspider/crypto-md5.js
js/src/metrics/jint/sunspider/crypto-sha1.js
js/src/metrics/jint/sunspider/date-format-tofte.js
js/src/metrics/jint/sunspider/date-format-xparb.js
js/src/metrics/jint/sunspider/math-cordic.js
js/src/metrics/jint/sunspider/math-partial-sums.js
js/src/metrics/jint/sunspider/math-spectral-norm.js
js/src/metrics/jint/sunspider/regexp-dna.js
js/src/metrics/jint/sunspider/string-base64.js
js/src/metrics/jint/sunspider/string-fasta.js
js/src/metrics/jint/sunspider/string-tagcloud.js
js/src/metrics/jint/sunspider/string-unpack-code.js
js/src/metrics/jint/sunspider/string-validate-input.js
js/src/metrics/jint/treesearch.py
js/src/metrics/jint/v8/base.js
js/src/metrics/jint/v8/crypto.js
js/src/metrics/jint/v8/deltablue.js
js/src/metrics/jint/v8/earley-boyer.js
js/src/metrics/jint/v8/raytrace.js
js/src/metrics/jint/v8/richards.js
js/src/metrics/jint/v8/run-earley-boyer.js
js/src/metrics/jint/v8/run-raytrace.js
js/src/metrics/jint/v8/run-richards.js
js/src/metrics/jint/v8/run.js
js/src/sharkctl.cpp
js/src/sharkctl.h
js/src/vm/GlobalObject.cpp
js/src/vm/Stack.cpp
js/src/vm/String.cpp
js/src/vm/String.h
js/src/vprof/manifest.mk
js/src/vprof/readme.txt
js/src/vprof/testVprofMT.c
js/src/vprof/vprof.cpp
js/src/vprof/vprof.h
js/xpconnect/src/Makefile.in
js/xpconnect/src/XPCQuickStubs.cpp
js/xpconnect/src/xpcpublic.h
layout/base/FrameLayerBuilder.cpp
layout/base/FrameLayerBuilder.h
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsDisplayList.cpp
layout/base/nsLayoutUtils.cpp
layout/base/nsPresShell.cpp
layout/build/Makefile.in
layout/forms/nsTextControlFrame.cpp
layout/generic/nsFrame.cpp
layout/generic/nsFrame.h
layout/generic/nsIFrame.h
layout/reftests/svg/reftest.list
layout/style/Loader.cpp
layout/style/Loader.h
layout/style/nsCSSStyleSheet.cpp
layout/style/nsCSSStyleSheet.h
layout/style/test/Makefile.in
layout/svg/base/src/nsSVGUtils.cpp
mobile/android/base/GeckoApp.java
mobile/android/chrome/content/browser.js
mobile/android/themes/core/aboutReader.css
modules/libpref/src/init/all.js
netwerk/base/src/nsBufferedStreams.cpp
netwerk/base/src/nsFileStreams.cpp
netwerk/base/src/nsMIMEInputStream.cpp
netwerk/base/src/nsProtocolProxyService.cpp
netwerk/dns/nsDNSService2.h
netwerk/protocol/http/PHttpChannelParams.h
parser/html/nsHtml5TreeBuilderCppSupplement.h
parser/html/nsHtml5TreeOpExecutor.cpp
parser/html/nsHtml5TreeOpExecutor.h
security/manager/ssl/src/SSLServerCertVerification.cpp
security/manager/ssl/src/TransportSecurityInfo.cpp
security/manager/ssl/src/TransportSecurityInfo.h
security/manager/ssl/src/nsNSSIOLayer.cpp
testing/jetpack/jetpack-location.txt
toolkit/components/telemetry/Telemetry.cpp
widget/android/nsAppShell.cpp
widget/gtk2/nsWindow.cpp
widget/nsGUIEvent.h
widget/xpwidgets/PuppetWidget.cpp
widget/xpwidgets/PuppetWidget.h
xpcom/base/nsCycleCollector.cpp
xpcom/build/nsXPCOM.h
xpcom/build/nsXPCOMPrivate.h
xpcom/io/nsStringStream.cpp
xpcom/stub/nsXPComStub.cpp
--- a/Makefile.in
+++ b/Makefile.in
@@ -64,17 +64,17 @@ endif
 ifdef COMPILE_ENVIRONMENT
 include $(topsrcdir)/$(MOZ_BUILD_APP)/build.mk
 endif
 
 
 include $(topsrcdir)/config/config.mk
 
 GARBAGE_DIRS += dist _javagen _profile _tests staticlib
-DIST_GARBAGE = config.cache config.log config.status config-defs.h \
+DIST_GARBAGE = config.cache config.log config.status* config-defs.h \
    config/autoconf.mk \
    unallmakefiles mozilla-config.h \
    netwerk/necko-config.h xpcom/xpcom-config.h xpcom/xpcom-private.h \
    $(topsrcdir)/.mozconfig.mk $(topsrcdir)/.mozconfig.out
 
 default alldep all:: $(topsrcdir)/configure config.status
 	$(RM) -r $(DIST)/sdk
 	$(RM) -r $(DIST)/include
--- a/accessible/src/base/AccCollector.cpp
+++ b/accessible/src/base/AccCollector.cpp
@@ -1,16 +1,18 @@
 /* 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 "AccCollector.h"
 
 #include "Accessible.h"
 
+using namespace mozilla::a11y;
+
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccCollector
 ////////////////////////////////////////////////////////////////////////////////
 
 AccCollector::
   AccCollector(Accessible* aRoot, filters::FilterFuncPtr aFilterFunc) :
   mFilterFunc(aFilterFunc), mRoot(aRoot), mRootChildIdx(0)
 {
@@ -51,34 +53,34 @@ AccCollector::GetIndexAt(Accessible* aAc
 // nsAccCollector protected
 
 Accessible*
 AccCollector::EnsureNGetObject(uint32_t aIndex)
 {
   uint32_t childCount = mRoot->ChildCount();
   while (mRootChildIdx < childCount) {
     Accessible* child = mRoot->GetChildAt(mRootChildIdx++);
-    if (!mFilterFunc(child))
+    if (!(mFilterFunc(child) & filters::eMatch))
       continue;
 
     AppendObject(child);
     if (mObjects.Length() - 1 == aIndex)
       return mObjects[aIndex];
   }
 
   return nullptr;
 }
 
 int32_t
 AccCollector::EnsureNGetIndex(Accessible* aAccessible)
 {
   uint32_t childCount = mRoot->ChildCount();
   while (mRootChildIdx < childCount) {
     Accessible* child = mRoot->GetChildAt(mRootChildIdx++);
-    if (!mFilterFunc(child))
+    if (!(mFilterFunc(child) & filters::eMatch))
       continue;
 
     AppendObject(child);
     if (child == aAccessible)
       return mObjects.Length() - 1;
   }
 
   return -1;
@@ -98,17 +100,18 @@ int32_t
 EmbeddedObjCollector::GetIndexAt(Accessible* aAccessible)
 {
   if (aAccessible->mParent != mRoot)
     return -1;
 
   if (aAccessible->mIndexOfEmbeddedChild != -1)
     return aAccessible->mIndexOfEmbeddedChild;
 
-  return mFilterFunc(aAccessible) ? EnsureNGetIndex(aAccessible) : -1;
+  return mFilterFunc(aAccessible) & filters::eMatch ?
+    EnsureNGetIndex(aAccessible) : -1;
 }
 
 void
 EmbeddedObjCollector::AppendObject(Accessible* aAccessible)
 {
   aAccessible->mIndexOfEmbeddedChild = mObjects.Length();
   mObjects.AppendElement(aAccessible);
 }
--- a/accessible/src/base/AccCollector.h
+++ b/accessible/src/base/AccCollector.h
@@ -1,19 +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/. */
 
-#ifndef AccCollector_h_
-#define AccCollector_h_
+#ifndef mozilla_a11y_AccCollector_h__
+#define mozilla_a11y_AccCollector_h__
+
+#include "AccFilters.h"
 
-#include "filters.h"
+#include "nsTArray.h"
 
-#include "nscore.h"
-#include "nsTArray.h"
+class Accessible;
+
+namespace mozilla {
+namespace a11y {
 
 /**
  * Collect accessible children complying with filter function. Provides quick
  * access to accessible by index.
  */
 class AccCollector
 {
 public:
@@ -77,12 +81,15 @@ public:
 
 protected:
   // Make sure it's used by Accessible class only.
   EmbeddedObjCollector(Accessible* aRoot) :
     AccCollector(aRoot, filters::GetEmbeddedObject) { }
 
   virtual void AppendObject(Accessible* aAccessible);
 
-  friend class Accessible;
+  friend class ::Accessible;
 };
 
+} // namespace a11y
+} // namespace mozilla
+
 #endif
rename from accessible/src/base/filters.cpp
rename to accessible/src/base/AccFilters.cpp
--- a/accessible/src/base/filters.cpp
+++ b/accessible/src/base/AccFilters.cpp
@@ -1,44 +1,60 @@
 /* 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 "filters.h"
+#include "AccFilters.h"
 
 #include "Accessible-inl.h"
 #include "nsAccUtils.h"
 #include "Role.h"
 #include "States.h"
 
 using namespace mozilla::a11y;
+using namespace mozilla::a11y::filters;
 
-bool
+uint32_t
 filters::GetSelected(Accessible* aAccessible)
 {
-  return aAccessible->State() & states::SELECTED;
+  if (aAccessible->State() & states::SELECTED)
+    return eMatch | eSkipSubtree;
+
+  return eSkip;
 }
 
-bool
+uint32_t
 filters::GetSelectable(Accessible* aAccessible)
 {
-  return aAccessible->InteractiveState() & states::SELECTABLE;
+  if (aAccessible->InteractiveState() & states::SELECTABLE)
+    return eMatch | eSkipSubtree;
+
+  return eSkip;
 }
 
-bool
+uint32_t
 filters::GetRow(Accessible* aAccessible)
 {
-  return aAccessible->Role() == roles::ROW;
+  a11y::role role = aAccessible->Role();
+  if (role == roles::ROW)
+    return eMatch | eSkipSubtree;
+
+  // Look for rows inside rowgroup.
+  if (role == roles::SECTION)
+    return eSkip;
+
+  return eSkipSubtree;
 }
 
-bool
+uint32_t
 filters::GetCell(Accessible* aAccessible)
 {
-  roles::Role role = aAccessible->Role();
+  a11y::role role = aAccessible->Role();
   return role == roles::GRID_CELL || role == roles::ROWHEADER ||
-      role == roles::COLUMNHEADER;
+    role == roles::COLUMNHEADER ? eMatch : eSkipSubtree;
 }
 
-bool
+uint32_t
 filters::GetEmbeddedObject(Accessible* aAccessible)
 {
-  return nsAccUtils::IsEmbeddedObject(aAccessible);
+  return nsAccUtils::IsEmbeddedObject(aAccessible) ?
+    eMatch | eSkipSubtree : eSkipSubtree;
 }
rename from accessible/src/base/filters.h
rename to accessible/src/base/AccFilters.h
--- a/accessible/src/base/filters.h
+++ b/accessible/src/base/AccFilters.h
@@ -1,27 +1,55 @@
 /* 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/. */
 
-#ifndef a11yFilters_h_
-#define a11yFilters_h_
+#ifndef mozilla_a11y_Filters_h__
+#define mozilla_a11y_Filters_h__
+
+#include "mozilla/StandardInteger.h"
 
 class Accessible;
 
 /**
  * Predefined filters used for nsAccIterator and nsAccCollector.
  */
+namespace mozilla {
+namespace a11y {
 namespace filters {
 
-  /**
-   * Return true if the traversed accessible complies with filter.
-   */
-  typedef bool (*FilterFuncPtr) (Accessible*);
+enum EResult {
+  eSkip = 0,
+  eMatch = 1,
+  eSkipSubtree = 2
+};
+
+/**
+ * Return true if the traversed accessible complies with filter.
+ */
+typedef uint32_t (*FilterFuncPtr) (Accessible*);
+
+/**
+ * Matches selected/selectable accessibles in subtree.
+ */
+uint32_t GetSelected(Accessible* aAccessible);
+uint32_t GetSelectable(Accessible* aAccessible);
 
-  bool GetSelected(Accessible* aAccessible);
-  bool GetSelectable(Accessible* aAccessible);
-  bool GetRow(Accessible* aAccessible);
-  bool GetCell(Accessible* aAccessible);
-  bool GetEmbeddedObject(Accessible* aAccessible);
-}
+/**
+ * Matches row accessibles in subtree.
+ */
+uint32_t GetRow(Accessible* aAccessible);
+
+/**
+ * Matches cell accessibles in children.
+ */
+uint32_t GetCell(Accessible* aAccessible);
+
+/**
+ * Matches embedded objects in children.
+ */
+uint32_t GetEmbeddedObject(Accessible* aAccessible);
+
+} // namespace filters
+} // namespace a11y
+} // namespace mozilla
 
 #endif
--- a/accessible/src/base/AccIterator.cpp
+++ b/accessible/src/base/AccIterator.cpp
@@ -13,19 +13,18 @@
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // AccIterator
 ////////////////////////////////////////////////////////////////////////////////
 
 AccIterator::AccIterator(Accessible* aAccessible,
-                         filters::FilterFuncPtr aFilterFunc,
-                         IterationType aIterationType) :
-  mFilterFunc(aFilterFunc), mIsDeep(aIterationType != eFlatNav)
+                         filters::FilterFuncPtr aFilterFunc) :
+  mFilterFunc(aFilterFunc)
 {
   mState = new IteratorState(aAccessible);
 }
 
 AccIterator::~AccIterator()
 {
   while (mState) {
     IteratorState *tmp = mState;
@@ -35,29 +34,29 @@ AccIterator::~AccIterator()
 }
 
 Accessible*
 AccIterator::Next()
 {
   while (mState) {
     Accessible* child = mState->mParent->GetChildAt(mState->mIndex++);
     if (!child) {
-      IteratorState *tmp = mState;
+      IteratorState* tmp = mState;
       mState = mState->mParentState;
       delete tmp;
 
       continue;
     }
 
-    bool isComplying = mFilterFunc(child);
-    if (isComplying)
+    uint32_t result = mFilterFunc(child);
+    if (result & filters::eMatch)
       return child;
 
-    if (mIsDeep) {
-      IteratorState *childState = new IteratorState(child, mState);
+    if (!(result & filters::eSkipSubtree)) {
+      IteratorState* childState = new IteratorState(child, mState);
       mState = childState;
     }
   }
 
   return nullptr;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
--- a/accessible/src/base/AccIterator.h
+++ b/accessible/src/base/AccIterator.h
@@ -1,21 +1,23 @@
 /* -*- 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/. */
 
-#ifndef nsAccIterator_h_
-#define nsAccIterator_h_
+#ifndef mozilla_a11y_AccIterator_h__
+#define mozilla_a11y_AccIterator_h__
 
+#include "DocAccessible.h"
+#include "AccFilters.h"
 #include "nsAccessibilityService.h"
-#include "filters.h"
-#include "nscore.h"
-#include "DocAccessible.h"
+
+namespace mozilla {
+namespace a11y {
 
 /**
  * AccIterable is a basic interface for iterators over accessibles.
  */
 class AccIterable
 {
 public:
   virtual ~AccIterable() { }
@@ -28,34 +30,17 @@ private:
 
 /**
  * Allows to iterate through accessible children or subtree complying with
  * filter function.
  */
 class AccIterator : public AccIterable
 {
 public:
-  /**
-   * Used to define iteration type.
-   */
-  enum IterationType {
-    /**
-     * Navigation happens through direct children.
-     */
-    eFlatNav,
-
-    /**
-     * Navigation through subtree excluding iterator root; if the accessible
-     * complies with filter, iterator ignores its children.
-     */
-    eTreeNav
-  };
-
-  AccIterator(Accessible* aRoot, filters::FilterFuncPtr aFilterFunc,
-              IterationType aIterationType = eFlatNav);
+  AccIterator(Accessible* aRoot, filters::FilterFuncPtr aFilterFunc);
   virtual ~AccIterator();
 
   /**
    * Return next accessible complying with filter function. Return the first
    * accessible for the first time.
    */
   virtual Accessible* Next();
 
@@ -65,22 +50,21 @@ private:
   AccIterator& operator =(const AccIterator&);
 
   struct IteratorState
   {
     IteratorState(Accessible* aParent, IteratorState* mParentState = nullptr);
 
     Accessible* mParent;
     int32_t mIndex;
-    IteratorState *mParentState;
+    IteratorState* mParentState;
   };
 
   filters::FilterFuncPtr mFilterFunc;
-  bool mIsDeep;
-  IteratorState *mState;
+  IteratorState* mState;
 };
 
 
 /**
  * Allows to traverse through related accessibles that are pointing to the given
  * dependent accessible by relation attribute.
  */
 class RelatedAccIterator : public AccIterable
@@ -277,9 +261,12 @@ public:
 private:
   SingleAccIterator();
   SingleAccIterator(const SingleAccIterator&);
   SingleAccIterator& operator = (const SingleAccIterator&);
 
   nsRefPtr<Accessible> mAcc;
 };
 
+} // namespace a11y
+} // namespace mozilla
+
 #endif
--- a/accessible/src/base/Makefile.in
+++ b/accessible/src/base/Makefile.in
@@ -14,18 +14,18 @@ LIBRARY_NAME = accessibility_base_s
 LIBXUL_LIBRARY = 1
 
 
 CPPSRCS = \
   AccCollector.cpp \
   AccEvent.cpp \
   AccGroupInfo.cpp \
   AccIterator.cpp \
+  AccFilters.cpp \
   ARIAStateMap.cpp \
-  filters.cpp \
   FocusManager.cpp \
   NotificationController.cpp \
   nsAccDocManager.cpp \
   nsAccessNode.cpp \
   nsARIAMap.cpp \
   nsCoreUtils.cpp \
   nsAccUtils.cpp \
   nsAccessibilityService.cpp \
--- a/accessible/src/base/Relation.h
+++ b/accessible/src/base/Relation.h
@@ -14,36 +14,38 @@ namespace a11y {
 
 /**
  * This class is used to return Relation objects from functions.  A copy
  * constructor doesn't work here because we need to mutate the old relation to
  * have its nsAutoPtr forget what it points to.
  */
 struct RelationCopyHelper
 {
-  RelationCopyHelper(AccIterable* aFirstIter, AccIterable* aLastIter) :
+  RelationCopyHelper(mozilla::a11y::AccIterable* aFirstIter,
+                     mozilla::a11y::AccIterable* aLastIter) :
     mFirstIter(aFirstIter), mLastIter(aLastIter) { }
 
-  AccIterable* mFirstIter;
-  AccIterable* mLastIter;
+  mozilla::a11y::AccIterable* mFirstIter;
+  mozilla::a11y::AccIterable* mLastIter;
 };
 
 /**
  * A collection of relation targets of a certain type.  Targets are computed
  * lazily while enumerating.
  */
 class Relation
 {
 public:
   Relation() : mFirstIter(nullptr), mLastIter(nullptr) { }
 
   Relation(const RelationCopyHelper aRelation) :
     mFirstIter(aRelation.mFirstIter), mLastIter(aRelation.mLastIter) { }
 
-  Relation(AccIterable* aIter) : mFirstIter(aIter), mLastIter(aIter) { }
+  Relation(mozilla::a11y::AccIterable* aIter) :
+    mFirstIter(aIter), mLastIter(aIter) { }
 
   Relation(Accessible* aAcc) :
     mFirstIter(nullptr), mLastIter(nullptr)
     { AppendTarget(aAcc); }
 
   Relation(DocAccessible* aDocument, nsIContent* aContent) :
     mFirstIter(nullptr), mLastIter(nullptr)
     { AppendTarget(aDocument, aContent); }
@@ -62,33 +64,33 @@ public:
     return *this;
   }
 
   operator RelationCopyHelper()
   {
     return RelationCopyHelper(mFirstIter.forget(), mLastIter);
   }
 
-  inline void AppendIter(AccIterable* aIter)
+  inline void AppendIter(mozilla::a11y::AccIterable* aIter)
   {
     if (mLastIter)
       mLastIter->mNextIter = aIter;
     else
       mFirstIter = aIter;
 
     mLastIter = aIter;
   }
 
   /**
    * Append the given accessible to the set of related accessibles.
    */
   inline void AppendTarget(Accessible* aAcc)
   {
     if (aAcc)
-      AppendIter(new SingleAccIterator(aAcc));
+      AppendIter(new mozilla::a11y::SingleAccIterator(aAcc));
   }
 
   /**
    * Append the one accessible for this content node to the set of related
    * accessibles.
    */
   void AppendTarget(DocAccessible* aDocument, nsIContent* aContent)
   {
@@ -111,17 +113,17 @@ public:
       mLastIter = nullptr;
 
     return target;
   }
 
 private:
   Relation& operator = (const Relation&);
 
-  nsAutoPtr<AccIterable> mFirstIter;
-  AccIterable* mLastIter;
+  nsAutoPtr<mozilla::a11y::AccIterable> mFirstIter;
+  mozilla::a11y::AccIterable* mLastIter;
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif
 
--- a/accessible/src/base/nsAccessNode.h
+++ b/accessible/src/base/nsAccessNode.h
@@ -98,17 +98,17 @@ public:
 
   /**
    * Return true if the accessible is primary accessible for the given DOM node.
    *
    * Accessible hierarchy may be complex for single DOM node, in this case
    * these accessibles share the same DOM node. The primary accessible "owns"
    * that DOM node in terms it gets stored in the accessible to node map.
    */
-  virtual bool IsPrimaryForNode() const;
+  virtual bool IsPrimaryForNode() const;//hello
 
   /**
    * Interface methods on nsIAccessible shared with ISimpleDOM.
    */
   void Language(nsAString& aLocale);
 
 protected:
   void LastRelease();
new file mode 100644
--- /dev/null
+++ b/accessible/src/generic/ARIAGridAccessible-inl.h
@@ -0,0 +1,53 @@
+/* -*- 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/. */
+
+#ifndef mozilla_a11y_ARIAGridAccessible_inl_h__
+#define mozilla_a11y_ARIAGridAccessible_inl_h__
+
+#include "ARIAGridAccessible.h"
+
+#include "AccIterator.h"
+
+inline Accessible*
+mozilla::a11y::ARIAGridCellAccessible::TableFor(Accessible* aRow) const
+{
+  if (aRow) {
+    Accessible* table = aRow->Parent();
+    if (table) {
+      roles::Role tableRole = table->Role();
+      if (tableRole == roles::SECTION) { // if there's a rowgroup.
+        table = table->Parent();
+        if (table)
+          tableRole = table->Role();
+      }
+
+      return tableRole == roles::TABLE || tableRole == roles::TREE_TABLE ?
+        table : nullptr;
+    }
+  }
+
+  return nullptr;
+}
+
+inline int32_t
+mozilla::a11y::ARIAGridCellAccessible::RowIndexFor(Accessible* aRow) const
+{
+  Accessible* table = TableFor(aRow);
+  if (table) {
+    int32_t rowIdx = 0;
+    Accessible* row = nullptr;
+    AccIterator rowIter(table, filters::GetRow);
+    while ((row = rowIter.Next()) && row != aRow)
+      rowIdx++;
+
+    if (row)
+      return rowIdx;
+  }
+
+  return -1;
+}
+
+#endif
--- a/accessible/src/generic/ARIAGridAccessible.cpp
+++ b/accessible/src/generic/ARIAGridAccessible.cpp
@@ -1,14 +1,14 @@
 /* -*- 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/. */
 
-#include "ARIAGridAccessible.h"
+#include "ARIAGridAccessible-inl.h"
 
 #include "Accessible-inl.h"
 #include "AccIterator.h"
 #include "nsAccUtils.h"
 #include "Role.h"
 #include "States.h"
 
 #include "nsIMutableArray.h"
@@ -546,29 +546,20 @@ NS_IMPL_ISUPPORTS_INHERITED1(ARIAGridCel
 // nsIAccessibleTableCell
 
 NS_IMETHODIMP
 ARIAGridCellAccessible::GetTable(nsIAccessibleTable** aTable)
 {
   NS_ENSURE_ARG_POINTER(aTable);
   *aTable = nullptr;
 
-  Accessible* thisRow = Parent();
-  if (!thisRow || thisRow->Role() != roles::ROW)
-    return NS_OK;
+  Accessible* table = TableFor(Row());
+  if (table)
+    CallQueryInterface(table, aTable);
 
-  Accessible* table = thisRow->Parent();
-  if (!table)
-    return NS_OK;
-
-  roles::Role tableRole = table->Role();
-  if (tableRole != roles::TABLE && tableRole != roles::TREE_TABLE)
-    return NS_OK;
-
-  CallQueryInterface(table, aTable);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 ARIAGridCellAccessible::GetColumnIndex(int32_t* aColumnIndex)
 {
   NS_ENSURE_ARG_POINTER(aColumnIndex);
   *aColumnIndex = -1;
@@ -598,33 +589,17 @@ NS_IMETHODIMP
 ARIAGridCellAccessible::GetRowIndex(int32_t* aRowIndex)
 {
   NS_ENSURE_ARG_POINTER(aRowIndex);
   *aRowIndex = -1;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  Accessible* row = Parent();
-  if (!row)
-    return NS_OK;
-
-  Accessible* table = row->Parent();
-  if (!table)
-    return NS_OK;
-
-  *aRowIndex = 0;
-
-  int32_t indexInTable = row->IndexInParent();
-  for (int32_t idx = 0; idx < indexInTable; idx++) {
-    row = table->GetChildAt(idx);
-    if (row->Role() == roles::ROW)
-      (*aRowIndex)++;
-  }
-
+  *aRowIndex = RowIndexFor(Row());
   return NS_OK;
 }
 
 NS_IMETHODIMP
 ARIAGridCellAccessible::GetColumnExtent(int32_t* aExtentCount)
 {
   NS_ENSURE_ARG_POINTER(aExtentCount);
   *aExtentCount = 0;
@@ -733,62 +708,42 @@ ARIAGridCellAccessible::ApplyARIAState(u
     *aState |= states::SELECTABLE | states::SELECTED;
 }
 
 nsresult
 ARIAGridCellAccessible::GetAttributesInternal(nsIPersistentProperties* aAttributes)
 {
   if (IsDefunct())
     return NS_ERROR_FAILURE;
-  
+
   nsresult rv = HyperTextAccessibleWrap::GetAttributesInternal(aAttributes);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Expose "table-cell-index" attribute.
-
-  Accessible* thisRow = Parent();
-  if (!thisRow || thisRow->Role() != roles::ROW)
+  Accessible* thisRow = Row();
+  if (!thisRow)
     return NS_OK;
 
   int32_t colIdx = 0, colCount = 0;
   uint32_t childCount = thisRow->ChildCount();
   for (uint32_t childIdx = 0; childIdx < childCount; childIdx++) {
     Accessible* child = thisRow->GetChildAt(childIdx);
     if (child == this)
       colIdx = colCount;
 
     roles::Role role = child->Role();
     if (role == roles::GRID_CELL || role == roles::ROWHEADER ||
         role == roles::COLUMNHEADER)
       colCount++;
   }
 
-  Accessible* table = thisRow->Parent();
-  if (!table)
-    return NS_OK;
-
-  roles::Role tableRole = table->Role();
-  if (tableRole != roles::TABLE && tableRole != roles::TREE_TABLE)
-    return NS_OK;
-
-  int32_t rowIdx = 0;
-  childCount = table->ChildCount();
-  for (uint32_t childIdx = 0; childIdx < childCount; childIdx++) {
-    Accessible* child = table->GetChildAt(childIdx);
-    if (child == thisRow)
-      break;
-
-    if (child->Role() == roles::ROW)
-      rowIdx++;
-  }
-
-  int32_t idx = rowIdx * colCount + colIdx;
+  int32_t rowIdx = RowIndexFor(thisRow);
 
   nsAutoString stringIdx;
-  stringIdx.AppendInt(idx);
+  stringIdx.AppendInt(rowIdx * colCount + colIdx);
   nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::tableCellIndex,
                          stringIdx);
 
   return NS_OK;
 }
 
 void
 ARIAGridCellAccessible::Shutdown()
--- a/accessible/src/generic/ARIAGridAccessible.h
+++ b/accessible/src/generic/ARIAGridAccessible.h
@@ -55,16 +55,17 @@ public:
   virtual void SelectedColIndices(nsTArray<uint32_t>* aCols);
   virtual void SelectedRowIndices(nsTArray<uint32_t>* aRows);
   virtual void SelectCol(uint32_t aColIdx);
   virtual void SelectRow(uint32_t aRowIdx);
   virtual void UnselectCol(uint32_t aColIdx);
   virtual void UnselectRow(uint32_t aRowIdx);
 
 protected:
+
   /**
    * Return true if the given row index is valid.
    */
   bool IsValidRow(int32_t aRow);
 
   /**
    * Retrn true if the given column index is valid.
    */
@@ -109,14 +110,35 @@ public:
 
   // nsIAccessibleTableCell
   NS_DECL_OR_FORWARD_NSIACCESSIBLETABLECELL_WITH_XPCACCESSIBLETABLECELL
 
   // Accessible
   virtual void Shutdown();
   virtual void ApplyARIAState(uint64_t* aState) const;
   virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
+
+protected:
+
+  /**
+   * Return a containing row.
+   */
+  Accessible* Row() const
+  {
+    Accessible* row = Parent();
+    return row && row->Role() == roles::ROW ? row : nullptr;
+  }
+
+  /**
+   * Return a table for the given row.
+   */
+  Accessible* TableFor(Accessible* aRow) const;
+
+  /**
+   * Return index of the given row.
+   */
+  int32_t RowIndexFor(Accessible* aRow) const;
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif
--- a/accessible/src/generic/Accessible.cpp
+++ b/accessible/src/generic/Accessible.cpp
@@ -2723,115 +2723,115 @@ Accessible::IsSelect()
 
 already_AddRefed<nsIArray>
 Accessible::SelectedItems()
 {
   nsCOMPtr<nsIMutableArray> selectedItems = do_CreateInstance(NS_ARRAY_CONTRACTID);
   if (!selectedItems)
     return nullptr;
 
-  AccIterator iter(this, filters::GetSelected, AccIterator::eTreeNav);
+  AccIterator iter(this, filters::GetSelected);
   nsIAccessible* selected = nullptr;
   while ((selected = iter.Next()))
     selectedItems->AppendElement(selected, false);
 
   nsIMutableArray* items = nullptr;
   selectedItems.forget(&items);
   return items;
 }
 
 uint32_t
 Accessible::SelectedItemCount()
 {
   uint32_t count = 0;
-  AccIterator iter(this, filters::GetSelected, AccIterator::eTreeNav);
+  AccIterator iter(this, filters::GetSelected);
   Accessible* selected = nullptr;
   while ((selected = iter.Next()))
     ++count;
 
   return count;
 }
 
 Accessible*
 Accessible::GetSelectedItem(uint32_t aIndex)
 {
-  AccIterator iter(this, filters::GetSelected, AccIterator::eTreeNav);
+  AccIterator iter(this, filters::GetSelected);
   Accessible* selected = nullptr;
 
   uint32_t index = 0;
   while ((selected = iter.Next()) && index < aIndex)
     index++;
 
   return selected;
 }
 
 bool
 Accessible::IsItemSelected(uint32_t aIndex)
 {
   uint32_t index = 0;
-  AccIterator iter(this, filters::GetSelectable, AccIterator::eTreeNav);
+  AccIterator iter(this, filters::GetSelectable);
   Accessible* selected = nullptr;
   while ((selected = iter.Next()) && index < aIndex)
     index++;
 
   return selected &&
     selected->State() & states::SELECTED;
 }
 
 bool
 Accessible::AddItemToSelection(uint32_t aIndex)
 {
   uint32_t index = 0;
-  AccIterator iter(this, filters::GetSelectable, AccIterator::eTreeNav);
+  AccIterator iter(this, filters::GetSelectable);
   Accessible* selected = nullptr;
   while ((selected = iter.Next()) && index < aIndex)
     index++;
 
   if (selected)
     selected->SetSelected(true);
 
   return static_cast<bool>(selected);
 }
 
 bool
 Accessible::RemoveItemFromSelection(uint32_t aIndex)
 {
   uint32_t index = 0;
-  AccIterator iter(this, filters::GetSelectable, AccIterator::eTreeNav);
+  AccIterator iter(this, filters::GetSelectable);
   Accessible* selected = nullptr;
   while ((selected = iter.Next()) && index < aIndex)
     index++;
 
   if (selected)
     selected->SetSelected(false);
 
   return static_cast<bool>(selected);
 }
 
 bool
 Accessible::SelectAll()
 {
   bool success = false;
   Accessible* selectable = nullptr;
 
-  AccIterator iter(this, filters::GetSelectable, AccIterator::eTreeNav);
+  AccIterator iter(this, filters::GetSelectable);
   while((selectable = iter.Next())) {
     success = true;
     selectable->SetSelected(true);
   }
   return success;
 }
 
 bool
 Accessible::UnselectAll()
 {
   bool success = false;
   Accessible* selected = nullptr;
 
-  AccIterator iter(this, filters::GetSelected, AccIterator::eTreeNav);
+  AccIterator iter(this, filters::GetSelected);
   while ((selected = iter.Next())) {
     success = true;
     selected->SetSelected(false);
   }
   return success;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
--- a/accessible/src/generic/Accessible.h
+++ b/accessible/src/generic/Accessible.h
@@ -18,25 +18,25 @@
 #include "nsIContent.h"
 
 #include "nsStringGlue.h"
 #include "nsTArray.h"
 #include "nsRefPtrHashtable.h"
 
 class AccEvent;
 class AccGroupInfo;
-class EmbeddedObjCollector;
 class KeyBinding;
 class Accessible;
 class HyperTextAccessible;
 struct nsRoleMapEntry;
 
 namespace mozilla {
 namespace a11y {
 
+class EmbeddedObjCollector;
 class HTMLImageMapAccessible;
 class HTMLLIAccessible;
 class ImageAccessible;
 class Relation;
 class TableAccessible;
 class TextLeafAccessible;
 class XULTreeAccessible;
 
@@ -870,19 +870,19 @@ protected:
   int32_t mIndexInParent;
 
   static const uint32_t kChildrenFlagsMask =
     eChildrenUninitialized | eMixedChildren | eEmbeddedChildren;
 
   uint32_t mFlags;
   friend class DocAccessible;
 
-  nsAutoPtr<EmbeddedObjCollector> mEmbeddedObjCollector;
+  nsAutoPtr<mozilla::a11y::EmbeddedObjCollector> mEmbeddedObjCollector;
   int32_t mIndexOfEmbeddedChild;
-  friend class EmbeddedObjCollector;
+  friend class mozilla::a11y::EmbeddedObjCollector;
 
   nsAutoPtr<AccGroupInfo> mGroupInfo;
   friend class AccGroupInfo;
 
   /**
    * Non-null indicates author-supplied role; possibly state & value as well
    */
   nsRoleMapEntry* mRoleMapEntry;
--- a/accessible/src/generic/DocAccessible.h
+++ b/accessible/src/generic/DocAccessible.h
@@ -28,16 +28,24 @@ template<class Class, class Arg>
 class TNotification;
 class NotificationController;
 
 class nsIScrollableView;
 class nsAccessiblePivot;
 
 const uint32_t kDefaultCacheSize = 256;
 
+namespace mozilla {
+namespace a11y {
+
+class RelatedAccIterator;
+
+} // namespace a11y
+} // namespace mozilla
+
 class DocAccessible : public HyperTextAccessibleWrap,
                       public nsIAccessibleDocument,
                       public nsIDocumentObserver,
                       public nsIObserver,
                       public nsIScrollPositionListener,
                       public nsSupportsWeakReference,
                       public nsIAccessibleCursorable,
                       public nsIAccessiblePivotObserver
@@ -562,17 +570,17 @@ protected:
   };
 
   /**
    * The cache of IDs pointed by relation attributes.
    */
   typedef nsTArray<nsAutoPtr<AttrRelProvider> > AttrRelProviderArray;
   nsClassHashtable<nsStringHashKey, AttrRelProviderArray> mDependentIDsHash;
 
-  friend class RelatedAccIterator;
+  friend class mozilla::a11y::RelatedAccIterator;
 
   /**
    * Used for our caching algorithm. We store the list of nodes that should be
    * invalidated.
    *
    * @see ProcessInvalidationList
    */
   nsTArray<nsIContent*> mInvalidationList;
--- a/accessible/tests/mochitest/table/test_indexes_ariagrid.html
+++ b/accessible/tests/mochitest/table/test_indexes_ariagrid.html
@@ -23,16 +23,24 @@
       var idxes = [
         [0, 1, 2],
         [3, 4, 5],
         [6, 7, 8],
         [9, 10, 11]
       ];
       testTableIndexes("grid", idxes);
 
+      idxes = [
+        [0, 1, 2],
+        [3, 4, 5],
+        [6, 7, 8],
+        [9, 10, 11]
+      ];
+      testTableIndexes("grid-rowgroups", idxes);
+
       //////////////////////////////////////////////////////////////////////////
       // a bit crazy ARIA grid
       idxes = [
         [0, 1],
         [2, 3]
       ];
       testTableIndexes("grid2", idxes);
 
@@ -46,16 +54,19 @@
 <body>
 
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=386813"
      title="support nsIAccessibleTable on ARIA grid/treegrid">Mozilla Bug 386813</a>
   <a target="_blank"
      title="nsHTMLTableCellAccessible is used in dojo's crazy ARIA grid"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=513848">Mozilla Bug 513848</a>
+  <a target="_blank"
+     title="ARIA grid with rowgroup breaks table row/col counting and indices"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=761853">Mozilla Bug 761853</a>
 
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <div role="grid" id="grid">
     <div role="row">
@@ -75,16 +86,41 @@
     </div>
     <div role="row">
       <span role="rowheader">row3</span>
       <span role="gridcell">cell5</span>
       <span role="gridcell">cell6</span>
     </div>
   </div>
 
+  <div role="grid" id="grid-rowgroups">
+    <div role="row">
+      <span role="columnheader">grid-rowgroups-col1</span>
+      <span role="columnheader">grid-rowgroups-col2</span>
+      <span role="columnheader">grid-rowgroups-col3</span>
+    </div>
+    <div role="rowgroup">
+      <div role="row">
+        <span role="rowheader">grid-rowgroups-row1</span>
+        <span role="gridcell">grid-rowgroups-cell1</span>
+        <span role="gridcell">grid-rowgroups-cell2</span>
+      </div>
+      <div role="row">
+        <span role="rowheader">grid-rowgroups-row2</span>
+        <span role="gridcell">grid-rowgroups-cell3</span>
+        <span role="gridcell">grid-rowgroups-cell4</span>
+      </div>
+    </div>
+    <div role="row">
+      <span role="rowheader">grid-rowgroups-row3</span>
+      <span role="gridcell">grid-rowgroups-cell5</span>
+      <span role="gridcell">grid-rowgroups-cell6</span>
+    </div>
+  </div>
+
   <div role="grid" id="grid2">
     <div role="row">
       <table role="presentation">
         <tr>
           <td role="columnheader">header1</td>
           <td role="columnheader">header2</td>
         </tr>
       </table>
--- a/b2g/chrome/content/settings.js
+++ b/b2g/chrome/content/settings.js
@@ -98,8 +98,11 @@ SettingsListener.observe('devtools.debug
 SettingsListener.observe('devtools.debugger.force-local', true, function(value) {
   Services.prefs.setBoolPref('devtools.debugger.force-local', value);
 });
 
 SettingsListener.observe('debug.log-animations.enabled', false, function(value) {
   Services.prefs.setBoolPref('layers.offmainthreadcomposition.log-animations', value);
 });
 
+SettingsListener.observe('debug.dev-mode', false, function(value) {
+  Services.prefs.setBoolPref('dom.mozApps.dev_mode', value);
+});
--- a/b2g/components/MozKeyboard.js
+++ b/b2g/components/MozKeyboard.js
@@ -8,20 +8,16 @@ const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 const kFormsFrameScript = "chrome://browser/content/forms.js";
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/ObjectWrapper.jsm");
 
-const messageManager = Cc["@mozilla.org/globalmessagemanager;1"]
-                         .getService(Ci.nsIMessageBroadcaster);
-
-
 // -----------------------------------------------------------------------
 // MozKeyboard
 // -----------------------------------------------------------------------
 
 function MozKeyboard() { } 
 
 MozKeyboard.prototype = {
   classID: Components.ID("{397a7fdf-2254-47be-b74e-76625a1a66d5}"),
@@ -34,60 +30,59 @@ MozKeyboard.prototype = {
     "classID": Components.ID("{397a7fdf-2254-47be-b74e-76625a1a66d5}"),
     "contractID": "@mozilla.org/b2g-keyboard;1",
     "interfaces": [Ci.nsIB2GKeyboard],
     "flags": Ci.nsIClassInfo.DOM_OBJECT,
     "classDescription": "B2G Virtual Keyboard"
   }),
 
   init: function mozKeyboardInit(win) {
-    messageManager.loadFrameScript(kFormsFrameScript, true);
-    messageManager.addMessageListener("Forms:Input", this);
-
     Services.obs.addObserver(this, "inner-window-destroyed", false);
     Services.obs.addObserver(this, 'in-process-browser-frame-shown', false);
     Services.obs.addObserver(this, 'remote-browser-frame-shown', false);
 
     this._window = win;
     this._utils = win.QueryInterface(Ci.nsIInterfaceRequestor)
                      .getInterface(Ci.nsIDOMWindowUtils);
     this.innerWindowID = this._utils.currentInnerWindowID;
 
     this._focusHandler = null;
   },
 
   uninit: function mozKeyboardUninit() {
     Services.obs.removeObserver(this, "inner-window-destroyed");
-    messageManager.removeMessageListener("Forms:Input", this);
+    if (this._messageManager) {
+      this._messageManager.removeMessageListener("Forms:Input", this);
+    }
     this._window = null;
     this._utils = null;
     this._focusHandler = null;
   },
 
   sendKey: function mozKeyboardSendKey(keyCode, charCode) {
     charCode = (charCode == undefined) ? keyCode : charCode;
     ["keydown", "keypress", "keyup"].forEach((function sendKey(type) {
       this._utils.sendKeyEvent(type, keyCode, charCode, null);
     }).bind(this));
   },
 
   setSelectedOption: function mozKeyboardSetSelectedOption(index) {
-    messageManager.broadcastAsyncMessage("Forms:Select:Choice", {
+    this._messageManager.broadcastAsyncMessage("Forms:Select:Choice", {
       "index": index
     });
   },
 
   setValue: function mozKeyboardSetValue(value) {
-    messageManager.broadcastAsyncMessage("Forms:Input:Value", {
+    this._messageManager.broadcastAsyncMessage("Forms:Input:Value", {
       "value": value
     });
   },
 
   setSelectedOptions: function mozKeyboardSetSelectedOptions(indexes) {
-    messageManager.broadcastAsyncMessage("Forms:Select:Choice", {
+    this._messageManager.broadcastAsyncMessage("Forms:Select:Choice", {
       "indexes": indexes || []
     });
   },
 
   set onfocuschange(val) {
     this._focusHandler = val;
   },
 
@@ -117,16 +112,17 @@ MozKeyboard.prototype = {
         this.uninit();
       }
       break;
     }
     case 'remote-browser-frame-shown':
     case 'in-process-browser-frame-shown': {
       let frameLoader = subject.QueryInterface(Ci.nsIFrameLoader);
       let mm = frameLoader.messageManager;
+      this._messageManager = mm;
       mm.addMessageListener("Forms:Input", this);
       try {
         mm.loadFrameScript(kFormsFrameScript, true);
       } catch (e) {
         dump('Error loading ' + kFormsFrameScript + ' as frame script: ' + e + '\n');
       }
       break;
     }
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -155,16 +155,17 @@
 @BINPATH@/components/dom.xpt
 @BINPATH@/components/dom_activities.xpt
 @BINPATH@/components/dom_apps.xpt
 @BINPATH@/components/dom_base.xpt
 #ifdef MOZ_B2G_RIL
 @BINPATH@/components/dom_telephony.xpt
 @BINPATH@/components/dom_wifi.xpt
 @BINPATH@/components/dom_system_gonk.xpt
+@BINPATH@/components/dom_icc.xpt
 #endif
 @BINPATH@/components/dom_battery.xpt
 #ifdef MOZ_B2G_BT
 @BINPATH@/components/dom_bluetooth.xpt
 #endif
 @BINPATH@/components/dom_camera.xpt
 @BINPATH@/components/dom_canvas.xpt
 @BINPATH@/components/dom_contacts.xpt
--- a/browser/devtools/scratchpad/scratchpad.js
+++ b/browser/devtools/scratchpad/scratchpad.js
@@ -41,18 +41,21 @@ let keysbundle = Services.strings.create
 
 function SP_Pretty_Key(aElemKey) {
 
   let elemString = "";
   let elemMod = aElemKey.getAttribute("modifiers");
 
   if (elemMod.match("accel")) {
     if (navigator.platform.indexOf("Mac") !== -1) {
-      elemString += keysbundle.GetStringFromName("VK_META") +
-                    keysbundle.GetStringFromName("MODIFIER_SEPARATOR");
+      // XXX bug 779642 Use "Cmd-" literal vs cloverleaf meta-key until
+      // Orion adds variable height lines
+      // elemString += keysbundle.GetStringFromName("VK_META_CMD") +
+      //               keysbundle.GetStringFromName("MODIFIER_SEPARATOR");
+      elemString += "Cmd-";
     } else {
       elemString += keysbundle.GetStringFromName("VK_CONTROL") +
                     keysbundle.GetStringFromName("MODIFIER_SEPARATOR");
     }
   }
 
   if (elemMod.match("shift")) {
     elemString += keysbundle.GetStringFromName("VK_SHIFT") +
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -164,16 +164,17 @@
 @BINPATH@/components/dom.xpt
 @BINPATH@/components/dom_apps.xpt
 @BINPATH@/components/dom_base.xpt
 @BINPATH@/components/dom_system.xpt
 #ifdef MOZ_B2G_RIL
 @BINPATH@/components/dom_telephony.xpt
 @BINPATH@/components/dom_wifi.xpt
 @BINPATH@/components/dom_system_gonk.xpt
+@BINPATH@/components/dom_icc.xpt
 #endif
 @BINPATH@/components/dom_battery.xpt
 #ifdef MOZ_B2G_BT
 @BINPATH@/components/dom_bluetooth.xpt
 #endif
 @BINPATH@/components/dom_camera.xpt
 @BINPATH@/components/dom_canvas.xpt
 @BINPATH@/components/dom_contacts.xpt
--- a/browser/locales/en-US/searchplugins/twitter.xml
+++ b/browser/locales/en-US/searchplugins/twitter.xml
@@ -1,15 +1,15 @@
 <!-- This Source Code Form is subject to the terms of the Mozilla Public
    - License, v. 2.0. If a copy of the MPL was not distributed with this
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 
 <SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
 <ShortName>Twitter</ShortName>
 <Description>Realtime Twitter Search</Description>
 <InputEncoding>UTF-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A/v7+D/7+/j/+/v5g/v7+YP7+/mD+/v5I/v7+KP///wD///8A////AP///wD///8A////AP///wD+/v4H/v7+UPbv4pHgx47B1K9Y3tWwWN7Ur1je3sKCx+rbuKj+/v5n/v7+GP///wD///8A////AP///wD+/v4Y+fbweM2ycMe2iB7/vI0f/8STIf/KlyL/zJki/8yZIv/LmCL/0ahK5/Hp1JH+/v4Y////AP///wD///8A7OTTaquHN+CujkXPs5ZTv6N6G/+2iB7/xpUh/8yZIv/MmSL/zJki/8yZIv/Kmy738OjUi////wD///8A////AMKtfY7w6+Ef////AP///wD///8A3sqbp8iWIf/MmSL/zJki/8yZIv/MmSL/y5gi/8mePO7+/v4w////AP///wD///8A////AP///wD+/v4H/v7+V9CtWN3KmCL/zJki/8yZIv/MmSL/zJki/8yZIv/JlyH/5tSqp/7+/mD+/v4/////AP///wD///8A+PXvJtGyZdXNnS/3y5gi/8qYIv/LmCL/zJki/8yZIv/MmSL/y5gi/82iPO7LqVfe0byMmf///wD///8A/v7+D/Do1JHKmy73ypci/8KSIP+/jyD/xpQh/8uYIv/MmSL/zJki/8qYIv+/jyD/rIEd/9nKqH7///8A////APPu4TzAlSz3wZEg/7mLH/+sgR3/uZdGz7mLH//JlyH/zJki/8yZIv/GlSH/to0r9eXbxD/Vx6dg////AP7+/h/p38WhtIsq9al/HP+kfyjuybaKgf///wCzjzjlwJAg/8qYIv/JlyH/u4wf/8CkYrn///8A////AP///wDj2sRMnHUa/7meYa7Vx6dg////AP///wD///8A2MmnYK6DHf++jiD/vo4g/62CHf/k2sQ/////AP///wD///8A8OvhH/f07w////8A////AP///wD///8A////AP///wC/p3Cfpnwc/66GKvPg1LZ8////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////ANXHp2DJtoqByLWKgf///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AADgPwAAwA8AAIAHAAB4BwAA+AMAAPAAAADgAQAA4AMAAMEDAADPhwAA/48AAP/nAAD//wAA//8AAA==</Image>
+<Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAABZWlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNC40LjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iPgogICAgICAgICA8eG1wOkNyZWF0b3JUb29sPkFjb3JuIHZlcnNpb24gMy4zPC94bXA6Q3JlYXRvclRvb2w+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgqo9EsfAAACMUlEQVQ4jX2TMWtTURTHf+e+l1CTtCapLuLgoIuOolPB+AlqDekgpeDSufoFmoIfwNmtCKKmtYNUcJAGQcVBQSyFKuImOthE+9q0zXv37/ASWxvwwB3Ouefc8z/87jFJmGEAEuKImWHUmwFUPOcbBjVYT/M0h0cSkgAZdbm+LwkkO+wfPUgWAliTUCIGZE1CVYjNsL4iW25PI38NaCO7y6/kK6PBGY2XPjoANluTtvhzAUAVYrv3LsMzsgC21LrDSHGBY8MTDJdvgl4zYu/p+nGAEACvU5wenbbFVpHQ3dbMxS8Adv9HnlxmliiCeG8PnBFm8khnSeJtAJOELW1eAF5RKB4nau+APcHxCPkMsoeYy4IXwjOUD9jdfqlq+cqBAlQAPhG1L+GCHLmRKXwyRWerx8YDGCCCDMB3AGs0gvQBcyfIFy/R+Q2JT4ha6gEMeoX/cMXYSJ0azsB0vbTCVmueON4FuVSZgh7fvgkI6WyBtALAetMcDVISiX+A2Q7ZIQN8v9/frtClUIKk+0LV0bcGRv1q4pjsJTt9A3vO/i4D/1HsE2azRK0Y52YBaOAkyfU/i2onI1VLNzBu4ayL8IgukJAbzuITMFfVRGnN5puhaiQHGJdbYyQaxxhDXCZXcOnEISQxdKI1HDOaKL+x+WaouUrcF5dSiDMbBN3PiHOY/0AnChDbGBs495RqeVkgaxAcLu4POLAwrK6GgzENxHoLJajLsaqQxwqOXKbx/2zlH1DoZhoGHT3iAAAAAElFTkSuQmCC</Image>
 <SearchForm>https://twitter.com/search/</SearchForm>
 <Url type="text/html" method="GET" template="https://twitter.com/search/{searchTerms}">
   <Param name="partner" value="Firefox"/>
   <Param name="source" value="desktop-search"/>
 </Url>
 </SearchPlugin>
--- a/build/autoconf/config.status.m4
+++ b/build/autoconf/config.status.m4
@@ -8,40 +8,40 @@ define([MOZ_DIVERSION_SUBST], 11)
 dnl Replace AC_SUBST to store values in a format suitable for python.
 dnl The necessary comma after the tuple can't be put here because it
 dnl can mess around with things like:
 dnl    AC_SOMETHING(foo,AC_SUBST(),bar)
 define([AC_SUBST],
 [ifdef([AC_SUBST_$1], ,
 [define([AC_SUBST_$1], )dnl
 AC_DIVERT_PUSH(MOZ_DIVERSION_SUBST)dnl
-        (''' $1 ''', r''' [$]$1 ''')
+    (''' $1 ''', r''' [$]$1 ''')
 AC_DIVERT_POP()dnl
 ])])
 
 dnl Wrap AC_DEFINE to store values in a format suitable for python.
 dnl autoconf's AC_DEFINE still needs to be used to fill confdefs.h,
 dnl which is #included during some compile checks.
 dnl The necessary comma after the tuple can't be put here because it
 dnl can mess around with things like:
 dnl    AC_SOMETHING(foo,AC_DEFINE(),bar)
 define([_MOZ_AC_DEFINE], defn([AC_DEFINE]))
 define([AC_DEFINE],
 [cat >> confdefs.pytmp <<\EOF
-        (''' $1 ''', ifelse($#, 2, [r''' $2 '''], $#, 3, [r''' $2 '''], ' 1 '))
+    (''' $1 ''', ifelse($#, 2, [r''' $2 '''], $#, 3, [r''' $2 '''], ' 1 '))
 EOF
 ifelse($#, 2, _MOZ_AC_DEFINE([$1], [$2]), $#, 3, _MOZ_AC_DEFINE([$1], [$2], [$3]),_MOZ_AC_DEFINE([$1]))dnl
 ])
 
 dnl Wrap AC_DEFINE_UNQUOTED to store values in a format suitable for
 dnl python.
 define([_MOZ_AC_DEFINE_UNQUOTED], defn([AC_DEFINE_UNQUOTED]))
 define([AC_DEFINE_UNQUOTED],
 [cat >> confdefs.pytmp <<EOF
-        (''' $1 ''', ifelse($#, 2, [r''' $2 '''], $#, 3, [r''' $2 '''], ' 1 '))
+    (''' $1 ''', ifelse($#, 2, [r''' $2 '''], $#, 3, [r''' $2 '''], ' 1 '))
 EOF
 ifelse($#, 2, _MOZ_AC_DEFINE_UNQUOTED($1, $2), $#, 3, _MOZ_AC_DEFINE_UNQUOTED($1, $2, $3),_MOZ_AC_DEFINE_UNQUOTED($1))dnl
 ])
 
 dnl Replace AC_OUTPUT to create and call a python config.status
 define([AC_OUTPUT],
 [dnl Top source directory in Windows format (as opposed to msys format).
 WIN_TOP_SRC=
@@ -75,98 +75,100 @@ changequote(<<<, >>>)dnl
 echo creating $CONFIG_STATUS
 
 extra_python_path=${COMM_BUILD:+"'mozilla', "}
 
 cat > $CONFIG_STATUS <<EOF
 #!${PYTHON}
 # coding=$encoding
 
-import os, sys
+import os
 dnl topsrcdir is the top source directory in native form, as opposed to a
 dnl form suitable for make.
 topsrcdir = '''${WIN_TOP_SRC:-$srcdir}'''
 if not os.path.isabs(topsrcdir):
     topsrcdir = os.path.normpath(os.path.join(os.path.dirname(<<<__file__>>>), topsrcdir))
-dnl Don't rely on virtualenv here. Standalone js doesn't use it.
-sys.path.append(os.path.join(topsrcdir, ${extra_python_path}'build'))
-from ConfigStatus import config_status
 
-args = {
-    'topsrcdir': topsrcdir,
-    'topobjdir': os.path.dirname(<<<__file__>>>),
+topobjdir = os.path.dirname(<<<__file__>>>)
 
 dnl All defines and substs are stored with an additional space at the beginning
 dnl and at the end of the string, to avoid any problem with values starting or
 dnl ending with quotes.
-    'defines': [(name[1:-1], value[1:-1]) for name, value in [
+defines = [(name[1:-1], value[1:-1]) for name, value in [
 EOF
 
 dnl confdefs.pytmp contains AC_DEFINEs, in the expected format, but
 dnl lacks the final comma (see above).
 sed 's/$/,/' confdefs.pytmp >> $CONFIG_STATUS
 rm confdefs.pytmp confdefs.h
 
 cat >> $CONFIG_STATUS <<\EOF
-    ] ],
+] ]
 
-    'substs': [(name[1:-1], value[1:-1]) for name, value in [
+substs = [(name[1:-1], value[1:-1]) for name, value in [
 EOF
 
 dnl The MOZ_DIVERSION_SUBST output diversion contains AC_SUBSTs, in the
 dnl expected format, but lacks the final comma (see above).
 sed 's/$/,/' >> $CONFIG_STATUS <<EOF
 undivert(MOZ_DIVERSION_SUBST)dnl
 EOF
 
 cat >> $CONFIG_STATUS <<\EOF
-    ] ],
+] ]
 
 dnl List of files to apply AC_SUBSTs to. This is the list of files given
 dnl as an argument to AC_OUTPUT ($1)
-    'files': [
+files = [
 EOF
 
 for out in $1; do
-  echo "        '$out'," >> $CONFIG_STATUS
+  echo "    '$out'," >> $CONFIG_STATUS
 done
 
 cat >> $CONFIG_STATUS <<\EOF
-    ],
+]
 
 dnl List of header files to apply AC_DEFINEs to. This is stored in the
 dnl AC_LIST_HEADER m4 macro by AC_CONFIG_HEADER.
-    'headers': [
+headers = [
 EOF
 
 ifdef(<<<AC_LIST_HEADER>>>, <<<
 HEADERS="AC_LIST_HEADER"
 for header in $HEADERS; do
-  echo "        '$header'," >> $CONFIG_STATUS
+  echo "    '$header'," >> $CONFIG_STATUS
 done
 >>>)dnl
 
 cat >> $CONFIG_STATUS <<\EOF
-    ],
+]
 
 dnl List of AC_DEFINEs that aren't to be exposed in ALLDEFINES
-    'non_global_defines': [
+non_global_defines = [
 EOF
 
 if test -n "$_NON_GLOBAL_ACDEFINES"; then
   for var in $_NON_GLOBAL_ACDEFINES; do
-    echo "        '$var'," >> $CONFIG_STATUS
+    echo "    '$var'," >> $CONFIG_STATUS
   done
 fi
 
-cat >> $CONFIG_STATUS <<\EOF
-    ]
-}
+cat >> $CONFIG_STATUS <<EOF
+]
+
+__all__ = ['topobjdir', 'topsrcdir', 'defines', 'non_global_defines', 'substs', 'files', 'headers']
 
 dnl Do the actual work
-config_status(**args)
+if __name__ == '__main__':
+    args = dict([(name, globals()[name]) for name in __all__])
+    import sys
+dnl Don't rely on virtualenv here. Standalone js doesn't use it.
+    sys.path.append(os.path.join(topsrcdir, ${extra_python_path}'build'))
+    from ConfigStatus import config_status
+    config_status(**args)
 EOF
 changequote([, ])
 chmod +x $CONFIG_STATUS
 rm -fr confdefs* $ac_clean_files
 dnl Execute config.status, unless --no-create was passed to configure.
 test "$no_create" = yes || ${PYTHON} $CONFIG_STATUS || exit 1
 ])
--- a/build/cl.py
+++ b/build/cl.py
@@ -39,17 +39,17 @@ def InvokeClWithDependencyGeneration(cmd
         else:
             sys.stdout.write(line) # Make sure we preserve the relevant output
                                    # from cl
 
     ret = cl.wait()
     if ret != 0 or target == "":
         sys.exit(ret)
 
-    depsdir = os.path.normpath(os.path.join(os.path.dirname(target), ".deps"))
+    depsdir = os.path.normpath(os.path.join(os.curdir, ".deps"))
     depstarget = os.path.join(depsdir, depstarget)
     if not os.path.isdir(depsdir):
         try:
             os.makedirs(depsdir)
         except OSError:
             pass # This suppresses the error we get when the dir exists, at the
                  # cost of masking failure to create the directory.  We'll just
                  # die on the next line though, so it's not that much of a loss.
--- a/caps/src/nsPrincipal.cpp
+++ b/caps/src/nsPrincipal.cpp
@@ -25,16 +25,19 @@
 #include "nsContentUtils.h"
 #include "jswrapper.h"
 
 #include "nsPrincipal.h"
 
 #include "mozilla/Preferences.h"
 #include "mozilla/HashFunctions.h"
 
+#include "nsIAppsService.h"
+#include "mozIApplication.h"
+
 using namespace mozilla;
 
 static bool gCodeBasePrincipalSupport = false;
 static bool gIsObservingCodeBasePrincipalSupport = false;
 
 static bool URIIsImmutable(nsIURI* aURI)
 {
   nsCOMPtr<nsIMutable> mutableObj(do_QueryInterface(aURI));
@@ -1294,20 +1297,55 @@ nsPrincipal::Write(nsIObjectOutputStream
 
 uint16_t
 nsPrincipal::GetAppStatus()
 {
   MOZ_ASSERT(mAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID);
 
   // Installed apps have a valid app id (not NO_APP_ID or UNKNOWN_APP_ID)
   // and they are not inside a mozbrowser.
-  return mAppId != nsIScriptSecurityManager::NO_APP_ID &&
-         mAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID && !mInMozBrowser
-          ? nsIPrincipal::APP_STATUS_INSTALLED
-          : nsIPrincipal::APP_STATUS_NOT_INSTALLED;
+  if (mAppId == nsIScriptSecurityManager::NO_APP_ID ||
+      mAppId == nsIScriptSecurityManager::UNKNOWN_APP_ID || mInMozBrowser) {
+    return nsIPrincipal::APP_STATUS_NOT_INSTALLED;
+  }
+
+  nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID);
+  NS_ENSURE_TRUE(appsService, nsIPrincipal::APP_STATUS_NOT_INSTALLED);
+
+  nsCOMPtr<mozIDOMApplication> domApp;
+  appsService->GetAppByLocalId(mAppId, getter_AddRefs(domApp));
+  nsCOMPtr<mozIApplication> app = do_QueryInterface(domApp);
+  NS_ENSURE_TRUE(app, nsIPrincipal::APP_STATUS_NOT_INSTALLED);
+
+  uint16_t status = nsIPrincipal::APP_STATUS_INSTALLED;
+  NS_ENSURE_SUCCESS(app->GetAppStatus(&status),
+                    nsIPrincipal::APP_STATUS_NOT_INSTALLED);
+
+  nsCAutoString origin;
+  NS_ENSURE_SUCCESS(GetOrigin(getter_Copies(origin)),
+                    nsIPrincipal::APP_STATUS_NOT_INSTALLED);
+  nsString appOrigin;
+  NS_ENSURE_SUCCESS(app->GetOrigin(appOrigin),
+                    nsIPrincipal::APP_STATUS_NOT_INSTALLED);
+
+  // We go from string -> nsIURI -> origin to be sure we
+  // compare two punny-encoded origins.
+  nsCOMPtr<nsIURI> appURI;
+  NS_ENSURE_SUCCESS(NS_NewURI(getter_AddRefs(appURI), appOrigin),
+                    nsIPrincipal::APP_STATUS_NOT_INSTALLED);
+
+  nsCAutoString appOriginPunned;
+  NS_ENSURE_SUCCESS(GetOriginForURI(appURI, getter_Copies(appOriginPunned)),
+                    nsIPrincipal::APP_STATUS_NOT_INSTALLED);
+
+  if (!appOriginPunned.Equals(origin)) {
+    return nsIPrincipal::APP_STATUS_NOT_INSTALLED;
+  }
+
+  return status;
 }
 
 /************************************************************************************************************************/
 
 static const char EXPANDED_PRINCIPAL_SPEC[] = "[Expanded Principal]";
 
 NS_IMPL_CLASSINFO(nsExpandedPrincipal, NULL, nsIClassInfo::MAIN_THREAD_ONLY,
                   NS_EXPANDEDPRINCIPAL_CID)
--- a/caps/tests/mochitest/test_principal_extendedorigin_appid_appstatus.html
+++ b/caps/tests/mochitest/test_principal_extendedorigin_appid_appstatus.html
@@ -8,17 +8,17 @@ https://bugzilla.mozilla.org/show_bug.cg
   <title>Test for nsIPrincipal extendedOrigin, appStatus and appId</title>
   <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=758258">Mozilla Bug 758258</a>
 <p id="display"></p>
 <div id="content">
-  
+
 </div>
 <pre id="test">
 <script type="application/javascript;version=1.7">
 
 /** Test for Bug 758258 **/
 
 var Ci = Components.interfaces;
 
@@ -124,23 +124,23 @@ var gData = [
     src: "file:///tmp/",
     isapp: false,
     test: [ "eo-unique" ],
   },
   {
     app: "http://example.org/manifest.webapp",
     src: "file:///",
     isapp: true,
-    test: [ "eo-unique" ],
+    test: [ "eo-unique", "in-app-not-installed" ],
   },
   {
     app: "http://example.org/manifest.webapp",
     src: "file:///tmp/",
     isapp: true,
-    test: [ "eo-unique" ],
+    test: [ "eo-unique", "in-app-not-installed" ],
   },
   // iframe inside an app is part of the app.
   {
     app: "http://example.org/manifest.webapp",
     src: "http://example.org/",
     isapp: true,
     child: {
       src: "http://example.org/chrome/",
@@ -276,22 +276,21 @@ function checkIFrame(aFrame, data) {
        data.src.replace('file:///tmp/', 'file:///private/tmp/'),
        'the correct URL should have been loaded');
   } else {
     is(principal.URI.spec, data.src,
        'the correct URL should have been loaded');
   }
 
   if (data.isapp) {
-    is(principal.appStatus, Ci.nsIPrincipal.APP_STATUS_INSTALLED,
-       'this should be an installed app');
-    isnot(principal.appId, Ci.nsIScriptSecurityManager.NO_APP_ID,
-          "installed app should have a valid appId");
-    isnot(principal.appId, Ci.nsIScriptSecurityManager.UNKNOWN_APP_ID,
-          "installed app should have a valid appId");
+    if (data.test.indexOf("in-app-not-installed") != -1) {
+      is(principal.appStatus, Ci.nsIPrincipal.APP_STATUS_NOT_INSTALLED, 'this should not be an installed app');
+    } else {
+      is(principal.appStatus, Ci.nsIPrincipal.APP_STATUS_INSTALLED, 'this should be an installed app');
+    }
   } else {
     is(principal.appStatus, Ci.nsIPrincipal.APP_STATUS_NOT_INSTALLED,
        'this should not be an installed app');
     is(principal.appId, Ci.nsIScriptSecurityManager.NO_APP_ID,
        "principals from non-installed app should have NO_APP_ID");
   }
 
   if (!data.isapp && !data.browser) {
--- a/chrome/src/RegistryMessageUtils.h
+++ b/chrome/src/RegistryMessageUtils.h
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; 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/. */
 
 #ifndef mozilla_RegistryMessageUtils_h
 #define mozilla_RegistryMessageUtils_h
 
-#include "IPC/IPCMessageUtils.h"
+#include "ipc/IPCMessageUtils.h"
 #include "nsStringGlue.h"
 
 struct SerializedURI
 {
   nsCString spec;
   nsCString charset;
 };
 
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -1495,17 +1495,17 @@ endif
 #   a previous build in the source tree) and thus neglect to create a
 #   dependency directory in the object directory, where we really need
 #   it.
 
 $(CURDIR)/$(MDDEPDIR):
 	$(MKDIR) -p $@
 
 ifneq (,$(filter-out all chrome default export realchrome tools clean clobber clobber_all distclean realclean,$(MAKECMDGOALS)))
-MDDEPEND_FILES		:= $(strip $(wildcard $(MDDEPDIR)/*.pp))
+MDDEPEND_FILES		:= $(strip $(wildcard $(foreach file,$(OBJS) $(PROGOBJS) $(HOST_OBJS) $(HOST_PROGOBJS) $(TARGETS) $(XPIDLSRCS:.idl=.h) $(XPIDLSRCS:.idl=.xpt),$(MDDEPDIR)/$(notdir $(file)).pp) $(addprefix $(MDDEPDIR)/,$(EXTRA_MDDEPEND_FILES))))
 
 ifneq (,$(MDDEPEND_FILES))
 # The script mddepend.pl checks the dependencies and writes to stdout
 # one rule to force out-of-date objects. For example,
 #   foo.o boo.o: FORCE
 # The script has an advantage over including the *.pp files directly
 # because it handles the case when header files are removed from the build.
 # 'make' would complain that there is no way to build missing headers.
--- a/config/system-headers
+++ b/config/system-headers
@@ -1062,8 +1062,12 @@ nestegg/nestegg.h
 cubeb/cubeb.h
 #endif
 gst/gst.h
 gst/app/gstappsink.h
 gst/app/gstappsrc.h
 gst/video/video.h
 sys/msg.h
 sys/ipc.h
+sys/thr.h
+sys/user.h
+kvm.h
+spawn.h
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -1478,20 +1478,22 @@ public:
    * to nsPreloadURIs::PreloadURIs() in file nsParser.cpp whenever the
    * parser-module is linked with gklayout-module.  aCrossOriginAttr should
    * be a void string if the attr is not present.
    */
   virtual void MaybePreLoadImage(nsIURI* uri,
                                  const nsAString& aCrossOriginAttr) = 0;
 
   /**
-   * Called by nsParser to preload style sheets.  Can also be merged into
-   * the parser if and when the parser is merged with libgklayout.
+   * Called by nsParser to preload style sheets.  Can also be merged into the
+   * parser if and when the parser is merged with libgklayout.  aCrossOriginAttr
+   * should be a void string if the attr is not present.
    */
-  virtual void PreloadStyle(nsIURI* aURI, const nsAString& aCharset) = 0;
+  virtual void PreloadStyle(nsIURI* aURI, const nsAString& aCharset,
+                            const nsAString& aCrossOriginAttr) = 0;
 
   /**
    * Called by the chrome registry to load style sheets.  Can be put
    * back there if and when when that module is merged with libgklayout.
    *
    * This always does a synchronous load.  If aIsAgentSheet is true,
    * it also uses the system principal and enables unsafe rules.
    * DO NOT USE FOR UNTRUSTED CONTENT.
--- a/content/base/src/FileIOObject.cpp
+++ b/content/base/src/FileIOObject.cpp
@@ -33,25 +33,27 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(FileIOObj
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(FileIOObject,
                                                   nsDOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mProgressNotifier)
   NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(abort)
   NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(error)
   NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(progress)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mError)
+  // Can't traverse mChannel because it's a multithreaded object.
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(FileIOObject,
                                                 nsDOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mProgressNotifier)
   NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(abort)
   NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(error)
   NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(progress)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mError)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mChannel)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 FileIOObject::FileIOObject()
   : mProgressEventWasDelayed(false),
     mTimerIsActive(false),
     mReadyState(0),
     mTotal(0), mTransferred(0)
 {}
--- a/content/base/src/nsBlobProtocolHandler.cpp
+++ b/content/base/src/nsBlobProtocolHandler.cpp
@@ -168,17 +168,17 @@ nsBlobProtocolHandler::NewChannel(nsIURI
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsISupports> owner = do_QueryInterface(info->mPrincipal);
 
   nsAutoString type;
   rv = info->mFile->GetType(type);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  PRUint64 size;
+  uint64_t size;
   rv = info->mFile->GetSize(&size);
   NS_ENSURE_SUCCESS(rv, rv);
 
   channel->SetOwner(owner);
   channel->SetOriginalURI(uri);
   channel->SetContentType(NS_ConvertUTF16toUTF8(type));
   channel->SetContentLength(size);
 
--- a/content/base/src/nsContentSink.cpp
+++ b/content/base/src/nsContentSink.cpp
@@ -345,17 +345,17 @@ nsContentSink::ProcessHeaderData(nsIAtom
 }
 
 
 void
 nsContentSink::DoProcessLinkHeader()
 {
   nsAutoString value;
   mDocument->GetHeaderData(nsGkAtoms::link, value);
-  ProcessLinkHeader(nullptr, value);
+  ProcessLinkHeader(value);
 }
 
 // check whether the Link header field applies to the context resource
 // see <http://tools.ietf.org/html/rfc5988#section-5.2>
 
 bool
 nsContentSink::LinkContextIsOurDocument(const nsSubstring& aAnchor)
 {
@@ -435,18 +435,17 @@ nsContentSink::Decode5987Format(nsAStrin
   if (NS_FAILED(rv))
     return false;
 
   aEncoded = decoded;
   return true;
 }
 
 nsresult
-nsContentSink::ProcessLinkHeader(nsIContent* aElement,
-                                 const nsAString& aLinkData)
+nsContentSink::ProcessLinkHeader(const nsAString& aLinkData)
 {
   nsresult rv = NS_OK;
 
   // keep track where we are within the header field
   bool seenParameters = false;
 
   // parse link content and call process style link
   nsAutoString href;
@@ -635,17 +634,17 @@ nsContentSink::ProcessLinkHeader(nsICont
       }
     }
 
     if (endCh == kComma) {
       // hit a comma, process what we've got so far
 
       href.Trim(" \t\n\r\f"); // trim HTML5 whitespace
       if (!href.IsEmpty() && !rel.IsEmpty()) {
-        rv = ProcessLink(aElement, anchor, href, rel,
+        rv = ProcessLink(anchor, href, rel,
                          // prefer RFC 5987 variant over non-I18zed version
                          titleStar.IsEmpty() ? title : titleStar,
                          type, media);
       }
 
       href.Truncate();
       rel.Truncate();
       title.Truncate();
@@ -656,59 +655,58 @@ nsContentSink::ProcessLinkHeader(nsICont
       seenParameters = false;
     }
 
     start = ++end;
   }
                 
   href.Trim(" \t\n\r\f"); // trim HTML5 whitespace
   if (!href.IsEmpty() && !rel.IsEmpty()) {
-    rv = ProcessLink(aElement, anchor, href, rel,
+    rv = ProcessLink(anchor, href, rel,
                      // prefer RFC 5987 variant over non-I18zed version
                      titleStar.IsEmpty() ? title : titleStar,
                      type, media);
   }
 
   return rv;
 }
 
 
 nsresult
-nsContentSink::ProcessLink(nsIContent* aElement,
-                           const nsSubstring& aAnchor, const nsSubstring& aHref,
+nsContentSink::ProcessLink(const nsSubstring& aAnchor, const nsSubstring& aHref,
                            const nsSubstring& aRel, const nsSubstring& aTitle,
                            const nsSubstring& aType, const nsSubstring& aMedia)
 {
   uint32_t linkTypes = nsStyleLinkElement::ParseLinkTypes(aRel);
 
   // The link relation may apply to a different resource, specified
   // in the anchor parameter. For the link relations supported so far,
   // we simply abort if the link applies to a resource different to the
   // one we've loaded
   if (!LinkContextIsOurDocument(aAnchor)) {
     return NS_OK;
   }
   
   bool hasPrefetch = linkTypes & PREFETCH;
   // prefetch href if relation is "next" or "prefetch"
   if (hasPrefetch || (linkTypes & NEXT)) {
-    PrefetchHref(aHref, aElement, hasPrefetch);
+    PrefetchHref(aHref, nullptr, hasPrefetch);
   }
 
   if (!aHref.IsEmpty() && (linkTypes & DNS_PREFETCH)) {
     PrefetchDNS(aHref);
   }
 
   // is it a stylesheet link?
   if (!(linkTypes & STYLESHEET)) {
     return NS_OK;
   }
 
   bool isAlternate = linkTypes & ALTERNATE;
-  return ProcessStyleLink(aElement, aHref, isAlternate, aTitle, aType,
+  return ProcessStyleLink(nullptr, aHref, isAlternate, aTitle, aType,
                           aMedia);
 }
 
 nsresult
 nsContentSink::ProcessStyleLink(nsIContent* aElement,
                                 const nsSubstring& aHref,
                                 bool aAlternate,
                                 const nsSubstring& aTitle,
@@ -734,19 +732,25 @@ nsContentSink::ProcessStyleLink(nsIConte
   nsresult rv = NS_NewURI(getter_AddRefs(url), aHref, nullptr,
                           mDocument->GetDocBaseURI());
   
   if (NS_FAILED(rv)) {
     // The URI is bad, move along, don't propagate the error (for now)
     return NS_OK;
   }
 
+  NS_ASSERTION(!aElement ||
+               aElement->NodeType() == nsIDOMNode::PROCESSING_INSTRUCTION_NODE,
+               "We only expect processing instructions here");
+
   // If this is a fragment parser, we don't want to observe.
+  // We don't support CORS for processing instructions
   bool isAlternate;
   rv = mCSSLoader->LoadStyleLink(aElement, url, aTitle, aMedia, aAlternate,
+                                 CORS_NONE,
                                  mRunsToCompletion ? nullptr : this, &isAlternate);
   NS_ENSURE_SUCCESS(rv, rv);
   
   if (!isAlternate && !mRunsToCompletion) {
     ++mPendingSheetCount;
     mScriptLoader->AddExecuteBlocker();
   }
 
--- a/content/base/src/nsContentSink.h
+++ b/content/base/src/nsContentSink.h
@@ -141,19 +141,18 @@ protected:
   };
 
   nsresult Init(nsIDocument* aDoc, nsIURI* aURI,
                 nsISupports* aContainer, nsIChannel* aChannel);
 
   nsresult ProcessHTTPHeaders(nsIChannel* aChannel);
   nsresult ProcessHeaderData(nsIAtom* aHeader, const nsAString& aValue,
                              nsIContent* aContent = nullptr);
-  nsresult ProcessLinkHeader(nsIContent* aElement,
-                             const nsAString& aLinkData);
-  nsresult ProcessLink(nsIContent* aElement, const nsSubstring& aAnchor,
+  nsresult ProcessLinkHeader(const nsAString& aLinkData);
+  nsresult ProcessLink(const nsSubstring& aAnchor,
                        const nsSubstring& aHref, const nsSubstring& aRel,
                        const nsSubstring& aTitle, const nsSubstring& aType,
                        const nsSubstring& aMedia);
 
   virtual nsresult ProcessStyleLink(nsIContent* aElement,
                                     const nsSubstring& aHref,
                                     bool aAlternate,
                                     const nsSubstring& aTitle,
--- a/content/base/src/nsDOMFileReader.cpp
+++ b/content/base/src/nsDOMFileReader.cpp
@@ -57,17 +57,16 @@ using namespace mozilla;
 using mozilla::dom::FileIOObject;
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMFileReader)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMFileReader,
                                                   FileIOObject)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFile)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mPrincipal)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mChannel)
   NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(load)
   NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(loadstart)
   NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(loadend)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMFileReader,
                                                 FileIOObject)
   tmp->mResultArrayBuffer = nullptr;
@@ -333,16 +332,23 @@ nsDOMFileReader::DoOnDataAvailable(nsIRe
 
 nsresult
 nsDOMFileReader::DoOnStopRequest(nsIRequest *aRequest,
                                  nsISupports *aContext,
                                  nsresult aStatus,
                                  nsAString& aSuccessEvent,
                                  nsAString& aTerminationEvent)
 {
+  // Make sure we drop all the objects that could hold files open now.
+  nsCOMPtr<nsIChannel> channel;
+  mChannel.swap(channel);
+
+  nsCOMPtr<nsIDOMBlob> file;
+  mFile.swap(file);
+
   aSuccessEvent = NS_LITERAL_STRING(LOAD_STR);
   aTerminationEvent = NS_LITERAL_STRING(LOADEND_STR);
 
   // Clear out the data if necessary
   if (NS_FAILED(aStatus)) {
     FreeFileData();
     return NS_OK;
   }
@@ -352,17 +358,17 @@ nsDOMFileReader::DoOnStopRequest(nsIRequ
     case FILE_AS_ARRAYBUFFER:
       break; //Already accumulated mResultArrayBuffer
     case FILE_AS_BINARY:
       break; //Already accumulated mResult
     case FILE_AS_TEXT:
       rv = GetAsText(mCharset, mFileData, mDataLen, mResult);
       break;
     case FILE_AS_DATAURL:
-      rv = GetAsDataURL(mFile, mFileData, mDataLen, mResult);
+      rv = GetAsDataURL(file, mFileData, mDataLen, mResult);
       break;
   }
   
   mResult.SetIsVoid(false);
 
   FreeFileData();
 
   return rv;
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -7757,25 +7757,27 @@ public:
   }
   NS_DECL_ISUPPORTS
 };
 NS_IMPL_ISUPPORTS1(StubCSSLoaderObserver, nsICSSLoaderObserver)
 
 }
 
 void
-nsDocument::PreloadStyle(nsIURI* uri, const nsAString& charset)
+nsDocument::PreloadStyle(nsIURI* uri, const nsAString& charset,
+                         const nsAString& aCrossOriginAttr)
 {
   // The CSSLoader will retain this object after we return.
   nsCOMPtr<nsICSSLoaderObserver> obs = new StubCSSLoaderObserver();
 
   // Charset names are always ASCII.
   CSSLoader()->LoadSheet(uri, NodePrincipal(),
                          NS_LossyConvertUTF16toASCII(charset),
-                         obs);
+                         obs,
+                         nsGenericElement::StringToCORSMode(aCrossOriginAttr));
 }
 
 nsresult
 nsDocument::LoadChromeSheetSync(nsIURI* uri, bool isAgentSheet,
                                 nsCSSStyleSheet** sheet)
 {
   return CSSLoader()->LoadSheetSync(uri, isAgentSheet, isAgentSheet, sheet);
 }
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -872,17 +872,18 @@ public:
 
   void MaybeInitializeFinalizeFrameLoaders();
 
   void MaybeEndOutermostXBLUpdate();
 
   virtual void MaybePreLoadImage(nsIURI* uri,
                                  const nsAString &aCrossOriginAttr);
 
-  virtual void PreloadStyle(nsIURI* uri, const nsAString& charset);
+  virtual void PreloadStyle(nsIURI* uri, const nsAString& charset,
+                            const nsAString& aCrossOriginAttr);
 
   virtual nsresult LoadChromeSheetSync(nsIURI* uri, bool isAgentSheet,
                                        nsCSSStyleSheet** sheet);
 
   virtual nsISupports* GetCurrentContentSink();
 
   virtual nsEventStates GetDocumentState();
 
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -817,33 +817,43 @@ nsFrameScriptExecutor::Shutdown()
 void
 nsFrameScriptExecutor::LoadFrameScriptInternal(const nsAString& aURL)
 {
   if (!mGlobal || !mCx || !sCachedScripts) {
     return;
   }
 
   nsFrameJSScriptExecutorHolder* holder = sCachedScripts->Get(aURL);
+  if (!holder) {
+    TryCacheLoadAndCompileScript(aURL, EXECUTE_IF_CANT_CACHE);
+    holder = sCachedScripts->Get(aURL);
+  }
+
   if (holder) {
     nsContentUtils::ThreadJSContextStack()->Push(mCx);
     {
       // Need to scope JSAutoRequest to happen after Push but before Pop,
       // at least for now. See bug 584673.
       JSAutoRequest ar(mCx);
       JSObject* global = nullptr;
       mGlobal->GetJSObject(&global);
       if (global) {
         (void) JS_ExecuteScript(mCx, global, holder->mScript, nullptr);
       }
     }
     JSContext* unused;
     nsContentUtils::ThreadJSContextStack()->Pop(&unused);
     return;
   }
+}
 
+void
+nsFrameScriptExecutor::TryCacheLoadAndCompileScript(const nsAString& aURL,
+                                                    CacheFailedBehavior aBehavior)
+{
   nsCString url = NS_ConvertUTF16toUTF8(aURL);
   nsCOMPtr<nsIURI> uri;
   nsresult rv = NS_NewURI(getter_AddRefs(uri), url);
   if (NS_FAILED(rv)) {
     return;
   }
   
   bool hasFlags;
@@ -902,18 +912,19 @@ nsFrameScriptExecutor::LoadFrameScriptIn
           // We don't cache data: scripts!
           if (!scheme.EqualsLiteral("data")) {
             nsFrameJSScriptExecutorHolder* holder =
               new nsFrameJSScriptExecutorHolder(script);
             // Root the object also for caching.
             JS_AddNamedScriptRoot(mCx, &(holder->mScript),
                                   "Cached message manager script");
             sCachedScripts->Put(aURL, holder);
+          } else if (aBehavior == EXECUTE_IF_CANT_CACHE) {
+            (void) JS_ExecuteScript(mCx, global, script, nullptr);
           }
-          (void) JS_ExecuteScript(mCx, global, script, nullptr);
         }
       }
     } 
     JSContext* unused;
     nsContentUtils::ThreadJSContextStack()->Pop(&unused);
   }
 }
 
--- a/content/base/src/nsFrameMessageManager.h
+++ b/content/base/src/nsFrameMessageManager.h
@@ -219,16 +219,19 @@ protected:
                             mDelayedCxDestroy(false)
   { MOZ_COUNT_CTOR(nsFrameScriptExecutor); }
   ~nsFrameScriptExecutor()
   { MOZ_COUNT_DTOR(nsFrameScriptExecutor); }
   void DidCreateCx();
   // Call this when you want to destroy mCx.
   void DestroyCx();
   void LoadFrameScriptInternal(const nsAString& aURL);
+  enum CacheFailedBehavior { EXECUTE_IF_CANT_CACHE, DONT_EXECUTE };
+  void TryCacheLoadAndCompileScript(const nsAString& aURL,
+                                    CacheFailedBehavior aBehavior = DONT_EXECUTE);
   bool InitTabChildGlobalInternal(nsISupports* aScope);
   static void Traverse(nsFrameScriptExecutor *tmp,
                        nsCycleCollectionTraversalCallback &cb);
   nsCOMPtr<nsIXPConnectJSObjectHolder> mGlobal;
   JSContext* mCx;
   uint32_t mCxStackRefCnt;
   bool mDelayedCxDestroy;
   nsCOMPtr<nsIPrincipal> mPrincipal;
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -2268,19 +2268,19 @@ nsObjectLoadingContent::LoadFallback(Fal
 
   //
   // Fixup mFallbackType
   //
   nsCOMPtr<nsIContent> thisContent =
   do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
   NS_ASSERTION(thisContent, "must be a content");
 
-  if (!thisContent->IsHTML()) {
-    // Don't let custom fallback handlers run outside HTML
-    LOG(("OBJLC [%p]: Non-HTML content, forcing eFallbackAlternate", this));
+  if (!thisContent->IsHTML() || mContentType.IsEmpty()) {
+    // Don't let custom fallback handlers run outside HTML, tags without a
+    // determined type should always just be alternate content
     aType = eFallbackAlternate;
   }
 
   /// XXX(johns): This block is just mimicing legacy behavior, not any spec
   // Check if we have any significant content (excluding param tags) OR a
   // param named 'pluginUrl'
   bool hasAlternateContent = false;
   bool hasPluginUrl = false;
--- a/content/base/src/nsStyleLinkElement.cpp
+++ b/content/base/src/nsStyleLinkElement.cpp
@@ -271,18 +271,18 @@ nsStyleLinkElement::DoUpdateStyleSheet(n
                       aObserver, &doneLoading, &isAlternate);
   }
   else {
     // XXXbz clone the URI here to work around content policies modifying URIs.
     nsCOMPtr<nsIURI> clonedURI;
     uri->Clone(getter_AddRefs(clonedURI));
     NS_ENSURE_TRUE(clonedURI, NS_ERROR_OUT_OF_MEMORY);
     rv = doc->CSSLoader()->
-      LoadStyleLink(thisContent, clonedURI, title, media, isAlternate, aObserver,
-                    &isAlternate);
+      LoadStyleLink(thisContent, clonedURI, title, media, isAlternate,
+                    GetCORSMode(), aObserver, &isAlternate);
     if (NS_FAILED(rv)) {
       // Don't propagate LoadStyleLink() errors further than this, since some
       // consumers (e.g. nsXMLContentSink) will completely abort on innocuous
       // things like a stylesheet load being blocked by the security system.
       doneLoading = true;
       isAlternate = false;
       rv = NS_OK;
     }
--- a/content/base/src/nsStyleLinkElement.h
+++ b/content/base/src/nsStyleLinkElement.h
@@ -14,16 +14,17 @@
 #define nsStyleLinkElement_h___
 
 #include "nsCOMPtr.h"
 #include "nsIDOMLinkStyle.h"
 #include "nsIStyleSheetLinkingElement.h"
 #include "nsIStyleSheet.h"
 #include "nsIURI.h"
 #include "nsTArray.h"
+#include "mozilla/CORSMode.h"
 
 #define PREFETCH      0x00000001
 #define DNS_PREFETCH  0x00000002
 #define STYLESHEET    0x00000004
 #define NEXT          0x00000008
 #define ALTERNATE     0x00000010
 
 class nsIDocument;
@@ -71,16 +72,22 @@ protected:
   virtual already_AddRefed<nsIURI> GetStyleSheetURL(bool* aIsInline) = 0;
   virtual void GetStyleSheetInfo(nsAString& aTitle,
                                  nsAString& aType,
                                  nsAString& aMedia,
                                  bool* aIsAlternate) = 0;
 
   nsIStyleSheet* GetStyleSheet() { return mStyleSheet; }
 
+  virtual mozilla::CORSMode GetCORSMode() const
+  {
+    // Default to no CORS
+    return mozilla::CORS_NONE;
+  }
+
 private:
   /**
    * @param aOldDocument should be non-null only if we're updating because we
    *                     removed the node from the document.
    * @param aForceUpdate true will force the update even if the URI has not
    *                     changed.  This should be used in cases when something
    *                     about the content that affects the resulting sheet
    *                     changed but the URI may not have changed.
--- a/content/base/src/nsTreeSanitizer.cpp
+++ b/content/base/src/nsTreeSanitizer.cpp
@@ -1115,17 +1115,17 @@ nsTreeSanitizer::SanitizeStyleSheet(cons
                                     nsIURI* aBaseURI)
 {
   nsresult rv;
   aSanitized.Truncate();
   // aSanitized will hold the permitted CSS text.
   // -moz-binding is blacklisted.
   bool didSanitize = false;
   // Create a sheet to hold the parsed CSS
-  nsRefPtr<nsCSSStyleSheet> sheet = new nsCSSStyleSheet();
+  nsRefPtr<nsCSSStyleSheet> sheet = new nsCSSStyleSheet(CORS_NONE);
   sheet->SetURIs(aDocument->GetDocumentURI(), nullptr, aBaseURI);
   sheet->SetPrincipal(aDocument->NodePrincipal());
   // Create the CSS parser, and parse the CSS text.
   nsCSSParser parser(nullptr, sheet);
   rv = parser.ParseSheet(aOriginal, aDocument->GetDocumentURI(), aBaseURI,
                          aDocument->NodePrincipal(), 0, false);
   NS_ENSURE_SUCCESS(rv, true);
   // Mark the sheet as complete.
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -1465,17 +1465,17 @@ nsXMLHttpRequest::GetAllResponseHeaders(
     AppendASCIItoUTF16(value, aResponseHeaders);
     if (NS_SUCCEEDED(mChannel->GetContentCharset(value)) && !value.IsEmpty()) {
       aResponseHeaders.AppendLiteral(";charset=");
       AppendASCIItoUTF16(value, aResponseHeaders);
     }
     aResponseHeaders.AppendLiteral("\r\n");
   }
 
-  PRInt32 length;
+  int32_t length;
   if (NS_SUCCEEDED(mChannel->GetContentLength(&length))) {
     aResponseHeaders.AppendLiteral("Content-Length: ");
     aResponseHeaders.AppendInt(length);
     aResponseHeaders.AppendLiteral("\r\n");
   }
 }
 
 NS_IMETHODIMP
@@ -1526,17 +1526,17 @@ nsXMLHttpRequest::GetResponseHeader(cons
           !value.IsEmpty()) {
         _retval.Append(";charset=");
         _retval.Append(value);
       }
     }
 
     // Content Length:
     else if (header.LowerCaseEqualsASCII("content-length")) {
-      PRInt32 length;
+      int32_t length;
       if (NS_SUCCEEDED(mChannel->GetContentLength(&length))) {
         _retval.AppendInt(length);
       }
     }
 
     return;
   }
 
--- a/content/canvas/src/CanvasUtils.cpp
+++ b/content/canvas/src/CanvasUtils.cpp
@@ -49,19 +49,21 @@ DoDrawImageSecurityCheck(nsHTMLCanvasEle
         aCanvasElement->SetWriteOnly();
         return;
     }
 
     // No need to do a security check if the image used CORS for the load
     if (CORSUsed)
         return;
 
+    // Ignore document.domain in this check.
     bool subsumes;
     nsresult rv =
-        aCanvasElement->NodePrincipal()->Subsumes(aPrincipal, &subsumes);
+        aCanvasElement->NodePrincipal()->SubsumesIgnoringDomain(aPrincipal,
+                                                                &subsumes);
 
     if (NS_SUCCEEDED(rv) && subsumes) {
         // This canvas has access to that image anyway
         return;
     }
 
     aCanvasElement->SetWriteOnly();
 }
--- a/content/canvas/test/Makefile.in
+++ b/content/canvas/test/Makefile.in
@@ -52,16 +52,18 @@ MOCHITEST_FILES = \
 	test_toDataURL_lowercase_ascii.html \
 	test_toDataURL_parameters.html \
 	test_mozGetAsFile.html \
 	test_canvas_strokeStyle_getter.html \
 	test_bug613794.html \
 	test_bug753758.html \
 	test_bug764125.html \
 	test_drawImage_edge_cases.html \
+	test_drawImage_document_domain.html \
+	file_drawImage_document_domain.html \
 	$(NULL)
 
 ifneq (1_Linux,$(MOZ_SUITE)_$(OS_ARCH))
 # This test fails in Suite on Linux for some reason, disable it there
 MOCHITEST_FILES += test_2d.composite.uncovered.image.destination-atop.html
 endif
 
 # xor and lighter aren't well handled by cairo; they mostly work, but we don't want
new file mode 100644
--- /dev/null
+++ b/content/canvas/test/file_drawImage_document_domain.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+  <canvas id="c" width="1" height="1"></canvas>
+  <img id="img" src="image_green-1x1.png">
+<script>
+  window.onmessage = function(ev) {
+    if (ev.data != "start") {
+      parent.postMessage({ msg: "unknown_message", data: ev.data }, "*");
+      return;
+    }
+
+    // Set document.domain to itself, so we trigger the
+    // "set effective script origin" cases.
+    document.domain = document.domain
+    var ctx = document.getElementById("c").getContext("2d");
+    ctx.drawImage(document.getElementById("img"), 0, 0);
+    try {
+      var data = ctx.getImageData(0, 0, 1, 1).data;
+      parent.postMessage(
+        {
+          msg: "color",
+          data: "rgba(" + data[0] + ", " + data[1] + ", " + data[2] + ", " + data[3]/255 + ")"
+        },
+        "*");
+    } catch (e) {
+      parent.postMessage({ msg: "exception", data: e.toString() }, "*");
+    }
+
+    parent.postMessage({ msg: "done" }, "*");
+  }
+</script>
--- a/content/canvas/test/test_canvas.html
+++ b/content/canvas/test/test_canvas.html
@@ -16120,22 +16120,19 @@ var _thrown = undefined; try {
 <canvas id="c496" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
 <script>
 
 function test_2d_pattern_repeat_undefined() {
 
 var canvas = document.getElementById('c496');
 var ctx = canvas.getContext('2d');
 
-var undefinedHandler = IsAzureEnabled() ? todo : ok;
-
 var _thrown = undefined; try {
   ctx.createPattern(canvas, undefined);
-  // XXXbz TODO fix bug 784869
-} catch (e) { _thrown = e }; undefinedHandler(_thrown && _thrown.name == "SyntaxError" && _thrown.code == DOMException.SYNTAX_ERR, "should throw SyntaxError");
+} catch (e) { _thrown = e }; ok(_thrown && _thrown.name == "SyntaxError" && _thrown.code == DOMException.SYNTAX_ERR, "should throw SyntaxError");
 
 
 }
 </script>
 
 <!-- [[[ test_2d.pattern.repeat.unrecognised.html ]]] -->
 
 <p>Canvas test: 2d.pattern.repeat.unrecognised</p>
new file mode 100644
--- /dev/null
+++ b/content/canvas/test/test_drawImage_document_domain.html
@@ -0,0 +1,48 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=567511
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 567511</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=567511">Mozilla Bug 567511</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  <iframe src="file_drawImage_document_domain.html"></iframe>
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 567511 **/
+
+SimpleTest.waitForExplicitFinish();
+
+window.onmessage = function(ev) {
+  if (ev.data.msg == "done") {
+    SimpleTest.finish();
+  } else if (ev.data.msg == "exception") {
+    ok(false, ev.data.data);
+  } else if (ev.data.msg == "color") {
+    is(ev.data.data, "rgba(0, 255, 0, 1)", "Should get correct color");
+  } else if (ev.data.msg == "unknown_message") {
+    ok(false, "Unknown message to child: " + ev.data.data);
+  } else {
+    ok(false, "Unknown message from child: " + ev.data.msg);
+  }
+}
+
+function doTest() {
+  frames[0].postMessage("start", "*");
+}
+
+addLoadEvent(doTest);
+
+</script>
+</pre>
+</body>
+</html>
--- a/content/events/public/nsEventNameList.h
+++ b/content/events/public/nsEventNameList.h
@@ -46,16 +46,40 @@
  * Event names that are not exposed as IDL attributes at all should be
  * enclosed in NON_IDL_EVENT.  If NON_IDL_EVENT is not defined, it
  * will be defined to the empty string.
  *
  * If you change which macros event names are enclosed in, please
  * update the tests for bug 689564 and bug 659350 as needed.
  */
 
+#ifdef ID_TO_EVENT
+#ifdef EVENT
+#error "Don't define EVENT"
+#endif /* EVENT */
+#ifdef WINDOW_ONLY_EVENT
+#error "Don't define WINDOW_ONLY_EVENT"
+#endif /* WINDOW_ONLY_EVENT */
+#ifdef TOUCH_EVENT
+#error "Don't define TOUCH_EVENT"
+#endif /* TOUCH_EVENT */
+#ifdef DOCUMENT_ONLY_EVENT
+#error "Don't define DOCUMENT_ONLY_EVENT"
+#endif /* DOCUMENT_ONLY_EVENT */
+#ifdef NON_IDL_EVENT
+#error "Don't define NON_IDL_EVENT"
+#endif /* NON_IDL_EVENT */
+
+#define EVENT ID_TO_EVENT
+#define WINDOW_ONLY_EVENT ID_TO_EVENT
+#define TOUCH_EVENT ID_TO_EVENT
+#define DOCUMENT_ONLY_EVENT ID_TO_EVENT
+#define NON_IDL_EVENT ID_TO_EVENT
+#endif
+
 #ifdef DEFINED_FORWARDED_EVENT
 #error "Don't define DEFINED_FORWARDED_EVENT"
 #endif /* DEFINED_FORWARDED_EVENT */
 
 #ifndef FORWARDED_EVENT
 #define FORWARDED_EVENT EVENT
 #define DEFINED_FORWARDED_EVENT
 #endif /* FORWARDED_EVENT */
@@ -630,41 +654,54 @@ NON_IDL_EVENT(SVGScroll,
               NS_SVG_SCROLL,
               EventNameType_None,
               NS_SVG_EVENT)
 
 NON_IDL_EVENT(SVGZoom,
               NS_SVG_ZOOM,
               EventNameType_None,
               NS_SVGZOOM_EVENT)
+
+// Only map the ID to the real event name when ID_TO_EVENT is defined.
+#ifndef ID_TO_EVENT
 // This is a bit hackish, but SVG's event names are weird.
 NON_IDL_EVENT(zoom,
               NS_SVG_ZOOM,
               EventNameType_SVGSVG,
               NS_EVENT_NULL)
+#endif
+// Only map the ID to the real event name when ID_TO_EVENT is defined.
+#ifndef ID_TO_EVENT
 NON_IDL_EVENT(begin,
               NS_SMIL_BEGIN,
               EventNameType_SMIL,
               NS_EVENT_NULL)
+#endif
 NON_IDL_EVENT(beginEvent,
               NS_SMIL_BEGIN,
               EventNameType_None,
               NS_SMIL_TIME_EVENT)
+// Only map the ID to the real event name when ID_TO_EVENT is defined.
+#ifndef ID_TO_EVENT
 NON_IDL_EVENT(end,
               NS_SMIL_END,
               EventNameType_SMIL,
               NS_EVENT_NULL)
+#endif
 NON_IDL_EVENT(endEvent,
               NS_SMIL_END,
               EventNameType_None,
               NS_SMIL_TIME_EVENT)
+// Only map the ID to the real event name when ID_TO_EVENT is defined.
+#ifndef ID_TO_EVENT
 NON_IDL_EVENT(repeat,
               NS_SMIL_REPEAT,
               EventNameType_SMIL,
               NS_EVENT_NULL)
+#endif
 NON_IDL_EVENT(repeatEvent,
               NS_SMIL_REPEAT,
               EventNameType_None,
               NS_SMIL_TIME_EVENT)
 
 NON_IDL_EVENT(MozAudioAvailable,
               NS_MOZAUDIOAVAILABLE,
               EventNameType_None,
@@ -776,8 +813,16 @@ NON_IDL_EVENT(animationiteration,
 #undef DOCUMENT_ONLY_EVENT
 #endif /* DEFINED_DOCUMENT_ONLY_EVENT */
 
 #ifdef DEFINED_NON_IDL_EVENT
 #undef DEFINED_NON_IDL_EVENT
 #undef NON_IDL_EVENT
 #endif /* DEFINED_NON_IDL_EVENT */
 
+#ifdef ID_TO_EVENT
+#undef EVENT
+#undef WINDOW_ONLY_EVENT
+#undef TOUCH_EVENT
+#undef DOCUMENT_ONLY_EVENT
+#undef NON_IDL_EVENT
+#endif /* ID_TO_EVENT */
+
--- a/content/events/src/nsDOMEvent.cpp
+++ b/content/events/src/nsDOMEvent.cpp
@@ -3,17 +3,17 @@
  * 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 "base/basictypes.h"
 
 /* This must occur *after* base/basictypes.h to avoid typedefs conflicts. */
 #include "mozilla/Util.h"
 
-#include "IPC/IPCMessageUtils.h"
+#include "ipc/IPCMessageUtils.h"
 #include "nsCOMPtr.h"
 #include "nsError.h"
 #include "nsDOMEvent.h"
 #include "nsEventStateManager.h"
 #include "nsIFrame.h"
 #include "nsIContent.h"
 #include "nsIPresShell.h"
 #include "nsIDocument.h"
@@ -30,81 +30,16 @@
 #include "nsJSUtils.h"
 #include "DictionaryHelpers.h"
 #include "nsLayoutUtils.h"
 #include "nsIScrollableFrame.h"
 #include "nsDOMClassInfoID.h"
 
 using namespace mozilla;
 
-static const char* const sEventNames[] = {
-  "mousedown", "mouseup", "click", "dblclick", "mouseenter", "mouseleave", "mouseover",
-  "mouseout", "MozMouseHittest", "mousemove", "contextmenu", "keydown", "keyup", "keypress",
-  "focus", "blur", "load", "popstate", "beforescriptexecute",
-  "afterscriptexecute", "beforeunload", "unload",
-  "hashchange", "readystatechange", "abort", "error",
-  "submit", "reset", "change", "select", "input", "invalid", "text",
-  "compositionstart", "compositionend", "compositionupdate",
-  "popupshowing", "popupshown",
-  "popuphiding", "popuphidden", "close", "command", "broadcast", "commandupdate",
-  "dragenter", "dragover", "dragexit", "dragdrop", "draggesture",
-  "drag", "dragend", "dragstart", "dragleave", "drop", "resize",
-  "scroll", "overflow", "underflow", "overflowchanged",
-  "DOMSubtreeModified", "DOMNodeInserted", "DOMNodeRemoved", 
-  "DOMNodeRemovedFromDocument", "DOMNodeInsertedIntoDocument",
-  "DOMAttrModified", "DOMCharacterDataModified",
-  "DOMActivate", "DOMFocusIn", "DOMFocusOut",
-  "pageshow", "pagehide", "DOMMouseScroll", "MozMousePixelScroll", "wheel",
-  "offline", "online", "copy", "cut", "paste", "open", "message", "show",
-  "SVGLoad", "SVGUnload", "SVGAbort", "SVGError", "SVGResize", "SVGScroll",
-  "SVGZoom",
-  "beginEvent", "endEvent", "repeatEvent",
-#ifdef MOZ_MEDIA
-  "loadstart", "progress", "suspend", "emptied", "stalled", "play", "pause",
-  "loadedmetadata", "loadeddata", "waiting", "playing", "canplay",
-  "canplaythrough", "seeking", "seeked", "timeupdate", "ended", "ratechange",
-  "durationchange", "volumechange", "MozAudioAvailable",
-#endif // MOZ_MEDIA
-  "MozAfterPaint",
-  "MozBeforeResize",
-  "mozfullscreenchange",
-  "mozfullscreenerror",
-  "mozpointerlockchange",
-  "mozpointerlockerror",
-  "MozSwipeGesture",
-  "MozMagnifyGestureStart",
-  "MozMagnifyGestureUpdate",
-  "MozMagnifyGesture",
-  "MozRotateGestureStart",
-  "MozRotateGestureUpdate",
-  "MozRotateGesture",
-  "MozTapGesture",
-  "MozPressTapGesture",
-  "MozEdgeUIGesture",
-  "MozTouchDown",
-  "MozTouchMove",
-  "MozTouchUp",
-  "touchstart",
-  "touchend",
-  "touchmove",
-  "touchcancel",
-  "touchenter",
-  "touchleave",
-  "MozScrolledAreaChanged",
-  "transitionend",
-  "animationstart",
-  "animationend",
-  "animationiteration",
-  "devicemotion",
-  "deviceorientation",
-  "deviceproximity",
-  "userproximity",
-  "devicelight"
-};
-
 static char *sPopupAllowedEvents;
 
 
 nsDOMEvent::nsDOMEvent(nsPresContext* aPresContext, nsEvent* aEvent)
 {
   mPrivateDataDuplicated = false;
 
   if (aEvent) {
@@ -1231,310 +1166,20 @@ nsDOMEvent::GetClientCoords(nsPresContex
 }
 
 // To be called ONLY by nsDOMEvent::GetType (which has the additional
 // logic for handling user-defined events).
 // static
 const char* nsDOMEvent::GetEventName(uint32_t aEventType)
 {
   switch(aEventType) {
-  case NS_MOUSE_BUTTON_DOWN:
-    return sEventNames[eDOMEvents_mousedown];
-  case NS_MOUSE_BUTTON_UP:
-    return sEventNames[eDOMEvents_mouseup];
-  case NS_MOUSE_CLICK:
-    return sEventNames[eDOMEvents_click];
-  case NS_MOUSE_DOUBLECLICK:
-    return sEventNames[eDOMEvents_dblclick];
-  case NS_MOUSEENTER:
-    return sEventNames[eDOMEvents_mouseenter];
-  case NS_MOUSELEAVE:
-    return sEventNames[eDOMEvents_mouseleave];
-  case NS_MOUSE_ENTER_SYNTH:
-    return sEventNames[eDOMEvents_mouseover];
-  case NS_MOUSE_EXIT_SYNTH:
-    return sEventNames[eDOMEvents_mouseout];
-  case NS_MOUSE_MOZHITTEST:
-    return sEventNames[eDOMEvents_MozMouseHittest];
-  case NS_MOUSE_MOVE:
-    return sEventNames[eDOMEvents_mousemove];
-  case NS_KEY_UP:
-    return sEventNames[eDOMEvents_keyup];
-  case NS_KEY_DOWN:
-    return sEventNames[eDOMEvents_keydown];
-  case NS_KEY_PRESS:
-    return sEventNames[eDOMEvents_keypress];
-  case NS_COMPOSITION_START:
-    return sEventNames[eDOMEvents_compositionstart];
-  case NS_COMPOSITION_UPDATE:
-    return sEventNames[eDOMEvents_compositionupdate];
-  case NS_COMPOSITION_END:
-    return sEventNames[eDOMEvents_compositionend];
-  case NS_FOCUS_CONTENT:
-    return sEventNames[eDOMEvents_focus];
-  case NS_BLUR_CONTENT:
-    return sEventNames[eDOMEvents_blur];
-  case NS_XUL_CLOSE:
-    return sEventNames[eDOMEvents_close];
-  case NS_LOAD:
-    return sEventNames[eDOMEvents_load];
-  case NS_POPSTATE:
-    return sEventNames[eDOMEvents_popstate];
-  case NS_BEFORE_SCRIPT_EXECUTE:
-    return sEventNames[eDOMEvents_beforescriptexecute];
-  case NS_AFTER_SCRIPT_EXECUTE:
-    return sEventNames[eDOMEvents_afterscriptexecute];
-  case NS_BEFORE_PAGE_UNLOAD:
-    return sEventNames[eDOMEvents_beforeunload];
-  case NS_PAGE_UNLOAD:
-    return sEventNames[eDOMEvents_unload];
-  case NS_HASHCHANGE:
-    return sEventNames[eDOMEvents_hashchange];
-  case NS_READYSTATECHANGE:
-    return sEventNames[eDOMEvents_readystatechange];
-  case NS_IMAGE_ABORT:
-    return sEventNames[eDOMEvents_abort];
-  case NS_LOAD_ERROR:
-    return sEventNames[eDOMEvents_error];
-  case NS_FORM_SUBMIT:
-    return sEventNames[eDOMEvents_submit];
-  case NS_FORM_RESET:
-    return sEventNames[eDOMEvents_reset];
-  case NS_FORM_CHANGE:
-    return sEventNames[eDOMEvents_change];
-  case NS_FORM_SELECTED:
-    return sEventNames[eDOMEvents_select];
-  case NS_FORM_INPUT:
-    return sEventNames[eDOMEvents_input];
-  case NS_FORM_INVALID:
-    return sEventNames[eDOMEvents_invalid];
-  case NS_RESIZE_EVENT:
-    return sEventNames[eDOMEvents_resize];
-  case NS_SCROLL_EVENT:
-    return sEventNames[eDOMEvents_scroll];
-  case NS_TEXT_TEXT:
-    return sEventNames[eDOMEvents_text];
-  case NS_XUL_POPUP_SHOWING:
-    return sEventNames[eDOMEvents_popupShowing];
-  case NS_XUL_POPUP_SHOWN:
-    return sEventNames[eDOMEvents_popupShown];
-  case NS_XUL_POPUP_HIDING:
-    return sEventNames[eDOMEvents_popupHiding];
-  case NS_XUL_POPUP_HIDDEN:
-    return sEventNames[eDOMEvents_popupHidden];
-  case NS_XUL_COMMAND:
-    return sEventNames[eDOMEvents_command];
-  case NS_XUL_BROADCAST:
-    return sEventNames[eDOMEvents_broadcast];
-  case NS_XUL_COMMAND_UPDATE:
-    return sEventNames[eDOMEvents_commandupdate];
-  case NS_DRAGDROP_ENTER:
-    return sEventNames[eDOMEvents_dragenter];
-  case NS_DRAGDROP_OVER_SYNTH:
-    return sEventNames[eDOMEvents_dragover];
-  case NS_DRAGDROP_EXIT_SYNTH:
-    return sEventNames[eDOMEvents_dragexit];
-  case NS_DRAGDROP_DRAGDROP:
-    return sEventNames[eDOMEvents_dragdrop];
-  case NS_DRAGDROP_GESTURE:
-    return sEventNames[eDOMEvents_draggesture];
-  case NS_DRAGDROP_DRAG:
-    return sEventNames[eDOMEvents_drag];
-  case NS_DRAGDROP_END:
-    return sEventNames[eDOMEvents_dragend];
-  case NS_DRAGDROP_START:
-    return sEventNames[eDOMEvents_dragstart];
-  case NS_DRAGDROP_LEAVE_SYNTH:
-    return sEventNames[eDOMEvents_dragleave];
-  case NS_DRAGDROP_DROP:
-    return sEventNames[eDOMEvents_drop];
-  case NS_SCROLLPORT_OVERFLOW:
-    return sEventNames[eDOMEvents_overflow];
-  case NS_SCROLLPORT_UNDERFLOW:
-    return sEventNames[eDOMEvents_underflow];
-  case NS_SCROLLPORT_OVERFLOWCHANGED:
-    return sEventNames[eDOMEvents_overflowchanged];
-  case NS_MUTATION_SUBTREEMODIFIED:
-    return sEventNames[eDOMEvents_subtreemodified];
-  case NS_MUTATION_NODEINSERTED:
-    return sEventNames[eDOMEvents_nodeinserted];
-  case NS_MUTATION_NODEREMOVED:
-    return sEventNames[eDOMEvents_noderemoved];
-  case NS_MUTATION_NODEREMOVEDFROMDOCUMENT:
-    return sEventNames[eDOMEvents_noderemovedfromdocument];
-  case NS_MUTATION_NODEINSERTEDINTODOCUMENT:
-    return sEventNames[eDOMEvents_nodeinsertedintodocument];
-  case NS_MUTATION_ATTRMODIFIED:
-    return sEventNames[eDOMEvents_attrmodified];
-  case NS_MUTATION_CHARACTERDATAMODIFIED:
-    return sEventNames[eDOMEvents_characterdatamodified];
-  case NS_CONTEXTMENU:
-    return sEventNames[eDOMEvents_contextmenu];
-  case NS_UI_ACTIVATE:
-    return sEventNames[eDOMEvents_DOMActivate];
-  case NS_UI_FOCUSIN:
-    return sEventNames[eDOMEvents_DOMFocusIn];
-  case NS_UI_FOCUSOUT:
-    return sEventNames[eDOMEvents_DOMFocusOut];
-  case NS_PAGE_SHOW:
-    return sEventNames[eDOMEvents_pageshow];
-  case NS_PAGE_HIDE:
-    return sEventNames[eDOMEvents_pagehide];
-  case NS_MOUSE_SCROLL:
-    return sEventNames[eDOMEvents_DOMMouseScroll];
-  case NS_MOUSE_PIXEL_SCROLL:
-    return sEventNames[eDOMEvents_MozMousePixelScroll];
-  case NS_WHEEL_WHEEL:
-    return sEventNames[eDOMEvents_wheel];
-  case NS_OFFLINE:
-    return sEventNames[eDOMEvents_offline];
-  case NS_ONLINE:
-    return sEventNames[eDOMEvents_online];
-  case NS_COPY:
-    return sEventNames[eDOMEvents_copy];
-  case NS_CUT:
-    return sEventNames[eDOMEvents_cut];
-  case NS_PASTE:
-    return sEventNames[eDOMEvents_paste];
-  case NS_OPEN:
-    return sEventNames[eDOMEvents_open];
-  case NS_MESSAGE:
-    return sEventNames[eDOMEvents_message];
-  case NS_SHOW_EVENT:
-    return sEventNames[eDOMEvents_show];
-  case NS_SVG_LOAD:
-    return sEventNames[eDOMEvents_SVGLoad];
-  case NS_SVG_UNLOAD:
-    return sEventNames[eDOMEvents_SVGUnload];
-  case NS_SVG_ABORT:
-    return sEventNames[eDOMEvents_SVGAbort];
-  case NS_SVG_ERROR:
-    return sEventNames[eDOMEvents_SVGError];
-  case NS_SVG_RESIZE:
-    return sEventNames[eDOMEvents_SVGResize];
-  case NS_SVG_SCROLL:
-    return sEventNames[eDOMEvents_SVGScroll];
-  case NS_SVG_ZOOM:
-    return sEventNames[eDOMEvents_SVGZoom];
-  case NS_TOUCH_START:
-    return sEventNames[eDOMEvents_touchstart];
-  case NS_TOUCH_MOVE:
-    return sEventNames[eDOMEvents_touchmove];
-  case NS_TOUCH_END:
-    return sEventNames[eDOMEvents_touchend];
-  case NS_TOUCH_ENTER:
-    return sEventNames[eDOMEvents_touchenter];
-  case NS_TOUCH_LEAVE:
-    return sEventNames[eDOMEvents_touchleave];
-  case NS_TOUCH_CANCEL:
-    return sEventNames[eDOMEvents_touchcancel];
-  case NS_SMIL_BEGIN:
-    return sEventNames[eDOMEvents_beginEvent];
-  case NS_SMIL_END:
-    return sEventNames[eDOMEvents_endEvent];
-  case NS_SMIL_REPEAT:
-    return sEventNames[eDOMEvents_repeatEvent];
-#ifdef MOZ_MEDIA
-  case NS_LOADSTART:
-    return sEventNames[eDOMEvents_loadstart];
-  case NS_PROGRESS:
-    return sEventNames[eDOMEvents_progress];
-  case NS_SUSPEND:
-    return sEventNames[eDOMEvents_suspend];
-  case NS_EMPTIED:
-    return sEventNames[eDOMEvents_emptied];
-  case NS_STALLED:
-    return sEventNames[eDOMEvents_stalled];
-  case NS_PLAY:
-    return sEventNames[eDOMEvents_play];
-  case NS_PAUSE:
-    return sEventNames[eDOMEvents_pause];
-  case NS_LOADEDMETADATA:
-    return sEventNames[eDOMEvents_loadedmetadata];
-  case NS_LOADEDDATA:
-    return sEventNames[eDOMEvents_loadeddata];
-  case NS_WAITING:
-    return sEventNames[eDOMEvents_waiting];
-  case NS_PLAYING:
-    return sEventNames[eDOMEvents_playing];
-  case NS_CANPLAY:
-    return sEventNames[eDOMEvents_canplay];
-  case NS_CANPLAYTHROUGH:
-    return sEventNames[eDOMEvents_canplaythrough];
-  case NS_SEEKING:
-    return sEventNames[eDOMEvents_seeking];
-  case NS_SEEKED:
-    return sEventNames[eDOMEvents_seeked];
-  case NS_TIMEUPDATE:
-    return sEventNames[eDOMEvents_timeupdate];
-  case NS_ENDED:
-    return sEventNames[eDOMEvents_ended];
-  case NS_RATECHANGE:
-    return sEventNames[eDOMEvents_ratechange];
-  case NS_DURATIONCHANGE:
-    return sEventNames[eDOMEvents_durationchange];
-  case NS_VOLUMECHANGE:
-    return sEventNames[eDOMEvents_volumechange];
-  case NS_MOZAUDIOAVAILABLE:
-    return sEventNames[eDOMEvents_mozaudioavailable];
-#endif
-  case NS_AFTERPAINT:
-    return sEventNames[eDOMEvents_afterpaint];
-  case NS_BEFORERESIZE_EVENT:
-    return sEventNames[eDOMEvents_beforeresize];
-  case NS_SIMPLE_GESTURE_SWIPE:
-    return sEventNames[eDOMEvents_MozSwipeGesture];
-  case NS_SIMPLE_GESTURE_MAGNIFY_START:
-    return sEventNames[eDOMEvents_MozMagnifyGestureStart];
-  case NS_SIMPLE_GESTURE_MAGNIFY_UPDATE:
-    return sEventNames[eDOMEvents_MozMagnifyGestureUpdate];
-  case NS_SIMPLE_GESTURE_MAGNIFY:
-    return sEventNames[eDOMEvents_MozMagnifyGesture];
-  case NS_SIMPLE_GESTURE_ROTATE_START:
-    return sEventNames[eDOMEvents_MozRotateGestureStart];
-  case NS_SIMPLE_GESTURE_ROTATE_UPDATE:
-    return sEventNames[eDOMEvents_MozRotateGestureUpdate];
-  case NS_SIMPLE_GESTURE_ROTATE:
-    return sEventNames[eDOMEvents_MozRotateGesture];
-  case NS_SIMPLE_GESTURE_TAP:
-    return sEventNames[eDOMEvents_MozTapGesture];
-  case NS_SIMPLE_GESTURE_PRESSTAP:
-    return sEventNames[eDOMEvents_MozPressTapGesture];
-  case NS_SIMPLE_GESTURE_EDGEUI:
-    return sEventNames[eDOMEvents_MozEdgeUIGesture];
-  case NS_MOZTOUCH_DOWN:
-    return sEventNames[eDOMEvents_MozTouchDown];
-  case NS_MOZTOUCH_MOVE:
-    return sEventNames[eDOMEvents_MozTouchMove];
-  case NS_MOZTOUCH_UP:
-    return sEventNames[eDOMEvents_MozTouchUp];
-  case NS_SCROLLEDAREACHANGED:
-    return sEventNames[eDOMEvents_MozScrolledAreaChanged];
-  case NS_TRANSITION_END:
-    return sEventNames[eDOMEvents_transitionend];
-  case NS_ANIMATION_START:
-    return sEventNames[eDOMEvents_animationstart];
-  case NS_ANIMATION_END:
-    return sEventNames[eDOMEvents_animationend];
-  case NS_ANIMATION_ITERATION:
-    return sEventNames[eDOMEvents_animationiteration];
-  case NS_DEVICE_MOTION:
-    return sEventNames[eDOMEvents_devicemotion];
-  case NS_DEVICE_ORIENTATION:
-    return sEventNames[eDOMEvents_deviceorientation];
-  case NS_DEVICE_PROXIMITY:
-    return sEventNames[eDOMEvents_deviceproximity];
-  case NS_USER_PROXIMITY:
-    return sEventNames[eDOMEvents_userproximity];
-  case NS_DEVICE_LIGHT:
-    return sEventNames[eDOMEvents_devicelight];
-  case NS_FULLSCREENCHANGE:
-    return sEventNames[eDOMEvents_mozfullscreenchange];
-  case NS_FULLSCREENERROR:
-    return sEventNames[eDOMEvents_mozfullscreenerror];
+#define ID_TO_EVENT(name_, _id, _type, _struct) \
+  case _id: return #name_;
+#include "nsEventNameList.h"
+#undef ID_TO_EVENT
   default:
     break;
   }
   // XXXldb We can hit this case for nsEvent objects that we didn't
   // create and that are not user defined events since this function and
   // SetEventType are incomplete.  (But fixing that requires fixing the
   // arrays in nsEventListenerManager too, since the events for which
   // this is a problem generally *are* created by nsDOMEvent.)
--- a/content/events/src/nsDOMEvent.h
+++ b/content/events/src/nsDOMEvent.h
@@ -22,170 +22,16 @@ class nsPresContext;
 struct JSContext;
 struct JSObject;
  
 class nsDOMEvent : public nsIDOMEvent,
                    public nsIJSNativeInitializer
 {
 public:
 
-  // Note: this enum must be kept in sync with sEventNames in nsDOMEvent.cpp
-  enum nsDOMEvents {
-    eDOMEvents_mousedown=0,
-    eDOMEvents_mouseup,
-    eDOMEvents_click,
-    eDOMEvents_dblclick,
-    eDOMEvents_mouseenter,
-    eDOMEvents_mouseleave,
-    eDOMEvents_mouseover,
-    eDOMEvents_mouseout,
-    eDOMEvents_MozMouseHittest,
-    eDOMEvents_mousemove,
-    eDOMEvents_contextmenu,
-    eDOMEvents_keydown,
-    eDOMEvents_keyup,
-    eDOMEvents_keypress,
-    eDOMEvents_focus,
-    eDOMEvents_blur,
-    eDOMEvents_load,
-    eDOMEvents_popstate,
-    eDOMEvents_beforescriptexecute,
-    eDOMEvents_afterscriptexecute,
-    eDOMEvents_beforeunload,
-    eDOMEvents_unload,
-    eDOMEvents_hashchange,
-    eDOMEvents_readystatechange,
-    eDOMEvents_abort,
-    eDOMEvents_error,
-    eDOMEvents_submit,
-    eDOMEvents_reset,
-    eDOMEvents_change,
-    eDOMEvents_select,
-    eDOMEvents_input,
-    eDOMEvents_invalid,
-    eDOMEvents_text,
-    eDOMEvents_compositionstart,
-    eDOMEvents_compositionend,
-    eDOMEvents_compositionupdate,
-    eDOMEvents_popupShowing,
-    eDOMEvents_popupShown,
-    eDOMEvents_popupHiding,
-    eDOMEvents_popupHidden,
-    eDOMEvents_close,
-    eDOMEvents_command,
-    eDOMEvents_broadcast,
-    eDOMEvents_commandupdate,
-    eDOMEvents_dragenter,
-    eDOMEvents_dragover,
-    eDOMEvents_dragexit,
-    eDOMEvents_dragdrop,
-    eDOMEvents_draggesture,
-    eDOMEvents_drag,
-    eDOMEvents_dragend,
-    eDOMEvents_dragstart,
-    eDOMEvents_dragleave,
-    eDOMEvents_drop,
-    eDOMEvents_resize,
-    eDOMEvents_scroll,
-    eDOMEvents_overflow,
-    eDOMEvents_underflow,
-    eDOMEvents_overflowchanged,
-    eDOMEvents_subtreemodified,
-    eDOMEvents_nodeinserted,
-    eDOMEvents_noderemoved,
-    eDOMEvents_noderemovedfromdocument,
-    eDOMEvents_nodeinsertedintodocument,
-    eDOMEvents_attrmodified,
-    eDOMEvents_characterdatamodified,
-    eDOMEvents_DOMActivate,
-    eDOMEvents_DOMFocusIn,
-    eDOMEvents_DOMFocusOut,
-    eDOMEvents_pageshow,
-    eDOMEvents_pagehide,
-    eDOMEvents_DOMMouseScroll,
-    eDOMEvents_MozMousePixelScroll,
-    eDOMEvents_wheel,
-    eDOMEvents_offline,
-    eDOMEvents_online,
-    eDOMEvents_copy,
-    eDOMEvents_cut,
-    eDOMEvents_paste,
-    eDOMEvents_open,
-    eDOMEvents_message,
-    eDOMEvents_show,
-    eDOMEvents_SVGLoad,
-    eDOMEvents_SVGUnload,
-    eDOMEvents_SVGAbort,
-    eDOMEvents_SVGError,
-    eDOMEvents_SVGResize,
-    eDOMEvents_SVGScroll,
-    eDOMEvents_SVGZoom,
-    eDOMEvents_beginEvent,
-    eDOMEvents_endEvent,
-    eDOMEvents_repeatEvent,
-#ifdef MOZ_MEDIA
-    eDOMEvents_loadstart,
-    eDOMEvents_progress,
-    eDOMEvents_suspend,
-    eDOMEvents_emptied,
-    eDOMEvents_stalled,
-    eDOMEvents_play,
-    eDOMEvents_pause,
-    eDOMEvents_loadedmetadata,
-    eDOMEvents_loadeddata,
-    eDOMEvents_waiting,
-    eDOMEvents_playing,
-    eDOMEvents_canplay,
-    eDOMEvents_canplaythrough,
-    eDOMEvents_seeking,
-    eDOMEvents_seeked,
-    eDOMEvents_timeupdate,
-    eDOMEvents_ended,
-    eDOMEvents_ratechange,
-    eDOMEvents_durationchange,
-    eDOMEvents_volumechange,
-    eDOMEvents_mozaudioavailable,
-#endif
-    eDOMEvents_afterpaint,
-    eDOMEvents_beforeresize,
-    eDOMEvents_mozfullscreenchange,
-    eDOMEvents_mozfullscreenerror,
-    eDOMEvents_mozpointerlockchange,
-    eDOMEvents_mozpointerlockerror,
-    eDOMEvents_MozSwipeGesture,
-    eDOMEvents_MozMagnifyGestureStart,
-    eDOMEvents_MozMagnifyGestureUpdate,
-    eDOMEvents_MozMagnifyGesture,
-    eDOMEvents_MozRotateGestureStart,
-    eDOMEvents_MozRotateGestureUpdate,
-    eDOMEvents_MozRotateGesture,
-    eDOMEvents_MozTapGesture,
-    eDOMEvents_MozPressTapGesture,
-    eDOMEvents_MozEdgeUIGesture,
-    eDOMEvents_MozTouchDown,
-    eDOMEvents_MozTouchMove,
-    eDOMEvents_MozTouchUp,
-    eDOMEvents_touchstart,
-    eDOMEvents_touchend,
-    eDOMEvents_touchmove,
-    eDOMEvents_touchcancel,
-    eDOMEvents_touchenter,
-    eDOMEvents_touchleave,
-    eDOMEvents_MozScrolledAreaChanged,
-    eDOMEvents_transitionend,
-    eDOMEvents_animationstart,
-    eDOMEvents_animationend,
-    eDOMEvents_animationiteration,
-    eDOMEvents_devicemotion,
-    eDOMEvents_deviceorientation,
-    eDOMEvents_deviceproximity,
-    eDOMEvents_userproximity,
-    eDOMEvents_devicelight
-  };
-
   nsDOMEvent(nsPresContext* aPresContext, nsEvent* aEvent);
   virtual ~nsDOMEvent();
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsDOMEvent, nsIDOMEvent)
 
   // nsIDOMEvent Interface
   NS_DECL_NSIDOMEVENT
--- a/content/events/src/nsDOMNotifyPaintEvent.cpp
+++ b/content/events/src/nsDOMNotifyPaintEvent.cpp
@@ -1,15 +1,15 @@
 /* -*- 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/. */
 
 #include "base/basictypes.h"
-#include "IPC/IPCMessageUtils.h"
+#include "ipc/IPCMessageUtils.h"
 #include "nsDOMNotifyPaintEvent.h"
 #include "nsContentUtils.h"
 #include "nsClientRect.h"
 #include "nsPaintRequest.h"
 #include "nsIFrame.h"
 #include "nsDOMClassInfoID.h"
 
 nsDOMNotifyPaintEvent::nsDOMNotifyPaintEvent(nsPresContext* aPresContext,
--- a/content/events/src/nsDOMScrollAreaEvent.cpp
+++ b/content/events/src/nsDOMScrollAreaEvent.cpp
@@ -1,15 +1,15 @@
 /* -*- 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/. */
 
 #include "base/basictypes.h"
-#include "IPC/IPCMessageUtils.h"
+#include "ipc/IPCMessageUtils.h"
 
 #include "nsDOMScrollAreaEvent.h"
 #include "nsGUIEvent.h"
 #include "nsClientRect.h"
 #include "nsDOMClassInfoID.h"
 #include "nsIClassInfo.h"
 #include "nsIXPCScriptable.h"
 
--- a/content/events/src/nsDOMUIEvent.cpp
+++ b/content/events/src/nsDOMUIEvent.cpp
@@ -1,15 +1,15 @@
 /* -*- 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/. */
 
 #include "base/basictypes.h"
-#include "IPC/IPCMessageUtils.h"
+#include "ipc/IPCMessageUtils.h"
 #include "nsCOMPtr.h"
 #include "nsDOMUIEvent.h"
 #include "nsIPresShell.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIDOMWindow.h"
 #include "nsIDOMNode.h"
 #include "nsIContent.h"
 #include "nsContentUtils.h"
--- a/content/html/content/src/nsHTMLLinkElement.cpp
+++ b/content/html/content/src/nsHTMLLinkElement.cpp
@@ -19,16 +19,18 @@
 #include "nsIDocument.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMEventTarget.h"
 #include "nsContentUtils.h"
 #include "nsPIDOMWindow.h"
 #include "nsAsyncDOMEvent.h"
 
 #include "Link.h"
+
+using namespace mozilla;
 using namespace mozilla::dom;
 
 class nsHTMLLinkElement : public nsGenericHTMLElement,
                           public nsIDOMHTMLLinkElement,
                           public nsILink,
                           public nsStyleLinkElement,
                           public Link
 {
@@ -58,16 +60,20 @@ public:
   NS_IMETHOD    LinkAdded();
   NS_IMETHOD    LinkRemoved();
 
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               bool aCompileEventHandlers);
   virtual void UnbindFromTree(bool aDeep = true,
                               bool aNullParent = true);
+  virtual bool ParseAttribute(int32_t aNamespaceID,
+                              nsIAtom* aAttribute,
+                              const nsAString& aValue,
+                              nsAttrValue& aResult);
   void CreateAndDispatchEvent(nsIDocument* aDoc, const nsAString& aEventName);
   nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                    const nsAString& aValue, bool aNotify)
   {
     return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify);
   }
   virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                            nsIAtom* aPrefix, const nsAString& aValue,
@@ -89,16 +95,17 @@ public:
   virtual nsXPCClassInfo* GetClassInfo();
   virtual nsIDOMNode* AsDOMNode() { return this; }
 protected:
   virtual already_AddRefed<nsIURI> GetStyleSheetURL(bool* aIsInline);
   virtual void GetStyleSheetInfo(nsAString& aTitle,
                                  nsAString& aType,
                                  nsAString& aMedia,
                                  bool* aIsAlternate);
+  virtual CORSMode GetCORSMode() const;
 protected:
   virtual void GetItemValueText(nsAString& text);
   virtual void SetItemValueText(const nsAString& text);
 };
 
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Link)
 
@@ -237,16 +244,32 @@ nsHTMLLinkElement::UnbindFromTree(bool a
   if (oldDoc) {
     oldDoc->UnregisterPendingLinkUpdate(this);
   }
   CreateAndDispatchEvent(oldDoc, NS_LITERAL_STRING("DOMLinkRemoved"));
   nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
   UpdateStyleSheetInternal(oldDoc);
 }
 
+bool
+nsHTMLLinkElement::ParseAttribute(int32_t aNamespaceID,
+                                  nsIAtom* aAttribute,
+                                  const nsAString& aValue,
+                                  nsAttrValue& aResult)
+{
+  if (aNamespaceID == kNameSpaceID_None &&
+      aAttribute == nsGkAtoms::crossorigin) {
+    ParseCORSValue(aValue, aResult);
+    return true;
+  }
+
+  return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
+                                              aResult);
+}
+
 void
 nsHTMLLinkElement::CreateAndDispatchEvent(nsIDocument* aDoc,
                                           const nsAString& aEventName)
 {
   if (!aDoc)
     return;
 
   // In the unlikely case that both rev is specified *and* rel=stylesheet,
@@ -438,16 +461,22 @@ nsHTMLLinkElement::GetStyleSheetInfo(nsA
 
   // If we get here we assume that we're loading a css file, so set the
   // type to 'text/css'
   aType.AssignLiteral("text/css");
 
   return;
 }
 
+CORSMode
+nsHTMLLinkElement::GetCORSMode() const
+{
+  return AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin)); 
+}
+
 nsEventStates
 nsHTMLLinkElement::IntrinsicState() const
 {
   return Link::LinkState() | nsGenericHTMLElement::IntrinsicState();
 }
 
 size_t
 nsHTMLLinkElement::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
--- a/content/media/MediaResource.cpp
+++ b/content/media/MediaResource.cpp
@@ -913,17 +913,18 @@ ChannelMediaResource::PossiblyResume()
   }
 }
 
 class FileMediaResource : public MediaResource
 {
 public:
   FileMediaResource(nsMediaDecoder* aDecoder, nsIChannel* aChannel, nsIURI* aURI) :
     MediaResource(aDecoder, aChannel, aURI), mSize(-1),
-    mLock("FileMediaResource.mLock")
+    mLock("FileMediaResource.mLock"),
+    mSizeInitialized(false)
   {
   }
   ~FileMediaResource()
   {
   }
 
   // Main thread
   virtual nsresult Open(nsIStreamListener** aStreamListener);
@@ -950,17 +951,21 @@ public:
   virtual void    Pin() {}
   virtual void    Unpin() {}
   virtual double  GetDownloadRate(bool* aIsReliable)
   {
     // The data's all already here
     *aIsReliable = true;
     return 100*1024*1024; // arbitray, use 100MB/s
   }
-  virtual int64_t GetLength() { return mSize; }
+  virtual int64_t GetLength() {
+    MutexAutoLock lock(mLock);
+    EnsureLengthInitialized();
+    return mSize;
+  }
   virtual int64_t GetNextCachedData(int64_t aOffset)
   {
     return (aOffset < mSize) ? aOffset : -1;
   }
   virtual int64_t GetCachedDataEnd(int64_t aOffset) { return NS_MAX(aOffset, mSize); }
   virtual bool    IsDataCachedToEndOfResource(int64_t aOffset) { return true; }
   virtual bool    IsSuspendedByCache(MediaResource** aActiveResource)
   {
@@ -969,16 +974,19 @@ public:
     }
     return false;
   }
   virtual bool    IsSuspended() { return false; }
 
   nsresult GetCachedRanges(nsTArray<MediaByteRange>& aRanges);
 
 private:
+  // Ensures mSize is initialized, if it can be.
+  void EnsureLengthInitialized();
+
   // The file size, or -1 if not known. Immutable after Open().
   int64_t mSize;
 
   // This lock handles synchronisation between calls to Close() and
   // the Read, Seek, etc calls. Close must not be called while a
   // Read or Seek is in progress since it resets various internal
   // values to null.
   // This lock protects mSeekable and mInput.
@@ -986,16 +994,21 @@ private:
 
   // Seekable stream interface to file. This can be used from any
   // thread.
   nsCOMPtr<nsISeekableStream> mSeekable;
 
   // Input stream for the media data. This can be used from any
   // thread.
   nsCOMPtr<nsIInputStream>  mInput;
+
+  // Whether we've attempted to initialize mSize. Note that mSize can be -1
+  // when mSizeInitialized is true if we tried and failed to get the size
+  // of the file.
+  bool mSizeInitialized;
 };
 
 class LoadedEvent : public nsRunnable
 {
 public:
   LoadedEvent(nsMediaDecoder* aDecoder) :
     mDecoder(aDecoder)
   {
@@ -1010,18 +1023,37 @@ public:
     mDecoder->NotifyDownloadEnded(NS_OK);
     return NS_OK;
   }
 
 private:
   nsRefPtr<nsMediaDecoder> mDecoder;
 };
 
+void FileMediaResource::EnsureLengthInitialized()
+{
+  mLock.AssertCurrentThreadOwns();
+  if (mSizeInitialized) {
+    return;
+  }
+  mSizeInitialized = true;
+  // Get the file size and inform the decoder.
+  uint64_t size;
+  nsresult res = mInput->Available(&size);
+  if (NS_SUCCEEDED(res) && size <= PR_INT64_MAX) {
+    mSize = (int64_t)size;
+    nsCOMPtr<nsIRunnable> event = new LoadedEvent(mDecoder);
+    NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
+  }
+}
+
 nsresult FileMediaResource::GetCachedRanges(nsTArray<MediaByteRange>& aRanges)
 {
+  MutexAutoLock lock(mLock);
+  EnsureLengthInitialized();
   if (mSize == -1) {
     return NS_ERROR_FAILURE;
   }
   aRanges.AppendElement(MediaByteRange(0, mSize));
   return NS_OK;
 }
 
 nsresult FileMediaResource::Open(nsIStreamListener** aStreamListener)
@@ -1066,26 +1098,16 @@ nsresult FileMediaResource::Open(nsIStre
   if (!mSeekable) {
     // XXX The file may just be a .url or similar
     // shortcut that points to a Web site. We need to fix this by
     // doing an async open and waiting until we locate the real resource,
     // then using that (if it's still a file!).
     return NS_ERROR_FAILURE;
   }
 
-  // Get the file size and inform the decoder.
-  uint64_t size;
-  rv = mInput->Available(&size);
-  NS_ENSURE_SUCCESS(rv, rv);
-  NS_ENSURE_TRUE(size <= PR_INT64_MAX, NS_ERROR_FILE_TOO_BIG);
- 
-  mSize = (int64_t)size;
-
-  nsCOMPtr<nsIRunnable> event = new LoadedEvent(mDecoder);
-  NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
   return NS_OK;
 }
 
 nsresult FileMediaResource::Close()
 {
   NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
 
   MutexAutoLock lock(mLock);
@@ -1135,16 +1157,17 @@ MediaResource* FileMediaResource::CloneD
     return nullptr;
 
   return new FileMediaResource(aDecoder, channel, mURI);
 }
 
 nsresult FileMediaResource::ReadFromCache(char* aBuffer, int64_t aOffset, uint32_t aCount)
 {
   MutexAutoLock lock(mLock);
+  EnsureLengthInitialized();
   if (!mInput || !mSeekable)
     return NS_ERROR_FAILURE;
   int64_t offset = 0;
   nsresult res = mSeekable->Tell(&offset);
   NS_ENSURE_SUCCESS(res,res);
   res = mSeekable->Seek(nsISeekableStream::NS_SEEK_SET, aOffset);
   NS_ENSURE_SUCCESS(res,res);
   uint32_t bytesRead = 0;
@@ -1164,38 +1187,41 @@ nsresult FileMediaResource::ReadFromCach
 
   // Else we succeed if the reset-seek succeeds.
   return seekres;
 }
 
 nsresult FileMediaResource::Read(char* aBuffer, uint32_t aCount, uint32_t* aBytes)
 {
   MutexAutoLock lock(mLock);
+  EnsureLengthInitialized();
   if (!mInput)
     return NS_ERROR_FAILURE;
   return mInput->Read(aBuffer, aCount, aBytes);
 }
 
 nsresult FileMediaResource::Seek(int32_t aWhence, int64_t aOffset)
 {
   NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread");
 
   MutexAutoLock lock(mLock);
   if (!mSeekable)
     return NS_ERROR_FAILURE;
+  EnsureLengthInitialized();
   return mSeekable->Seek(aWhence, aOffset);
 }
 
 int64_t FileMediaResource::Tell()
 {
   NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread");
 
   MutexAutoLock lock(mLock);
   if (!mSeekable)
     return 0;
+  EnsureLengthInitialized();
 
   int64_t offset = 0;
   mSeekable->Tell(&offset);
   return offset;
 }
 
 MediaResource*
 MediaResource::Create(nsMediaDecoder* aDecoder, nsIChannel* aChannel)
--- a/content/media/MediaStreamGraph.cpp
+++ b/content/media/MediaStreamGraph.cpp
@@ -909,20 +909,17 @@ MediaStreamGraphImpl::UpdateStreamOrderF
   if (stream->mIsOnOrderingStack) {
     for (int32_t i = aStack->Length() - 1; ; --i) {
       aStack->ElementAt(i)->AsProcessedStream()->mInCycle = true;
       if (aStack->ElementAt(i) == stream)
         break;
     }
     return;
   }
-  SourceMediaStream* s = stream->AsSourceStream();
-  if (s) {
-    DetermineWhetherStreamIsConsumed(stream);
-  }
+  DetermineWhetherStreamIsConsumed(stream);
   ProcessedMediaStream* ps = stream->AsProcessedStream();
   if (ps) {
     aStack->AppendElement(stream);
     stream->mIsOnOrderingStack = true;
     for (uint32_t i = 0; i < ps->mInputs.Length(); ++i) {
       MediaStream* source = ps->mInputs[i]->mSource;
       if (!source->mHasBeenOrdered) {
         nsRefPtr<MediaStream> s = source;
@@ -941,16 +938,17 @@ void
 MediaStreamGraphImpl::UpdateStreamOrder()
 {
   nsTArray<nsRefPtr<MediaStream> > oldStreams;
   oldStreams.SwapElements(mStreams);
   for (uint32_t i = 0; i < oldStreams.Length(); ++i) {
     MediaStream* stream = oldStreams[i];
     stream->mHasBeenOrdered = false;
     stream->mKnowIsConsumed = false;
+    stream->mIsConsumed = false;
     stream->mIsOnOrderingStack = false;
     stream->mInBlockingSet = false;
     ProcessedMediaStream* ps = stream->AsProcessedStream();
     if (ps) {
       ps->mInCycle = false;
     }
   }
 
--- a/content/media/wave/nsWaveReader.cpp
+++ b/content/media/wave/nsWaveReader.cpp
@@ -431,20 +431,22 @@ nsWaveReader::LoadFormatChunk()
 
   // RIFF chunks are always word (two byte) aligned.
   NS_ABORT_IF_FALSE(mDecoder->GetResource()->Tell() % 2 == 0,
                     "LoadFormatChunk left resource unaligned");
 
   // Make sure metadata is fairly sane.  The rate check is fairly arbitrary,
   // but the channels check is intentionally limited to mono or stereo
   // because that's what the audio backend currently supports.
+  unsigned int actualFrameSize = sampleFormat == 8 ? 1 : 2 * channels;
   if (rate < 100 || rate > 96000 ||
       channels < 1 || channels > MAX_CHANNELS ||
       (frameSize != 1 && frameSize != 2 && frameSize != 4) ||
-      (sampleFormat != 8 && sampleFormat != 16)) {
+      (sampleFormat != 8 && sampleFormat != 16) ||
+      frameSize != actualFrameSize) {
     NS_WARNING("Invalid WAVE metadata");
     return false;
   }
 
   ReentrantMonitorAutoEnter monitor(mDecoder->GetReentrantMonitor());
   mSampleRate = rate;
   mChannels = channels;
   mFrameSize = frameSize;
--- a/content/smil/nsSMILAnimationController.cpp
+++ b/content/smil/nsSMILAnimationController.cpp
@@ -353,16 +353,20 @@ nsSMILAnimationController::DoSample()
 
 void
 nsSMILAnimationController::DoSample(bool aSkipUnchangedContainers)
 {
   if (!mDocument) {
     NS_ERROR("Shouldn't be sampling after document has disconnected");
     return;
   }
+  if (mRunningSample) {
+    NS_ERROR("Shouldn't be recursively sampling");
+    return;
+  }
 
   mResampleNeeded = false;
   // Set running sample flag -- do this before flushing styles so that when we
   // flush styles we don't end up requesting extra samples
   mRunningSample = true;
   nsCOMPtr<nsIDocument> kungFuDeathGrip(mDocument);  // keeps 'this' alive too
   mDocument->FlushPendingNotifications(Flush_Style);
 
--- a/content/smil/nsSMILInstanceTime.cpp
+++ b/content/smil/nsSMILInstanceTime.cpp
@@ -162,19 +162,18 @@ nsSMILInstanceTime::IsDependentOn(const 
 
   const nsSMILInstanceTime* myBaseTime = GetBaseTime();
   if (!myBaseTime)
     return false;
 
   if (myBaseTime == &aOther)
     return true;
 
-  // mVisited is mutable
-  mozilla::AutoRestore<bool> setVisited(const_cast<nsSMILInstanceTime*>(this)->mVisited);
-  const_cast<nsSMILInstanceTime*>(this)->mVisited = true;
+  mozilla::AutoRestore<bool> setVisited(mVisited);
+  mVisited = true;
   return myBaseTime->IsDependentOn(aOther);
 }
 
 const nsSMILInstanceTime*
 nsSMILInstanceTime::GetBaseTime() const
 {
   if (!mBaseInterval) {
     return nullptr;
--- a/content/smil/nsSMILInstanceTime.h
+++ b/content/smil/nsSMILInstanceTime.h
@@ -127,17 +127,17 @@ protected:
     kFromDOM = 4,
 
     // Indicates that this instance time was used as the endpoint of an interval
     // that has been filtered or removed. However, since it is a dynamic time it
     // should be preserved and not filtered.
     kWasDynamicEndpoint = 8
   };
   uint8_t       mFlags;   // Combination of kDynamic, kMayUpdate, etc.
-  bool          mVisited; // (mutable) Cycle tracking
+  mutable bool  mVisited; // Cycle tracking
 
   // Additional reference count to determine if this instance time is currently
   // used as a fixed endpoint in any intervals. Instance times that are used in
   // this way should not be removed when the owning nsSMILTimedElement removes
   // instance times in response to a restart or in an attempt to free up memory
   // by filtering out old instance times.
   //
   // Instance times are only shared in a few cases, namely:
--- a/content/svg/content/src/nsSVGStyleElement.cpp
+++ b/content/svg/content/src/nsSVGStyleElement.cpp
@@ -6,16 +6,18 @@
 #include "nsSVGElement.h"
 #include "nsGkAtoms.h"
 #include "nsIDOMSVGStyleElement.h"
 #include "nsUnicharUtils.h"
 #include "nsIDocument.h"
 #include "nsStyleLinkElement.h"
 #include "nsContentUtils.h"
 
+using namespace mozilla;
+
 typedef nsSVGElement nsSVGStyleElementBase;
 
 class nsSVGStyleElement : public nsSVGStyleElementBase,
                           public nsIDOMSVGStyleElement,
                           public nsStyleLinkElement,
                           public nsStubMutationObserver
 {
 protected:
@@ -43,16 +45,20 @@ public:
   {
     return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify);
   }
   virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                            nsIAtom* aPrefix, const nsAString& aValue,
                            bool aNotify);
   virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
                              bool aNotify);
+  virtual bool ParseAttribute(int32_t aNamespaceID,
+                              nsIAtom* aAttribute,
+                              const nsAString& aValue,
+                              nsAttrValue& aResult);
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   // nsIMutationObserver
   NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
@@ -71,16 +77,18 @@ protected:
 
   // nsStyleLinkElement overrides
   already_AddRefed<nsIURI> GetStyleSheetURL(bool* aIsInline);
 
   void GetStyleSheetInfo(nsAString& aTitle,
                          nsAString& aType,
                          nsAString& aMedia,
                          bool* aIsAlternate);
+  virtual CORSMode GetCORSMode() const;
+
   /**
    * Common method to call from the various mutation observer methods.
    * aContent is a content node that's either the one that changed or its
    * parent; we should only respond to the change if aContent is non-anonymous.
    */
   void ContentChanged(nsIContent* aContent);
 };
 
@@ -179,16 +187,32 @@ nsSVGStyleElement::UnsetAttr(int32_t aNa
                              (aAttribute == nsGkAtoms::title ||
                               aAttribute == nsGkAtoms::media ||
                               aAttribute == nsGkAtoms::type));
   }
 
   return rv;
 }
 
+bool
+nsSVGStyleElement::ParseAttribute(int32_t aNamespaceID,
+                                  nsIAtom* aAttribute,
+                                  const nsAString& aValue,
+                                  nsAttrValue& aResult)
+{
+  if (aNamespaceID == kNameSpaceID_None &&
+      aAttribute == nsGkAtoms::crossorigin) {
+    ParseCORSValue(aValue, aResult);
+    return true;
+  }
+
+  return nsSVGStyleElementBase::ParseAttribute(aNamespaceID, aAttribute, aValue,
+                                               aResult);
+}
+
 //----------------------------------------------------------------------
 // nsIMutationObserver methods
 
 void
 nsSVGStyleElement::CharacterDataChanged(nsIDocument* aDocument,
                                         nsIContent* aContent,
                                         CharacterDataChangeInfo* aInfo)
 {
@@ -312,8 +336,14 @@ nsSVGStyleElement::GetStyleSheetInfo(nsA
 
   GetAttr(kNameSpaceID_None, nsGkAtoms::type, aType);
   if (aType.IsEmpty()) {
     aType.AssignLiteral("text/css");
   }
 
   return;
 }
+
+CORSMode
+nsSVGStyleElement::GetCORSMode() const
+{
+  return AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
+}
--- a/docshell/base/SerializedLoadContext.h
+++ b/docshell/base/SerializedLoadContext.h
@@ -3,17 +3,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef SerializedLoadContext_h
 #define SerializedLoadContext_h
 
 #include "base/basictypes.h"
-#include "IPC/IPCMessageUtils.h"
+#include "ipc/IPCMessageUtils.h"
 #include "nsILoadContext.h"
 
 /*
  *  This file contains the IPC::SerializedLoadContext class, which is used to
  *  copy data across IPDL from Child process contexts so it is available in the
  *  Parent.
  */
 
--- a/docshell/base/nsDSURIContentListener.cpp
+++ b/docshell/base/nsDSURIContentListener.cpp
@@ -255,17 +255,17 @@ nsDSURIContentListener::SetParentContent
         mParentContentListener = nullptr;
     }
     return NS_OK;
 }
 
 bool nsDSURIContentListener::CheckOneFrameOptionsPolicy(nsIRequest *request,
                                                         const nsAString& policy) {
     static const char allowFrom[] = "allow-from ";
-    const PRUint32 allowFromLen = ArrayLength(allowFrom) - 1;
+    const uint32_t allowFromLen = ArrayLength(allowFrom) - 1;
     bool isAllowFrom =
         StringHead(policy, allowFromLen).LowerCaseEqualsLiteral(allowFrom);
 
     // return early if header does not have one of the values with meaning
     if (!policy.LowerCaseEqualsLiteral("deny") &&
         !policy.LowerCaseEqualsLiteral("sameorigin") &&
         !isAllowFrom)
         return true;
--- a/dom/Makefile.in
+++ b/dom/Makefile.in
@@ -70,16 +70,17 @@ PARALLEL_DIRS += \
   workers \
   camera \
   $(NULL)
 
 ifdef MOZ_B2G_RIL
 PARALLEL_DIRS += \
   telephony \
   wifi \
+  icc \
   $(NULL)
 endif
 
 ifdef MOZ_B2G_BT
 PARALLEL_DIRS += \
   bluetooth \
   $(NULL)
 endif
--- a/dom/apps/src/AppsService.js
+++ b/dom/apps/src/AppsService.js
@@ -1,79 +1,54 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict"
 
 function debug(s) {
-  //dump("-*- AppsService: " + s + "\n");
+  //dump("-*- AppsService.js: " + s + "\n");
 }
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 const APPS_SERVICE_CID = Components.ID("{05072afa-92fe-45bf-ae22-39b69c117058}");
 
 function AppsService()
 {
   debug("AppsService Constructor");
-  this.inParent = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime)
-                  .processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
-  debug("inParent: " + this.inParent);
-  if (this.inParent) {
-    Cu.import("resource://gre/modules/Webapps.jsm");
-  } else {
-    this.cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"]
-                .getService(Ci.nsISyncMessageSender);
-  }
+  let inParent = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime)
+                   .processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
+  debug("inParent: " + inParent);
+  Cu.import(inParent ? "resource://gre/modules/Webapps.jsm" :
+                       "resource://gre/modules/AppsServiceChild.jsm");
 }
 
 AppsService.prototype = {
   getAppByManifestURL: function getAppByManifestURL(aManifestURL) {
     debug("GetAppByManifestURL( " + aManifestURL + " )");
-    if (this.inParent) {
-      return DOMApplicationRegistry.getAppByManifestURL(aManifestURL);
-    } else {
-      return this.cpmm.sendSyncMessage("WebApps:GetAppByManifestURL",
-                                       { url: aManifestURL })[0];
-    }
+    return DOMApplicationRegistry.getAppByManifestURL(aManifestURL);
   },
 
   getAppLocalIdByManifestURL: function getAppLocalIdByManifestURL(aManifestURL) {
     debug("getAppLocalIdByManifestURL( " + aManifestURL + " )");
-    if (this.inParent) {
-      return DOMApplicationRegistry.getAppLocalIdByManifestURL(aManifestURL);
-    } else {
-      let res = this.cpmm.sendSyncMessage("WebApps:GetAppLocalIdByManifestURL",
-                                          { url: aManifestURL })[0];
-      return res.id;
-    }
+    return DOMApplicationRegistry.getAppLocalIdByManifestURL(aManifestURL);
   },
 
   getAppByLocalId: function getAppByLocalId(aLocalId) {
     debug("getAppByLocalId( " + aLocalId + " )");
-    if (this.inParent) {
-      return DOMApplicationRegistry.getAppByLocalId(aLocalId);
-    } else {
-      return this.cpmm.sendSyncMessage("WebApps:GetAppByLocalId",
-                                       { id: aLocalId })[0];
-    }
+    return DOMApplicationRegistry.getAppByLocalId(aLocalId);
   },
 
   getManifestURLByLocalId: function getManifestURLByLocalId(aLocalId) {
     debug("getManifestURLByLocalId( " + aLocalId + " )");
-    if (this.inParent) {
-      return DOMApplicationRegistry.getManifestURLByLocalId(aLocalId);
-    } else {
-      return this.cpmm.sendSyncMessage("WebApps:GetManifestURLByLocalId",
-                                       { id: aLocalId })[0];
-    }
+    return DOMApplicationRegistry.getManifestURLByLocalId(aLocalId);
   },
 
   classID : APPS_SERVICE_CID,
   QueryInterface : XPCOMUtils.generateQI([Ci.nsIAppsService])
 }
 
 const NSGetFactory = XPCOMUtils.generateNSGetFactory([AppsService])
new file mode 100644
--- /dev/null
+++ b/dom/apps/src/AppsServiceChild.jsm
@@ -0,0 +1,82 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const Cu = Components.utils;
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+// This module exposes a subset of the functionnalities of the parent DOM
+// Registry to content processes, to be be used from the AppsService component.
+
+let EXPORTED_SYMBOLS = ["DOMApplicationRegistry"];
+
+Cu.import("resource://gre/modules/AppsUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+
+function debug(s) {
+  //dump("-*- AppsServiceChild.jsm: " + s + "\n");
+}
+
+let DOMApplicationRegistry = {
+  init: function init() {
+    debug("init");
+    this.cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"]
+                  .getService(Ci.nsISyncMessageSender);
+
+    ["Webapps:AddApp", "Webapps:RemoveApp"].forEach((function(aMsgName) {
+      this.cpmm.addMessageListener(aMsgName, this);
+    }).bind(this));
+
+    // We need to prime the cache with the list of apps.
+    // XXX shoud we do this async and block callers if it's not yet there?
+    this.webapps = this.cpmm.sendSyncMessage("Webapps:GetList", { })[0];
+    Services.obs.addObserver(this, "xpcom-shutdown", false);
+  },
+
+  observe: function(aSubject, aTopic, aData) {
+    // cpmm.addMessageListener causes the DOMApplicationRegistry object to live
+    // forever if we don't clean up properly.
+    this.webapps = null;
+    ["Webapps:AddApp", "Webapps:RemoveApp"].forEach((function(aMsgName) {
+      this.cpmm.removeMessageListener(aMsgName, this);
+    }).bind(this));
+  },
+
+  receiveMessage: function receiveMessage(aMessage) {
+    debug("Received " + aMessage.name + " message.");
+    let msg = aMessage.json;
+    switch (aMessage.name) {
+      case "Webapps:AddApp":
+        this.webapps[msg.id] = msg.app;
+        break;
+      case "Webapps:RemoveApp":
+        delete this.webapps[msg.id];
+        break;
+    }
+  },
+
+  getAppByManifestURL: function getAppByManifestURL(aManifestURL) {
+    debug("getAppByManifestURL " + aManifestURL);
+    return AppsUtils.getAppByManifestURL(this.webapps, aManifestURL);
+  },
+
+  getAppLocalIdByManifestURL: function getAppLocalIdByManifestURL(aManifestURL) {
+    debug("getAppLocalIdByManifestURL " + aManifestURL);
+    return AppsUtils.getAppLocalIdByManifestURL(this.webapps, aManifestURL);
+  },
+
+  getAppByLocalId: function getAppByLocalId(aLocalId) {
+    debug("getAppByLocalId " + aLocalId);
+    return AppsUtils.getAppByLocalId(this.webapps, aLocalId);
+  },
+
+  getManifestURLByLocalId: function getManifestURLByLocalId(aLocalId) {
+    debug("getManifestURLByLocalId " + aLocalId);
+    return AppsUtils.getManifestURLByLocalId(this.webapps, aLocalId);
+  }
+}
+
+DOMApplicationRegistry.init();
new file mode 100644
--- /dev/null
+++ b/dom/apps/src/AppsUtils.jsm
@@ -0,0 +1,108 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const Cu = Components.utils;
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cr = Components.results;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+
+// Shared code for AppsServiceChild.jsm and Webapps.jsm
+
+let EXPORTED_SYMBOLS = ["AppsUtils"];
+
+function debug(s) {
+  //dump("-*- AppsUtils.jsm: " + s + "\n");
+}
+
+let AppsUtils = {
+  // Clones a app, without the manifest.
+  cloneAppObject: function cloneAppObject(aApp) {
+    return {
+      installOrigin: aApp.installOrigin,
+      origin: aApp.origin,
+      receipts: aApp.receipts ? JSON.parse(JSON.stringify(aApp.receipts)) : null,
+      installTime: aApp.installTime,
+      manifestURL: aApp.manifestURL,
+      appStatus: aApp.appStatus,
+      localId: aApp.localId,
+      progress: aApp.progress || 0.0,
+      status: aApp.status || "installed"
+    };
+  },
+
+  cloneAsMozIApplication: function cloneAsMozIApplication(aApp) {
+    let res = this.cloneAppObject(aApp);
+    res.hasPermission = function(aPermission) {
+      let uri = Services.io.newURI(this.origin, null, null);
+      let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"]
+                     .getService(Ci.nsIScriptSecurityManager);
+      // This helper checks an URI inside |aApp|'s origin and part of |aApp| has a
+      // specific permission. It is not checking if browsers inside |aApp| have such
+      // permission.
+      let principal = secMan.getAppCodebasePrincipal(uri, aApp.localId,
+                                                     /*mozbrowser*/false);
+      let perm = Services.perms.testExactPermissionFromPrincipal(principal,
+                                                                 aPermission);
+      return (perm === Ci.nsIPermissionManager.ALLOW_ACTION);
+    };
+    res.QueryInterface = XPCOMUtils.generateQI([Ci.mozIDOMApplication,
+                                                Ci.mozIApplication]);
+    return res;
+  },
+
+  getAppByManifestURL: function getAppByManifestURL(aApps, aManifestURL) {
+    debug("getAppByManifestURL " + aManifestURL);
+    // This could be O(1) if |webapps| was a dictionary indexed on manifestURL
+    // which should be the unique app identifier.
+    // It's currently O(n).
+    for (let id in aApps) {
+      let app = aApps[id];
+      if (app.manifestURL == aManifestURL) {
+        return this.cloneAsMozIApplication(app);
+      }
+    }
+
+    return null;
+  },
+
+  getAppLocalIdByManifestURL: function getAppLocalIdByManifestURL(aApps, aManifestURL) {
+    debug("getAppLocalIdByManifestURL " + aManifestURL);
+    for (let id in aApps) {
+      if (aApps[id].manifestURL == aManifestURL) {
+        return aApps[id].localId;
+      }
+    }
+
+    return Ci.nsIScriptSecurityManager.NO_APP_ID;
+  },
+
+  getAppByLocalId: function getAppByLocalId(aApps, aLocalId) {
+    debug("getAppByLocalId " + aLocalId);
+    for (let id in aApps) {
+      let app = aApps[id];
+      if (app.localId == aLocalId) {
+        return this.cloneAsMozIApplication(app);
+      }
+    }
+
+    return null;
+  },
+
+  getManifestURLByLocalId: function getManifestURLByLocalId(aApps, aLocalId) {
+    debug("getManifestURLByLocalId " + aLocalId);
+    for (let id in aApps) {
+      let app = aApps[id];
+      if (app.localId == aLocalId) {
+        return app.manifestURL;
+      }
+    }
+
+    return "";
+  }
+}
--- a/dom/apps/src/Makefile.in
+++ b/dom/apps/src/Makefile.in
@@ -13,11 +13,13 @@ EXTRA_COMPONENTS = \
   AppsService.js \
   AppsService.manifest \
   Webapps.js \
   Webapps.manifest \
   $(NULL)
 
 EXTRA_PP_JS_MODULES += \
   Webapps.jsm \
+  AppsServiceChild.jsm \
+  AppsUtils.jsm \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
--- a/dom/apps/src/Webapps.jsm
+++ b/dom/apps/src/Webapps.jsm
@@ -10,16 +10,17 @@ const Ci = Components.interfaces;
 const Cr = Components.results;
 
 let EXPORTED_SYMBOLS = ["DOMApplicationRegistry", "DOMApplicationManifest"];
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/FileUtils.jsm");
 Cu.import('resource://gre/modules/ActivitiesService.jsm');
+Cu.import("resource://gre/modules/AppsUtils.jsm");
 
 const WEBAPP_RUNTIME = Services.appinfo.ID == "webapprt@mozilla.org";
 
 XPCOMUtils.defineLazyGetter(this, "NetUtil", function() {
   Cu.import("resource://gre/modules/NetUtil.jsm");
   return NetUtil;
 });
 
@@ -45,26 +46,26 @@ XPCOMUtils.defineLazyGetter(this, "msgmg
   // are in a different directory (currently the Firefox profile that installed
   // the webapp); otherwise, they're in the current profile.
   const DIRECTORY_NAME = WEBAPP_RUNTIME ? "WebappRegD" : "ProfD";
 #endif
 
 let DOMApplicationRegistry = {
   appsFile: null,
   webapps: { },
+  children: [ ],
   allAppsLaunchable: false,
 
   init: function() {
     this.messages = ["Webapps:Install", "Webapps:Uninstall",
-                    "Webapps:GetSelf",
-                    "Webapps:GetInstalled", "Webapps:GetNotInstalled",
-                    "Webapps:Launch", "Webapps:GetAll",
-                    "Webapps:InstallPackage", "Webapps:GetBasePath",
-                    "WebApps:GetAppByManifestURL", "WebApps:GetAppLocalIdByManifestURL",
-                    "WebApps:GetAppByLocalId", "WebApps:GetManifestURLByLocalId"];
+                     "Webapps:GetSelf",
+                     "Webapps:GetInstalled", "Webapps:GetNotInstalled",
+                     "Webapps:Launch", "Webapps:GetAll",
+                     "Webapps:InstallPackage", "Webapps:GetBasePath",
+                     "Webapps:GetList"];
 
     this.messages.forEach((function(msgName) {
       ppmm.addMessageListener(msgName, this);
     }).bind(this));
 
     Services.obs.addObserver(this, "xpcom-shutdown", false);
 
     this.appsFile = FileUtils.getFile(DIRECTORY_NAME,
@@ -75,16 +76,21 @@ let DOMApplicationRegistry = {
         this.webapps = aData;
         for (let id in this.webapps) {
 #ifdef MOZ_SYS_MSG
           this._processManifestForId(id);
 #endif
           if (!this.webapps[id].localId) {
             this.webapps[id].localId = this._nextLocalId();
           }
+
+          // Default to a non privileged status.
+          if (this.webapps[id].appStatus === undefined) {
+            this.webapps[id].appStatus = Ci.nsIPrincipal.APP_STATUS_INSTALLED;
+          }
         };
       }).bind(this));
     }
 
     try {
       let hosts = Services.prefs.getCharPref("dom.mozApps.whitelist");
       hosts.split(",").forEach(function(aHost) {
         Services.perms.add(Services.io.newURI(aHost, null, null),
@@ -245,28 +251,19 @@ let DOMApplicationRegistry = {
           ppmm.broadcastAsyncMessage("Webapps:GetAll:Return:KO", msg);
         break;
       case "Webapps:InstallPackage":
         this.installPackage(msg);
         break;
       case "Webapps:GetBasePath":
         return FileUtils.getFile(DIRECTORY_NAME, ["webapps"], true).path;
         break;
-      case "WebApps:GetAppByManifestURL":
-        return this.getAppByManifestURL(msg.url);
-        break;
-      case "WebApps:GetAppLocalIdByManifestURL":
-        return { id: this.getAppLocalIdByManifestURL(msg.url) };
-        break;
-      case "WebApps:GetAppByLocalId":
-        return this.getAppByLocalId(msg.id);
-        break;
-      case "WebApps:GetManifestURLByLocalId":
-        return this.getManifestURLByLocalId(msg.id);
-        break;
+      case "Webapps:GetList":
+        this.children.push(aMessage.target);
+        return this.webapps;
     }
   },
 
   _writeFile: function ss_writeFile(aFile, aData, aCallbak) {
     // Initialize the file output stream.
     let ostream = FileUtils.openSafeFileOutputStream(aFile);
 
     // Obtain a converter to convert our data to a UTF-8 encoded input stream.
@@ -277,30 +274,16 @@ let DOMApplicationRegistry = {
     // Asynchronously copy the data to the file.
     let istream = converter.convertToInputStream(aData);
     NetUtil.asyncCopy(istream, ostream, function(rc) {
       if (aCallbak)
         aCallbak();
     });
   },
 
-  // clones a app object, without the manifest
-  _cloneAppObject: function(aApp) {
-    let clone = {
-      installOrigin: aApp.installOrigin,
-      origin: aApp.origin,
-      receipts: aApp.receipts ? JSON.parse(JSON.stringify(aApp.receipts)) : null,
-      installTime: aApp.installTime,
-      manifestURL: aApp.manifestURL,
-      progress: aApp.progress || 0.0,
-      status: aApp.status || "installed"
-    };
-    return clone;
-  },
-
   denyInstall: function(aData) {
     let packageId = aData.app.packageId;
     if (packageId) {
       let dir = FileUtils.getDir("TmpD", ["webapps", packageId],
                                  true, true);
       try {
         dir.remove(true);
       } catch(e) {
@@ -326,51 +309,55 @@ let DOMApplicationRegistry = {
       localId = this._nextLocalId();
     }
 
     if (app.packageId) {
       // Override the origin with the correct id.
       app.origin = "app://" + id;
     }
 
-    let appObject = this._cloneAppObject(app);
+    let appObject = AppsUtils.cloneAppObject(app);
+    appObject.appStatus = app.appStatus || Ci.nsIPrincipal.APP_STATUS_INSTALLED;
     appObject.installTime = app.installTime = Date.now();
     let appNote = JSON.stringify(appObject);
     appNote.id = id;
 
     appObject.localId = localId;
 
     let dir = FileUtils.getDir(DIRECTORY_NAME, ["webapps", id], true, true);
     let manFile = dir.clone();
     manFile.append("manifest.webapp");
     this._writeFile(manFile, JSON.stringify(app.manifest), function() {
       // If this a packaged app, move the zip file from the temp directory,
       // and delete the temp directory.
       if (app.packageId) {
-        let appFile = FileUtils.getFile("TmpD", ["webapps", app.packageId, "application.zip"], 
+        let appFile = FileUtils.getFile("TmpD", ["webapps", app.packageId, "application.zip"],
                                         true, true);
         appFile.moveTo(dir, "application.zip");
-        let tmpDir = FileUtils.getDir("TmpD", ["webapps", app.packageId], 
+        let tmpDir = FileUtils.getDir("TmpD", ["webapps", app.packageId],
                                         true, true);
         try {
           tmpDir.remove(true);
         } catch(e) {
         }
       }
     });
     this.webapps[id] = appObject;
 
     appObject.status = "installed";
-    
+
     let manifest = new DOMApplicationManifest(app.manifest, app.origin);
 
     if (!aFromSync)
       this._saveApps((function() {
         ppmm.broadcastAsyncMessage("Webapps:Install:Return:OK", aData);
         Services.obs.notifyObservers(this, "webapps-sync-install", appNote);
+        this.children.forEach(function(aMsgMgr) {
+          aMsgMgr.broadcastAsyncMessage("Webapps:AddApp", { id: id, app: appObject });
+        });
       }).bind(this));
 
 #ifdef MOZ_SYS_MSG
     this._registerSystemMessages(id, app);
 #endif
 
     // if the manifest has an appcache_path property, use it to populate the appcache
     if (manifest.appcache_path) {
@@ -561,17 +548,17 @@ let DOMApplicationRegistry = {
     let found = false;
     for (let id in this.webapps) {
       let app = this.webapps[id];
       if (app.origin != aData.origin) {
         continue;
       }
 
       found = true;
-      let appNote = JSON.stringify(this._cloneAppObject(app));
+      let appNote = JSON.stringify(AppsUtils.cloneAppObject(app));
       appNote.id = id;
 
       this._readManifests([{ id: id }], (function unregisterManifest(aResult) {
 #ifdef MOZ_SYS_MSG
         this._unregisterActivities(aResult[0].manifest, app);
 #endif
       }).bind(this));
 
@@ -580,31 +567,34 @@ let DOMApplicationRegistry = {
         dir.remove(true);
       } catch (e) {}
 
       delete this.webapps[id];
 
       this._saveApps((function() {
         ppmm.broadcastAsyncMessage("Webapps:Uninstall:Return:OK", aData);
         Services.obs.notifyObservers(this, "webapps-sync-uninstall", appNote);
+        this.children.forEach(function(aMsgMgr) {
+          aMsgMgr.broadcastAsyncMessage("Webapps:RemoveApp", { id: id });
+        });
       }).bind(this));
     }
 
     if (!found) {
       ppmm.broadcastAsyncMessage("Webapps:Uninstall:Return:KO", aData);
     }
   },
 
   getSelf: function(aData) {
     aData.apps = [];
     let tmp = [];
     let id = this._appId(aData.origin);
 
     if (id && this._isLaunchable(this.webapps[id].origin)) {
-      let app = this._cloneAppObject(this.webapps[id]);
+      let app = AppsUtils.cloneAppObject(this.webapps[id]);
       aData.apps.push(app);
       tmp.push({ id: id });
     }
 
     this._readManifests(tmp, (function(aResult) {
       for (let i = 0; i < aResult.length; i++)
         aData.apps[i].manifest = aResult[i].manifest;
       ppmm.broadcastAsyncMessage("Webapps:GetSelf:Return:OK", aData);
@@ -613,17 +603,17 @@ let DOMApplicationRegistry = {
 
   getInstalled: function(aData) {
     aData.apps = [];
     let tmp = [];
 
     for (let id in this.webapps) {
       if (this.webapps[id].installOrigin == aData.origin &&
           this._isLaunchable(this.webapps[id].origin)) {
-        aData.apps.push(this._cloneAppObject(this.webapps[id]));
+        aData.apps.push(AppsUtils.cloneAppObject(this.webapps[id]));
         tmp.push({ id: id });
       }
     }
 
     this._readManifests(tmp, (function(aResult) {
       for (let i = 0; i < aResult.length; i++)
         aData.apps[i].manifest = aResult[i].manifest;
       ppmm.broadcastAsyncMessage("Webapps:GetInstalled:Return:OK", aData);
@@ -631,34 +621,34 @@ let DOMApplicationRegistry = {
   },
 
   getNotInstalled: function(aData) {
     aData.apps = [];
     let tmp = [];
 
     for (let id in this.webapps) {
       if (!this._isLaunchable(this.webapps[id].origin)) {
-        aData.apps.push(this._cloneAppObject(this.webapps[id]));
+        aData.apps.push(AppsUtils.cloneAppObject(this.webapps[id]));
         tmp.push({ id: id });
       }
     }
 
     this._readManifests(tmp, (function(aResult) {
       for (let i = 0; i < aResult.length; i++)
         aData.apps[i].manifest = aResult[i].manifest;
       ppmm.broadcastAsyncMessage("Webapps:GetNotInstalled:Return:OK", aData);
     }).bind(this));
   },
 
   getAll: function(aData) {
     aData.apps = [];
     let tmp = [];
 
     for (let id in this.webapps) {
-      let app = this._cloneAppObject(this.webapps[id]);
+      let app = AppsUtils.cloneAppObject(this.webapps[id]);
       if (!this._isLaunchable(app.origin))
         continue;
 
       aData.apps.push(app);
       tmp.push({ id: id });
     }
 
     this._readManifests(tmp, (function(aResult) {
@@ -687,88 +677,40 @@ let DOMApplicationRegistry = {
   itemExists: function(aId) {
     return !!this.webapps[aId];
   },
 
   getAppById: function(aId) {
     if (!this.webapps[aId])
       return null;
 
-    let app = this._cloneAppObject(this.webapps[aId]);
+    let app = AppsUtils.cloneAppObject(this.webapps[aId]);
     return app;
   },
 
   getAppByManifestURL: function(aManifestURL) {
-    // This could be O(1) if |webapps| was a dictionary indexed on manifestURL
-    // which should be the unique app identifier.
-    // It's currently O(n).
-    for (let id in this.webapps) {
-      let app = this.webapps[id];
-      if (app.manifestURL == aManifestURL) {
-        let res = this._cloneAppObject(app);
-        res.hasPermission = function(permission) {
-          let localId = DOMApplicationRegistry.getAppLocalIdByManifestURL(
-            this.manifestURL);
-          let uri = Services.io.newURI(this.manifestURL, null, null);
-          let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"]
-                       .getService(Ci.nsIScriptSecurityManager);
-          // XXX for the purposes of permissions checking, this helper
-          // should always be called on !isBrowser frames, so we
-          // assume false here.
-          let principal = secMan.getAppCodebasePrincipal(uri, localId,
-                                                         /*mozbrowser*/false);
-          let perm = Services.perms.testExactPermissionFromPrincipal(principal,
-                                                                     permission);
-          return (perm === Ci.nsIPermissionManager.ALLOW_ACTION);
-        };
-        res.QueryInterface = XPCOMUtils.generateQI([Ci.mozIDOMApplication,
-                                                    Ci.mozIApplication]);
-        return res;
-      }
-    }
-
-    return null;
+    return AppsUtils.getAppByManifestURL(this.webapps, aManifestURL);
   },
 
   getAppByLocalId: function(aLocalId) {
-    for (let id in this.webapps) {
-      let app = this.webapps[id];
-      if (app.localId == aLocalId) {
-        return this._cloneAppObject(app);
-      }
-    }
-
-    return null;
+    return AppsUtils.getAppByLocalId(this.webapps, aLocalId);
   },
 
   getManifestURLByLocalId: function(aLocalId) {
-    for (let id in this.webapps) {
-      let app = this.webapps[id];
-      if (app.localId == aLocalId) {
-        return app.manifestURL;
-      }
-    }
-
-    return null;
+    return AppsUtils.getManifestURLByLocalId(this.webapps, aLocalId);
   },
 
   getAppLocalIdByManifestURL: function(aManifestURL) {
-    for (let id in this.webapps) {
-      if (this.webapps[id].manifestURL == aManifestURL) {
-        return this.webapps[id].localId;
-      }
-    }
-
-    return Ci.nsIScriptSecurityManager.NO_APP_ID;
+    return AppsUtils.getAppLocalIdByManifestURL(this.webapps, aManifestURL);
   },
 
   getAllWithoutManifests: function(aCallback) {
     let result = {};
     for (let id in this.webapps) {
-      let app = this._cloneAppObject(this.webapps[id]);
+      let app = AppsUtils.cloneAppObject(this.webapps[id]);
       result[id] = app;
     }
     aCallback(result);
   },
 
   updateApps: function(aRecords, aCallback) {
     for (let i = 0; i < aRecords.length; i++) {
       let record = aRecords[i];
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -31,17 +31,19 @@
 #include "nsIPowerManagerService.h"
 #include "SmsManager.h"
 #include "nsISmsService.h"
 #include "mozilla/Hal.h"
 #include "nsIWebNavigation.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/StaticPtr.h"
 #include "Connection.h"
+#ifdef MOZ_B2G_RIL
 #include "MobileConnection.h"
+#endif
 #include "nsIIdleObserver.h"
 #include "nsIPermissionManager.h"
 #include "nsNetUtil.h"
 #include "nsIHttpChannel.h"
 
 #ifdef MOZ_MEDIA_NAVIGATOR
 #include "MediaManager.h"
 #endif
@@ -111,16 +113,19 @@ NS_INTERFACE_MAP_BEGIN(Navigator)
   NS_INTERFACE_MAP_ENTRY(nsIDOMMozNavigatorSms)
 #ifdef MOZ_MEDIA_NAVIGATOR
   NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorUserMedia)
 #endif
 #ifdef MOZ_B2G_RIL
   NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorTelephony)
 #endif
   NS_INTERFACE_MAP_ENTRY(nsIDOMMozNavigatorNetwork)
+#ifdef MOZ_B2G_RIL
+  NS_INTERFACE_MAP_ENTRY(nsIMozNavigatorMobileConnection)
+#endif
 #ifdef MOZ_B2G_BT
   NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorBluetooth)
 #endif
   NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorCamera)
   NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorSystemMessages)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Navigator)
 NS_INTERFACE_MAP_END
 
@@ -173,20 +178,22 @@ Navigator::Invalidate()
   }
 #endif
 
   if (mConnection) {
     mConnection->Shutdown();
     mConnection = nullptr;
   }
 
+#ifdef MOZ_B2G_RIL
   if (mMobileConnection) {
     mMobileConnection->Shutdown();
     mMobileConnection = nullptr;
   }
+#endif
 
 #ifdef MOZ_B2G_BT
   if (mBluetooth) {
     mBluetooth = nullptr;
   }
 #endif
 
   mCameraManager = nullptr;
@@ -1180,16 +1187,20 @@ Navigator::GetMozConnection(nsIDOMMozCon
     mConnection = new network::Connection();
     mConnection->Init(window);
   }
 
   NS_ADDREF(*aConnection = mConnection);
   return NS_OK;
 }
 
+#ifdef MOZ_B2G_RIL
+//*****************************************************************************
+//    Navigator::nsINavigatorMobileConnection
+//*****************************************************************************
 NS_IMETHODIMP
 Navigator::GetMozMobileConnection(nsIDOMMozMobileConnection** aMobileConnection)
 {
   *aMobileConnection = nullptr;
 
   if (!mMobileConnection) {
     nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
     NS_ENSURE_TRUE(window, NS_OK);
@@ -1210,16 +1221,17 @@ Navigator::GetMozMobileConnection(nsIDOM
 
     mMobileConnection = new network::MobileConnection();
     mMobileConnection->Init(window);
   }
 
   NS_ADDREF(*aMobileConnection = mMobileConnection);
   return NS_OK;
 }
+#endif // MOZ_B2G_RIL
 
 #ifdef MOZ_B2G_BT
 //*****************************************************************************
 //    nsNavigator::nsIDOMNavigatorBluetooth
 //*****************************************************************************
 
 NS_IMETHODIMP
 Navigator::GetMozBluetooth(nsIDOMBluetoothManager** aBluetooth)
--- a/dom/base/Navigator.h
+++ b/dom/base/Navigator.h
@@ -10,16 +10,19 @@
 #include "nsIDOMNavigator.h"
 #include "nsIDOMNavigatorGeolocation.h"
 #include "nsIDOMNavigatorDeviceStorage.h"
 #include "nsIDOMNavigatorDesktopNotification.h"
 #include "nsIDOMClientInformation.h"
 #include "nsINavigatorBattery.h"
 #include "nsIDOMNavigatorSms.h"
 #include "nsIDOMNavigatorNetwork.h"
+#ifdef MOZ_B2G_RIL
+#include "nsINavigatorMobileConnection.h"
+#endif
 #include "nsAutoPtr.h"
 #include "nsWeakReference.h"
 #include "DeviceStorage.h"
 
 class nsPluginArray;
 class nsMimeTypeArray;
 class nsGeolocation;
 class nsDesktopNotificationCenter;
@@ -57,17 +60,19 @@ class BatteryManager;
 } // namespace battery
 
 namespace sms {
 class SmsManager;
 } // namespace sms
 
 namespace network {
 class Connection;
+#ifdef MOZ_B2G_RIL
 class MobileConnection;
+#endif
 } // namespace Connection;
 
 namespace power {
 class PowerManager;
 } // namespace power
 
 class Navigator : public nsIDOMNavigator
                 , public nsIDOMClientInformation
@@ -78,16 +83,19 @@ class Navigator : public nsIDOMNavigator
                 , public nsIDOMMozNavigatorSms
 #ifdef MOZ_MEDIA_NAVIGATOR
                 , public nsIDOMNavigatorUserMedia
 #endif
 #ifdef MOZ_B2G_RIL
                 , public nsIDOMNavigatorTelephony
 #endif
                 , public nsIDOMMozNavigatorNetwork
+#ifdef MOZ_B2G_RIL
+                , public nsIMozNavigatorMobileConnection
+#endif
 #ifdef MOZ_B2G_BT
                 , public nsIDOMNavigatorBluetooth
 #endif
                 , public nsIDOMNavigatorCamera
                 , public nsIDOMNavigatorSystemMessages
 {
 public:
   Navigator(nsPIDOMWindow *aInnerWindow);
@@ -103,16 +111,19 @@ public:
   NS_DECL_NSIDOMMOZNAVIGATORSMS
 #ifdef MOZ_MEDIA_NAVIGATOR
   NS_DECL_NSIDOMNAVIGATORUSERMEDIA
 #endif
 #ifdef MOZ_B2G_RIL
   NS_DECL_NSIDOMNAVIGATORTELEPHONY
 #endif
   NS_DECL_NSIDOMMOZNAVIGATORNETWORK
+#ifdef MOZ_B2G_RIL
+  NS_DECL_NSIMOZNAVIGATORMOBILECONNECTION
+#endif
 
 #ifdef MOZ_B2G_BT
   NS_DECL_NSIDOMNAVIGATORBLUETOOTH
 #endif
   NS_DECL_NSIDOMNAVIGATORSYSTEMMESSAGES
 
   static void Init();
 
@@ -151,17 +162,19 @@ private:
   nsRefPtr<battery::BatteryManager> mBatteryManager;
   nsRefPtr<power::PowerManager> mPowerManager;
   nsRefPtr<sms::SmsManager> mSmsManager;
 #ifdef MOZ_B2G_RIL
   nsCOMPtr<nsIDOMTelephony> mTelephony;
   nsCOMPtr<nsIDOMMozVoicemail> mVoicemail;
 #endif
   nsRefPtr<network::Connection> mConnection;
+#ifdef MOZ_B2G_RIL
   nsRefPtr<network::MobileConnection> mMobileConnection;
+#endif
 #ifdef MOZ_B2G_BT
   nsCOMPtr<nsIDOMBluetoothManager> mBluetooth;
 #endif
   nsRefPtr<nsDOMCameraManager> mCameraManager;
   nsCOMPtr<nsIDOMNavigatorSystemMessages> mMessagesManager;
   nsTArray<nsRefPtr<nsDOMDeviceStorage> > mDeviceStorageStores;
   nsWeakPtr mWindow;
 };
--- a/dom/base/ScreenOrientation.h
+++ b/dom/base/ScreenOrientation.h
@@ -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/. */
 
 #ifndef mozilla_dom_ScreenOrientation_h
 #define mozilla_dom_ScreenOrientation_h
 
-#include "IPC/IPCMessageUtils.h"
+#include "ipc/IPCMessageUtils.h"
 
 namespace mozilla {
 namespace dom {
 
 // Make sure that any change here is also made in
 // * mobile/android/base/GeckoScreenOrientationListener.java
 // * embedding/android/GeckoScreenOrientationListener.java
 enum ScreenOrientation {
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -496,26 +496,30 @@ using mozilla::dom::indexedDB::IDBWrappe
 #include "nsIDOMWakeLock.h"
 #include "nsIDOMSmsManager.h"
 #include "nsIDOMSmsMessage.h"
 #include "nsIDOMSmsEvent.h"
 #include "nsIDOMSmsRequest.h"
 #include "nsIDOMSmsFilter.h"
 #include "nsIDOMSmsCursor.h"
 #include "nsIDOMConnection.h"
+#ifdef MOZ_B2G_RIL
 #include "nsIDOMMobileConnection.h"
+#endif
 #include "USSDReceivedEvent.h"
 #include "mozilla/dom/network/Utils.h"
 
 #ifdef MOZ_B2G_RIL
 #include "Telephony.h"
 #include "TelephonyCall.h"
 #include "CallEvent.h"
 #include "nsIDOMVoicemail.h"
 #include "nsIDOMVoicemailEvent.h"
+#include "nsIDOMIccManager.h"
+#include "StkCommandEvent.h"
 #endif
 
 #ifdef MOZ_B2G_BT
 #include "BluetoothManager.h"
 #include "BluetoothAdapter.h"
 #include "BluetoothDevice.h"
 #include "BluetoothPropertyEvent.h"
 #endif
@@ -1485,18 +1489,20 @@ static nsDOMClassInfoData sClassInfoData
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(MozSmsCursor, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(MozConnection, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
+#ifdef MOZ_B2G_RIL
   NS_DEFINE_CLASSINFO_DATA(MozMobileConnection, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
+#endif
 
   NS_DEFINE_CLASSINFO_DATA(USSDReceivedEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(CSSFontFaceRule, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(CSSFontFaceStyleDecl, nsCSSStyleDeclSH,
                            ARRAY_SCRIPTABLE_FLAGS)
@@ -1671,16 +1677,20 @@ static nsDOMClassInfoData sClassInfoData
   NS_DEFINE_CLASSINFO_DATA(TelephonyCall, nsEventTargetSH,
                            EVENTTARGET_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(CallEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(MozVoicemail, nsEventTargetSH,
                            EVENTTARGET_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(MozVoicemailEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(MozIccManager, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(MozStkCommandEvent, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
 #endif
 
 #ifdef MOZ_B2G_BT
   NS_DEFINE_CLASSINFO_DATA(BluetoothManager, nsEventTargetSH,
                            EVENTTARGET_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(BluetoothAdapter, nsEventTargetSH,
                            EVENTTARGET_SCRIPTABLE_FLAGS)  
   NS_DEFINE_CLASSINFO_DATA(BluetoothDevice, nsEventTargetSH,
@@ -2481,16 +2491,19 @@ nsDOMClassInfo::Init()
 #ifdef MOZ_MEDIA_NAVIGATOR
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNavigatorUserMedia)
 #endif
 #ifdef MOZ_B2G_RIL
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNavigatorTelephony)
 #endif
     DOM_CLASSINFO_MAP_CONDITIONAL_ENTRY(nsIDOMMozNavigatorNetwork,
                                         network::IsAPIEnabled())
+#ifdef MOZ_B2G_RIL
+    DOM_CLASSINFO_MAP_ENTRY(nsIMozNavigatorMobileConnection)
+#endif
 #ifdef MOZ_B2G_BT
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNavigatorBluetooth)
 #endif
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNavigatorCamera)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNavigatorSystemMessages)
 
   DOM_CLASSINFO_MAP_END
 
@@ -4123,20 +4136,22 @@ nsDOMClassInfo::Init()
      DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozSmsCursor)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(MozConnection, nsIDOMMozConnection)
      DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozConnection)
      DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
   DOM_CLASSINFO_MAP_END
 
+#ifdef MOZ_B2G_RIL
   DOM_CLASSINFO_MAP_BEGIN(MozMobileConnection, nsIDOMMozMobileConnection)
      DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozMobileConnection)
      DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
   DOM_CLASSINFO_MAP_END
+#endif
 
   DOM_CLASSINFO_MAP_BEGIN(USSDReceivedEvent, nsIDOMUSSDReceivedEvent)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMUSSDReceivedEvent)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEvent)
   DOM_CLASSINFO_MAP_END
  
   DOM_CLASSINFO_MAP_BEGIN(CSSFontFaceRule, nsIDOMCSSFontFaceRule)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSFontFaceRule)
@@ -4472,16 +4487,27 @@ nsDOMClassInfo::Init()
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozVoicemail)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(MozVoicemailEvent, nsIDOMMozVoicemailEvent)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozVoicemailEvent)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEvent)
   DOM_CLASSINFO_MAP_END
+
+  DOM_CLASSINFO_MAP_BEGIN(MozIccManager, nsIDOMMozIccManager)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozIccManager)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
+  DOM_CLASSINFO_MAP_END
+
+  DOM_CLASSINFO_MAP_BEGIN(MozStkCommandEvent, nsIDOMMozStkCommandEvent)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozStkCommandEvent)
+    DOM_CLASSINFO_EVENT_MAP_ENTRIES
+  DOM_CLASSINFO_MAP_END
+
 #endif
 
 #ifdef MOZ_B2G_BT
   DOM_CLASSINFO_MAP_BEGIN(BluetoothManager, nsIDOMBluetoothManager)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMBluetoothManager)
   DOM_CLASSINFO_MAP_END  
 
   DOM_CLASSINFO_MAP_BEGIN(BluetoothAdapter, nsIDOMBluetoothAdapter)
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -402,17 +402,19 @@ DOMCI_CLASS(MozWakeLock)
 DOMCI_CLASS(MozSmsManager)
 DOMCI_CLASS(MozSmsMessage)
 DOMCI_CLASS(MozSmsEvent)
 DOMCI_CLASS(MozSmsRequest)
 DOMCI_CLASS(MozSmsFilter)
 DOMCI_CLASS(MozSmsCursor)
 
 DOMCI_CLASS(MozConnection)
+#ifdef MOZ_B2G_RIL
 DOMCI_CLASS(MozMobileConnection)
+#endif
 
 DOMCI_CLASS(USSDReceivedEvent)
 
 // @font-face in CSS
 DOMCI_CLASS(CSSFontFaceRule)
 DOMCI_CLASS(CSSFontFaceStyleDecl)
 
 #if defined(MOZ_MEDIA)
@@ -514,16 +516,18 @@ DOMCI_CLASS(MutationRecord)
 #ifdef MOZ_B2G_RIL
 DOMCI_CLASS(MozWifiStatusChangeEvent)
 DOMCI_CLASS(MozWifiConnectionInfoEvent)
 DOMCI_CLASS(Telephony)
 DOMCI_CLASS(TelephonyCall)
 DOMCI_CLASS(CallEvent)
 DOMCI_CLASS(MozVoicemail)
 DOMCI_CLASS(MozVoicemailEvent)
+DOMCI_CLASS(MozIccManager)
+DOMCI_CLASS(MozStkCommandEvent)
 #endif
 
 #ifdef MOZ_B2G_BT
 DOMCI_CLASS(BluetoothManager)
 DOMCI_CLASS(BluetoothAdapter)
 DOMCI_CLASS(BluetoothDevice)
 DOMCI_CLASS(BluetoothPropertyEvent)
 #endif
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -5,17 +5,24 @@
 # DOM Bindings Configuration.
 #
 # The WebIDL interfaces are defined in dom/webidl. For each such interface, there
 # is a corresponding entry in the configuration table below. The configuration
 # table maps each interface name to a |descriptor| or list of |descriptor|s.
 #
 # Valid fields for all descriptors:
 #   * nativeType - The native type (concrete class or XPCOM interface) that
-#                  instances of this interface will unwrap to (required).
+#                  instances of this interface will unwrap to.  If not
+#                  specified, defaults to "mozilla::dom::InterfaceName" for
+#                  non-worker non-external-or-callback interfaces, to
+#                  "mozilla::dom::workers::InterfaceName" for worker
+#                  non-external interfaces, to 'nsIDOM' followed by the
+#                  interface name for non-worker external-or-callback
+#                  interfaces, and to "JSObject" for worker external-or-callback
+#                  interfaces.
 #   * headerFile - The file in which the nativeType is declared (defaults
 #                  to an educated guess).
 #   * castable - Indicates whether the value in the wrapper can be cast to
 #                nativeType, or whether it needs to be QI-ed (defaults to True
 #                for everything but callback interfaces and external interfaces,
 #                for which it defaults to false and is not allowed to be set
 #                at all).
 #   * concrete - Indicates whether there exist objects with this interface as
@@ -51,23 +58,20 @@
 #                         that require a JSContext as the first argument
 #   * resultNotAddRefed - attributes and methods specified in the .webidl file
 #                         that do not AddRef the return value
 
 DOMInterfaces = {
 
 'Blob': [
 {
-    'nativeType': 'nsIDOMBlob',
     'headerFile': 'nsIDOMFile.h',
 },
 {
     'workers': True,
-    'nativeType': 'JSObject',
-    'headerFile': 'jsapi.h',
 }],
 
 'CanvasRenderingContext2D': [
 {
     'nativeType': 'nsCanvasRenderingContext2DAzure',
     # Making this non-prefable requires that we ensure that nothing takes this
     # type as an argument or that the non-Azure variant is removed.
     'prefable': True,
@@ -93,96 +97,77 @@ DOMInterfaces = {
 },
 
 'Document': [
 {
     'nativeType': 'nsIDocument',
 },
 {
     'workers': True,
-    'nativeType': 'JSObject',
-    'headerFile': 'jsapi.h',
 }],
 
 'Event': [
 {
-    'nativeType': 'nsIDOMEvent',
 },
 {
     'workers': True,
-    'nativeType': 'JSObject',
-    'headerFile': 'jsapi.h',
 }],
 
 'EventListener': [
 {
-    'nativeType': 'nsIDOMEventListener',
-    'prefable': True
 },
 {
     'workers': True,
-    'nativeType': 'JSObject',
-    'headerFile': 'jsapi.h'
 }],
 
 'EventTarget': [
 {
     'nativeType': 'nsDOMEventTargetHelper',
     'hasInstanceInterface': 'nsIDOMEventTarget',
     'concrete': False,
     'prefable': True,
 },
 {
     'workers': True,
-    'nativeType': 'mozilla::dom::workers::EventTarget',
     'headerFile': 'mozilla/dom/workers/bindings/EventTarget.h',
     'concrete': False
 }],
 
 'FormData': [
 {
-    'nativeType': 'nsIDOMFormData',
 },
 {
     'workers': True,
-    'nativeType': 'JSObject',
-    'headerFile': 'jsapi.h',
 }],
 
 'IID': [
 {
     'nativeType': 'nsIJSIID',
     'headerFile': 'xpcjsid.h',
 },
 {
     'workers': True,
-    'nativeType': 'JSObject',
-    'headerFile': 'jsapi.h',
 }],
 
 'InputStream': [
 {
     'nativeType': 'nsIInputStream',
     'notflattened': True
 },
 {
     'workers': True,
-    'nativeType': 'JSObject',
-    'headerFile': 'jsapi.h',
 }],
 
 'MozChannel': [
 {
     'nativeType': 'nsIChannel',
     'notflattened': True
 },
 {
     'workers': True,
-    'nativeType': 'JSObject',
-    'headerFile': 'jsapi.h',
 }],
 
 'Performance': {
     'nativeType': 'nsPerformance',
     'resultNotAddRefed': [ 'timing', 'navigation' ]
 },
 
 'PerformanceTiming': {
@@ -214,52 +199,48 @@ DOMInterfaces = {
 {
     'nativeType': 'nsXMLHttpRequest',
     'prefable': True,
     'implicitJSContext': [ 'constructor', ],
     'resultNotAddRefed': [ 'upload', 'responseXML' ]
 },
 {
     'workers': True,
-    'nativeType': 'mozilla::dom::workers::XMLHttpRequest',
     'headerFile': 'mozilla/dom/workers/bindings/XMLHttpRequest.h',
 }],
 
 'XMLHttpRequestEventTarget': [
 {
     'nativeType': 'nsXHREventTarget',
     'headerFile': 'nsXMLHttpRequest.h',
     'concrete': False,
     'prefable': True,
 },
 {
     'workers': True,
     'concrete': False,
-    'nativeType': 'mozilla::dom::workers::XMLHttpRequestEventTarget',
     'headerFile': 'mozilla/dom/workers/bindings/XMLHttpRequestEventTarget.h'
 }],
 
 'XMLHttpRequestUpload': [
 {
     'nativeType': 'nsXMLHttpRequestUpload',
     'headerFile': 'nsXMLHttpRequest.h',
     'prefable': True
 },
 {
     'workers': True,
-    'nativeType': 'mozilla::dom::workers::XMLHttpRequestUpload',
     'headerFile': 'mozilla/dom/workers/bindings/XMLHttpRequestUpload.h'
 }],
 
 ####################################
 # Test Interfaces of various sorts #
 ####################################
 
 'TestInterface' : {
-        'nativeType': 'mozilla::dom::TestInterface',
         'headerFile': 'TestBindingHeader.h',
         'register': False,
         'resultNotAddRefed': [ 'receiveWeakSelf', 'receiveWeakNullableSelf',
                                'receiveWeakOther', 'receiveWeakNullableOther',
                                'receiveWeakExternal', 'receiveWeakNullableExternal',
                                'ReceiveWeakCallbackInterface',
                                'ReceiveWeakNullableCallbackInterface',
                                'receiveWeakCastableObjectSequence',
@@ -267,111 +248,99 @@ DOMInterfaces = {
                                'receiveWeakCastableObjectNullableSequence',
                                'receiveWeakNullableCastableObjectNullableSequence' ],
         'binaryNames': { 'methodRenamedFrom': 'methodRenamedTo',
                          'attributeGetterRenamedFrom': 'attributeGetterRenamedTo',
                          'attributeRenamedFrom': 'attributeRenamedTo' }
         },
 
 'TestNonCastableInterface' : {
-        'nativeType': 'mozilla::dom::TestNonCastableInterface',
         'headerFile': 'TestBindingHeader.h',
         'register': False,
         'castable': False
         },
 
 'TestExternalInterface' : {
         'nativeType': 'mozilla::dom::TestExternalInterface',
         'headerFile': 'TestBindingHeader.h',
         'register': False
         },
 
 'TestNonWrapperCacheInterface' : {
-        'nativeType': 'mozilla::dom::TestNonWrapperCacheInterface',
         'headerFile': 'TestBindingHeader.h',
         'register': False,
         'wrapperCache': False
         },
 
 'TestCallbackInterface': {
         'nativeType': 'mozilla::dom::TestCallbackInterface',
         'headerFile': 'TestBindingHeader.h',
         'register': False
         },
 
 'IndirectlyImplementedInterface': {
-        'nativeType': 'mozilla::dom::IndirectlyImplementedInterface',
         'headerFile': 'TestBindingHeader.h',
         'register': False,
         'castable': False,
         'concrete': False
         },
 
 'OnlyForUseInConstructor' : {
-        'nativeType': 'mozilla::dom::OnlyForUseInConstructor',
         'headerFile': 'TestBindingHeader.h',
         'register': False
         },
 
 
 'TestIndexedGetterInterface' : {
-        'nativeType': 'mozilla::dom::TestIndexedGetterInterface',
         'headerFile': 'TestBindingHeader.h',
         'register': False,
         'infallible': [ 'length' ]
         },
 
 'TestNamedGetterInterface' : {
-        'nativeType': 'mozilla::dom::TestNamedGetterInterface',
         'headerFile': 'TestBindingHeader.h',
         'register': False
         },
 
 'TestIndexedAndNamedGetterInterface' : {
-        'nativeType': 'mozilla::dom::TestIndexedAndNamedGetterInterface',
         'headerFile': 'TestBindingHeader.h',
         'register': False,
         'infallible': [ 'length' ]
         },
 
 'TestIndexedSetterInterface' : {
-        'nativeType': 'mozilla::dom::TestIndexedSetterInterface',
         'headerFile': 'TestBindingHeader.h',
         'register': False
         },
 
 'TestNamedSetterInterface' : {
-        'nativeType': 'mozilla::dom::TestNamedSetterInterface',
         'headerFile': 'TestBindingHeader.h',
         'register': False
         },
 
 'TestIndexedAndNamedSetterInterface' : {
-        'nativeType': 'mozilla::dom::TestIndexedAndNamedSetterInterface',
         'headerFile': 'TestBindingHeader.h',
         'register': False
         },
 
 'TestIndexedAndNamedGetterAndSetterInterface' : {
-        'nativeType': 'mozilla::dom::TestIndexedAndNamedGetterAndSetterInterface',
         'headerFile': 'TestBindingHeader.h',
         'register': False,
         'infallible': [ 'length', '__stringifier' ],
         'binaryNames': { '__stringifier': 'Stringify' }
         },
 }
 
 # These are temporary, until they've been converted to use new DOM bindings
 def addExternalIface(iface, nativeType=None, headerFile=None):
-    if nativeType is None:
-        nativeType = 'nsIDOM' + iface
     domInterface = {
-        'nativeType': nativeType,
         'concrete': False
     }
+    if not nativeType is None:
+        domInterface['nativeType'] = nativeType
     if not headerFile is None:
         domInterface['headerFile'] = headerFile
     DOMInterfaces[iface] = domInterface
 
 # If you add one of these, you need to make sure nsDOMQS.h has the relevant
 # macros added for it
 def addExternalHTMLElement(element):
    nativeElement = 'ns' + element
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -1465,21 +1465,39 @@ class CastableObjectUnwrapper():
     A class for unwrapping an object named by the "source" argument
     based on the passed-in descriptor and storing it in a variable
     called by the name in the "target" argument.
 
     codeOnFailure is the code to run if unwrapping fails.
     """
     def __init__(self, descriptor, source, target, codeOnFailure):
         assert descriptor.castable
+
         self.substitution = { "type" : descriptor.nativeType,
                               "protoID" : "prototypes::id::" + descriptor.name,
                               "source" : source,
                               "target" : target,
                               "codeOnFailure" : CGIndenter(CGGeneric(codeOnFailure), 4).define() }
+        if descriptor.hasXPConnectImpls:
+            # We don't use xpc_qsUnwrapThis because it will always throw on
+            # unwrap failure, whereas we want to control whether we throw or
+            # not.
+            self.substitution["codeOnFailure"] = CGIndenter(CGGeneric(string.Template(
+                "${type} *objPtr;\n"
+                "xpc_qsSelfRef objRef;\n"
+                "JS::Value val = JS::ObjectValue(*${source});\n"
+                "nsresult rv = xpc_qsUnwrapArg<${type}>(cx, val, &objPtr, &objRef.ptr, &val);\n"
+                "if (NS_FAILED(rv)) {\n"
+                "${codeOnFailure}\n"
+                "}\n"
+                "// We should be castable!\n"
+                "MOZ_ASSERT(!objRef.ptr);\n"
+                "// We should have an object, too!\n"
+                "MOZ_ASSERT(objPtr);\n"
+                "${target} = objPtr;").substitute(self.substitution)), 4).define()
 
     def __str__(self):
         return string.Template(
 """{
   nsresult rv = UnwrapObject<${protoID}, ${type}>(cx, ${source}, ${target});
   if (NS_FAILED(rv)) {
 ${codeOnFailure}
   }
@@ -2665,17 +2683,17 @@ if (!%(resultStr)s) {
         return (setValue("JS::ObjectOrNullValue(%s)" % result, True), False)
 
     if type.tag() == IDLType.Tags.any:
         # See comments in WrapNewBindingObject explaining why we need
         # to wrap here.
         # NB: setValue(..., True) calls JS_WrapValue(), so is fallible
         return (setValue(result, True), False)
 
-    if type.isObject():
+    if type.isObject() or type.isSpiderMonkeyInterface():
         # See comments in WrapNewBindingObject explaining why we need
         # to wrap here.
         if type.nullable():
             toValue = "JS::ObjectOrNullValue(%s)"
         else:
             toValue = "JS::ObjectValue(*%s)"
         # NB: setValue(..., True) calls JS_WrapValue(), so is fallible
         return (setValue(toValue % result, True), False)
@@ -2789,17 +2807,17 @@ def getRetvalDeclarationForType(returnTy
             result = CGWrapper(result, post="*")
         return result, False
     if returnType.isCallback():
         # XXXbz we're going to assume that callback types are always
         # nullable for now.
         return CGGeneric("JSObject*"), False
     if returnType.tag() is IDLType.Tags.any:
         return CGGeneric("JS::Value"), False
-    if returnType.isObject():
+    if returnType.isObject() or returnType.isSpiderMonkeyInterface():
         return CGGeneric("JSObject*"), False
     if returnType.isSequence():
         nullable = returnType.nullable()
         if nullable:
             returnType = returnType.inner
         # If our result is already addrefed, use the right type in the
         # sequence argument here.
         (result, _) = getRetvalDeclarationForType(returnType.inner,
@@ -3296,16 +3314,17 @@ class CGSetterCall(CGPerSignatureCall):
         return ""
 
 class FakeCastableDescriptor():
     def __init__(self, descriptor):
         self.castable = True
         self.workers = descriptor.workers
         self.nativeType = descriptor.nativeType
         self.name = descriptor.name
+        self.hasXPConnectImpls = descriptor.hasXPConnectImpls
 
 class CGAbstractBindingMethod(CGAbstractStaticMethod):
     """
     Common class to generate the JSNatives for all our methods, getters, and
     setters.  This will generate the function declaration and unwrap the
     |this| object.  Subclasses are expected to override the generate_code
     function to do the rest of the work.  This function should return a
     CGThing which is already properly indented.
--- a/dom/bindings/Configuration.py
+++ b/dom/bindings/Configuration.py
@@ -122,34 +122,52 @@ class Descriptor(DescriptorProvider):
     """
     Represents a single descriptor for an interface. See Bindings.conf.
     """
     def __init__(self, config, interface, desc):
         DescriptorProvider.__init__(self, config, desc.get('workers', False))
         self.interface = interface
 
         # Read the desc, and fill in the relevant defaults.
-        self.nativeType = desc['nativeType']
+        ifaceName = self.interface.identifier.name
+        if self.interface.isExternal() or self.interface.isCallback():
+            if self.workers:
+                nativeTypeDefault = "JSObject"
+            else:
+                nativeTypeDefault = "nsIDOM" + ifaceName
+        else:
+            if self.workers:
+                nativeTypeDefault = "mozilla::dom::workers::" + ifaceName
+            else:
+                nativeTypeDefault = "mozilla::dom::" + ifaceName
+
+        self.nativeType = desc.get('nativeType', nativeTypeDefault)
         self.hasInstanceInterface = desc.get('hasInstanceInterface', None)
 
-        headerDefault = self.nativeType
-        headerDefault = headerDefault.replace("::", "/") + ".h"
+        # Do something sane for JSObject
+        if self.nativeType == "JSObject":
+            headerDefault = "jsapi.h"
+        else:
+            headerDefault = self.nativeType
+            headerDefault = headerDefault.replace("::", "/") + ".h"
         self.headerFile = desc.get('headerFile', headerDefault)
 
         if self.interface.isCallback() or self.interface.isExternal():
             if 'castable' in desc:
                 raise TypeError("%s is external or callback but has a castable "
                                 "setting" % self.interface.identifier.name)
             self.castable = False
         else:
             self.castable = desc.get('castable', True)
 
         self.notflattened = desc.get('notflattened', False)
         self.register = desc.get('register', True)
 
+        self.hasXPConnectImpls = desc.get('hasXPConnectImpls', False)
+
         # If we're concrete, we need to crawl our ancestor interfaces and mark
         # them as having a concrete descendant.
         self.concrete = desc.get('concrete', not self.interface.isExternal())
         if self.concrete:
             self.proxy = False
             operations = {
                 'IndexedGetter': None,
                 'IndexedSetter': None,
--- a/dom/bindings/Makefile.in
+++ b/dom/bindings/Makefile.in
@@ -89,17 +89,17 @@ bindinggen_dependencies := \
   $(NULL)
 
 CSS2Properties.webidl: $(topsrcdir)/layout/style/nsCSSPropList.h \
                        $(topsrcdir)/layout/style/nsCSSPropAliasList.h \
                        $(webidl_base)/CSS2Properties.webidl.in \
                        $(webidl_base)/CSS2PropertiesProps.h \
                        $(srcdir)/GenerateCSS2PropertiesWebIDL.py \
                        $(GLOBAL_DEPS)
-	$(CPP) -I$(topsrcdir)/layout/style $(webidl_base)/CSS2PropertiesProps.h | \
+	$(CPP) $(DEFINES) $(ACDEFINES) -I$(topsrcdir)/layout/style $(webidl_base)/CSS2PropertiesProps.h | \
 	  PYTHONDONTWRITEBYTECODE=1 $(PYTHON) \
 	  $(srcdir)/GenerateCSS2PropertiesWebIDL.py $(webidl_base)/CSS2Properties.webidl.in > CSS2Properties.webidl
 
 $(webidl_files): %: $(webidl_base)/%
 	$(INSTALL) $(IFLAGS1) $(webidl_base)/$* .
 
 $(test_webidl_files): %: $(srcdir)/test/%
 	$(INSTALL) $(IFLAGS1) $(srcdir)/test/$* .
--- a/dom/bindings/test/TestBindingHeader.h
+++ b/dom/bindings/test/TestBindingHeader.h
@@ -325,16 +325,17 @@ public:
   void PassInt16Array(Int16Array&, ErrorResult&);
   void PassInt32Array(Int32Array&, ErrorResult&);
   void PassUint8Array(Uint8Array&, ErrorResult&);
   void PassUint16Array(Uint16Array&, ErrorResult&);
   void PassUint32Array(Uint32Array&, ErrorResult&);
   void PassUint8ClampedArray(Uint8ClampedArray&, ErrorResult&);
   void PassFloat32Array(Float32Array&, ErrorResult&);
   void PassFloat64Array(Float64Array&, ErrorResult&);
+  JSObject* ReceiveUint8Array(ErrorResult&);
 
   // String types
   void PassString(const nsAString&, ErrorResult&);
   void PassNullableString(const nsAString&, ErrorResult&);
   void PassOptionalString(const Optional<nsAString>&, ErrorResult&);
   void PassOptionalStringWithDefaultValue(const nsAString&, ErrorResult&);
   void PassOptionalNullableString(const Optional<nsAString>&, ErrorResult&);
   void PassOptionalNullableStringWithDefaultValue(const nsAString&, ErrorResult&);
--- a/dom/bindings/test/TestCodeGen.webidl
+++ b/dom/bindings/test/TestCodeGen.webidl
@@ -223,16 +223,17 @@ interface TestInterface {
   void passInt16Array(Int16Array arg);
   void passInt32Array(Int32Array arg);
   void passUint8Array(Uint8Array arg);
   void passUint16Array(Uint16Array arg);
   void passUint32Array(Uint32Array arg);
   void passUint8ClampedArray(Uint8ClampedArray arg);
   void passFloat32Array(Float32Array arg);
   void passFloat64Array(Float64Array arg);
+  Uint8Array receiveUint8Array();
 
   // String types
   void passString(DOMString arg);
   void passNullableString(DOMString? arg);
   void passOptionalString(optional DOMString arg);
   void passOptionalStringWithDefaultValue(optional DOMString arg = "abc");
   void passOptionalNullableString(optional DOMString? arg);
   void passOptionalNullableStringWithDefaultValue(optional DOMString? arg = null);
--- a/dom/devicestorage/DeviceStorageRequestParent.cpp
+++ b/dom/devicestorage/DeviceStorageRequestParent.cpp
@@ -12,16 +12,18 @@
 #include "ContentParent.h"
 #include "nsProxyRelease.h"
 
 namespace mozilla {
 namespace dom {
 namespace devicestorage {
 
 DeviceStorageRequestParent::DeviceStorageRequestParent(const DeviceStorageParams& aParams)
+  : mMutex("DeviceStorageRequestParent::mMutex")
+  , mActorDestoryed(false)
 {
   MOZ_COUNT_CTOR(DeviceStorageRequestParent);
 
   switch (aParams.type()) {
     case DeviceStorageParams::TDeviceStorageAddParams:
     {
       DeviceStorageAddParams p = aParams;
 
@@ -122,16 +124,18 @@ DeviceStorageRequestParent::~DeviceStora
 }
 
 NS_IMPL_THREADSAFE_ADDREF(DeviceStorageRequestParent);
 NS_IMPL_THREADSAFE_RELEASE(DeviceStorageRequestParent);
 
 void
 DeviceStorageRequestParent::ActorDestroy(ActorDestroyReason)
 {
+  MutexAutoLock lock(mMutex);
+  mActorDestoryed = true;
   int32_t count = mRunnables.Length();
   for (int32_t index = 0; index < count; index++) {
     mRunnables[index]->Cancel();
   }
 }
 
 DeviceStorageRequestParent::PostErrorEvent::PostErrorEvent(DeviceStorageRequestParent* aParent,
                                                            const char* aError)
--- a/dom/devicestorage/DeviceStorageRequestParent.h
+++ b/dom/devicestorage/DeviceStorageRequestParent.h
@@ -32,39 +32,32 @@ protected:
 private:
   nsAutoRefCnt mRefCnt;
 
   class CancelableRunnable : public nsRunnable
   {
   public:
     CancelableRunnable(DeviceStorageRequestParent* aParent)
       : mParent(aParent)
-      , mCanceled(false)
     {
-      mParent->AddRunnable(this);
+      mCanceled = !(mParent->AddRunnable(this));
     }
 
     virtual ~CancelableRunnable() {
     }
 
     NS_IMETHOD Run() {
       nsresult rv = NS_OK;
       if (!mCanceled) {
         rv = CancelableRun();
-
-        nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(this, &CancelableRunnable::RemoveRunnable);
-        NS_DispatchToMainThread(event);
+        mParent->RemoveRunnable(this);
       }
       return rv;
     }
 
-    void RemoveRunnable() {
-      mParent->RemoveRunnable(this);
-    }
-
     void Cancel() {
       mCanceled = true;
     }
 
     virtual nsresult CancelableRun() = 0;
 
   protected:
     nsRefPtr<DeviceStorageRequestParent> mParent;
@@ -184,24 +177,32 @@ private:
                           int64_t aTotalBytes);
       virtual ~PostStatResultEvent();
       virtual nsresult CancelableRun();
     private:
       int64_t mFreeBytes, mTotalBytes;
    };
 
 protected:
-  void AddRunnable(CancelableRunnable* aRunnable) {
-    NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+  bool AddRunnable(CancelableRunnable* aRunnable) {
+    MutexAutoLock lock(mMutex);
+    if (mActorDestoryed)
+      return false;
+
     mRunnables.AppendElement(aRunnable);
+    return true;
   }
+
   void RemoveRunnable(CancelableRunnable* aRunnable) {
-    NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+    MutexAutoLock lock(mMutex);
     mRunnables.RemoveElement(aRunnable);
   }
+
+  Mutex mMutex;
+  bool mActorDestoryed;
   nsTArray<nsRefPtr<CancelableRunnable> > mRunnables;
 };
 
 } // namespace devicestorage
 } // namespace dom
 } // namespace mozilla
 
 #endif
--- a/dom/devicestorage/nsDeviceStorage.cpp
+++ b/dom/devicestorage/nsDeviceStorage.cpp
@@ -259,19 +259,35 @@ DeviceStorageFile::Write(InfallibleTArra
     return NS_ERROR_FAILURE;
   }
   return NS_OK;
 }
 
 nsresult
 DeviceStorageFile::Remove()
 {
-  mFile->Remove(true);
+  NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
+
+  bool check;
+  nsresult rv = mFile->Exists(&check);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  
+  if (!check) {
+    return NS_OK;
+  }
+
+  rv = mFile->Remove(true);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+
   nsCOMPtr<IOEventComplete> iocomplete = new IOEventComplete(mFile, "deleted");
-  NS_DispatchToMainThread(iocomplete);    
+  NS_DispatchToMainThread(iocomplete);
   return NS_OK;
 }
 
 void
 DeviceStorageFile::CollectFiles(nsTArray<nsRefPtr<DeviceStorageFile> > &aFiles,
                                 uint64_t aSince)
 {
   nsString rootPath;
@@ -1091,17 +1107,16 @@ public:
   ~DeleteFileEvent() {}
 
   NS_IMETHOD Run()
   {
     NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
     mFile->Remove();
 
     nsRefPtr<nsRunnable> r;
-
     bool check = false;
     mFile->mFile->Exists(&check);
     if (check) {
       r = new PostErrorEvent(mRequest, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST, mFile);
     }
     else {
       r = new PostResultEvent(mRequest, mFile->mPath);
     }
--- a/dom/dom-config.mk
+++ b/dom/dom-config.mk
@@ -33,16 +33,17 @@ DOM_SRCDIRS = \
   dom/camera \
   $(NULL)
 
 ifdef MOZ_B2G_RIL
 DOM_SRCDIRS += \
   dom/system/gonk \
   dom/telephony \
   dom/wifi \
+  dom/icc/src \
   $(NULL)
 endif
 
 ifdef MOZ_B2G_BT
 DOM_SRCDIRS += dom/bluetooth
 endif
 
 LOCAL_INCLUDES += $(DOM_SRCDIRS:%=-I$(topsrcdir)/%)
new file mode 100644
--- /dev/null
+++ b/dom/icc/Makefile.in
@@ -0,0 +1,14 @@
+# 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@
+
+include $(DEPTH)/config/autoconf.mk
+
+PARALLEL_DIRS = interfaces src
+
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/dom/icc/interfaces/Makefile.in
@@ -0,0 +1,21 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DEPTH            = ../../..
+topsrcdir        = @top_srcdir@
+srcdir           = @srcdir@
+VPATH            = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+XPIDL_MODULE = dom_icc
+
+include $(topsrcdir)/dom/dom-config.mk
+
+XPIDLSRCS = \
+  nsIDOMIccManager.idl \
+  SimToolKit.idl \
+  $(NULL)
+
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/dom/icc/interfaces/SimToolKit.idl
@@ -0,0 +1,377 @@
+/* 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 "nsIDOMEvent.idl"
+
+interface nsIDOMEvent;
+
+dictionary MozStkTextMessage
+{
+  /**
+   * Text String.
+   *
+   * @see TS 11.14, clause 12.15, Text String.
+   */
+  DOMString text;
+
+  /**
+   * Indicate this text message is high priority or normal priority.
+   *
+   * @see TS 11.14, clause 12.6, Command Qualifier, Display Text, bit 1.
+   *
+   * High priority text shall be displayed on the screen immediately, except if
+   * there is a conflict of priority level of alerting such as incoming calls
+   * or a low battery warning. In that situation, the resolution is left to
+   * the terminal. If the command is rejected in spite of the high priority,
+   * the terminal shall inform the ICC with resultCode is
+   * TERMINAL_CRNTLY_UNABLE_TO_PROCESS in MozStkResponse.
+   *
+   * true: high priority
+   * false: normal priority
+   */
+  boolean isHighPriority;
+
+  /**
+   * Need to wait for user to clear message or not.
+   *
+   * @see TS 11.14, clause 12.6, Command Qualifier, Display Text, bit 8.
+   *
+   * If this attribute is true, but user doesn't give any input within a period
+   * of time(said 30 secs), the terminal shall inform the ICC with resultCode
+   * is NO_RESPONSE_FROM_USER in MozStkResponse.
+   *
+   * true: Wait for user to clear message.
+   * false: clear message after a delay.
+   */
+  boolean userClear;
+
+  /**
+   * Need to response immediately or not.
+   *
+   * @see TS 11.14, clause 12.43, Immediate response.
+   *
+   * When this attribute is true, the terminal shall immediately send
+   * MozStkResponse with resultCode is OK.
+   *
+   * true: The terminal shall send response immediately.
+   * false: otherwise.
+   */
+  boolean responseNeeded;
+};
+
+dictionary MozStkItem
+{
+  /**
+   * Identifier of item.
+   *
+   * The identifier is a single byte between '01' and 'FF'. Each item shall
+   * have a unique identifier within an Item list.
+   */
+  unsigned short identifier;
+
+  /**
+   * Text string of item.
+   */
+  DOMString text;
+};
+
+dictionary MozStkMenu
+{
+  /**
+   * Array of MozStkItem.
+   *
+   * @see TS 11.14, clause 12.9
+   */
+  jsval items; // MozStkItem[]
+
+  /**
+   * Presentation type, one of TYPE_*.
+   */
+  unsigned short presentationType;
+
+  /**
+   * Title of the menu.
+   */
+  DOMString title;
+
+  /**
+   * Default item identifier of the menu.
+   */
+  unsigned short defaultItem;
+
+  /**
+   * Help information available or not.
+   *
+   * @see TS 11.14, clause 12.6, Command Qualifier, SET UP MENU, bit 8.
+   *
+   * true: help information available.
+   * false: no help information available.
+   */
+  boolean isHelpAvailable;
+};
+
+dictionary MozStkInput
+{
+  /**
+   * Text for the ME to display in conjunction with asking the user to respond.
+   */
+  DOMString text;
+
+  /**
+   * Minimum length of response.
+   */
+  unsigned short minLength;
+
+  /**
+   * Maximum length of response.
+   */
+  unsigned short maxLength;
+
+  /**
+   * Text for the ME to display, corresponds to a default text string offered
+   * by the ICC.
+   */
+  DOMString defaultText;
+
+  /**
+   * Input format.
+   *
+   * @see TS 11.14, clause 12.6, Command Qualifier, GET INPUT, bit 1.
+   *
+   * true: Alphabet set.
+   * false: Digits only.
+   */
+  boolean isAlphabet;
+
+  /**
+   * Alphabet encoding.
+   *
+   * @see TS 11.14, clause 12.6, Command Qualifier, GET INPUT, bit 2.
+   *
+   * true: UCS2 alphabet.
+   * false: default SMS alphabet.
+   */
+  boolean isUCS2;
+
+  /**
+   * Visibility of input.
+   *
+   * @see TS 11.14, clause 12.6, Command Qualifier, GET INPUT, bit 3.
+   *
+   * true: User input shall not be revealed in any way.
+   * false: ME may echo user input on the display.
+   */
+  boolean hideInput;
+
+  /**
+   * Yes/No response is requested.
+   *
+   * @see TS 11.14, clause 12.6, Command Qualifier, GET INKEY, bit 3.
+   *
+   * true: Yes/No response is requested, and character sets
+   *       (Alphabet set and UCS2) are disabled.
+   * false: Character sets (Alphabet set and UCS2) are enabled.
+   */
+  boolean isYesNoRequested;
+
+  /**
+   * User input in packed or unpacked format.
+   *
+   * @see TS 11.14, clause 12.6, Command Qualifier, GET INPUT, bit 4.
+   *
+   * true: User input to be in SMS packed format.
+   * false: User input to be in unpacked format.
+   */
+  boolean isPacked;
+
+  /**
+   * Help information available or not.
+   *
+   * @see TS 11.14, clause 12.6, Command Qualifier, GET INPUT/GET INKEY, bit 8.
+   *
+   * true: help information available.
+   * false: no help information available.
+   */
+  boolean isHelpAvailable;
+};
+
+dictionary MozStkBrowserSetting
+{
+  /**
+   * Confirm message to launch browser.
+   *
+   * @see MozStkTextMessage for the detail specification of
+   *      confirmMessage.
+   */
+  jsval confirmMessage;
+
+  /**
+   * The URL to be opened by browser.
+   */
+  DOMString url;
+
+  /**
+   * One of STK_BROWSER_MODE_*.
+   *
+   * @see nsIDOMMozIccManager.STK_BROWSER_MODE_*
+   */
+  unsigned short mode;
+};
+
+dictionary MozStkSetUpCall
+{
+  /**
+   * The Dialling number.
+   */
+  DOMString address;
+
+  /**
+   * The text message used in user confirmation phase.
+   *
+   * @see MozStkTextMessage for the detail specification of
+   *      confirmMessage.
+   */
+  jsval confirmMessage;
+
+  /**
+   * The text message used in call set up phase.
+   *
+   * @see MozStkTextMessage for the detail specification of
+   *      callMessage.
+   */
+  jsval callMessage;
+};
+
+dictionary MozStkCommand
+{
+  /**
+   * The number of command issued by ICC. And it is assigned
+   * by ICC may take any hexadecimal value betweean '01' and 'FE'.
+   *
+   * @see TS 11.14, clause 6.5.1
+   */
+  unsigned short commandNumber;
+
+  /**
+   * One of STK_CMD_*
+   */
+  unsigned short typeOfCommand;
+
+  /**
+   * Qualifiers specific to the command.
+   */
+  unsigned short commandQualifier;
+
+  /**
+   * options varies accrording to the typeOfCommand in MozStkCommand.
+   *
+   * When typeOfCommand is
+   * - STK_DISPLAY_TEXT
+   * - STK_SET_UP_IDLE_MODE_TEXT
+   * - STK_REFRESH
+   * - STK_SEND_{SS|USSD|SMS|DTMF},
+   * options is MozStkTextMessage.
+   *
+   * When typeOfCommand is
+   * - STK_SELECT_ITEM
+   * - STK_SET_UP_MENU
+   * options is MozStkMenu.
+   *
+   * When typeOfCommand is
+   * - STK_GET_INKEY
+   * - STK_GET_INPUT,
+   * options is MozStkInput.
+   *
+   * When typeOfCommand is
+   * - STK_LAUNCH_BROWSER
+   * options is MozStkBrowserSetting.
+   *
+   * When typeOfCommand is
+   * - STK_SET_UP_CALL
+   * options is MozStkSetUpCall.
+   */
+  jsval options;
+};
+
+[scriptable, builtinclass, uuid(06bbc6fa-9b59-4db6-b66b-3b26f9c379df)]
+interface nsIDOMMozStkCommandEvent : nsIDOMEvent
+{
+  /**
+   * See nsIDOMMozStkCommand for the detail of command.
+   */
+  [implicit_jscontext]
+  readonly attribute jsval command;
+};
+
+dictionary MozStkResponse
+{
+  /**
+   * commandNumber from MozStkCommand.
+   *
+   * @see MozStkCommand.commandNumber
+   */
+  unsigned short commandNumber;
+
+  /**
+   * One of MozStkCommand.typeOfCommand
+   *
+   * @see MozStkCommand.typeOfCommand
+   */
+  unsigned short typeOfCommand;
+
+  /**
+   * Qualifiers specific to the command.
+   *
+   * @see MozStkCommand.commandQualifier
+   */
+  unsigned short commandQualifier;
+
+  /**
+   * One of RESULT_*
+   */
+  unsigned short resultCode;
+
+  /**
+   * The identifier of the item selected by user.
+   *
+   * @see MozStkItem.identifier
+   */
+  unsigned short itemIdentifier;
+
+  /**
+   * User input.
+   */
+  DOMString input;
+
+  /**
+   * Alphabet encoding.
+   *
+   * @see MozStkInput.isUCS2
+   */
+  boolean isUCS2;
+
+  /**
+   * YES/NO response.
+   *
+   * @see MozStkInput.isYesNoRequested
+   */
+  boolean isYesNo;
+
+  /**
+   * Packed or unpacked format.
+   *
+   * @see MozStkInput.isPacked
+   */
+  boolean isPacked;
+
+  /**
+   * User has confirmed or rejected the call during STK_CMD_CALL_SET_UP.
+   *
+   * @see RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM
+   *
+   * true: Confirmed by User.
+   * false: Rejected by User.
+   */
+  boolean hasConfirmed;
+};
new file mode 100644
--- /dev/null
+++ b/dom/icc/interfaces/nsIDOMIccManager.idl
@@ -0,0 +1,175 @@
+/* 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 "nsIDOMEventTarget.idl"
+#include "SimToolKit.idl"
+
+interface nsIDOMEventListener;
+
+[scriptable, builtinclass, uuid(6ca8ac2b-0c7b-40bf-8eb3-dbd16f89d82f)]
+interface nsIDOMMozIccManager : nsIDOMEventTarget
+{
+  /**
+   * STK Menu Presentation types.
+   */
+  const unsigned short STK_MENU_TYPE_NOT_SPECIFIED      = 0x00;
+  const unsigned short STK_MENU_TYPE_DATA_VALUES        = 0x01;
+  const unsigned short STK_MENU_TYPE_NAVIGATION_OPTIONS = 0x03;
+
+  /**
+   * Browser launch mode.
+   */
+  const unsigned short STK_BROWSER_MODE_LAUNCH_IF_NOT_ALREADY_LAUNCHED = 0x00;
+  const unsigned short STK_BROWSER_MODE_USING_EXISTING_BROWSER         = 0x02;
+  const unsigned short STK_BROWSER_MODE_USING_NEW_BROWSER              = 0x03;
+
+  /**
+   * STK Proactive commands.
+   *
+   * @see TS 11.14, clause 13.4
+   */
+  const unsigned short STK_CMD_REFRESH               = 0x01;
+  const unsigned short STK_CMD_SET_UP_CALL           = 0x10;
+  const unsigned short STK_CMD_SEND_SS               = 0x11;
+  const unsigned short STK_CMD_SEND_USSD             = 0x12;
+  const unsigned short STK_CMD_SEND_SMS              = 0x13;
+  const unsigned short STK_CMD_SEND_DTMF             = 0x14;
+  const unsigned short STK_CMD_LAUNCH_BROWSER        = 0x15;
+  const unsigned short STK_CMD_DISPLAY_TEXT          = 0x21;
+  const unsigned short STK_CMD_GET_INKEY             = 0x22;
+  const unsigned short STK_CMD_GET_INPUT             = 0x23;
+  const unsigned short STK_CMD_SELECT_ITEM           = 0x24;
+  const unsigned short STK_CMD_SET_UP_MENU           = 0x25;
+  const unsigned short STK_CMD_SET_UP_IDLE_MODE_TEXT = 0x28;
+
+  /**
+   * STK Result code.
+   *
+   * @see TS 11.14, clause 12.12
+   *
+   * Results '0X' and '1X' indicate that the command has been performed.
+   */
+  /** Command performed successfully */
+  const unsigned short STK_RESULT_OK                                = 0x00;
+
+  /** Command performed with partial comprehension */
+  const unsigned short STK_RESULT_PRFRMD_WITH_PARTIAL_COMPREHENSION = 0x01;
+
+  /** Command performed, with missing information */
+  const unsigned short STK_RESULT_PRFRMD_WITH_MISSING_INFO          = 0x02;
+
+  /** REFRESH performed with additional EFs read */
+  const unsigned short STK_RESULT_PRFRMD_WITH_ADDITIONAL_EFS_READ   = 0x03;
+
+  /** Command performed successfully, limited service */
+  const unsigned short STK_RESULT_PRFRMD_LIMITED_SERVICE            = 0x06;
+
+  /** Proactive UICC session terminated by the user */
+  const unsigned short STK_RESULT_UICC_SESSION_TERM_BY_USER         = 0x10;
+
+  /** Backward move in the proactive UICC session requested by the user */
+  const unsigned short STK_RESULT_BACKWARD_MOVE_BY_USER             = 0x11;
+
+  /** No response from user */
+  const unsigned short STK_RESULT_NO_RESPONSE_FROM_USER             = 0x12;
+
+  /** Help information required by the user */
+  const unsigned short STK_RESULT_HELP_INFO_REQUIRED                = 0x13;
+
+  /** USSD or SS transaction terminated by the user */
+  const unsigned short STK_RESULT_USSD_SS_SESSION_TERM_BY_USER      = 0x14;
+
+  /**
+   * Results '2X' indicate to the UICC that it may be worth re-trying the
+   * command at a later opportunity.
+   */
+  /** Terminal currently unable to process command */
+  const unsigned short STK_RESULT_TERMINAL_CRNTLY_UNABLE_TO_PROCESS = 0x20;
+
+  /** Network currently unable to process command */
+  const unsigned short STK_RESULT_NETWORK_CRNTLY_UNABLE_TO_PROCESS  = 0x21;
+
+  /** User did not accept the proactive command */
+  const unsigned short STK_RESULT_USER_NOT_ACCEPT                   = 0x22;
+
+  /** User cleared down call before connection or network release */
+  const unsigned short STK_RESULT_USER_CLEAR_DOWN_CALL              = 0x23;
+
+  /** Launch browser generic error code */
+  const unsigned short STK_RESULT_LAUNCH_BROWSER_ERROR              = 0x26;
+
+  /**
+   * Results '3X' indicate that it is not worth the UICC re-trying with an
+   * identical command, as it will only get the same response. However, the
+   * decision to retry lies with the application.
+   */
+  /** Command beyond terminal's capabilities */
+  const unsigned short STK_RESULT_BEYOND_TERMINAL_CAPABILITY        = 0x30;
+
+  /** Command type not understood by terminal */
+  const unsigned short STK_RESULT_CMD_TYPE_NOT_UNDERSTOOD           = 0x31;
+
+  /** Command data not understood by terminal */
+  const unsigned short STK_RESULT_CMD_DATA_NOT_UNDERSTOOD           = 0x32;
+
+  /** Command number not known by terminal */
+  const unsigned short STK_RESULT_CMD_NUM_NOT_KNOWN                 = 0x33;
+
+  /** SS Return Error */
+  const unsigned short STK_RESULT_SS_RETURN_ERROR                   = 0x34;
+
+  /** SMS RP-ERROR */
+  const unsigned short STK_RESULT_SMS_RP_ERROR                      = 0x35;
+
+  /** Error, required values are missing */
+  const unsigned short STK_RESULT_REQUIRED_VALUES_MISSING           = 0x36;
+
+  /** USSD Return Error */
+  const unsigned short STK_RESULT_USSD_RETURN_ERROR                 = 0x37;
+
+  /** MultipleCard commands error */
+  const unsigned short STK_RESULT_MULTI_CARDS_CMD_ERROR             = 0x38;
+
+  /**
+   * Interaction with call control by USIM or MO short message control by
+   * USIM, permanent problem
+   */
+  const unsigned short STK_RESULT_USIM_CALL_CONTROL_PERMANENT       = 0x39;
+
+  /** Bearer Independent Protocol error */
+  const unsigned short STK_RESULT_BIP_ERROR                         = 0x3a;
+
+  /**
+   * Send the response back to ICC after an attempt to execute STK Proactive
+   * Command.
+   *
+   * @param response
+   *        The response that will be sent to ICC.
+   * @see MozStkResponse for the detail of response.
+   */
+  void sendStkResponse(in jsval response);
+
+  /**
+   * Send the "Menu Selection" Envelope command to ICC for menu selection.
+   *
+   * @param itemIdentifier
+   *        The identifier of the item selected by user.
+   * @param helpRequested
+   *        true if user requests to provide help information, false otherwise.
+   */
+  void sendStkMenuSelection(in unsigned short itemIdentifier,
+                            in boolean        helpRequested);
+
+  /**
+   * The 'stkcommand' event is notified whenever STK Proactive Command is
+   * issued from ICC.
+   */
+  attribute nsIDOMEventListener onstkcommand;
+
+  /**
+   * 'stksessionend' event is notified whenever STK Session is terminated by
+   * ICC.
+   */
+  attribute nsIDOMEventListener onstksessionend;
+};
new file mode 100644
--- /dev/null
+++ b/dom/icc/src/IccManager.cpp
@@ -0,0 +1,166 @@
+/* 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 "mozilla/Services.h"
+#include "nsIDOMClassInfo.h"
+#include "nsIObserverService.h"
+#include "IccManager.h"
+#include "SimToolKit.h"
+#include "StkCommandEvent.h"
+
+#define NS_RILCONTENTHELPER_CONTRACTID "@mozilla.org/ril/content-helper;1"
+
+#define STKCOMMAND_EVENTNAME      NS_LITERAL_STRING("stkcommand")
+#define STKSESSIONEND_EVENTNAME   NS_LITERAL_STRING("stksessionend")
+
+DOMCI_DATA(MozIccManager, mozilla::dom::icc::IccManager)
+
+namespace mozilla {
+namespace dom {
+namespace icc {
+
+const char* kStkCommandTopic     = "icc-manager-stk-command";
+const char* kStkSessionEndTopic  = "icc-manager-stk-session-end";
+
+NS_IMPL_CYCLE_COLLECTION_CLASS(IccManager)
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IccManager,
+                                                  nsDOMEventTargetHelper)
+  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(stkcommand)
+  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(stksessionend)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IccManager,
+                                                nsDOMEventTargetHelper)
+  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(stkcommand)
+  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(stksessionend)
+  tmp->mProvider = nullptr;
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IccManager)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMMozIccManager)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMMozIccManager)
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozIccManager)
+NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
+
+NS_IMPL_ADDREF_INHERITED(IccManager, nsDOMEventTargetHelper)
+NS_IMPL_RELEASE_INHERITED(IccManager, nsDOMEventTargetHelper)
+
+IccManager::IccManager()
+{
+  mProvider = do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
+
+  // Not being able to acquire the provider isn't fatal since we check
+  // for it explicitly below.
+  if (!mProvider) {
+    NS_WARNING("Could not acquire nsIMobileConnectionProvider!");
+  }
+}
+
+void
+IccManager::Init(nsPIDOMWindow* aWindow)
+{
+  BindToOwner(aWindow);
+
+  nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
+  if (!obs) {
+    NS_WARNING("Could not acquire nsIObserverService!");
+    return;
+  }
+
+  obs->AddObserver(this, kStkCommandTopic, false);
+  obs->AddObserver(this, kStkSessionEndTopic, false);
+}
+
+void
+IccManager::Shutdown()
+{
+  nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
+  if (!obs) {
+    NS_WARNING("Could not acquire nsIObserverService!");
+    return;
+  }
+
+  obs->RemoveObserver(this, kStkCommandTopic);
+  obs->RemoveObserver(this, kStkSessionEndTopic);
+}
+
+// nsIObserver
+
+NS_IMETHODIMP
+IccManager::Observe(nsISupports* aSubject,
+                    const char* aTopic,
+                    const PRUnichar* aData)
+{
+  if (!strcmp(aTopic, kStkCommandTopic)) {
+    nsString stkMsg;
+    stkMsg.Assign(aData);
+    nsRefPtr<StkCommandEvent> event = StkCommandEvent::Create(stkMsg);
+
+    NS_ASSERTION(event, "This should never fail!");
+
+    nsresult rv = event->Dispatch(ToIDOMEventTarget(), STKCOMMAND_EVENTNAME);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    return NS_OK;
+  }
+
+  if (!strcmp(aTopic, kStkSessionEndTopic)) {
+    InternalDispatchEvent(STKSESSIONEND_EVENTNAME);
+    return NS_OK;
+  }
+
+  MOZ_NOT_REACHED("Unknown observer topic!");
+
+  return NS_OK;
+}
+
+// nsIDOMMozIccManager
+
+NS_IMETHODIMP
+IccManager::SendStkResponse(const JS::Value& aResponse)
+{
+  if (!mProvider) {
+    return NS_ERROR_FAILURE;
+  }
+
+  mProvider->SendStkResponse(GetOwner(), aResponse);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+IccManager::SendStkMenuSelection(uint16_t aItemIdentifier, bool aHelpRequested)
+{
+  if (!mProvider) {
+    return NS_ERROR_FAILURE;
+  }
+
+  mProvider->SendStkMenuSelection(GetOwner(), aItemIdentifier, aHelpRequested);
+  return NS_OK;
+}
+
+nsresult
+IccManager::InternalDispatchEvent(const nsAString& aType)
+{
+  nsRefPtr<nsDOMEvent> event = new nsDOMEvent(nullptr, nullptr);
+  nsresult rv = event->InitEvent(aType, false, false);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = event->SetTrusted(true);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  bool dummy;
+  rv = DispatchEvent(event, &dummy);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return NS_OK;
+}
+
+
+NS_IMPL_EVENT_HANDLER(IccManager, stkcommand)
+NS_IMPL_EVENT_HANDLER(IccManager, stksessionend)
+
+} // namespace icc
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/icc/src/IccManager.h
@@ -0,0 +1,57 @@
+/* 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/. */
+
+#ifndef mozilla_dom_icc_IccManager_h
+#define mozilla_dom_icc_IccManager_h
+
+#include "nsCycleCollectionParticipant.h"
+#include "nsDOMEventTargetHelper.h"
+#include "nsIDOMIccManager.h"
+#include "nsIMobileConnectionProvider.h"
+#include "nsIObserver.h"
+
+namespace mozilla {
+namespace dom {
+namespace icc {
+
+class IccManager : public nsDOMEventTargetHelper
+                 , public nsIDOMMozIccManager
+                 , public nsIObserver
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIOBSERVER
+  NS_DECL_NSIDOMMOZICCMANAGER
+
+  NS_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetHelper::)
+
+  IccManager();
+
+  void Init(nsPIDOMWindow *aWindow);
+  void Shutdown();
+
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IccManager,
+                                           nsDOMEventTargetHelper)
+
+private:
+  nsCOMPtr<nsIMobileConnectionProvider> mProvider;
+
+  nsIDOMEventTarget*
+  ToIDOMEventTarget() const
+  {
+    return static_cast<nsDOMEventTargetHelper*>(
+           const_cast<IccManager*>(this));
+  }
+
+  nsresult InternalDispatchEvent(const nsAString& aType);
+
+  NS_DECL_EVENT_HANDLER(stkcommand)
+  NS_DECL_EVENT_HANDLER(stksessionend)
+};
+
+} // namespace icc
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_icc_IccManager_h
new file mode 100644
--- /dev/null
+++ b/dom/icc/src/Makefile.in
@@ -0,0 +1,35 @@
+# 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)
+
+include $(DEPTH)/config/autoconf.mk
+
+LIBRARY_NAME     = dom_icc_s
+LIBXUL_LIBRARY   = 1
+FORCE_STATIC_LIB = 1
+
+include $(topsrcdir)/dom/dom-config.mk
+
+EXPORTS_NAMESPACES = mozilla/dom/icc
+
+EXPORTS_mozilla/dom/icc = \
+  StkCommandEvent.h \
+  $(NULL)
+
+CPPSRCS = \
+  IccManager.cpp \
+  StkCommandEvent.cpp \
+  $(NULL)
+
+LOCAL_INCLUDES = \
+  -I$(topsrcdir)/content/events/src \
+  $(NULL)
+
+include $(topsrcdir)/config/config.mk
+include $(topsrcdir)/ipc/chromium/chromium-config.mk
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/dom/icc/src/StkCommandEvent.cpp
@@ -0,0 +1,55 @@
+/* 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 "nsIDOMClassInfo.h"
+#include "nsDOMClassInfoID.h"
+#include "nsContentUtils.h"
+#include "SimToolKit.h"
+#include "StkCommandEvent.h"
+
+#include "nsJSON.h"
+#include "jsapi.h"
+#include "jsfriendapi.h"
+
+DOMCI_DATA(MozStkCommandEvent, mozilla::dom::icc::StkCommandEvent)
+
+namespace mozilla {
+namespace dom {
+namespace icc {
+
+already_AddRefed<StkCommandEvent>
+StkCommandEvent::Create(nsAString& aMessage)
+{
+  nsRefPtr<StkCommandEvent> event = new StkCommandEvent();
+  event->mCommand = aMessage;
+  return event.forget();
+}
+
+NS_IMPL_ADDREF_INHERITED(StkCommandEvent, nsDOMEvent)
+NS_IMPL_RELEASE_INHERITED(StkCommandEvent, nsDOMEvent)
+
+NS_INTERFACE_MAP_BEGIN(StkCommandEvent)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMMozStkCommandEvent)
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozStkCommandEvent)
+NS_INTERFACE_MAP_END_INHERITING(nsDOMEvent)
+
+NS_IMETHODIMP
+StkCommandEvent::GetCommand(JSContext* aCx, jsval* aCommand)
+
+{
+  nsCOMPtr<nsIJSON> json(new nsJSON());
+
+  if (!mCommand.IsEmpty()) {
+    nsresult rv = json->DecodeToJSVal(mCommand, aCx, aCommand);
+    NS_ENSURE_SUCCESS(rv, rv);
+  } else {
+    *aCommand = JSVAL_VOID;
+  }
+
+  return NS_OK;
+}
+
+}
+}
+}
new file mode 100644
--- /dev/null
+++ b/dom/icc/src/StkCommandEvent.h
@@ -0,0 +1,64 @@
+/* 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/. */
+
+#ifndef mozilla_dom_icc_stkcommandevent_h
+#define mozilla_dom_icc_stkcommandevent_h
+
+#include "nsDOMEvent.h"
+#include "SimToolKit.h"
+
+namespace mozilla {
+namespace dom {
+namespace icc {
+
+class StkCommandEvent : public nsDOMEvent,
+                        public nsIDOMMozStkCommandEvent
+{
+  nsString mCommand;
+
+public:
+  NS_DECL_ISUPPORTS_INHERITED
+  NS_FORWARD_TO_NSDOMEVENT
+  NS_DECL_NSIDOMMOZSTKCOMMANDEVENT
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(StkCommandEvent, nsDOMEvent)
+
+  static already_AddRefed<StkCommandEvent>
+  Create(nsAString& aMessage);
+
+  nsresult
+  Dispatch(nsIDOMEventTarget* aTarget, const nsAString& aEventType)
+  {
+    NS_ASSERTION(aTarget, "Null pointer!");
+    NS_ASSERTION(!aEventType.IsEmpty(), "Empty event type!");
+
+    nsresult rv = InitEvent(aEventType, false, false);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    rv = SetTrusted(true);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    nsIDOMEvent* thisEvent =
+      static_cast<nsDOMEvent*>(const_cast<StkCommandEvent*>(this));
+
+    bool dummy;
+    rv = aTarget->DispatchEvent(thisEvent, &dummy);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    return NS_OK;
+  }
+
+private:
+  StkCommandEvent()
+  : nsDOMEvent(nullptr, nullptr)
+  { }
+
+  ~StkCommandEvent()
+  { }
+};
+
+}
+}
+}
+
+#endif // mozilla_dom_icc_stkcommandevent_h
--- a/dom/indexedDB/IDBFactory.cpp
+++ b/dom/indexedDB/IDBFactory.cpp
@@ -203,21 +203,16 @@ IDBFactory::Create(ContentParent* aConte
       NS_ASSERTION(!lastCx, "We should only be called from C++!");
     }
     else {
       NS_ERROR("nsIThreadJSContextStack::Peek should never fail!");
     }
   }
 #endif
 
-  nsCString origin;
-  nsresult rv =
-    IndexedDatabaseManager::GetASCIIOriginFromWindow(nullptr, origin);
-  NS_ENSURE_SUCCESS(rv, rv);
-
   nsCOMPtr<nsIPrincipal> principal =
     do_CreateInstance("@mozilla.org/nullprincipal;1");
   NS_ENSURE_TRUE(principal, NS_ERROR_FAILURE);
 
   JSContext* cx = nsContentUtils::GetSafeJSContext();
   NS_ENSURE_TRUE(cx, NS_ERROR_FAILURE);
 
   nsCxPusher pusher;
@@ -227,17 +222,17 @@ IDBFactory::Create(ContentParent* aConte
   }
 
   JSAutoRequest ar(cx);
 
   nsIXPConnect* xpc = nsContentUtils::XPConnect();
   NS_ASSERTION(xpc, "This should never be null!");
 
   nsCOMPtr<nsIXPConnectJSObjectHolder> globalHolder;
-  rv = xpc->CreateSandbox(cx, principal, getter_AddRefs(globalHolder));
+  nsresult rv = xpc->CreateSandbox(cx, principal, getter_AddRefs(globalHolder));
   NS_ENSURE_SUCCESS(rv, rv);
 
   JSObject* global;
   rv = globalHolder->GetJSObject(&global);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // The CreateSandbox call returns a proxy to the actual sandbox object. We
   // don't need a proxy here.
--- a/dom/indexedDB/IndexedDatabaseManager.cpp
+++ b/dom/indexedDB/IndexedDatabaseManager.cpp
@@ -981,17 +981,17 @@ IndexedDatabaseManager::GetASCIIOriginFr
 
   nsCOMPtr<nsIPrincipal> principal = sop->GetPrincipal();
   NS_ENSURE_TRUE(principal, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   if (nsContentUtils::IsSystemPrincipal(principal)) {
     aASCIIOrigin.AssignLiteral("chrome");
   }
   else {
-    nsresult rv = nsContentUtils::GetASCIIOrigin(principal, aASCIIOrigin);
+    nsresult rv = principal->GetExtendedOrigin(aASCIIOrigin);
     NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
     if (aASCIIOrigin.EqualsLiteral("null")) {
       NS_WARNING("IndexedDB databases not allowed for this principal!");
       return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
     }
   }
 
--- a/dom/indexedDB/ipc/SerializationHelpers.h
+++ b/dom/indexedDB/ipc/SerializationHelpers.h
@@ -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/. */
 
 #ifndef mozilla_dom_indexeddb_serializationhelpers_h__
 #define mozilla_dom_indexeddb_serializationhelpers_h__
 
-#include "IPC/IPCMessageUtils.h"
+#include "ipc/IPCMessageUtils.h"
 
 #include "mozilla/dom/indexedDB/DatabaseInfo.h"
 #include "mozilla/dom/indexedDB/Key.h"
 #include "mozilla/dom/indexedDB/KeyPath.h"
 #include "mozilla/dom/indexedDB/IDBCursor.h"
 #include "mozilla/dom/indexedDB/IDBTransaction.h"
 
 namespace IPC {
--- a/dom/indexedDB/test/Makefile.in
+++ b/dom/indexedDB/test/Makefile.in
@@ -24,16 +24,17 @@ MOCHITEST_FILES = \
   helpers.js \
   leaving_page_iframe.html \
   test_add_put.html \
   test_add_twice_failure.html \
   test_advance.html \
   test_autoIncrement_indexes.html \
   test_autoIncrement.html \
   test_bfcache.html \
+  test_blob_archive.html \
   test_blob_simple.html \
   test_clear.html \
   test_complex_keyPaths.html \
   test_count.html \
   test_create_index.html \
   test_create_index_with_integer_keys.html \
   test_create_objectStore.html \
   test_cursors.html \
@@ -96,16 +97,20 @@ MOCHITEST_FILES = \
   test_transaction_ordering.html \
   test_setVersion.html \
   test_setVersion_abort.html \
   test_setVersion_events.html \
   test_setVersion_exclusion.html \
   test_unique_index_update.html \
   third_party_iframe1.html \
   third_party_iframe2.html \
+  test_app_isolation_inproc.html \
+  test_app_isolation_oop.html \
+  file_app_isolation.html \
+  file_app_isolation.js \
   $(NULL)
 
 #   test_writer_starvation.html  disabled for infinite loops, bug 595368
 
 ifeq (browser,$(MOZ_BUILD_APP))
 MOCHITEST_BROWSER_FILES = \
   browser_forgetThisSite.js \
   browser_forgetThisSiteAdd.html \
new file mode 100644
--- /dev/null
+++ b/dom/indexedDB/test/file_app_isolation.html
@@ -0,0 +1,88 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    foobar!
+  </body>
+  <script>
+    var data = [
+      { id: "0", name: "foo" },
+    ];
+
+    var action = window.location.search.substring(1);
+    var finished = false;
+    var created = false; // We use that for 'read-no' action.
+
+    function finish(value) {
+      value ? alert('success') : alert('failure');
+      finished = true;
+    }
+
+    var request = window.indexedDB.open('AppIsolationTest');
+
+    request.onupgradeneeded = function(event) {
+      if (finished) {
+        finish(false);
+        return;
+      }
+
+      switch (action) {
+        case 'read-no':
+          created = true;
+          break;
+        case 'read-yes':
+          finish(false);
+          break;
+        case 'write':
+          created = true;
+
+          var db = event.target.result;
+
+          var objectStore = db.createObjectStore("test", { keyPath: "id" });
+          for (var i in data) {
+            objectStore.add(data[i]);
+          }
+          break;
+      }
+    }
+
+    request.onsuccess = function(event) {
+      if (finished) {
+        finish(false);
+        return;
+      }
+
+      var db = event.target.result;
+
+      // Think about close the db!
+      switch (action) {
+        case 'read-no':
+          db.close();
+
+          if (created) { // That means we have created it.
+            indexedDB.deleteDatabase('AppIsolationTest').onsuccess = function() {
+              finish(true);
+            };
+          } else {
+            finish(false);
+          }
+          break;
+        case 'read-yes':
+          db.transaction("test").objectStore("test").get("0").onsuccess = function(event) {
+            var name = event.target.result.name;
+            db.close();
+
+            indexedDB.deleteDatabase('AppIsolationTest').onsuccess = function() {
+              finish(name == 'foo');
+            };
+          };
+          break;
+        case 'write':
+          db.close();
+
+          // Success only if the db was actually created.
+          finish(created);
+          break;
+      }
+    };
+  </script>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/indexedDB/test/file_app_isolation.js
@@ -0,0 +1,163 @@
+SimpleTest.waitForExplicitFinish();
+
+var fileTestOnCurrentOrigin = (location.protocol + '//' + location.host + location.pathname)
+                              .replace('test_', 'file_')
+                              .replace('_inproc', '').replace('_oop', '');
+
+var previousPrefs = {
+  mozBrowserFramesEnabled: undefined,
+  oop_by_default: undefined,
+};
+
+try {
+  previousPrefs.mozBrowserFramesEnabled = SpecialPowers.getBoolPref('dom.mozBrowserFramesEnabled');
+} catch(e)
+{
+}
+
+try {
+  previousPrefs.oop_by_default = SpecialPowers.getBoolPref('dom.ipc.browser_frames.oop_by_default');
+} catch(e) {
+}
+
+SpecialPowers.setBoolPref('dom.mozBrowserFramesEnabled', true);
+SpecialPowers.setBoolPref("dom.ipc.browser_frames.oop_by_default", location.pathname.indexOf('_inproc') == -1);
+
+SpecialPowers.addPermission("browser", true, window.document);
+
+var gData = [
+  // APP 1
+  {
+    app: 'http://example.org/manifest.webapp',
+    action: 'read-no',
+    src: fileTestOnCurrentOrigin,
+  },
+  {
+    app: 'http://example.org/manifest.webapp',
+    action: 'write',
+    src: fileTestOnCurrentOrigin,
+  },
+  {
+    app: 'http://example.org/manifest.webapp',
+    action: 'read-yes',
+    src: fileTestOnCurrentOrigin,
+  },
+  // APP 2
+  {
+    app: 'https://example.com/manifest.webapp',
+    action: 'read-no',
+    src: fileTestOnCurrentOrigin,
+  },
+  {
+    app: 'https://example.com/manifest.webapp',
+    action: 'write',
+    src: fileTestOnCurrentOrigin,
+  },
+  {
+    app: 'https://example.com/manifest.webapp',
+    action: 'read-yes',
+    src: fileTestOnCurrentOrigin,
+  },
+  // Browser
+  {
+    browser: true,
+    action: 'read-no',
+    src: fileTestOnCurrentOrigin,
+  },
+  {
+    browser: true,
+    action: 'write',
+    src: fileTestOnCurrentOrigin,
+  },
+  {
+    browser: true,
+    action: 'read-yes',
+    src: fileTestOnCurrentOrigin,
+  },
+];
+
+function runTest() {
+  for (var i in gData) {
+    var iframe = document.createElement('iframe');
+    var data = gData[i];
+
+    if (data.app) {
+      iframe.setAttribute('mozbrowser', '');
+      iframe.setAttribute('mozapp', data.app);
+    } else if (data.browser) {
+      iframe.setAttribute('mozbrowser', '');
+    }
+
+    if (data.app || data.browser) {
+      iframe.addEventListener('mozbrowsershowmodalprompt', function(e) {
+        is(e.detail.message, 'success', 'test number ' + i);
+
+//        document.getElementById('content').removeChild(iframe);
+
+        i++;
+        if (i >= gData.length) {
+          if (previousPrefs.mozBrowserFramesEnabled !== undefined) {
+            SpecialPowers.setBoolPref('dom.mozBrowserFramesEnabled', previousPrefs.mozBrowserFramesEnabled);
+          }
+          if (previousPrefs.oop_by_default !== undefined) {
+            SpecialPowers.setBoolPref("dom.ipc.browser_frames.oop_by_default", previousPrefs.oop_by_default);
+          }
+
+          SpecialPowers.removePermission("browser", window.document);
+
+          indexedDB.deleteDatabase('AppIsolationTest').onsuccess = function() {
+            SimpleTest.finish();
+          };
+        } else {
+          gTestRunner.next();
+        }
+      });
+    }
+
+    iframe.src = data.src + '?' + data.action;
+
+    document.getElementById('content').appendChild(iframe);
+
+    yield;
+  }
+}
+
+var gTestRunner = runTest();
+
+function startTest() {
+  var request = window.indexedDB.open('AppIsolationTest');
+  var created = false;
+
+  request.onupgradeneeded = function(event) {
+    created = true;
+    var db = event.target.result;
+    var data = [
+      { id: "0", name: "foo" },
+    ];
+    var objectStore = db.createObjectStore("test", { keyPath: "id" });
+    for (var i in data) {
+      objectStore.add(data[i]);
+    }
+  }
+
+  request.onsuccess = function(event) {
+    var db = event.target.result;
+    is(created, true, "we should have created the db");
+
+    db.transaction("test").objectStore("test").get("0").onsuccess = function(event) {
+      is(event.target.result.name, 'foo', 'data have been written');
+      db.close();
+
+      gTestRunner.next();
+    };
+  }
+}
+
+// test_ipc.html executes all the tests in this directory in content process.
+// It will fail on this one for the moment.
+if (!SpecialPowers.isMainProcess()) {
+  todo(false, "We should make this work on content process");
+  SimpleTest.finish();
+} else {
+  startTest();
+}
--- a/dom/indexedDB/test/helpers.js
+++ b/dom/indexedDB/test/helpers.js
@@ -36,18 +36,19 @@ function clearAllDatabases(callback) {
     comp.classes["@mozilla.org/dom/indexeddb/manager;1"]
         .getService(comp.interfaces.nsIIndexedDatabaseManager);
 
   let uri = SpecialPowers.getDocumentURIObject(document);
 
   idbManager.clearDatabasesForURI(uri);
   idbManager.getUsageForURI(uri, function(uri, usage, fileUsage) {
     if (usage) {
-      throw new Error("getUsageForURI returned non-zero usage after " +
-                      "clearing all databases!");
+      ok(false,
+         "getUsageForURI returned non-zero usage after clearing all " +
+         "databases!");
     }
     runCallback();
   });
 }
 
 if (!window.runTest) {
   window.runTest = function(limitedQuota)
   {
new file mode 100644
--- /dev/null
+++ b/dom/indexedDB/test/test_app_isolation_inproc.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=756645
+-->
+<head>
+  <title>Test for IndexedDB app isolation (unique process)</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=756645">Mozilla Bug 756645</a>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script type="application/javascript;version=1.7" src="file_app_isolation.js">
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/indexedDB/test/test_app_isolation_oop.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=756645
+-->
+<head>
+  <title>Test for IndexedDB app isolation (unique process)</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=756645">Mozilla Bug 756645</a>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script type="application/javascript;version=1.7" src="file_app_isolation.js">
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/indexedDB/test/test_blob_archive.html
@@ -0,0 +1,127 @@
+<!--
+  Any copyright is dedicated to the Public Domain.
+  http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+<head>
+  <title>Indexed Database Property Test</title>
+
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+
+  <script type="text/javascript;version=1.7">
+
+  function testSteps()
+  {
+    const BLOB_DATA =
+      "504B03040A00000000002E6BF14000000000000000000000000005001C00746573742F" +
+      "555409000337CA055039CA055075780B000104E803000004E8030000504B0304140000" +
+      "0008002D6BF1401780E15015000000580200000A001C00746573742F612E7478745554" +
+      "09000336CA05503ACA055075780B000104E803000004E8030000CB48CDC9C95728CF2F" +
+      "CA49E1CA18658FB2A9C40600504B03040A00000000002F88EC40662E84701000000010" +
+      "0000000A001C00746573742F622E74787455540900035A65FF4F42C5055075780B0001" +
+      "04E803000004E803000068656C6C6F20776F726C642C2032210A504B01021E030A0000" +
+      "0000002E6BF140000000000000000000000000050018000000000000001000FD410000" +
+      "0000746573742F555405000337CA055075780B000104E803000004E8030000504B0102" +
+      "1E031400000008002D6BF1401780E15015000000580200000A00180000000000010000" +
+      "00B4813F000000746573742F612E747874555405000336CA055075780B000104E80300" +
+      "0004E8030000504B01021E030A00000000002F88EC40662E847010000000100000000A" +
+      "0018000000000001000000B48198000000746573742F622E74787455540500035A65FF" +
+      "4F75780B000104E803000004E8030000504B05060000000003000300EB000000EC0000" +
+      "000000";
+
+    const TEST_FILE_1 = "test/a.txt";
+    const TEST_FILE_2 = "test/b.txt";
+
+    let TEST_FILE_1_CONTENTS = "";
+    for (let i = 0; i < 50; i++) {
+      TEST_FILE_1_CONTENTS += "hello world\n";
+    }
+    const TEST_FILE_2_CONTENTS = "hello world, 2!\n";
+
+    let binaryData = new Uint8Array(BLOB_DATA.length / 2);
+    for (let i = 0, len = BLOB_DATA.length / 2; i < len; i++) {
+      let hex = BLOB_DATA[i * 2] + BLOB_DATA[i * 2 + 1];
+      binaryData[i] = parseInt(hex, 16);
+    }
+
+    let request = indexedDB.open(window.location.pathname, 1);
+    request.onerror = errorHandler;
+    request.onupgradeneeded = grabEventAndContinueHandler;
+    request.onsuccess = unexpectedSuccessHandler;
+    let event = yield;
+
+    let db = event.target.result;
+    db.onerror = errorHandler;
+
+    let objectStore = db.createObjectStore("foo", { autoIncrement: true });
+    let index = objectStore.createIndex("foo", "index");
+
+    request.onsuccess = grabEventAndContinueHandler;
+    event = yield;
+
+    let data = new Blob([binaryData]);
+
+    objectStore = db.transaction("foo", "readwrite").objectStore("foo");
+    objectStore.add(data).onsuccess = grabEventAndContinueHandler;
+    event = yield;
+
+    let key = event.target.result;
+
+    objectStore = db.transaction("foo").objectStore("foo");
+    objectStore.get(key).onsuccess = grabEventAndContinueHandler;
+    event = yield;
+
+    let archiveReader = new ArchiveReader(event.target.result);
+    ok(archiveReader, "Got an ArchiveReader");
+
+    request = archiveReader.getFilenames();
+    request.onsuccess = grabEventAndContinueHandler;
+    request.onerror = errorHandler;
+    event = yield;
+
+    is(event.target.result.length, 2, "Got 2 archive items");
+    is(event.target.result[0], TEST_FILE_1,
+       "First file is '" + TEST_FILE_1 + "'");
+    is(event.target.result[1], TEST_FILE_2,
+       "Second file is '" + TEST_FILE_2 + "'");
+
+    request = archiveReader.getFile(TEST_FILE_1);
+    request.onsuccess = grabEventAndContinueHandler;
+    request.onerror = errorHandler;
+    event = yield;
+
+    let fileReader = new FileReader();
+    fileReader.readAsText(event.target.result);
+    fileReader.onload = grabEventAndContinueHandler;
+    fileReader.onerror = errorHandler;
+    event = yield;
+
+    // Don't use is() because it prints out 100 lines of text...
+    ok(event.target.result == TEST_FILE_1_CONTENTS, "Correct text");
+
+    request = archiveReader.getFile(TEST_FILE_2);
+    request.onsuccess = grabEventAndContinueHandler;
+    request.onerror = errorHandler;
+    event = yield;
+
+    fileReader = new FileReader();
+    fileReader.readAsText(event.target.result);
+    fileReader.onload = grabEventAndContinueHandler;
+    fileReader.onerror = errorHandler;
+    event = yield;
+
+    // Don't use is() because it prints out a newline...
+    ok(event.target.result == TEST_FILE_2_CONTENTS, "Correct text");
+
+    finishTest();
+    yield;
+  }
+  </script>
+  <script type="text/javascript;version=1.7" src="helpers.js"></script>
+
+</head>
+
+<body onload="runTest();"></body>
+
+</html>
--- a/dom/indexedDB/test/test_blob_simple.html
+++ b/dom/indexedDB/test/test_blob_simple.html
@@ -48,16 +48,34 @@
 
     let fileReader = new FileReader();
     fileReader.onload = grabEventAndContinueHandler;
     fileReader.readAsText(event.target.result.blob);
     event = yield;
 
     is(event.target.result, BLOB_DATA.join(""), "Correct text");
 
+    info("Trying blob url");
+
+    objectStore = db.transaction("foo").objectStore("foo");
+    objectStore.get(key).onsuccess = grabEventAndContinueHandler;
+    event = yield;
+
+    let blobURL = URL.createObjectURL(event.target.result.blob);
+
+    let xhr = new XMLHttpRequest();
+    xhr.open("GET", blobURL);
+    xhr.onload = grabEventAndContinueHandler;
+    xhr.send();
+    yield;
+
+    URL.revokeObjectURL(blobURL);
+
+    is(xhr.responseText, BLOB_DATA.join(""), "Correct responseText");
+
     objectStore = db.transaction("foo").objectStore("foo");
     objectStore.mozGetAll().onsuccess = grabEventAndContinueHandler;
     event = yield;
 
     is(event.target.result.length, 2, "Got right number of items");
 
     fileReader = new FileReader();
     fileReader.onload = grabEventAndContinueHandler;
--- a/dom/interfaces/apps/mozIApplication.idl
+++ b/dom/interfaces/apps/mozIApplication.idl
@@ -6,14 +6,17 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIDOMApplicationRegistry.idl"
 
 /**
  * We expose Gecko-internal helpers related to "web apps" through this
  * sub-interface.
  */
-[scriptable, uuid(8de25e36-b4cb-4e89-9310-a199dce4e5f4)]
+[scriptable, uuid(acf46a46-729a-4ab4-9da3-8d59ecfd103d)]
 interface mozIApplication: mozIDOMApplication
 {
   /* Return true if this app has |permission|. */
   boolean hasPermission(in string permission);
+
+  /* Application status as defined in nsIPrincipal. */
+  readonly attribute unsigned short appStatus;
 };
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -22,16 +22,17 @@
 #include "mozilla/dom/ExternalHelperAppChild.h"
 #include "mozilla/dom/PCrashReporterChild.h"
 #include "mozilla/dom/StorageChild.h"
 #include "mozilla/hal_sandbox/PHalChild.h"
 #include "mozilla/ipc/TestShellChild.h"
 #include "mozilla/ipc/XPCShellEnvironment.h"
 #include "mozilla/jsipc/PContextWrapperChild.h"
 #include "mozilla/layers/CompositorChild.h"
+#include "mozilla/layers/ImageBridgeChild.h"
 #include "mozilla/layers/PCompositorChild.h"
 #include "mozilla/net/NeckoChild.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Attributes.h"
 
 #if defined(MOZ_SYDNEYAUDIO)
 #include "nsAudioStream.h"
 #endif
@@ -411,24 +412,31 @@ ContentChild::DeallocPMemoryReportReques
 
 PCompositorChild*
 ContentChild::AllocPCompositor(mozilla::ipc::Transport* aTransport,
                                base::ProcessId aOtherProcess)
 {
     return CompositorChild::Create(aTransport, aOtherProcess);
 }
 
+PImageBridgeChild*
+ContentChild::AllocPImageBridge(mozilla::ipc::Transport* aTransport,
+                                base::ProcessId aOtherProcess)
+{
+    return ImageBridgeChild::StartUpInChildProcess(aTransport, aOtherProcess);
+}
+
 PBrowserChild*
 ContentChild::AllocPBrowser(const uint32_t& aChromeFlags,
                             const bool& aIsBrowserElement, const AppId& aApp)
 {
-    uint32_t appId = aApp.get_uint32_t();
-    nsRefPtr<TabChild> iframe = new TabChild(aChromeFlags, aIsBrowserElement,
-                                             appId);
-    return NS_SUCCEEDED(iframe->Init()) ? iframe.forget().get() : NULL;
+    nsRefPtr<TabChild> child =
+        TabChild::Create(aChromeFlags, aIsBrowserElement, aApp.get_uint32_t());
+    // The ref here is released below.
+    return child.forget().get();
 }
 
 bool
 ContentChild::DeallocPBrowser(PBrowserChild* iframe)
 {
     TabChild* child = static_cast<TabChild*>(iframe);
     NS_RELEASE(child);
     return true;
@@ -924,16 +932,18 @@ ContentChild::RecvCycleCollect()
     return true;
 }
 
 static void
 PreloadSlowThings()
 {
     // This fetches and creates all the built-in stylesheets.
     nsLayoutStylesheetCache::UserContentSheet();
+
+    TabChild::PreloadSlowThings();
 }
 
 bool
 ContentChild::RecvAppInfo(const nsCString& version, const nsCString& buildID)
 {
     mAppInfo.version.Assign(version);
     mAppInfo.buildID.Assign(buildID);
 
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -36,17 +36,16 @@ namespace dom {
 class AlertObserver;
 class PrefObserver;
 class ConsoleListener;
 class PStorageChild;
 class ClonedMessageData;
 
 class ContentChild : public PContentChild
 {
-    typedef layers::PCompositorChild PCompositorChild;
     typedef mozilla::dom::ClonedMessageData ClonedMessageData;
     typedef mozilla::ipc::OptionalURIParams OptionalURIParams;
     typedef mozilla::ipc::URIParams URIParams;
 
 public:
     ContentChild();
     virtual ~ContentChild();
 
@@ -65,18 +64,22 @@ public:
         NS_ASSERTION(sSingleton, "not initialized");
         return sSingleton;
     }
 
     const AppInfo& GetAppInfo() {
         return mAppInfo;
     }
 
-    PCompositorChild* AllocPCompositor(mozilla::ipc::Transport* aTransport,
-                                       base::ProcessId aOtherProcess) MOZ_OVERRIDE;
+    PCompositorChild*
+    AllocPCompositor(mozilla::ipc::Transport* aTransport,
+                     base::ProcessId aOtherProcess) MOZ_OVERRIDE;
+    PImageBridgeChild*
+    AllocPImageBridge(mozilla::ipc::Transport* aTransport,
+                      base::ProcessId aOtherProcess) MOZ_OVERRIDE;
 
     virtual PBrowserChild* AllocPBrowser(const uint32_t& aChromeFlags,
                                          const bool& aIsBrowserElement,
                                          const AppId& aAppId);
     virtual bool DeallocPBrowser(PBrowserChild*);
 
     virtual PDeviceStorageRequestChild* AllocPDeviceStorageRequest(const DeviceStorageParams&);
     virtual bool DeallocPDeviceStorageRequest(PDeviceStorageRequestChild*);
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -26,16 +26,17 @@
 #include "mozilla/dom/ExternalHelperAppParent.h"
 #include "mozilla/dom/PMemoryReportRequestParent.h"
 #include "mozilla/dom/StorageParent.h"
 #include "mozilla/dom/devicestorage/DeviceStorageRequestParent.h"
 #include "mozilla/dom/sms/SmsParent.h"
 #include "mozilla/hal_sandbox/PHalParent.h"
 #include "mozilla/ipc/TestShellParent.h"
 #include "mozilla/layers/CompositorParent.h"
+#include "mozilla/layers/ImageBridgeParent.h"
 #include "mozilla/net/NeckoParent.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/Util.h"
 #include "mozilla/unused.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsAppDirectoryServiceDefs.h"
@@ -183,17 +184,18 @@ ContentParent::PreallocateAppProcess()
     if (sPreallocateAppProcessTask) {
         // We were called directly while a delayed task was scheduled.
         sPreallocateAppProcessTask->Cancel();
         sPreallocateAppProcessTask = nullptr;
     }
 
     sPreallocatedAppProcess =
         new ContentParent(MAGIC_PREALLOCATED_APP_MANIFEST_URL,
-                          /*isBrowserElement=*/false);
+                          /*isBrowserElement=*/false,
+                          base::PRIVILEGES_DEFAULT);
     sPreallocatedAppProcess->Init();
 }
 
 /*static*/ void
 ContentParent::DelayedPreallocateAppProcess()
 {
     sPreallocateAppProcessTask = nullptr;
     if (!sPreallocatedAppProcess) {
@@ -269,16 +271,29 @@ ContentParent::GetNewOrUsed(bool aForBro
     nsRefPtr<ContentParent> p =
         new ContentParent(/* appManifestURL = */ EmptyString(),
                           aForBrowserElement);
     p->Init();
     gNonAppContentParents->AppendElement(p);
     return p;
 }
 
+static bool
+AppNeedsInheritedOSPrivileges(mozIApplication* aApp)
+{
+    bool needsInherit = false;
+    // FIXME/bug 785592: implement a CameraBridge so we don't have to
+    // hack around with OS permissions
+    if (NS_FAILED(aApp->HasPermission("camera", &needsInherit))) {
+        NS_WARNING("Unable to check permissions.  Breakage may follow.");
+        return false;
+    }
+    return needsInherit;
+}
+
 /*static*/ TabParent*
 ContentParent::CreateBrowser(mozIApplication* aApp, bool aIsBrowserElement)
 {
     // We currently don't set the <app> ancestor for <browser> content
     // correctly.  This assertion is to notify the person who fixes
     // this code that they need to reevaluate places here where we may
     // make bad assumptions based on that bug.
     MOZ_ASSERT(!aApp || !aIsBrowserElement);
@@ -320,23 +335,30 @@ ContentParent::CreateBrowser(mozIApplica
     uint32_t appId;
     if (NS_FAILED(appsService->GetAppLocalIdByManifestURL(manifestURL, &appId))) {
         NS_ERROR("Failed to get local app ID");
         return nullptr;
     }
 
     nsRefPtr<ContentParent> p = gAppContentParents->Get(manifestURL);
     if (!p) {
-        p = MaybeTakePreallocatedAppProcess();
-        if (p) {
-            p->SetManifestFromPreallocated(manifestURL);
+        if (AppNeedsInheritedOSPrivileges(aApp)) {
+            p = new ContentParent(manifestURL, aIsBrowserElement,
+                                  base::PRIVILEGES_INHERIT);
+            p->Init();
         } else {
-            NS_WARNING("Unable to use pre-allocated app process");
-            p = new ContentParent(manifestURL, aIsBrowserElement);
-            p->Init();
+            p = MaybeTakePreallocatedAppProcess();
+            if (p) {
+                p->SetManifestFromPreallocated(manifestURL);
+            } else {
+                NS_WARNING("Unable to use pre-allocated app process");
+                p = new ContentParent(manifestURL, aIsBrowserElement,
+                                      base::PRIVILEGES_DEFAULT);
+                p->Init();
+            }
         }
         gAppContentParents->Put(manifestURL, p);
     }
 
     nsRefPtr<TabParent> tp(new TabParent(aApp, aIsBrowserElement));
     return static_cast<TabParent*>(
         // DeallocPBrowserParent() releases the ref we take here
         p->SendPBrowserConstructor(tp.forget().get(),
@@ -652,30 +674,34 @@ TestShellParent*
 ContentParent::GetTestShellSingleton()
 {
     if (!ManagedPTestShellParent().Length())
         return nullptr;
     return static_cast<TestShellParent*>(ManagedPTestShellParent()[0]);
 }
 
 ContentParent::ContentParent(const nsAString& aAppManifestURL,
-                             bool aIsForBrowser)
-    : mGeolocationWatchID(-1)
+                             bool aIsForBrowser,
+                             ChildOSPrivileges aOSPrivileges)
+    : mSubprocess(nullptr)
+    , mOSPrivileges(aOSPrivileges)
+    , mGeolocationWatchID(-1)
     , mRunToCompletionDepth(0)
     , mShouldCallUnblockChild(false)
     , mIsAlive(true)
     , mSendPermissionUpdates(false)
     , mAppManifestURL(aAppManifestURL)
 {
     // From this point on, NS_WARNING, NS_ASSERTION, etc. should print out the
     // PID along with the warning.
     nsDebugImpl::SetMultiprocessMode("Parent");
 
     NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
-    mSubprocess = new GeckoChildProcessHost(GeckoProcessType_Content);
+    mSubprocess = new GeckoChildProcessHost(GeckoProcessType_Content,
+                                            aOSPrivileges);
 
     bool useOffMainThreadCompositing = !!CompositorParent::CompositorLoop();
     if (useOffMainThreadCompositing) {
         // We need the subprocess's ProcessHandle to create the
         // PCompositor channel below.  Block just until we have that.
         mSubprocess->LaunchAndWaitForProcessHandle();
     } else {
         mSubprocess->AsyncLaunch();
@@ -690,16 +716,21 @@ ContentParent::ContentParent(const nsASt
     // channel, so delivery will happen-before any other messages
     // we send.  The CompositorChild must be created before any
     // PBrowsers are created, because they rely on the Compositor
     // already being around.  (Creation is async, so can't happen
     // on demand.)
     if (useOffMainThreadCompositing) {
         DebugOnly<bool> opened = PCompositor::Open(this);
         MOZ_ASSERT(opened);
+
+        if (Preferences::GetBool("layers.async-video.enabled",false)) {
+            opened = PImageBridge::Open(this);
+            MOZ_ASSERT(opened);
+        }
     }
 
     nsCOMPtr<nsIChromeRegistry> registrySvc = nsChromeRegistry::GetService();
     nsChromeRegistryChrome* chromeRegistry =
         static_cast<nsChromeRegistryChrome*>(registrySvc.get());
     chromeRegistry->SendRegisteredChrome(this);
     mMessageManager = nsFrameMessageManager::NewProcessMessageManager(this);
 
@@ -1046,16 +1077,23 @@ ContentParent::Observe(nsISupports* aSub
 
 PCompositorParent*
 ContentParent::AllocPCompositor(mozilla::ipc::Transport* aTransport,
                                 base::ProcessId aOtherProcess)
 {
     return CompositorParent::Create(aTransport, aOtherProcess);
 }
 
+PImageBridgeParent*
+ContentParent::AllocPImageBridge(mozilla::ipc::Transport* aTransport,
+                                 base::ProcessId aOtherProcess)
+{
+    return ImageBridgeParent::Create(aTransport, aOtherProcess);
+}
+
 PBrowserParent*
 ContentParent::AllocPBrowser(const uint32_t& aChromeFlags,
                              const bool& aIsBrowserElement, const AppId& aApp)
 {
     // We only use this Alloc() method when the content processes asks
     // us to open a window.  In that case, we're expecting to see the
     // opening PBrowser as its app descriptor, and we can trust the data
     // associated with that PBrowser since it's fully owned by this
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -51,17 +51,16 @@ class ContentParent : public PContentPar
                     , public nsIObserver
                     , public nsIThreadObserver
                     , public nsIDOMGeoPositionCallback
 {
     typedef mozilla::ipc::GeckoChildProcessHost GeckoChildProcessHost;
     typedef mozilla::ipc::OptionalURIParams OptionalURIParams;
     typedef mozilla::ipc::TestShellParent TestShellParent;
     typedef mozilla::ipc::URIParams URIParams;
-    typedef mozilla::layers::PCompositorParent PCompositorParent;
     typedef mozilla::dom::ClonedMessageData ClonedMessageData;
 
 public:
     /**
      * Start up the content-process machinery.  This might include
      * scheduling pre-launch tasks.
      */
     static void StartUp();
@@ -113,31 +112,34 @@ public:
 
     BlobParent* GetOrCreateActorForBlob(nsIDOMBlob* aBlob);
 
 protected:
     void OnChannelConnected(int32 pid);
     virtual void ActorDestroy(ActorDestroyReason why);
 
 private:
+    typedef base::ChildPrivileges ChildOSPrivileges;
+
     static nsDataHashtable<nsStringHashKey, ContentParent*> *gAppContentParents;
     static nsTArray<ContentParent*>* gNonAppContentParents;
     static nsTArray<ContentParent*>* gPrivateContent;
 
     static void PreallocateAppProcess();
     static void DelayedPreallocateAppProcess();
     static void ScheduleDelayedPreallocateAppProcess();
     static already_AddRefed<ContentParent> MaybeTakePreallocatedAppProcess();
 
     // Hide the raw constructor methods since we don't want client code
     // using them.
     using PContentParent::SendPBrowserConstructor;
     using PContentParent::SendPTestShellConstructor;
 
-    ContentParent(const nsAString& aAppManifestURL, bool aIsForBrowser);
+    ContentParent(const nsAString& aAppManifestURL, bool aIsForBrowser,
+                  ChildOSPrivileges aOSPrivileges = base::PRIVILEGES_DEFAULT);
     virtual ~ContentParent();
 
     void Init();
 
     // Transform a pre-allocated app process into a "real" app
     // process, for the specified manifest URL.
     void SetManifestFromPreallocated(const nsAString& aAppManifestURL);
 
@@ -150,18 +152,22 @@ private:
     /**
      * Exit the subprocess and vamoose.  After this call IsAlive()
      * will return false and this ContentParent will not be returned
      * by the Get*() funtions.  However, the shutdown sequence itself
      * may be asynchronous.
      */
     void ShutDownProcess();
 
-    PCompositorParent* AllocPCompositor(mozilla::ipc::Transport* aTransport,
-                                        base::ProcessId aOtherProcess) MOZ_OVERRIDE;
+    PCompositorParent*
+    AllocPCompositor(mozilla::ipc::Transport* aTransport,
+                     base::ProcessId aOtherProcess) MOZ_OVERRIDE;
+    PImageBridgeParent*
+    AllocPImageBridge(mozilla::ipc::Transport* aTransport,
+                      base::ProcessId aOtherProcess) MOZ_OVERRIDE;
 
     virtual PBrowserParent* AllocPBrowser(const uint32_t& aChromeFlags,
                                           const bool& aIsBrowserElement,
                                           const AppId& aApp);
     virtual bool DeallocPBrowser(PBrowserParent* frame);
 
     virtual PDeviceStorageRequestParent* AllocPDeviceStorageRequest(const DeviceStorageParams&);
     virtual bool DeallocPDeviceStorageRequest(PDeviceStorageRequestParent*);
@@ -274,16 +280,17 @@ private:
                                  const uint32_t& aFlags,
                                  const nsCString& aCategory);
 
     virtual bool RecvPrivateDocShellsExist(const bool& aExist);
 
     virtual void ProcessingError(Result what) MOZ_OVERRIDE;
 
     GeckoChildProcessHost* mSubprocess;
+    ChildOSPrivileges mOSPrivileges;
 
     int32_t mGeolocationWatchID;
     int mRunToCompletionDepth;
     bool mShouldCallUnblockChild;
 
     // This is a cache of all of the memory reporters
     // registered in the child process.  To update this, one
     // can broadcast the topic "child-memory-reporter-request" using
--- a/dom/ipc/Makefile.in
+++ b/dom/ipc/Makefile.in
@@ -95,16 +95,17 @@ LOCAL_INCLUDES += \
 	-I$(topsrcdir)/dom/indexedDB \
 	-I$(topsrcdir)/dom/indexedDB/ipc \
 	-I$(topsrcdir)/extensions/cookie \
 	-I$(topsrcdir)/dom/base \
 	-I$(topsrcdir)/toolkit/xre \
 	-I$(topsrcdir)/hal/sandbox \
 	-I$(topsrcdir)/dom/sms/src/ipc \
 	-I$(topsrcdir)/dom/devicestorage \
+	-I$(topsrcdir)/widget/xpwidgets \
 	$(NULL)
 
 DEFINES += -DBIN_SUFFIX='"$(BIN_SUFFIX)"'
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),$(findstring $(MOZ_WIDGET_TOOLKIT),android gtk2 gonk qt))
 DEFINES += -DMOZ_ENABLE_FREETYPE
 endif
 
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -7,16 +7,17 @@
 include protocol PAudio;
 include protocol PBlob;
 include protocol PBrowser;
 include protocol PCompositor;
 include protocol PCrashReporter;
 include protocol PExternalHelperApp;
 include protocol PDeviceStorageRequest;
 include protocol PHal;
+include protocol PImageBridge;
 include protocol PIndexedDB;
 include protocol PMemoryReportRequest;
 include protocol PNecko;
 include protocol PSms;
 include protocol PStorage;
 include protocol PTestShell;
 include DOMTypes;
 include URIParams;
@@ -148,16 +149,17 @@ struct PrefSetting {
   nsCString name;
   MaybePrefValue defaultValue;
   MaybePrefValue userValue;
 };
 
 rpc protocol PContent
 {
     parent opens PCompositor;
+    parent opens PImageBridge;
 
     manages PAudio;
     manages PBlob;
     manages PBrowser;
     manages PCrashReporter;
     manages PDeviceStorageRequest;
     manages PExternalHelperApp;
     manages PHal;
--- a/dom/ipc/PermissionMessageUtils.h
+++ b/dom/ipc/PermissionMessageUtils.h
@@ -1,17 +1,17 @@
 /* -*- 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/. */
 
 #ifndef mozilla_dom_permission_message_utils_h__
 #define mozilla_dom_permission_message_utils_h__
 
-#include "IPC/IPCMessageUtils.h"
+#include "ipc/IPCMessageUtils.h"
 #include "nsCOMPtr.h"
 #include "nsIPrincipal.h"
 
 namespace IPC {
 
 class Principal {
   friend struct ParamTraits<Principal>;
 
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -7,24 +7,26 @@
 #include "base/basictypes.h"
 
 #include "TabChild.h"
 
 #include "BasicLayers.h"
 #include "Blob.h"
 #include "ContentChild.h"
 #include "IndexedDBChild.h"
+#include "mozilla/ClearOnShutdown.h"
 #include "mozilla/IntentionalCrash.h"
 #include "mozilla/docshell/OfflineCacheUpdateChild.h"
 #include "mozilla/dom/PContentChild.h"
 #include "mozilla/dom/PContentDialogChild.h"
 #include "mozilla/ipc/DocumentRendererChild.h"
 #include "mozilla/layers/CompositorChild.h"
 #include "mozilla/layers/PLayersChild.h"
 #include "mozilla/layout/RenderFrameChild.h"
+#include "mozilla/StaticPtr.h"
 #include "mozilla/unused.h"
 #include "nsComponentManagerUtils.h"
 #include "nsComponentManagerUtils.h"
 #include "nsContentUtils.h"
 #include "nsEmbedCID.h"
 #include "nsEventListenerManager.h"
 #include "nsIBaseWindow.h"
 #include "nsIComponentManager.h"
@@ -57,19 +59,23 @@
 #include "nsPIWindowRoot.h"
 #include "nsPresContext.h"
 #include "nsPrintfCString.h"
 #include "nsScriptLoader.h"
 #include "nsSerializationHelper.h"
 #include "nsThreadUtils.h"
 #include "nsWeakReference.h"
 #include "PCOMContentPermissionRequestChild.h"
+#include "PuppetWidget.h"
 #include "StructuredCloneUtils.h"
 #include "xpcpublic.h"
 
+#define BROWSER_ELEMENT_CHILD_SCRIPT \
+    NS_LITERAL_STRING("chrome://global/content/BrowserElementChild.js")
+
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::ipc;
 using namespace mozilla::layers;
 using namespace mozilla::layout;
 using namespace mozilla::docshell;
 using namespace mozilla::dom::indexedDB;
 using namespace mozilla::widget;
@@ -88,28 +94,71 @@ ContentListener::HandleEvent(nsIDOMEvent
 
 class ContentDialogChild : public PContentDialogChild
 {
 public:
   virtual bool Recv__delete__(const InfallibleTArray<int>& aIntParams,
                               const InfallibleTArray<nsString>& aStringParams);
 };
 
+StaticRefPtr<TabChild> sPreallocatedTab;
+
+/*static*/ void
+TabChild::PreloadSlowThings()
+{
+    MOZ_ASSERT(!sPreallocatedTab);
+
+    nsRefPtr<TabChild> tab(new TabChild(0, false,
+                                        nsIScriptSecurityManager::NO_APP_ID));
+    if (!NS_SUCCEEDED(tab->Init()) ||
+        !tab->InitTabChildGlobal(DONT_LOAD_SCRIPTS)) {
+        return;
+    }
+    tab->TryCacheLoadAndCompileScript(BROWSER_ELEMENT_CHILD_SCRIPT);
+
+    sPreallocatedTab = tab;
+    ClearOnShutdown(&sPreallocatedTab);
+}
+
+/*static*/ already_AddRefed<TabChild>
+TabChild::Create(uint32_t aChromeFlags,
+                 bool aIsBrowserElement, uint32_t aAppId)
+{
+    if (sPreallocatedTab &&
+        sPreallocatedTab->mChromeFlags == aChromeFlags &&
+        (aIsBrowserElement || 
+         aAppId != nsIScriptSecurityManager::NO_APP_ID)) {
+        nsRefPtr<TabChild> child = sPreallocatedTab.get();
+        sPreallocatedTab = nullptr;
+
+        MOZ_ASSERT(!child->mTriedBrowserInit);
+
+        child->SetAppBrowserConfig(aIsBrowserElement, aAppId);
+
+        return child.forget();
+    }
+
+    nsRefPtr<TabChild> iframe = new TabChild(aChromeFlags, aIsBrowserElement,
+                                             aAppId);
+    return NS_SUCCEEDED(iframe->Init()) ? iframe.forget() : nullptr;
+}
+
 
 TabChild::TabChild(uint32_t aChromeFlags, bool aIsBrowserElement,
                    uint32_t aAppId)
   : mRemoteFrame(nullptr)
   , mTabChildGlobal(nullptr)
   , mChromeFlags(aChromeFlags)
   , mOuterRect(0, 0, 0, 0)
   , mLastBackgroundColor(NS_RGB(255, 255, 255))
+  , mAppId(aAppId)
   , mDidFakeShow(false)
   , mIsBrowserElement(aIsBrowserElement)
   , mNotified(false)
-  , mAppId(aAppId)
+  , mTriedBrowserInit(false)
 {
     printf("creating %d!\n", NS_IsMainThread());
 }
 
 nsresult
 TabChild::Observe(nsISupports *aSubject,
                   const char *aTopic,
                   const PRUnichar *aData)
@@ -145,32 +194,72 @@ TabChild::Init()
   }
 
   webBrowser->SetContainerWindow(this);
   mWebNav = do_QueryInterface(webBrowser);
   NS_ASSERTION(mWebNav, "nsWebBrowser doesn't implement nsIWebNavigation?");
 
   nsCOMPtr<nsIDocShellTreeItem> docShellItem(do_QueryInterface(mWebNav));
   docShellItem->SetItemType(nsIDocShellTreeItem::typeContentWrapper);
-
-  nsCOMPtr<nsIObserverService> observerService =
-    do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
+  
+  nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(mWebNav);
+  if (!baseWindow) {
+    NS_ERROR("mWebNav doesn't QI to nsIBaseWindow");
+    return false;
+  }
 
-  if (observerService) {
-    observerService->AddObserver(this,
-                                 "cancel-default-pan-zoom",
-                                 false);
-    observerService->AddObserver(this,
-                                 "browser-zoom-to-rect",
-                                 false);
+  mWidget = nsIWidget::CreatePuppetWidget(this);
+  if (!mWidget) {
+    NS_ERROR("couldn't create fake widget");
+    return false;
+  }
+  mWidget->Create(
+    nullptr, 0,              // no parents
+    nsIntRect(nsIntPoint(0, 0), nsIntSize(0, 0)),
+    nullptr,                 // HandleWidgetEvent
+    nullptr                  // nsDeviceContext
+  );
+
+  baseWindow->InitWindow(0, mWidget, 0, 0, 0, 0);
+  baseWindow->Create();
+
+  SetAppBrowserConfig(mIsBrowserElement, mAppId);
+
+  // IPC uses a WebBrowser object for which DNS prefetching is turned off
+  // by default. But here we really want it, so enable it explicitly
+  nsCOMPtr<nsIWebBrowserSetup> webBrowserSetup =
+    do_QueryInterface(baseWindow);
+  if (webBrowserSetup) {
+    webBrowserSetup->SetProperty(nsIWebBrowserSetup::SETUP_ALLOW_DNS_PREFETCH,
+                                 true);
+  } else {
+    NS_WARNING("baseWindow doesn't QI to nsIWebBrowserSetup, skipping "
+               "DNS prefetching enable step.");
   }
 
   return NS_OK;
 }
 
+void
+TabChild::SetAppBrowserConfig(bool aIsBrowserElement, uint32_t aAppId)
+{
+    mIsBrowserElement = aIsBrowserElement;
+    mAppId = aAppId;
+
+    nsCOMPtr<nsIDocShell> docShell = do_GetInterface(mWebNav);
+    MOZ_ASSERT(docShell);
+
+    if (docShell) {
+        docShell->SetAppId(mAppId);
+        if (mIsBrowserElement) {
+            docShell->SetIsBrowserElement();
+        }
+    }
+}
+
 NS_INTERFACE_MAP_BEGIN(TabChild)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebBrowserChrome)
   NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome)
   NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome2)
   NS_INTERFACE_MAP_ENTRY(nsIEmbeddingSiteWindow)
   NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChromeFocus)
   NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
   NS_INTERFACE_MAP_ENTRY(nsIWindowProvider)
@@ -564,16 +653,18 @@ TabChild::ActorDestroy(ActorDestroyReaso
     static_cast<nsFrameMessageManager*>
       (mTabChildGlobal->mMessageManager.get())->Disconnect();
     mTabChildGlobal->mMessageManager = nullptr;
   }
 }
 
 TabChild::~TabChild()
 {
+    DestroyWindow();
+
     nsCOMPtr<nsIWebBrowser> webBrowser = do_QueryInterface(mWebNav);
     if (webBrowser) {
       webBrowser->SetContainerWindow(nullptr);
     }
     if (mCx) {
       DestroyCx();
     }
     
@@ -606,63 +697,39 @@ TabChild::DoFakeShow()
 {
   RecvShow(nsIntSize(0, 0));
   mDidFakeShow = true;
 }
 
 bool
 TabChild::RecvShow(const nsIntSize& size)
 {
+
     if (mDidFakeShow) {
         return true;
     }
 
     printf("[TabChild] SHOW (w,h)= (%d, %d)\n", size.width, size.height);
 
     nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(mWebNav);
     if (!baseWindow) {
         NS_ERROR("mWebNav doesn't QI to nsIBaseWindow");
         return false;
     }
 
-    if (!InitWidget(size)) {
+    if (!InitRenderingState()) {
         // We can fail to initialize our widget if the <browser
         // remote> has already been destroyed, and we couldn't hook
         // into the parent-process's layer system.  That's not a fatal
         // error.
         return true;
     }
 
-    baseWindow->InitWindow(0, mWidget,
-                           0, 0, size.width, size.height);
-    baseWindow->Create();
-
-    nsCOMPtr<nsIDocShell> docShell = do_GetInterface(mWebNav);
-    MOZ_ASSERT(docShell);
-
-    if (docShell) {
-      docShell->SetAppId(mAppId);
-      if (mIsBrowserElement) {
-        docShell->SetIsBrowserElement();
-      }
-    }
-
     baseWindow->SetVisibility(true);
 
-    // IPC uses a WebBrowser object for which DNS prefetching is turned off
-    // by default. But here we really want it, so enable it explicitly
-    nsCOMPtr<nsIWebBrowserSetup> webBrowserSetup = do_QueryInterface(baseWindow);
-    if (webBrowserSetup) {
-      webBrowserSetup->SetProperty(nsIWebBrowserSetup::SETUP_ALLOW_DNS_PREFETCH,
-                                   true);
-    } else {
-        NS_WARNING("baseWindow doesn't QI to nsIWebBrowserSetup, skipping "
-                   "DNS prefetching enable step.");
-    }
-
     return InitTabChildGlobal();
 }
 
 bool
 TabChild::RecvUpdateDimensions(const nsRect& rect, const nsIntSize& size)
 {
 #ifdef DEBUG
     printf("[TabChild] Update Dimensions to (x,y,w,h)= (%ud, %ud, %ud, %ud) and move to (w,h)= (%ud, %ud)\n", rect.x, rect.y, rect.width, rect.height, size.width, size.height);
@@ -1155,68 +1222,57 @@ TabChild::AllocPRenderFrame(ScrollingBeh
 bool
 TabChild::DeallocPRenderFrame(PRenderFrameChild* aFrame)
 {
     delete aFrame;
     return true;
 }
 
 bool
-TabChild::InitTabChildGlobal()
+TabChild::InitTabChildGlobal(FrameScriptLoading aScriptLoading)
 {
-  if (mCx && mTabChildGlobal)
-    return true;
+  if (!mCx && !mTabChildGlobal) {
+    nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(mWebNav);
+    NS_ENSURE_TRUE(window, false);
+    nsCOMPtr<nsIDOMEventTarget> chromeHandler =
+      do_QueryInterface(window->GetChromeEventHandler());
+    NS_ENSURE_TRUE(chromeHandler, false);
 
-  nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(mWebNav);
-  NS_ENSURE_TRUE(window, false);
-  nsCOMPtr<nsIDOMEventTarget> chromeHandler =
-    do_QueryInterface(window->GetChromeEventHandler());
-  NS_ENSURE_TRUE(chromeHandler, false);
+    nsRefPtr<TabChildGlobal> scope = new TabChildGlobal(this);
+    NS_ENSURE_TRUE(scope, false);
 
-  nsRefPtr<TabChildGlobal> scope = new TabChildGlobal(this);
-  NS_ENSURE_TRUE(scope, false);
-
-  mTabChildGlobal = scope;
+    mTabChildGlobal = scope;
 
-  nsISupports* scopeSupports =
-    NS_ISUPPORTS_CAST(nsIDOMEventTarget*, scope);
+    nsISupports* scopeSupports = NS_ISUPPORTS_CAST(nsIDOMEventTarget*, scope);
   
-  NS_ENSURE_TRUE(InitTabChildGlobalInternal(scopeSupports), false); 
+    NS_ENSURE_TRUE(InitTabChildGlobalInternal(scopeSupports), false); 
 
-  scope->Init();
+    scope->Init();
 
-  nsCOMPtr<nsPIWindowRoot> root = do_QueryInterface(chromeHandler);
-  NS_ENSURE_TRUE(root, false);
-  root->SetParentTarget(scope);
+    nsCOMPtr<nsPIWindowRoot> root = do_QueryInterface(chromeHandler);
+    NS_ENSURE_TRUE(root, false);
+    root->SetParentTarget(scope);
+  }
 
-  // Initialize the child side of the browser element machinery, if appropriate.
-  if (mIsBrowserElement || mAppId != nsIScriptSecurityManager::NO_APP_ID) {
-    RecvLoadRemoteScript(
-      NS_LITERAL_STRING("chrome://global/content/BrowserElementChild.js"));
+  if (aScriptLoading != DONT_LOAD_SCRIPTS && !mTriedBrowserInit) {
+    mTriedBrowserInit = true;
+    // Initialize the child side of the browser element machinery,
+    // if appropriate.
+    if (mIsBrowserElement || mAppId != nsIScriptSecurityManager::NO_APP_ID) {
+      RecvLoadRemoteScript(BROWSER_ELEMENT_CHILD_SCRIPT);
+    }
   }
 
   return true;
 }
 
 bool
-TabChild::InitWidget(const nsIntSize& size)
+TabChild::InitRenderingState()
 {
-    NS_ABORT_IF_FALSE(!mWidget && !mRemoteFrame, "CreateWidget twice?");
-
-    mWidget = nsIWidget::CreatePuppetWidget(this);
-    if (!mWidget) {
-        NS_ERROR("couldn't create fake widget");
-        return false;
-    }
-    mWidget->Create(
-        nullptr, 0,              // no parents
-        nsIntRect(nsIntPoint(0, 0), size),
-        nullptr,                 // HandleWidgetEvent
-        nullptr                  // nsDeviceContext
-        );
+    static_cast<PuppetWidget*>(mWidget.get())->InitIMEState();
 
     LayersBackend be;
     uint64_t id;
     int32_t maxTextureSize;
     RenderFrameChild* remoteFrame =
         static_cast<RenderFrameChild*>(SendPRenderFrameConstructor(
                                            &mScrolling, &be, &maxTextureSize, &id));
     if (!remoteFrame) {
@@ -1247,29 +1303,53 @@ TabChild::InitWidget(const nsIntSize& si
     ShadowLayerForwarder* lf =
         mWidget->GetLayerManager(shadowManager, be)->AsShadowForwarder();
     NS_ABORT_IF_FALSE(lf && lf->HasShadowManager(),
                       "PuppetWidget should have shadow manager");
     lf->SetParentBackendType(be);
     lf->SetMaxTextureSize(maxTextureSize);
 
     mRemoteFrame = remoteFrame;
+
+    nsCOMPtr<nsIObserverService> observerService =
+        do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
+
+    if (observerService) {
+        observerService->AddObserver(this,
+                                     "cancel-default-pan-zoom",
+                                     false);
+        observerService->AddObserver(this,
+                                     "browser-zoom-to-rect",
+                                     false);
+    }
+
     return true;
 }
 
 void
 TabChild::SetBackgroundColor(const nscolor& aColor)
 {
   if (mLastBackgroundColor != aColor) {
     mLastBackgroundColor = aColor;
     SendSetBackgroundColor(mLastBackgroundColor);
   }
 }
 
 void
+TabChild::GetDPI(float* aDPI)
+{
+    *aDPI = -1.0;
+    if (!mRemoteFrame) {
+        return;
+    }
+
+    SendGetDPI(aDPI);
+}
+
+void
 TabChild::NotifyPainted()
 {
     if (UseDirectCompositor() && !mNotified) {
         mRemoteFrame->SendNotifyCompositorTransaction();
         mNotified = true;
     }
 }
 
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -144,26 +144,28 @@ class TabChild : public PBrowserChild,
                  public nsIDialogCreator,
                  public nsITabChild,
                  public nsIObserver
 {
     typedef mozilla::layout::RenderFrameChild RenderFrameChild;
     typedef mozilla::dom::ClonedMessageData ClonedMessageData;
 
 public:
-    /**
-     * Create a new TabChild object.
-     *
-     * |aIsBrowserElement| indicates whether the tab is inside an <iframe mozbrowser>.
-     * |aAppId| is the app id of the app containing this tab. If the tab isn't
-     * contained in an app, aAppId will be nsIScriptSecurityManager::NO_APP_ID.
+    /** 
+     * This is expected to be called off the critical path to content
+     * startup.  This is an opportunity to load things that are slow
+     * on the critical path.
      */
-    TabChild(uint32_t aChromeFlags, bool aIsBrowserElement, uint32_t aAppId);
+    static void PreloadSlowThings();
+
+    /** Return a TabChild with the given attributes. */
+    static already_AddRefed<TabChild> 
+    Create(uint32_t aChromeFlags, bool aIsBrowserElement, uint32_t aAppId);
+
     virtual ~TabChild();
-    nsresult Init();
 
     uint32_t GetAppId() { return mAppId; }
 
     NS_DECL_ISUPPORTS
     NS_DECL_NSIWEBBROWSERCHROME
     NS_DECL_NSIWEBBROWSERCHROME2
     NS_DECL_NSIEMBEDDINGSITEWINDOW
     NS_DECL_NSIWEBBROWSERCHROMEFOCUS
@@ -254,16 +256,19 @@ public:
     virtual bool DeallocPOfflineCacheUpdate(POfflineCacheUpdateChild* offlineCacheUpdate);
 
     nsIWebNavigation* WebNavigation() { return mWebNav; }
 
     JSContext* GetJSContext() { return mCx; }
 
     nsIPrincipal* GetPrincipal() { return mPrincipal; }
 
+    /** Return the DPI of the widget this TabChild draws to. */
+    void GetDPI(float* aDPI);
+
     void SetBackgroundColor(const nscolor& aColor);
 
     void NotifyPainted();
 
     bool IsAsyncPanZoomEnabled();
 
 protected:
     virtual PRenderFrameChild* AllocPRenderFrame(ScrollingBehavior* aScrolling,
@@ -276,22 +281,36 @@ protected:
     nsEventStatus DispatchWidgetEvent(nsGUIEvent& event);
 
     virtual PIndexedDBChild* AllocPIndexedDB(const nsCString& aASCIIOrigin,
                                              bool* /* aAllowed */);
 
     virtual bool DeallocPIndexedDB(PIndexedDBChild* aActor);
 
 private:
+    /**
+     * Create a new TabChild object.
+     *
+     * |aIsBrowserElement| indicates whether the tab is inside an <iframe mozbrowser>.
+     * |aAppId| is the app id of the app containing this tab. If the tab isn't
+     * contained in an app, aAppId will be nsIScriptSecurityManager::NO_APP_ID.
+     */
+    TabChild(uint32_t aChromeFlags, bool aIsBrowserElement, uint32_t aAppId);
+
+    nsresult Init();
+
+    void SetAppBrowserConfig(bool aIsBrowserElement, uint32_t aAppId);
+
     bool UseDirectCompositor();
 
     void ActorDestroy(ActorDestroyReason why);
 
-    bool InitTabChildGlobal();
-    bool InitWidget(const nsIntSize& size);
+    enum FrameScriptLoading { DONT_LOAD_SCRIPTS, DEFAULT_LOAD_SCRIPTS };
+    bool InitTabChildGlobal(FrameScriptLoading aScriptLoading = DEFAULT_LOAD_SCRIPTS);
+    bool InitRenderingState();
     void DestroyWindow();
 
     // Call RecvShow(nsIntSize(0, 0)) and block future calls to RecvShow().
     void DoFakeShow();
 
     // Wraps up a JSON object as a structured clone and sends it to the browser
     // chrome script.
     //
@@ -311,20 +330,21 @@ private:
     nsCOMPtr<nsIWebNavigation> mWebNav;
     nsCOMPtr<nsIWidget> mWidget;
     RenderFrameChild* mRemoteFrame;
     nsRefPtr<TabChildGlobal> mTabChildGlobal;
     uint32_t mChromeFlags;
     nsIntRect mOuterRect;
     nscolor mLastBackgroundColor;
     ScrollingBehavior mScrolling;
+    uint32_t mAppId;
     bool mDidFakeShow;
     bool mIsBrowserElement;
     bool mNotified;
-    uint32_t mAppId;
+    bool mTriedBrowserInit;
 
     DISALLOW_EVIL_CONSTRUCTORS(TabChild);
 };
 
 inline TabChild*
 GetTabChildFrom(nsIDocShell* aDocShell)
 {
     nsCOMPtr<nsITabChild> tc = do_GetInterface(aDocShell);
--- a/dom/ipc/TabMessageUtils.h
+++ b/dom/ipc/TabMessageUtils.h
@@ -1,17 +1,17 @@
 /* -*- 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/. */
 
 #ifndef TABMESSAGE_UTILS_H
 #define TABMESSAGE_UTILS_H
 
-#include "IPC/IPCMessageUtils.h"
+#include "ipc/IPCMessageUtils.h"
 #include "nsIDOMEvent.h"
 #include "nsCOMPtr.h"
 
 #ifdef MOZ_CRASHREPORTER
 #include "nsExceptionHandler.h"
 #endif
 
 namespace mozilla {
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -167,16 +167,21 @@ TabParent::RecvEvent(const RemoteDOMEven
 
 bool
 TabParent::AnswerCreateWindow(PBrowserParent** retval)
 {
     if (!mBrowserDOMWindow) {
         return false;
     }
 
+    // Only non-app, non-browser processes may call CreateWindow.
+    if (GetApp() || IsBrowserElement()) {
+        return false;
+    }
+
     // Get a new rendering area from the browserDOMWin.  We don't want
     // to be starting any loads here, so get it with a null URI.
     nsCOMPtr<nsIFrameLoaderOwner> frameLoaderOwner;
     mBrowserDOMWindow->OpenURIInFrame(nullptr, nullptr,
                                       nsIBrowserDOMWindow::OPEN_NEWTAB,
                                       nsIBrowserDOMWindow::OPEN_NEW,
                                       getter_AddRefs(frameLoaderOwner));
     if (!frameLoaderOwner) {
@@ -352,16 +357,24 @@ bool TabParent::SendRealKeyEvent(nsKeyEv
   nsKeyEvent e(event);
   MaybeForwardEventToRenderFrame(event, &e);
   return PBrowserParent::SendRealKeyEvent(e);
 }
 
 bool TabParent::SendRealTouchEvent(nsTouchEvent& event)
 {
   nsTouchEvent e(event);
+  // PresShell::HandleEventInternal adds touches on touch end/cancel.
+  // This hack filters those out. Bug 785554
+  if (event.message == NS_TOUCH_END || event.message == NS_TOUCH_CANCEL) {
+    for (int i = e.touches.Length() - 1; i >= 0; i--) {
+      if (!e.touches[i]->mChanged)
+        e.touches.RemoveElementAt(i);
+    }
+  }
   MaybeForwardEventToRenderFrame(event, &e);
   return (e.message == NS_TOUCH_MOVE) ?
     PBrowserParent::SendRealTouchMoveEvent(e) :
     PBrowserParent::SendRealTouchEvent(e);
 }
 
 bool
 TabParent::RecvSyncMessage(const nsString& aMessage,
--- a/dom/network/interfaces/Makefile.in
+++ b/dom/network/interfaces/Makefile.in
@@ -11,20 +11,26 @@ include $(DEPTH)/config/autoconf.mk
 
 XPIDL_MODULE = dom_network
 
 include $(topsrcdir)/dom/dom-config.mk
 
 XPIDLSRCS = \
   nsIDOMNavigatorNetwork.idl \
   nsIDOMConnection.idl \
-  nsIDOMMobileConnection.idl \
-  nsIMobileConnectionProvider.idl \
   nsIDOMUSSDReceivedEvent.idl \
   nsIDOMTCPSocket.idl \
   $(NULL)
 
+ifdef MOZ_B2G_RIL
+XPIDLSRCS += \
+  nsIDOMMobileConnection.idl \
+  nsIMobileConnectionProvider.idl \
+  nsINavigatorMobileConnection.idl \
+  $(NULL)
+endif
+
 include $(topsrcdir)/config/rules.mk
 
 XPIDL_FLAGS += \
   -I$(topsrcdir)/dom/interfaces/base \
   -I$(topsrcdir)/dom/interfaces/events \
   $(NULL)
--- a/dom/network/interfaces/nsIDOMMobileConnection.idl
+++ b/dom/network/interfaces/nsIDOMMobileConnection.idl
@@ -4,18 +4,19 @@
 
 #include "nsIDOMEventTarget.idl"
 
 interface nsIDOMEventListener;
 interface nsIDOMDOMRequest;
 interface nsIDOMMozMobileConnectionInfo;
 interface nsIDOMMozMobileNetworkInfo;
 interface nsIDOMMozMobileCellInfo;
+interface nsIDOMMozIccManager;
 
-[scriptable, builtinclass, uuid(e7309c47-9a2e-4e12-84ab-f8f39214eaba)]
+[scriptable, builtinclass, uuid(46fa4f72-9c81-4b7f-b395-87202966e526)]
 interface nsIDOMMozMobileConnection : nsIDOMEventTarget
 {
   /**
    * Indicates the state of the device's ICC card.
    *
    * Possible values: null, 'absent', 'pinRequired', 'pukRequired',
    * 'networkLocked', 'ready'.
    */
@@ -34,16 +35,21 @@ interface nsIDOMMozMobileConnection : ns
   /**
    * The selection mode of the voice and data networks.
    *
    * Possible values: null (unknown), 'automatic', 'manual'
    */
   readonly attribute DOMString networkSelectionMode;
 
   /**
+   * IccManager provides access to ICC related funcionality.
+   */
+  readonly attribute nsIDOMMozIccManager icc;
+
+  /**
    * Search for available networks.
    *
    * If successful, the request's onsuccess will be called, and the request's
    * result will be an array of nsIDOMMozMobileNetworkInfo.
    *
    * Otherwise, the request's onerror will be called, and the request's error
    * will be either 'RadioNotAvailable', 'RequestNotSupported',
    * or 'GenericFailure'.
--- a/dom/network/interfaces/nsIDOMNavigatorNetwork.idl
+++ b/dom/network/interfaces/nsIDOMNavigatorNetwork.idl
@@ -1,15 +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/. */
 
 #include "nsISupports.idl"
 
 interface nsIDOMMozConnection;
-interface nsIDOMMozMobileConnection;
 
-[scriptable, uuid(fb7c3429-aa2c-4ccc-948a-467c0de29fff)]
+[scriptable, uuid(c1685d27-f2e2-4ed9-998f-ff5b1442058f)]
 interface nsIDOMMozNavigatorNetwork : nsISupports
 {
   readonly attribute nsIDOMMozConnection mozConnection;
-  readonly attribute nsIDOMMozMobileConnection mozMobileConnection;
 };
--- a/dom/network/interfaces/nsIMobileConnectionProvider.idl
+++ b/dom/network/interfaces/nsIMobileConnectionProvider.idl
@@ -23,11 +23,18 @@ interface nsIMobileConnectionProvider : 
 
   nsIDOMDOMRequest getNetworks(in nsIDOMWindow window);
   nsIDOMDOMRequest selectNetwork(in nsIDOMWindow window, in nsIDOMMozMobileNetworkInfo network);
   nsIDOMDOMRequest selectNetworkAutomatically(in nsIDOMWindow window);
 
   nsIDOMDOMRequest getCardLock(in nsIDOMWindow window, in DOMString lockType);
   nsIDOMDOMRequest unlockCardLock(in nsIDOMWindow window, in jsval info);
   nsIDOMDOMRequest setCardLock(in nsIDOMWindow window, in jsval info);
+
   nsIDOMDOMRequest sendUSSD(in nsIDOMWindow window, in DOMString ussd);
   nsIDOMDOMRequest cancelUSSD(in nsIDOMWindow window);
+
+  void sendStkResponse(in nsIDOMWindow window,
+                       in jsval        response);
+  void sendStkMenuSelection(in nsIDOMWindow   window,
+                            in unsigned short itemIdentifier,
+                            in boolean        helpRequested);
 };
new file mode 100644
--- /dev/null
+++ b/dom/network/interfaces/nsINavigatorMobileConnection.idl
@@ -0,0 +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/. */
+
+#include "nsISupports.idl"
+
+interface nsIDOMMozMobileConnection;
+
+[scriptable, uuid(d8672694-3334-4d0d-a4c3-38fa70c265d0)]
+interface nsIMozNavigatorMobileConnection : nsISupports
+{
+  readonly attribute nsIDOMMozMobileConnection mozMobileConnection;
+};
--- a/dom/network/src/Makefile.in
+++ b/dom/network/src/Makefile.in
@@ -25,20 +25,31 @@ EXPORTS_NAMESPACES = mozilla/dom/network
 EXPORTS_mozilla/dom/network = \
   Utils.h \
   Types.h \
   Constants.h \
   $(NULL)
 
 CPPSRCS = \
   Connection.cpp \
-  MobileConnection.cpp \
   Utils.cpp \
   USSDReceivedEvent.cpp \
   $(NULL)
 
+ifdef MOZ_B2G_RIL
+CPPSRCS += \
+  MobileConnection.cpp \
+  $(NULL)
+endif
+
 LOCAL_INCLUDES = \
   -I$(topsrcdir)/content/events/src \
   $(NULL)
 
+ifdef MOZ_B2G_RIL
+LOCAL_INCLUDES += \
+  -I$(topsrcdir)/dom/icc/src \
+  $(NULL)
+endif
+
 include $(topsrcdir)/config/config.mk
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
 include $(topsrcdir)/config/rules.mk
--- a/dom/network/src/MobileConnection.cpp
+++ b/dom/network/src/MobileConnection.cpp
@@ -4,16 +4,17 @@
 
 #include "MobileConnection.h"
 #include "nsIDOMDOMRequest.h"
 #include "nsIDOMClassInfo.h"
 #include "nsDOMEvent.h"
 #include "nsIObserverService.h"
 #include "USSDReceivedEvent.h"
 #include "mozilla/Services.h"
+#include "IccManager.h"
 
 #define NS_RILCONTENTHELPER_CONTRACTID "@mozilla.org/ril/content-helper;1"
 
 #define VOICECHANGE_EVENTNAME      NS_LITERAL_STRING("voicechange")
 #define DATACHANGE_EVENTNAME       NS_LITERAL_STRING("datachange")
 #define CARDSTATECHANGE_EVENTNAME  NS_LITERAL_STRING("cardstatechange")
 #define USSDRECEIVED_EVENTNAME     NS_LITERAL_STRING("ussdreceived")
 
@@ -40,16 +41,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(MobileConnection,
                                                 nsDOMEventTargetHelper)
   NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(cardstatechange)
   NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(voicechange)
   NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(datachange)
   NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(ussdreceived)
   tmp->mProvider = nullptr;
+  tmp->mIccManager = nullptr;
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(MobileConnection)
   NS_INTERFACE_MAP_ENTRY(nsIDOMMozMobileConnection)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMMozMobileConnection)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozMobileConnection)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
@@ -77,31 +79,39 @@ MobileConnection::Init(nsPIDOMWindow* aW
     NS_WARNING("Could not acquire nsIObserverService!");
     return;
   }
 
   obs->AddObserver(this, kVoiceChangedTopic, false);
   obs->AddObserver(this, kDataChangedTopic, false);
   obs->AddObserver(this, kCardStateChangedTopic, false);
   obs->AddObserver(this, kUssdReceivedTopic, false);
+
+  mIccManager = new icc::IccManager();
+  mIccManager->Init(aWindow);
 }
 
 void
 MobileConnection::Shutdown()
 {
   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
   if (!obs) {
     NS_WARNING("Could not acquire nsIObserverService!");
     return;
   }
 
   obs->RemoveObserver(this, kVoiceChangedTopic);
   obs->RemoveObserver(this, kDataChangedTopic);
   obs->RemoveObserver(this, kCardStateChangedTopic);
   obs->RemoveObserver(this, kUssdReceivedTopic);
+
+  if (mIccManager) {
+    mIccManager->Shutdown();
+    mIccManager = nullptr;
+  }
 }
 
 // nsIObserver
 
 NS_IMETHODIMP
 MobileConnection::Observe(nsISupports* aSubject,
                           const char* aTopic,
                           const PRUnichar* aData)
@@ -176,16 +186,23 @@ MobileConnection::GetNetworkSelectionMod
   if (!mProvider) {
     networkSelectionMode.SetIsVoid(true);
     return NS_OK;
   }
   return mProvider->GetNetworkSelectionMode(networkSelectionMode);
 }
 
 NS_IMETHODIMP
+MobileConnection::GetIcc(nsIDOMMozIccManager** aIcc)
+{
+  NS_IF_ADDREF(*aIcc = mIccManager);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 MobileConnection::GetNetworks(nsIDOMDOMRequest** request)
 {
   *request = nullptr;
 
   if (!mProvider) {
     return NS_ERROR_FAILURE;
   }
 
--- a/dom/network/src/MobileConnection.h
+++ b/dom/network/src/MobileConnection.h
@@ -5,19 +5,25 @@
 #ifndef mozilla_dom_network_MobileConnection_h
 #define mozilla_dom_network_MobileConnection_h
 
 #include "nsIObserver.h"
 #include "nsIDOMMobileConnection.h"
 #include "nsIMobileConnectionProvider.h"
 #include "nsDOMEventTargetHelper.h"
 #include "nsCycleCollectionParticipant.h"
+#include "IccManager.h"
 
 namespace mozilla {
 namespace dom {
+
+namespace icc {
+  class IccManager;
+} // namespace icc
+
 namespace network {
 
 class MobileConnection : public nsDOMEventTargetHelper
                        , public nsIDOMMozMobileConnection
                        , public nsIObserver
 {
 public:
   NS_DECL_ISUPPORTS
@@ -31,16 +37,17 @@ public:
   void Init(nsPIDOMWindow *aWindow);
   void Shutdown();
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MobileConnection,
                                            nsDOMEventTargetHelper)
 
 private:
   nsCOMPtr<nsIMobileConnectionProvider> mProvider;
+  nsRefPtr<icc::IccManager> mIccManager;
 
   nsIDOMEventTarget*
   ToIDOMEventTarget() const
   {
     return static_cast<nsDOMEventTargetHelper*>(
            const_cast<MobileConnection*>(this));
   }
 
--- a/dom/network/src/TCPSocket.js
+++ b/dom/network/src/TCPSocket.js
@@ -83,16 +83,25 @@ function TCPSocket() {
   this._onerror = null;
   this._onclose = null;
 
   this._binaryType = "string";
 
   this._host = "";
   this._port = 0;
   this._ssl = false;
+
+  // As a workaround for bug https://bugzilla.mozilla.org/show_bug.cgi?id=786639
+  // we want to create any Uint8Array's off of the owning window so that there
+  // is no need for a wrapper to exist around the typed array from the
+  // perspective of content.  (The wrapper is bad because it only lets content
+  // see length, and forbids access to the array indices unless we excplicitly
+  // list them all.)  We will then access the array through a wrapper, but
+  // since we are chrome-privileged, this does not pose a problem.
+  this.useWin = null;
 }
 
 TCPSocket.prototype = {
   __exposedProps__: {
     open: 'r',
     host: 'r',
     port: 'r',
     ssl: 'r',
@@ -267,16 +276,17 @@ TCPSocket.prototype = {
                  : Services.perms.testExactPermissionFromPrincipal(principal, "tcp-socket");
 
     this._hasPrivileges = perm == Ci.nsIPermissionManager.ALLOW_ACTION;
 
     let util = aWindow.QueryInterface(
       Ci.nsIInterfaceRequestor
     ).getInterface(Ci.nsIDOMWindowUtils);
 
+    this.useWin = XPCNativeWrapper.unwrap(aWindow);
     this.innerWindowID = util.currentInnerWindowID;
     LOG("window init: " + this.innerWindowID);
   },
 
   observe: function(aSubject, aTopic, aData) {
     if (aTopic == "inner-window-destroyed") {
       let wId = aSubject.QueryInterface(Ci.nsISupportsPRUint64).data;
       if (wId == this.innerWindowID) {
@@ -286,31 +296,34 @@ TCPSocket.prototype = {
         // so that we don't get a "can't access dead object" when the
         // underlying stream goes to tell us that we are closed
         this.onopen = null;
         this.ondrain = null;
         this.ondata = null;
         this.onerror = null;
         this.onclose = null;
 
+        this.useWin = null;
+
         // Clean up our socket
         this.close();
       }
     }
   },
 
   // nsIDOMTCPSocket
   open: function ts_open(host, port, options) {
     // in the testing case, init won't be called and
     // hasPrivileges will be null. We want to proceed to test.
     if (this._hasPrivileges !== true && this._hasPrivileges !== null) {
       throw new Error("TCPSocket does not have permission in this context.\n");
     }
     let that = new TCPSocket();
 
+    that.useWin = this.useWin;
     that.innerWindowID = this.innerWindowID;
 
     LOG("window init: " + that.innerWindowID);
     Services.obs.addObserver(that, "inner-window-destroyed", true);
 
     LOG("startup called\n");
     LOG("Host info: " + host + ":" + port + "\n");
 
@@ -471,17 +484,17 @@ TCPSocket.prototype = {
   // nsIRequestObserver (Triggered by _inputStreamPump.asyncRead)
   onStopRequest: function ts_onStopRequest(request, context, status) {
     let buffered_output = this._multiplexStream.count !== 0;
 
     this._inputStreamPump = null;
 
     if (buffered_output && !status) {
       // If we have some buffered output still, and status is not an
-      // error, the other side has done a half-close, but we don't 
+      // error, the other side has done a half-close, but we don't
       // want to be in the close state until we are done sending
       // everything that was buffered. We also don't want to call onclose
       // yet.
       return;
     }
 
     this._readyState = kCLOSED;
 
@@ -492,17 +505,18 @@ TCPSocket.prototype = {
     }
 
     this.callListener("onclose");
   },
 
   // nsIStreamListener (Triggered by _inputStreamPump.asyncRead)
   onDataAvailable: function ts_onDataAvailable(request, context, inputStream, offset, count) {
     if (this._binaryType === "arraybuffer") {
-      let ua = new Uint8Array(count);
+      let ua = this.useWin ? new this.useWin.Uint8Array(count)
+                           : new Uint8Array(count);
       ua.set(this._inputStreamBinary.readByteArray(count));
       this.callListener("ondata", ua);
     } else {
       this.callListener("ondata", this._inputStreamScriptable.read(count));
     }
   },
 
   classID: Components.ID("{cda91b22-6472-11e1-aa11-834fec09cd0a}"),
--- a/dom/plugins/ipc/PluginMessageUtils.h
+++ b/dom/plugins/ipc/PluginMessageUtils.h
@@ -2,17 +2,17 @@
  * vim: sw=4 ts=4 et :
  * 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/. */
 
 #ifndef DOM_PLUGINS_PLUGINMESSAGEUTILS_H
 #define DOM_PLUGINS_PLUGINMESSAGEUTILS_H
 
-#include "IPC/IPCMessageUtils.h"
+#include "ipc/IPCMessageUtils.h"
 #include "base/message_loop.h"
 
 #include "mozilla/ipc/RPCChannel.h"
 #include "mozilla/ipc/CrossProcessMutex.h"
 #include "gfxipc/ShadowLayerUtils.h"
 
 #include "npapi.h"
 #include "npruntime.h"
--- a/dom/plugins/ipc/PluginModuleChild.cpp
+++ b/dom/plugins/ipc/PluginModuleChild.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* vim: set sw=4 ts=4 et : */
 /* 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/. */
 
 #ifdef MOZ_WIDGET_QT
+#include <unistd.h> // for _exit()
 #include <QtCore/QTimer>
 #include "nsQAppInstance.h"
 #include "NestedLoopTimer.h"
 #endif
 
 #include "mozilla/plugins/PluginModuleChild.h"
 
 /* This must occur *after* plugins/PluginModuleChild.h to avoid typedefs conflicts. */
@@ -192,17 +193,17 @@ PluginModuleChild::Init(const std::strin
         return false;
 
     memset((void*) &mFunctions, 0, sizeof(mFunctions));
     mFunctions.size = sizeof(mFunctions);
     mFunctions.version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
 
     // TODO: use PluginPRLibrary here
 
-#if defined(OS_LINUX)
+#if defined(OS_LINUX) || defined(OS_BSD)
     mShutdownFunc =
         (NP_PLUGINSHUTDOWN) PR_FindFunctionSymbol(mLibrary, "NP_Shutdown");
 
     // create the new plugin handler
 
     mInitializeFunc =
         (NP_PLUGINUNIXINIT) PR_FindFunctionSymbol(mLibrary, "NP_Initialize");
     NS_ASSERTION(mInitializeFunc, "couldn't find NP_Initialize()");
@@ -1823,17 +1824,17 @@ void NP_CALLBACK
 //-----------------------------------------------------------------------------
 
 bool
 PluginModuleChild::AnswerNP_GetEntryPoints(NPError* _retval)
 {
     PLUGIN_LOG_DEBUG_METHOD;
     AssertPluginThread();
 
-#if defined(OS_LINUX)
+#if defined(OS_LINUX) || defined(OS_BSD)
     return true;
 #elif defined(OS_WIN) || defined(OS_MACOSX)
     *_retval = mGetEntryPointsFunc(&mFunctions);
     return true;
 #else
 #  error Please implement me for your platform
 #endif
 }
@@ -1852,17 +1853,17 @@ PluginModuleChild::AnswerNP_Initialize(c
 
 #ifdef MOZ_X11
     // Send the parent our X socket to act as a proxy reference for our X
     // resources.
     int xSocketFd = ConnectionNumber(DefaultXDisplay());
     SendBackUpXResources(FileDescriptor(xSocketFd));
 #endif
 
-#if defined(OS_LINUX)
+#if defined(OS_LINUX) || defined(OS_BSD)
     *_retval = mInitializeFunc(&sBrowserFuncs, &mFunctions);
     return true;
 #elif defined(OS_WIN) || defined(OS_MACOSX)
     *_retval = mInitializeFunc(&sBrowserFuncs);
     return true;
 #else
 #  error Please implement me for your platform
 #endif
--- a/dom/plugins/ipc/PluginModuleChild.h
+++ b/dom/plugins/ipc/PluginModuleChild.h
@@ -315,17 +315,17 @@ private:
     PRLibrary* mLibrary;
     nsCString mPluginFilename; // UTF8
     nsCString mUserAgent;
     int mQuirks;
     bool mAsyncDrawingAllowed;
 
     // we get this from the plugin
     NP_PLUGINSHUTDOWN mShutdownFunc;
-#ifdef OS_LINUX
+#if defined(OS_LINUX) || defined(OS_BSD)
     NP_PLUGINUNIXINIT mInitializeFunc;
 #elif defined(OS_WIN) || defined(OS_MACOSX)
     NP_PLUGININIT mInitializeFunc;
     NP_GETENTRYPOINTS mGetEntryPointsFunc;
 #endif
 
     NPPluginFuncs mFunctions;
     NPSavedData mSavedData;
--- a/dom/settings/SettingsManager.js
+++ b/dom/settings/SettingsManager.js
@@ -212,18 +212,20 @@ const SETTINGSMANAGER_CONTRACTID = "@moz
 const SETTINGSMANAGER_CID        = Components.ID("{dd9f5380-a454-11e1-b3dd-0800200c9a66}");
 const nsIDOMSettingsManager      = Ci.nsIDOMSettingsManager;
 
 let myGlobal = this;
 
 function SettingsManager()
 {
   this._locks = new Queue();
-  var idbManager = Components.classes["@mozilla.org/dom/indexeddb/manager;1"].getService(Ci.nsIIndexedDatabaseManager);
-  idbManager.initWindowless(myGlobal);
+  if (!("indexedDB" in myGlobal)) {
+    let idbManager = Components.classes["@mozilla.org/dom/indexeddb/manager;1"].getService(Ci.nsIIndexedDatabaseManager);
+    idbManager.initWindowless(myGlobal);
+  }
   this._settingsDB = new SettingsDB();
   this._settingsDB.init(myGlobal);
 }
 
 SettingsManager.prototype = {
   _onsettingchange: null,
   _callbacks: null,
 
--- a/dom/src/geolocation/nsGeoPositionIPCSerialiser.h
+++ b/dom/src/geolocation/nsGeoPositionIPCSerialiser.h
@@ -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/. */
 
 #ifndef dom_src_geolocation_IPC_serialiser
 #define dom_src_geolocation_IPC_serialiser
 
-#include "IPC/IPCMessageUtils.h"
+#include "ipc/IPCMessageUtils.h"
 #include "nsGeoPosition.h"
 #include "nsIDOMGeoPosition.h"
 
 typedef nsGeoPositionCoords       *GeoPositionCoords;
 typedef nsIDOMGeoPosition         *GeoPosition;
 
 namespace IPC {
 
--- a/dom/system/gonk/RILContentHelper.js
+++ b/dom/system/gonk/RILContentHelper.js
@@ -51,23 +51,27 @@ const RIL_IPC_MSG_NAMES = [
   "RIL:VoicemailNotification",
   "RIL:VoicemailNumberChanged",
   "RIL:CallError",
   "RIL:CardLockResult",
   "RIL:UssdReceived",
   "RIL:SendUssd:Return:OK",
   "RIL:SendUssd:Return:KO",
   "RIL:CancelUssd:Return:OK",
-  "RIL:CancelUssd:Return:KO"
+  "RIL:CancelUssd:Return:KO",
+  "RIL:StkCommand",
+  "RIL:StkSessionEnd"
 ];
 
 const kVoiceChangedTopic     = "mobile-connection-voice-changed";
 const kDataChangedTopic      = "mobile-connection-data-changed";
 const kCardStateChangedTopic = "mobile-connection-cardstate-changed";
 const kUssdReceivedTopic     = "mobile-connection-ussd-received";
+const kStkCommandTopic       = "icc-manager-stk-command";
+const kStkSessionEndTopic    = "icc-manager-stk-session-end";
 
 XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
                                    "@mozilla.org/childprocessmessagemanager;1",
                                    "nsISyncMessageSender");
 
 XPCOMUtils.defineLazyServiceGetter(this, "gUUIDGenerator",
                                    "@mozilla.org/uuid-generator;1",
                                    "nsIUUIDGenerator");
@@ -372,16 +376,35 @@ RILContentHelper.prototype = {
                                  Cr.NS_ERROR_UNEXPECTED);
     }
     let request = Services.DOMRequest.createRequest(window);
     let requestId = this.getRequestId(request);
     cpmm.sendAsyncMessage("RIL:CancelUSSD", {requestId: requestId});
     return request;
   },
 
+  sendStkResponse: function sendStkResponse(window, response) {
+    if (window == null) {
+      throw Components.Exception("Can't get window object",
+                                  Cr.NS_ERROR_UNEXPECTED);
+    }
+    cpmm.sendAsyncMessage("RIL:SendStkResponse", response);
+  },
+
+  sendStkMenuSelection: function sendStkMenuSelection(window,
+                                                      itemIdentifier,
+                                                      helpRequested) {
+    if (window == null) {
+      throw Components.Exception("Can't get window object",
+                                  Cr.NS_ERROR_UNEXPECTED);
+    }
+    cpmm.sendAsyncMessage("RIL:SendStkMenuSelection", {itemIdentifier: itemIdentifier,
+                                                       helpRequested: helpRequested});
+  },