Merge from mozilla-central.
authorDavid Anderson <danderson@mozilla.com>
Fri, 20 Jul 2012 12:02:04 -0700
changeset 106580 a21ef9ee88f4d0168b073a98cc9c7b9283cf8649
parent 106579 f2faee47a80ff0f75e336056f5c7beb6628e9173 (current diff)
parent 99909 eea94a9b40a1c5d88913adf597f5b84dd89fd4fc (diff)
child 106581 23a84dbb258f6d7221ae270708ef3ed42395cd71
push id23447
push userdanderson@mozilla.com
push dateTue, 11 Sep 2012 17:34:27 +0000
treeherderautoland@fdfaef738a00 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone17.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge from mozilla-central.
accessible/src/msaa/AccessibleWrap.cpp
aclocal.m4
b2g/chrome/content/webapi.js
b2g/chrome/jar.mn
browser/app/profile/firefox.js
browser/base/content/browser.xul
browser/components/privatebrowsing/test/unit/test_openLocationLastURL.js
browser/locales/en-US/chrome/browser/browser.dtd
browser/themes/winstripe/browser.css
caps/include/nsPrincipal.h
caps/include/nsScriptSecurityManager.h
caps/src/nsNullPrincipal.cpp
caps/src/nsPrincipal.cpp
caps/src/nsScriptSecurityManager.cpp
caps/src/nsSystemPrincipal.cpp
config/autoconf.mk.in
configure.in
content/base/src/nsDocument.cpp
content/base/src/nsFrameLoader.cpp
content/events/src/nsEventStateManager.cpp
content/events/test/Makefile.in
content/media/nsBuiltinDecoderStateMachine.cpp
content/smil/nsSMILCSSProperty.cpp
content/xslt/src/xslt/txMozillaXMLOutput.cpp
docshell/base/nsDSURIContentListener.cpp
docshell/base/nsDocShell.cpp
docshell/base/nsDocShell.h
dom/base/nsGlobalWindow.cpp
dom/base/nsJSEnvironment.cpp
dom/bindings/Codegen.py
dom/bindings/parser/WebIDL.py
dom/ipc/PBrowser.ipdl
dom/ipc/TabChild.cpp
dom/ipc/TabChild.h
dom/ipc/TabParent.cpp
dom/ipc/TabParent.h
dom/plugins/base/nsJSNPRuntime.cpp
dom/plugins/base/nsNPAPIPluginInstance.cpp
dom/plugins/base/nsNPAPIPluginInstance.h
dom/plugins/base/nsPluginHost.cpp
dom/plugins/base/nsPluginInstanceOwner.cpp
dom/plugins/base/nsPluginInstanceOwner.h
editor/libeditor/html/nsHTMLAbsPosition.cpp
editor/libeditor/html/nsHTMLAnonymousUtils.cpp
editor/libeditor/html/nsHTMLCSSUtils.cpp
editor/libeditor/html/nsHTMLCSSUtils.h
editor/libeditor/html/nsHTMLEditRules.cpp
editor/libeditor/html/nsHTMLEditorStyle.cpp
embedding/android/GeckoAppShell.java
embedding/components/windowwatcher/src/nsWindowWatcher.cpp
gfx/gl/GLContext.cpp
gfx/gl/GLContext.h
gfx/gl/GLContextProviderEGL.cpp
gfx/layers/ImageLayers.h
gfx/layers/basic/BasicCanvasLayer.cpp
gfx/layers/basic/BasicImageLayer.cpp
gfx/layers/basic/BasicLayerManager.cpp
gfx/layers/basic/BasicLayers.h
gfx/layers/opengl/CanvasLayerOGL.cpp
gfx/layers/opengl/ImageLayerOGL.cpp
gfx/layers/opengl/ImageLayerOGL.h
gfx/layers/opengl/LayerManagerOGL.cpp
gfx/layers/opengl/ThebesLayerOGL.cpp
gfx/layers/opengl/ThebesLayerOGL.h
gfx/thebes/gfxPlatform.cpp
ipc/chromium/src/chrome/common/ipc_message_utils.h
ipc/testshell/XPCShellEnvironment.cpp
js/src/config/autoconf.mk.in
js/src/configure.in
js/src/frontend/BytecodeEmitter.cpp
js/src/frontend/BytecodeEmitter.h
js/src/frontend/FoldConstants.cpp
js/src/frontend/ParseNode.cpp
js/src/frontend/ParseNode.h
js/src/frontend/Parser.cpp
js/src/frontend/Parser.h
js/src/gc/Marking.cpp
js/src/gc/Root.h
js/src/ion/CodeGenerator.cpp
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jsarray.cpp
js/src/jsatom.cpp
js/src/jsatom.h
js/src/jscntxt.cpp
js/src/jscntxt.h
js/src/jscntxtinlines.h
js/src/jsfriendapi.cpp
js/src/jsfriendapi.h
js/src/jsfun.cpp
js/src/jsgc.cpp
js/src/jsinfer.cpp
js/src/jsinterp.cpp
js/src/jsiter.cpp
js/src/jsiter.h
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jsobjinlines.h
js/src/jsopcode.cpp
js/src/jsprvtd.h
js/src/jsreflect.cpp
js/src/jsscript.h
js/src/jsstr.cpp
js/src/jstypedarray.cpp
js/src/jswrapper.cpp
js/src/jswrapper.h
js/src/jsxml.cpp
js/src/methodjit/Compiler.cpp
js/src/shell/js.cpp
js/src/vm/ArgumentsObject.cpp
js/src/vm/Debugger.cpp
js/src/vm/RegExpObject.cpp
js/src/vm/RegExpObject.h
js/src/vm/ScopeObject-inl.h
js/src/vm/ScopeObject.h
js/xpconnect/idl/xpccomponents.idl
js/xpconnect/shell/xpcshell.cpp
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCDebug.cpp
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/XPCMaps.cpp
js/xpconnect/src/XPCMaps.h
js/xpconnect/tests/components/native/xpctest_attributes.cpp
js/xpconnect/tests/components/native/xpctest_private.h
layout/base/FrameLayerBuilder.cpp
layout/base/nsChangeHint.h
layout/base/nsDisplayList.cpp
layout/base/nsDisplayList.h
layout/base/nsPresShell.cpp
layout/generic/nsFrame.cpp
layout/generic/nsObjectFrame.cpp
layout/ipc/RenderFrameParent.cpp
layout/ipc/RenderFrameParent.h
layout/reftests/text/reftest.list
layout/style/nsComputedDOMStyle.cpp
layout/style/nsComputedDOMStyle.h
layout/style/nsRuleNode.cpp
layout/style/nsStyleStruct.h
layout/svg/base/src/nsSVGEffects.cpp
layout/tools/reftest/reftest.js
mobile/android/base/GeckoApp.java
mobile/android/base/GeckoAppShell.java
mobile/android/base/Makefile.in
mobile/android/base/resources/drawable-hdpi/tab_new_normal.png
mobile/android/base/resources/drawable-hdpi/tab_new_pressed.png
mobile/android/base/resources/drawable-nodpi/abouthome_topsites_bg.png
mobile/android/base/resources/drawable/abouthome_topsites_bg_repeat.xml
mobile/android/base/resources/drawable/tab_new_normal.png
mobile/android/base/resources/drawable/tab_new_pressed.png
mobile/android/base/resources/layout-xlarge/awesomebar_tab_indicator.xml
mobile/android/base/resources/layout/abouthome_section_moretext.xml
mobile/android/base/resources/layout/abouthome_section_subtitle.xml
mobile/android/base/resources/layout/abouthome_section_title.xml
mobile/android/base/resources/raw/webapp_prefs_js
mobile/android/chrome/content/bindings/content.xml
mobile/android/chrome/content/browser.js
mobile/android/themes/core/images/handle-end.png
mobile/android/themes/core/images/handle-start.png
mozglue/android/APKOpen.cpp
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/protocol/http/nsHttpChannel.h
testing/mochitest/runtests.py
toolkit/components/passwordmgr/nsLoginManager.js
toolkit/components/telemetry/TelemetryPing.js
toolkit/content/widgets/videocontrols.xml
view/src/nsViewManager.cpp
widget/android/AndroidBridge.cpp
widget/android/AndroidBridge.h
widget/android/AndroidJNI.cpp
widget/android/nsWindow.cpp
widget/android/nsWindow.h
widget/cocoa/nsChildView.h
widget/cocoa/nsChildView.mm
widget/cocoa/nsCocoaWindow.h
widget/cocoa/nsCocoaWindow.mm
widget/gtk2/nsWindow.cpp
widget/gtk2/nsWindow.h
widget/nsGUIEvent.h
widget/nsIWidget.h
widget/os2/nsWindow.cpp
widget/os2/nsWindow.h
widget/qt/nsWindow.cpp
widget/qt/nsWindow.h
widget/windows/nsWindow.cpp
widget/windows/nsWindow.h
widget/xpwidgets/PuppetWidget.h
xpcom/base/nsrootidl.idl
xpcom/tests/TestTArray.cpp
xpfe/appshell/src/nsContentTreeOwner.cpp
xpfe/appshell/src/nsXULWindow.cpp
--- a/accessible/src/msaa/AccessibleWrap.cpp
+++ b/accessible/src/msaa/AccessibleWrap.cpp
@@ -1621,31 +1621,27 @@ AccessibleWrap::GetHWNDFor(Accessible* a
       return nsnull;
 
     // Popup lives in own windows, use its HWND until the popup window is
     // hidden to make old JAWS versions work with collapsed comboboxes (see
     // discussion in bug 379678).
     nsIFrame* frame = aAccessible->GetFrame();
     if (frame) {
       nsIWidget* widget = frame->GetNearestWidget();
-      if (widget) {
-        bool isVisible = false;
-        widget->IsVisible(isVisible);
-        if (isVisible) {
-          nsIPresShell* shell = document->PresShell();
-          nsIViewManager* vm = shell->GetViewManager();
-          if (vm) {
-            nsCOMPtr<nsIWidget> rootWidget;
-            vm->GetRootWidget(getter_AddRefs(rootWidget));
-            // Make sure the accessible belongs to popup. If not then use
-            // document HWND (which might be different from root widget in the
-            // case of window emulation).
-            if (rootWidget != widget)
-              return static_cast<HWND>(widget->GetNativeData(NS_NATIVE_WINDOW));
-          }
+      if (widget && widget->IsVisible()) {
+        nsIPresShell* shell = document->PresShell();
+        nsIViewManager* vm = shell->GetViewManager();
+        if (vm) {
+          nsCOMPtr<nsIWidget> rootWidget;
+          vm->GetRootWidget(getter_AddRefs(rootWidget));
+          // Make sure the accessible belongs to popup. If not then use
+          // document HWND (which might be different from root widget in the
+          // case of window emulation).
+          if (rootWidget != widget)
+            return static_cast<HWND>(widget->GetNativeData(NS_NATIVE_WINDOW));
         }
       }
     }
 
     return static_cast<HWND>(document->GetNativeWindow());
   }
   return nsnull;
 }
--- a/accessible/src/windows/uia/uiaRawElmProvider.cpp
+++ b/accessible/src/windows/uia/uiaRawElmProvider.cpp
@@ -141,16 +141,53 @@ STDMETHODIMP
 uiaRawElmProvider::GetPropertyValue(PROPERTYID aPropertyId,
                                     __RPC__out VARIANT* aPropertyValue)
 {
   A11Y_TRYBLOCK_BEGIN
 
   if (!aPropertyValue)
     return E_INVALIDARG;
 
+  if (mAcc->IsDefunct())
+    return CO_E_OBJNOTCONNECTED;
+
+  aPropertyValue->vt = VT_EMPTY;
+
+  switch (aPropertyId) {
+    // Accelerator Key / shortcut.
+    case UIA_AcceleratorKeyPropertyId: {
+      nsAutoString keyString;
+
+      mAcc->KeyboardShortcut().ToString(keyString);
+
+      if (!keyString.IsEmpty()) {
+        aPropertyValue->vt = VT_BSTR;
+        aPropertyValue->bstrVal = ::SysAllocString(keyString.get());
+        return S_OK;
+      }
+
+      break;
+    }
+
+    // Access Key / mneumonic.
+    case UIA_AccessKeyPropertyId: {
+      nsAutoString keyString;
+
+      mAcc->AccessKey().ToString(keyString);
+
+      if (!keyString.IsEmpty()) {
+        aPropertyValue->vt = VT_BSTR;
+        aPropertyValue->bstrVal = ::SysAllocString(keyString.get());
+        return S_OK;
+      }
+
+      break;
+    }
+  }
+
   // UI Automation will attempt to get the property from the host
   //window provider.
   aPropertyValue->vt = VT_EMPTY;
   return S_OK;
 
   A11Y_TRYBLOCK_END
 }
 
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1,13 +1,15 @@
 dnl
 dnl Local autoconf macros used with mozilla
 dnl The contents of this file are under the Public Domain.
 dnl 
 
+builtin(include, build/autoconf/toolchain.m4)dnl
+builtin(include, build/autoconf/ccache.m4)dnl
 builtin(include, build/autoconf/nspr.m4)dnl
 builtin(include, build/autoconf/nss.m4)dnl
 builtin(include, build/autoconf/pkg.m4)dnl
 builtin(include, build/autoconf/codeset.m4)dnl
 builtin(include, build/autoconf/altoptions.m4)dnl
 builtin(include, build/autoconf/mozprog.m4)dnl
 builtin(include, build/autoconf/mozheader.m4)dnl
 builtin(include, build/autoconf/mozcommonheader.m4)dnl
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -242,16 +242,17 @@ pref("editor.singleLine.pasteNewlines", 
 // The names of the preferences are to be in sync with nsEventStateManager.cpp
 pref("ui.dragThresholdX", 25);
 pref("ui.dragThresholdY", 25);
 
 // Layers Acceleration
 pref("layers.acceleration.disabled", false);
 pref("layers.offmainthreadcomposition.enabled", true);
 pref("layers.async-video.enabled", true);
+pref("layers.async-pan-zoom.enabled", true);
 
 // Web Notifications
 pref("notification.feature.enabled", true);
 
 // IndexedDB
 pref("indexedDB.feature.enabled", true);
 pref("dom.indexedDB.warningQuota", 5);
 
--- a/b2g/chrome/jar.mn
+++ b/b2g/chrome/jar.mn
@@ -11,17 +11,16 @@ chrome.jar:
   content/dbg-browser-actors.js         (content/dbg-browser-actors.js)
   content/forms.js                      (content/forms.js)
   content/settings.js                   (content/settings.js)
 * content/shell.xul                     (content/shell.xul)
 * content/shell.js                      (content/shell.js)
 #ifndef ANDROID
   content/screen.js                     (content/screen.js)
 #endif
-  content/webapi.js                     (content/webapi.js)
   content/content.css                   (content/content.css)
   content/touchcontrols.css             (content/touchcontrols.css)
 
 % override chrome://global/content/netError.xhtml chrome://browser/content/netError.xhtml
 % override chrome://global/skin/netError.css chrome://browser/content/netError.css
 % override chrome://global/skin/media/videocontrols.css chrome://browser/content/touchcontrols.css
 
   content/netError.xhtml                (content/netError.xhtml)
--- a/b2g/components/ProcessGlobal.js
+++ b/b2g/components/ProcessGlobal.js
@@ -13,17 +13,16 @@
  *
  * (It's written as an XPCOM service because it needs to watch
  * app-startup.)
  */
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
-const kWebApiShimFile = 'chrome://browser/content/webapi.js';
 
 Cu.import('resource://gre/modules/Services.jsm');
 Cu.import('resource://gre/modules/XPCOMUtils.jsm');
 
 function debug(msg) {
   log(msg);
 }
 function log(msg) {
@@ -36,39 +35,26 @@ ProcessGlobal.prototype = {
   classID: Components.ID('{1a94c87a-5ece-4d11-91e1-d29c29f21b28}'),
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
                                          Ci.nsISupportsWeakReference]),
 
   observe: function pg_observe(subject, topic, data) {
     switch (topic) {
     case 'app-startup': {
       Services.obs.addObserver(this, 'console-api-log-event', false);
-      Services.obs.addObserver(this, 'in-process-browser-frame-shown', false);
-      Services.obs.addObserver(this, 'remote-browser-frame-shown', false);
       break;
     }
     case 'console-api-log-event': {
       // Pipe `console` log messages to the nsIConsoleService which
       // writes them to logcat on Gonk.
       let message = subject.wrappedJSObject;
       let prefix = ('Content JS ' + message.level.toUpperCase() +
                     ' at ' + message.filename + ':' + message.lineNumber +
                     ' in ' + (message.functionName || 'anonymous') + ': ');
       Services.console.logStringMessage(prefix + Array.join(message.arguments,
                                                             ' '));
       break;
     }
-    case 'remote-browser-frame-shown':
-    case 'in-process-browser-frame-shown': {
-      let frameLoader = subject.QueryInterface(Ci.nsIFrameLoader);
-      let mm = frameLoader.messageManager;
-      try {
-        mm.loadFrameScript(kWebApiShimFile, true);
-      } catch (e) {
-        log('Error loading ' + kWebApiShimFile + ' as frame script: ' + e + '\n');
-      }
-      break;
-    }
     }
   },
 };
 
 var NSGetFactory = XPCOMUtils.generateNSGetFactory([ProcessGlobal]);
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1179,9 +1179,10 @@ pref("pdfjs.previousHandler.preferredAct
 pref("pdfjs.previousHandler.alwaysAskBeforeHandling", false);
 
 // The maximum amount of decoded image data we'll willingly keep around (we
 // might keep around more than this, but we'll try to get down to this value).
 // (This is intentionally on the high side; see bug 746055.)
 pref("image.mem.max_decoded_image_kb", 256000);
 
 // Example social provider
-pref("social.manifest.motown", "{\"origin\":\"https://motown-dev.mozillalabs.com\",\"name\":\"MoTown\",\"workerURL\":\"https://motown-dev.mozillalabs.com/social/worker.js\",\"iconURL\":\"https://motown-dev.mozillalabs.com/images/motown-icon.png\"}");
+pref("social.manifest.motown", "{\"origin\":\"https://motown-dev.mozillalabs.com\",\"name\":\"MoTown\",\"workerURL\":\"https://motown-dev.mozillalabs.com/social/worker.js\",\"iconURL\":\"https://motown-dev.mozillalabs.com/images/motown-icon.png\",\"sidebarURL\":\"https://motown-dev.mozillalabs.com/social/sidebar\"}");
+pref("social.sidebar.open", true);
--- a/browser/base/content/abouthome/aboutHome.css
+++ b/browser/base/content/abouthome/aboutHome.css
@@ -166,17 +166,17 @@ body[dir=rtl] #defaultSnippet2 {
   margin: 12px 0;
   color: #3c3c3c;
   font-size: 75%;
   /* 12px is the computed font size, 15px the computed line height of the snippets
      with Segoe UI on a default Windows 7 setup. The 15/12 multiplier approximately
      converts em from units of font-size to units of line-height. The goal is to
      preset the height of a three-line snippet to avoid visual moving/flickering as
      the snippets load. */
-  min-height: -moz-calc(15/12 * 3em);
+  min-height: calc(15/12 * 3em);
 }
 
 #launcher {
   display: -moz-box;
   -moz-box-align: center;
   -moz-box-pack: center;
   width: 100%;
   background-color: hsla(0,0%,0%,.03);
--- a/browser/base/content/browser-sets.inc
+++ b/browser/base/content/browser-sets.inc
@@ -102,16 +102,17 @@
     <command id="Tools:Sanitize"
      oncommand="Cc['@mozilla.org/browser/browserglue;1'].getService(Ci.nsIBrowserGlue).sanitize(window);"/>
     <command id="Tools:PrivateBrowsing" oncommand="gPrivateBrowsingUI.toggleMode();"/>
     <command id="History:UndoCloseTab" oncommand="undoCloseTab();"/>
     <command id="History:UndoCloseWindow" oncommand="undoCloseWindow();"/>
     <command id="Browser:ToggleAddonBar" oncommand="toggleAddonBar();"/>
     <command id="Social:SharePage" oncommand="SocialShareButton.sharePage();"/>
     <command id="Social:UnsharePage" oncommand="SocialShareButton.unsharePage();"/>
+    <command id="Social:ToggleSidebar" oncommand="Social.toggleSidebar();"/>
   </commandset>
 
   <commandset id="placesCommands">
     <command id="Browser:ShowAllBookmarks"
              oncommand="PlacesCommandHook.showPlacesOrganizer('AllBookmarks');"/>
     <command id="Browser:ShowAllHistory"
              oncommand="PlacesCommandHook.showPlacesOrganizer('History');"/>
   </commandset>
@@ -176,16 +177,17 @@
     <broadcaster id="singleFeedMenuitemState" disabled="true"/>
     <broadcaster id="multipleFeedsMenuState" hidden="true"/>
     <broadcaster id="tabviewGroupsNumber" groups="1"/>
 #ifdef MOZ_SERVICES_SYNC
     <broadcaster id="sync-setup-state"/>
     <broadcaster id="sync-syncnow-state"/>
 #endif
     <broadcaster id="workOfflineMenuitemState"/>
+    <broadcaster id="socialSidebarBroadcaster" hidden="true"/>
   </broadcasterset>
 
   <keyset id="mainKeyset">
     <key id="key_newNavigator"
          key="&newNavigatorCmd.key;"
          command="cmd_newNavigator"
          modifiers="accel"/>
     <key id="key_newNavigatorTab" key="&tabCmd.commandkey;" modifiers="accel" command="cmd_newNavigatorTab"/>
--- a/browser/base/content/browser-social.js
+++ b/browser/base/content/browser-social.js
@@ -4,56 +4,64 @@
 
 let SocialUI = {
   // Called on delayed startup to initialize UI
   init: function SocialUI_init() {
     Services.obs.addObserver(this, "social:pref-changed", false);
     Services.obs.addObserver(this, "social:ambient-notification-changed", false);
     Services.obs.addObserver(this, "social:profile-changed", false);
 
+    Services.prefs.addObserver("social.sidebar.open", this, false);
+
     Social.init(this._providerReady.bind(this));
   },
 
   // Called on window unload
   uninit: function SocialUI_uninit() {
     Services.obs.removeObserver(this, "social:pref-changed");
     Services.obs.removeObserver(this, "social:ambient-notification-changed");
     Services.obs.removeObserver(this, "social:profile-changed");
+
+    Services.prefs.removeObserver("social.sidebar.open", this);
   },
 
   showProfile: function SocialUI_showProfile() {
     if (Social.provider)
       openUILink(Social.provider.profile.profileURL);
   },
 
   observe: function SocialUI_observe(subject, topic, data) {
     switch (topic) {
       case "social:pref-changed":
         SocialShareButton.updateButtonHiddenState();
         SocialToolbar.updateButtonHiddenState();
+        SocialSidebar.updateSidebar();
         break;
       case "social:ambient-notification-changed":
         SocialToolbar.updateButton();
         break;
       case "social:profile-changed":
         SocialToolbar.updateProfile();
         break;
+      case "nsPref:changed":
+        SocialSidebar.updateSidebar();
     }
   },
 
   // Called once Social.jsm's provider has been set
   _providerReady: function SocialUI_providerReady() {
     SocialToolbar.init();
     SocialShareButton.init();
+    SocialSidebar.init();
   }
 }
 
 let SocialShareButton = {
+  // Called once, after window load, when the Social.provider object is initialized
   init: function SSB_init() {
-    this.sharePopup.hidden = false;
     this.updateButtonHiddenState();
 
     let profileRow = document.getElementById("editSharePopupHeader");
     let profile = Social.provider.profile;
     if (profile && profile.portrait && profile.displayName) {
       profileRow.hidden = false;
       let portrait = document.getElementById("socialUserPortrait");
       portrait.style.listStyleImage = profile.portrait;
@@ -93,16 +101,18 @@ let SocialShareButton = {
 
   panelShown: function SSB_panelShown(aEvent) {
     let sharePopupOkButton = document.getElementById("editSharePopupOkButton");
     if (sharePopupOkButton)
       sharePopupOkButton.focus();
   },
 
   sharePage: function SSB_sharePage() {
+    this.sharePopup.hidden = false;
+
     let uri = gBrowser.currentURI;
     if (!Social.isPageShared(uri)) {
       Social.sharePage(uri);
       this.updateShareState();
     } else {
       this.sharePopup.openPopup(this.shareButton, "bottomcenter topright");
     }
   },
@@ -243,14 +253,65 @@ var SocialToolbar = {
 
     panel.addEventListener("popuphiding", function onpopuphiding() {
       panel.removeEventListener("popuphiding", onpopuphiding);
       // unload the panel
       document.getElementById("social-toolbar-button").removeAttribute("open");
       notifBrowser.setAttribute("src", "about:blank");
     });
 
-    notifBrowser.service = Social.provider;
+    notifBrowser.setAttribute("origin", Social.provider.origin);
     notifBrowser.setAttribute("src", iconImage.getAttribute("contentPanel"));
     document.getElementById("social-toolbar-button").setAttribute("open", "true");
     panel.openPopup(iconImage, "bottomcenter topleft", 0, 0, false, false);
   }
 }
+
+var SocialSidebar = {
+  // Called once, after window load, when the Social.provider object is initialized
+  init: function SocialSidebar_init() {
+    this.updateSidebar();
+  },
+
+  // Whether the sidebar can be shown for this window.
+  get canShow() {
+    return Social.uiVisible && Social.provider.sidebarURL && !this.chromeless;
+  },
+
+  // Whether this is a "chromeless window" (e.g. popup window). We don't show
+  // the sidebar in these windows.
+  get chromeless() {
+    let docElem = document.documentElement;
+    return docElem.getAttribute('disablechrome') ||
+           docElem.getAttribute('chromehidden').indexOf("extrachrome") >= 0;
+  },
+
+  // Whether the user has toggled the sidebar on (for windows where it can appear)
+  get enabled() {
+    return Services.prefs.getBoolPref("social.sidebar.open");
+  },
+
+  updateSidebar: function SocialSidebar_updateSidebar() {
+    // Hide the toggle menu item if the sidebar cannot appear
+    let command = document.getElementById("Social:ToggleSidebar");
+    command.hidden = !this.canShow;
+
+    // Hide the sidebar if it cannot appear, or has been toggled off.
+    // Also set the command "checked" state accordingly.
+    let hideSidebar = !this.canShow || !this.enabled;
+    let broadcaster = document.getElementById("socialSidebarBroadcaster");
+    broadcaster.hidden = hideSidebar;
+    command.setAttribute("checked", !hideSidebar);
+
+    // If the sidebar is hidden, unload its document
+    // XXX this results in a poor UX, we should revisit
+    let sbrowser = document.getElementById("social-sidebar-browser");
+    if (broadcaster.hidden) {
+      sbrowser.removeAttribute("origin");
+      sbrowser.setAttribute("src", "about:blank");
+      return;
+    }
+
+    // Load the sidebar document
+    sbrowser.setAttribute("origin", Social.provider.origin);
+    sbrowser.setAttribute("src", Social.provider.sidebarURL);
+  }
+}
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -488,17 +488,17 @@ browser[tabmodalPromptShowing] {
 
 /* Status panel */
 
 statuspanel {
   -moz-binding: url("chrome://browser/content/tabbrowser.xml#statuspanel");
   position: fixed;
   margin-top: -3em;
   left: 0;
-  max-width: -moz-calc(100% - 5px);
+  max-width: calc(100% - 5px);
   pointer-events: none;
 }
 
 statuspanel:-moz-locale-dir(ltr)[mirror],
 statuspanel:-moz-locale-dir(rtl):not([mirror]) {
   left: auto;
   right: 0;
 }
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -633,16 +633,22 @@
                 <image id="social-statusarea-user-portrait"/>
                 <vbox>
                   <label id="social-statusarea-notloggedin"
                          value="&social.notLoggedIn.label;"/>
                   <button id="social-statusarea-username"
                           oncommand="SocialUI.showProfile(); document.getElementById('social-statusarea-popup').hidePopup();"/>
                 </vbox>
               </hbox>
+              <menuitem id="social-toggle-sidebar-menuitem"
+                        type="checkbox"
+                        autocheck="false"
+                        command="Social:ToggleSidebar"
+                        label="&social.toggleSidebar.label;"
+                        accesskey="&social.toggleSidebar.accesskey;"/>
             </menupopup>
           </button>
           <hbox id="social-status-iconbox" flex="1">
             <box class="social-notification-icon-container" collapsed="true"
                      onclick="SocialToolbar.showAmbientPopup(this);">
               <image class="social-notification-icon-image"/>
               <box class="social-notification-icon-counter" collapsed="true"/>
             </box>
@@ -1019,16 +1025,27 @@
       <tabbrowser id="content" disablehistory="true"
                   flex="1" contenttooltip="aHTMLTooltip"
                   tabcontainer="tabbrowser-tabs"
                   contentcontextmenu="contentAreaContextMenu"
                   autocompletepopup="PopupAutoComplete"
                   onclick="contentAreaClick(event, false);"/>
       <statuspanel id="statusbar-display" inactive="true"/>
     </vbox>
+    <splitter id="social-sidebar-splitter"
+              class="chromeclass-extrachrome"
+              observes="socialSidebarBroadcaster"/>
+    <vbox id="social-sidebar-box"
+          class="chromeclass-extrachrome"
+          observes="socialSidebarBroadcaster">
+      <browser id="social-sidebar-browser"
+               type="content"
+               flex="1"
+               style="min-width: 14em; width: 18em; max-width: 36em;"/>
+    </vbox>
     <splitter id="devtools-side-splitter" hidden="true"/>
     <vbox id="devtools-sidebar-box" hidden="true"
           style="min-width: 18em; width: 22em; max-width: 42em;" persist="width">
       <toolbar id="devtools-sidebar-toolbar"
                class="devtools-toolbar"
                nowindowdrag="true"/>
       <deck id="devtools-sidebar-deck" flex="1"/>
     </vbox>
--- a/browser/base/content/test/Makefile.in
+++ b/browser/base/content/test/Makefile.in
@@ -252,16 +252,17 @@ endif
                  browser_minimize.js \
                  browser_aboutSyncProgress.js \
                  browser_middleMouse_inherit.js \
                  redirect_bug623155.sjs \
                  browser_tabDrop.js \
                  browser_lastAccessedTab.js \
                  browser_bug734076.js \
                  browser_social_toolbar.js \
+                 browser_social_sidebar.js \
                  $(NULL)
 
 ifneq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 _BROWSER_FILES += \
 		browser_bug462289.js \
 		$(NULL)
 else
 _BROWSER_FILES += \
--- a/browser/base/content/test/browser_bug553455.js
+++ b/browser/base/content/test/browser_bug553455.js
@@ -66,16 +66,32 @@ function wait_for_install_dialog(aCallba
     onCloseWindow: function(aXULWindow) {
     },
 
     onWindowTitleChange: function(aXULWindow, aNewTitle) {
     }
   });
 }
 
+function wait_for_single_notification(aCallback) {
+  function inner_waiter() {
+    info("Waiting for single notification");
+    // Notification should never close while we wait
+    ok(PopupNotifications.isPanelOpen, "Notification should still be open");
+    if (PopupNotifications.panel.childNodes.length == 2) {
+      executeSoon(inner_waiter);
+      return;
+    }
+
+    aCallback();
+  }
+
+  executeSoon(inner_waiter);
+}
+
 function setup_redirect(aSettings) {
   var url = "https://example.com/browser/toolkit/mozapps/extensions/test/xpinstall/redirect.sjs?mode=setup";
   for (var name in aSettings) {
     url += "&" + name + "=" + aSettings[name];
   }
 
   var req = new XMLHttpRequest();
   req.open("GET", url, false);
@@ -433,17 +449,17 @@ function test_url() {
 },
 
 function test_localfile() {
   // Wait for the install to fail
   Services.obs.addObserver(function() {
     Services.obs.removeObserver(arguments.callee, "addon-install-failed");
 
     // Wait for the browser code to add the failure notification
-    executeSoon(function() {
+    wait_for_single_notification(function() {
       let notification = PopupNotifications.panel.childNodes[0];
       is(notification.id, "addon-install-failed-notification", "Should have seen the install fail");
       is(notification.getAttribute("label"),
          "This add-on could not be installed because it appears to be corrupt.",
          "Should have seen the right message");
 
       wait_for_notification_close(runNextTest);
       gBrowser.removeTab(gBrowser.selectedTab);
@@ -793,36 +809,27 @@ function test_failed_security() {
     is(PopupNotifications.panel.childNodes.length, 1, "Should be only one notification");
     notification = aPanel.childNodes[0];
     is(notification.id, "addon-progress-notification", "Should have seen the progress notification");
 
     // Wait for it to fail
     Services.obs.addObserver(function() {
       Services.obs.removeObserver(arguments.callee, "addon-install-failed");
 
-      function waitForSingleNotification() {
-        // Notification should never close while we wait
-        ok(PopupNotifications.isPanelOpen, "Notification should still be open");
-        if (PopupNotifications.panel.childNodes.length == 2) {
-          executeSoon(waitForSingleNotification);
-          return;
-        }
-
+      // Allow the browser code to add the failure notification and then wait
+      // for the progress notification to dismiss itself
+      wait_for_single_notification(function() {
         is(PopupNotifications.panel.childNodes.length, 1, "Should be only one notification");
         notification = aPanel.childNodes[0];
         is(notification.id, "addon-install-failed-notification", "Should have seen the install fail");
 
         Services.prefs.setBoolPref(PREF_INSTALL_REQUIREBUILTINCERTS, true);
         wait_for_notification_close(runNextTest);
         gBrowser.removeTab(gBrowser.selectedTab);
-      }
-
-      // Allow the browser code to add the failure notification and then wait
-      // for the progress notification to dismiss itself
-      executeSoon(waitForSingleNotification);
+      });
     }, "addon-install-failed", false);
   });
 
   var triggers = encodeURIComponent(JSON.stringify({
     "XPI": "redirect.sjs?mode=redirect"
   }));
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.loadURI(SECUREROOT + "installtrigger.html?" + triggers);
--- a/browser/base/content/test/browser_shareButton.js
+++ b/browser/base/content/test/browser_shareButton.js
@@ -46,17 +46,16 @@ function testInitial() {
   ok(Social.provider, "Social provider is active");
   ok(Social.provider.enabled, "Social provider is enabled");
   ok(Social.provider.port, "Social provider has a port to its FrameWorker");
 
   shareButton = SocialShareButton.shareButton;
   sharePopup = SocialShareButton.sharePopup;
   ok(shareButton, "share button exists");
   ok(sharePopup, "share popup exists");
-  ok(!sharePopup.hidden, "share popup is not hidden");
 
   okButton = document.getElementById("editSharePopupOkButton");
   undoButton = document.getElementById("editSharePopupUndoButton");
 
   is(shareButton.hidden, false, "share button should be visible");
 
   // Test clicking the share button
   shareButton.addEventListener("click", function listener() {
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_social_sidebar.js
@@ -0,0 +1,52 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+let SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService;
+
+function test() {
+  // XXX Bug 775779
+  if (Cc["@mozilla.org/xpcom/debug;1"].getService(Ci.nsIDebug2).isDebugBuild) {
+    ok(true, "can't run social sidebar test in debug builds because they falsely report leaks");
+    return;
+  }
+
+  waitForExplicitFinish();
+
+  let manifest = { // normal provider
+    name: "provider 1",
+    origin: "https://example1.com",
+    sidebarURL: "https://example1.com/sidebar.html",
+    workerURL: "https://example1.com/worker.js",
+    iconURL: "chrome://branding/content/icon48.png"
+  };
+  runSocialTestWithProvider(manifest, doTest);
+}
+
+function doTest() {
+  ok(SocialSidebar.canShow, "social sidebar should be able to be shown");
+  ok(SocialSidebar.enabled, "social sidebar should be on by default");
+
+  let command = document.getElementById("Social:ToggleSidebar");
+  let sidebar = document.getElementById("social-sidebar-box");
+
+  // Check the the sidebar is initially visible, and loaded
+  ok(!command.hidden, "sidebar toggle command should be visible");
+  is(command.getAttribute("checked"), "true", "sidebar toggle command should be checked");
+  ok(!sidebar.hidden, "sidebar itself should be visible");
+  ok(Services.prefs.getBoolPref("social.sidebar.open"), "sidebar open pref should be true");
+  is(sidebar.firstChild.getAttribute('src'), "https://example1.com/sidebar.html", "sidebar url should be set");
+
+  // Now toggle it!
+  info("Toggling sidebar");
+  Social.toggleSidebar();
+  is(command.getAttribute("checked"), "false", "sidebar toggle command should not be checked");
+  ok(sidebar.hidden, "sidebar itself should not be visible");
+  ok(!Services.prefs.getBoolPref("social.sidebar.open"), "sidebar open pref should be false");
+  is(sidebar.firstChild.getAttribute('src'), "about:blank", "sidebar url should not be set");
+
+  // Remove the test provider
+  SocialService.removeProvider(Social.provider.origin, finish);
+}
+
+// XXX test sidebar in popup
--- a/browser/base/content/test/browser_social_toolbar.js
+++ b/browser/base/content/test/browser_social_toolbar.js
@@ -1,94 +1,69 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 let SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService;
-let gProvider;
 
 function test() {
   waitForExplicitFinish();
 
-  Services.prefs.setBoolPref("social.enabled", true);
-  registerCleanupFunction(function () {
-    Services.prefs.clearUserPref("social.enabled");
-  });
-
-  let oldProvider;
-  function saveOldProviderAndStartTestWith(provider) {
-    oldProvider = Social.provider;
-    registerCleanupFunction(function () {
-      Social.provider = oldProvider;
-    });
-    Social.provider = gProvider = provider;
-    runTests(tests, undefined, undefined, function () {
-      SocialService.removeProvider(provider.origin, finish);
-    });
-  }
-
   let manifest = { // normal provider
     name: "provider 1",
     origin: "https://example1.com",
     workerURL: "https://example1.com/worker.js",
     iconURL: "chrome://branding/content/icon48.png"
   };
-  SocialService.addProvider(manifest, function(provider) {
-    // If the UI is already active, run the test immediately, otherwise wait
-    // for initialization.
-    if (Social.provider) {
-      saveOldProviderAndStartTestWith(provider);
-    } else {
-      Services.obs.addObserver(function obs() {
-        Services.obs.removeObserver(obs, "test-social-ui-ready");
-        saveOldProviderAndStartTestWith(provider);
-      }, "test-social-ui-ready", false);
-    }
+  runSocialTestWithProvider(manifest, function () {
+    runTests(tests, undefined, undefined, function () {
+      SocialService.removeProvider(Social.provider.origin, finish);
+    });
   });
 }
 
 var tests = {
   testProfileSet: function(next) {
     let profile = {
       portrait: "chrome://branding/content/icon48.png",
       userName: "trickster",
       displayName: "Kuma Lisa",
       profileURL: "http://en.wikipedia.org/wiki/Kuma_Lisa"
     }
-    gProvider.updateUserProfile(profile);
+    Social.provider.updateUserProfile(profile);
     // check dom values
     let portrait = document.getElementById("social-statusarea-user-portrait").getAttribute("src");
     is(portrait, profile.portrait, "portrait is set");
     let userButton = document.getElementById("social-statusarea-username");
     ok(!userButton.hidden, "username is visible");
     is(userButton.label, profile.userName, "username is set");
     next();
   },
   testAmbientNotifications: function(next) {
     let ambience = {
       name: "testIcon",
       iconURL: "chrome://branding/content/icon48.png",
       contentPanel: "about:blank",
       counter: 42
     };
-    gProvider.setAmbientNotification(ambience);
+    Social.provider.setAmbientNotification(ambience);
 
     let statusIcons = document.getElementById("social-status-iconbox");
     ok(!statusIcons.firstChild.collapsed, "status icon is visible");
     ok(!statusIcons.firstChild.lastChild.collapsed, "status value is visible");
     is(statusIcons.firstChild.lastChild.textContent, "42", "status value is correct");
 
     ambience.counter = 0;
-    gProvider.setAmbientNotification(ambience);
+    Social.provider.setAmbientNotification(ambience);
     ok(statusIcons.firstChild.lastChild.collapsed, "status value is not visible");
     is(statusIcons.firstChild.lastChild.textContent, "", "status value is correct");
     next();
   },
   testProfileUnset: function(next) {
-    gProvider.updateUserProfile({});
+    Social.provider.updateUserProfile({});
     // check dom values
     let portrait = document.getElementById("social-statusarea-user-portrait").getAttribute("src");
     is(portrait, "chrome://browser/skin/social/social.png", "portrait is generic");
     let userButton = document.getElementById("social-statusarea-username");
     ok(userButton.hidden, "username is not visible");
     let ambience = document.getElementById("social-status-iconbox").firstChild;
     while (ambience) {
       ok(ambience.collapsed, "ambient icon is collapsed");
--- a/browser/base/content/test/head.js
+++ b/browser/base/content/test/head.js
@@ -82,8 +82,39 @@ function waitForCondition(condition, nex
     }
     if (condition()) {
       moveOn();
     }
     tries++;
   }, 100);
   var moveOn = function() { clearInterval(interval); nextTest(); };
 }
+
+function runSocialTestWithProvider(manifest, callback) {
+  let oldProvider;
+  function saveOldProviderAndStartTestWith(provider) {
+    oldProvider = Social.provider;
+    Social.provider = provider;
+
+    // Now that we've set the UI's provider, enable the social functionality
+    Services.prefs.setBoolPref("social.enabled", true);
+
+    registerCleanupFunction(function () {
+      Social.provider = oldProvider;
+      Services.prefs.clearUserPref("social.enabled");
+    });
+
+    callback();
+  }
+
+  SocialService.addProvider(manifest, function(provider) {
+    // If the UI is already active, run the test immediately, otherwise wait
+    // for initialization.
+    if (Social.provider) {
+      saveOldProviderAndStartTestWith(provider);
+    } else {
+      Services.obs.addObserver(function obs() {
+        Services.obs.removeObserver(obs, "test-social-ui-ready");
+        saveOldProviderAndStartTestWith(provider);
+      }, "test-social-ui-ready", false);
+    }
+  });
+}
--- a/browser/components/privatebrowsing/test/browser/Makefile.in
+++ b/browser/components/privatebrowsing/test/browser/Makefile.in
@@ -9,16 +9,18 @@ VPATH		= @srcdir@
 relativesrcdir  = browser/components/privatebrowsing/test/browser
 
 include $(DEPTH)/config/autoconf.mk
 
 MOCHITEST_BROWSER_FILES =  \
 		head.js \
 		browser_console_clear.js \
 		browser_privatebrowsing_certexceptionsui.js \
+		browser_privatebrowsing_clearplugindata.js \
+		browser_privatebrowsing_clearplugindata.html \
 		browser_privatebrowsing_commandline_toggle.js \
 		browser_privatebrowsing_concurrent.js \
 		browser_privatebrowsing_concurrent_page.html \
 		browser_privatebrowsing_crh.js \
 		browser_privatebrowsing_fastswitch.js \
 		browser_privatebrowsing_findbar.js \
 		browser_privatebrowsing_forgetthissite.js \
 		browser_privatebrowsing_geoprompt.js \
@@ -29,16 +31,17 @@ MOCHITEST_BROWSER_FILES =  \
 		browser_privatebrowsing_localStorage_before_after.js \
 		browser_privatebrowsing_localStorage_before_after_page.html \
 		browser_privatebrowsing_localStorage_before_after_page2.html \
 		browser_privatebrowsing_localStorage_page1.html \
 		browser_privatebrowsing_localStorage_page2.html \
 		browser_privatebrowsing_newwindow_stopcmd.js \
 		browser_privatebrowsing_opendir.js \
 		browser_privatebrowsing_openlocation.js \
+		browser_privatebrowsing_openLocationLastURL.js \
 		browser_privatebrowsing_pageinfo.js \
 		browser_privatebrowsing_placestitle.js \
 		browser_privatebrowsing_popupblocker.js \
 		browser_privatebrowsing_popupmode.js \
 		browser_privatebrowsing_protocolhandler.js \
 		browser_privatebrowsing_protocolhandler_page.html \
 		browser_privatebrowsing_searchbar.js \
 		browser_privatebrowsing_sslsite_transition.js \
@@ -47,18 +50,16 @@ MOCHITEST_BROWSER_FILES =  \
 		browser_privatebrowsing_ui.js \
 		browser_privatebrowsing_urlbarfocus.js \
 		browser_privatebrowsing_urlbarundo.js \
 		browser_privatebrowsing_viewsource.js \
 		browser_privatebrowsing_windowtitle.js \
 		browser_privatebrowsing_windowtitle_page.html \
 		browser_privatebrowsing_zoom.js \
 		browser_privatebrowsing_zoomrestore.js \
-		browser_privatebrowsing_clearplugindata.js \
-		browser_privatebrowsing_clearplugindata.html \
 		ctxmenu.html \
 		ctxmenu-image.png \
 		popup.html \
 		staller.sjs \
 		title.sjs \
 		$(NULL)
 
 # Disabled until bug 564934 is fixed:
new file mode 100644
--- /dev/null
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_openLocationLastURL.js
@@ -0,0 +1,63 @@
+/* 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/. */
+
+function test() {
+  const URL_1 = "mozilla.org";
+  const URL_2 = "mozilla.com";
+
+  let openLocationLastURL = getLocationModule();
+  let privateBrowsingService =
+    Cc["@mozilla.org/privatebrowsing;1"].
+      getService(Ci.nsIPrivateBrowsingService);
+
+  function clearHistory() {
+    Services.obs.notifyObservers(null, "browser:purge-session-history", "");
+  }
+  function testURL(aTestNumber, aValue) {
+    is(openLocationLastURL.value, aValue,
+       "Test: " + aTestNumber + ": Validate last url value.");
+  }
+
+  // Clean to start testing.
+  is(typeof openLocationLastURL, "object", "Validate type of last url.");
+  openLocationLastURL.reset();
+  testURL(1, "");
+
+  // Test without private browsing.
+  openLocationLastURL.value = URL_1;
+  testURL(2, URL_1);
+  openLocationLastURL.value = "";
+  testURL(3, "");
+  openLocationLastURL.value = URL_2;
+  testURL(4, URL_2);
+  clearHistory();
+  testURL(5, "");
+
+  // Test changing private browsing.
+  openLocationLastURL.value = URL_2;
+  privateBrowsingService.privateBrowsingEnabled = true;
+  testURL(6, "");
+  privateBrowsingService.privateBrowsingEnabled = false;
+  testURL(7, URL_2);
+  privateBrowsingService.privateBrowsingEnabled = true;
+  openLocationLastURL.value = URL_1;
+  testURL(8, URL_1);
+  privateBrowsingService.privateBrowsingEnabled = false;
+  testURL(9, URL_2);
+  privateBrowsingService.privateBrowsingEnabled = true;
+  openLocationLastURL.value = URL_1;
+  testURL(10, URL_1);
+
+  // Test cleaning history.
+  clearHistory();
+  testURL(11, "");
+  privateBrowsingService.privateBrowsingEnabled = false;
+  testURL(12, "");
+}
+
+function getLocationModule() {
+  let openLocationModule = {};
+  Cu.import("resource:///modules/openLocationLastURL.jsm", openLocationModule);
+  return new openLocationModule.OpenLocationLastURL(window);
+}
deleted file mode 100644
--- a/browser/components/privatebrowsing/test/unit/test_openLocationLastURL.js
+++ /dev/null
@@ -1,78 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// Test the correct behavior of the openLocationLastURL.jsm JS module.
-
-function run_test_on_service()
-{
-  let openLocationModule = {};
-  // This variable fakes the window required for getting the PB flag
-  let window = { gPrivateBrowsingUI: { privateWindow: false } };
-  Cu.import("resource:///modules/openLocationLastURL.jsm", openLocationModule);
-  let gOpenLocationLastURL = new openLocationModule.OpenLocationLastURL(window);
-  
-  function clearHistory() {
-    // simulate clearing the private data
-    Cc["@mozilla.org/observer-service;1"].
-    getService(Ci.nsIObserverService).
-    notifyObservers(null, "browser:purge-session-history", "");
-  }
-  
-  let pb = Cc[PRIVATEBROWSING_CONTRACT_ID].
-           getService(Ci.nsIPrivateBrowsingService);
-  let pref = Cc["@mozilla.org/preferences-service;1"].
-             getService(Ci.nsIPrefBranch);
-  gOpenLocationLastURL.reset();
-
-  do_check_eq(typeof gOpenLocationLastURL, "object");
-  do_check_eq(gOpenLocationLastURL.value, "");
-
-  function switchPrivateBrowsing(flag) {
-    pb.privateBrowsingEnabled = flag;
-    window.gPrivateBrowsingUI.privateWindow = flag;
-  }
-
-  const url1 = "mozilla.org";
-  const url2 = "mozilla.com";
-
-  gOpenLocationLastURL.value = url1;
-  do_check_eq(gOpenLocationLastURL.value, url1);
-
-  gOpenLocationLastURL.value = "";
-  do_check_eq(gOpenLocationLastURL.value, "");
-
-  gOpenLocationLastURL.value = url2;
-  do_check_eq(gOpenLocationLastURL.value, url2);
-
-  clearHistory();
-  do_check_eq(gOpenLocationLastURL.value, "");
-  gOpenLocationLastURL.value = url2;
-
-  switchPrivateBrowsing(true);
-  do_check_eq(gOpenLocationLastURL.value, "");
-  
-  switchPrivateBrowsing(false);
-  do_check_eq(gOpenLocationLastURL.value, url2);
-  switchPrivateBrowsing(true);
-
-  gOpenLocationLastURL.value = url1;
-  do_check_eq(gOpenLocationLastURL.value, url1);
-
-  switchPrivateBrowsing(false);
-  do_check_eq(gOpenLocationLastURL.value, url2);
-
-  switchPrivateBrowsing(true);
-  gOpenLocationLastURL.value = url1;
-  do_check_neq(gOpenLocationLastURL.value, "");
-  clearHistory();
-  do_check_eq(gOpenLocationLastURL.value, "");
-
-  switchPrivateBrowsing(false);
-  do_check_eq(gOpenLocationLastURL.value, "");
-}
-
-// Support running tests on both the service itself and its wrapper
-function run_test() {
-  run_test_on_all_services();
-}
--- a/browser/components/privatebrowsing/test/unit/xpcshell.ini
+++ b/browser/components/privatebrowsing/test/unit/xpcshell.ini
@@ -2,17 +2,16 @@
 head = head_privatebrowsing.js
 tail = tail_privatebrowsing.js
 
 [test_0-privatebrowsing.js]
 [test_0-privatebrowsingwrapper.js]
 [test_aboutprivatebrowsing.js]
 [test_geoClearCookie.js]
 [test_httpauth.js]
-[test_openLocationLastURL.js]
 [test_placesTitleNoUpdate.js]
 [test_privatebrowsing_autostart.js]
 [test_privatebrowsing_commandline.js]
 [test_privatebrowsing_exit.js]
 [test_privatebrowsing_telemetry.js]
 [test_privatebrowsingwrapper_autostart.js]
 [test_privatebrowsingwrapper_commandline.js]
 [test_privatebrowsingwrapper_exit.js]
--- a/browser/components/tabview/tabview.css
+++ b/browser/components/tabview/tabview.css
@@ -112,17 +112,17 @@ body {
 .appTabTrayContainer {
   position: absolute;
 }
 
 .title-container {
   /* We want the title container to leave out width, position of the .close
      button and space between input and .close button. Keep an eye on LTR and
      RTL differences in .close. */
-  width: -moz-calc(100% - 16px - 6px - 6px);
+  width: calc(100% - 16px - 6px - 6px);
 }
 
 input.name {
   text-overflow: ellipsis;
   width: -moz-available;
 }
 
 input.name:focus {
--- a/browser/devtools/debugger/debugger-controller.js
+++ b/browser/devtools/debugger/debugger-controller.js
@@ -67,24 +67,23 @@ let DebuggerController = {
    */
   _shutdownDebugger: function DC__shutdownDebugger() {
     if (this._isDestroyed) {
       return;
     }
     this._isDestroyed = true;
     window.removeEventListener("unload", this._shutdownDebugger, true);
 
-    DebuggerView.destroyPanes();
-    DebuggerView.destroyEditor();
     DebuggerView.Scripts.destroy();
     DebuggerView.StackFrames.destroy();
     DebuggerView.Breakpoints.destroy();
     DebuggerView.Properties.destroy();
+    DebuggerView.destroyPanes();
+    DebuggerView.destroyEditor();
 
-    DebuggerController.Breakpoints.destroy();
     DebuggerController.SourceScripts.disconnect();
     DebuggerController.StackFrames.disconnect();
     DebuggerController.ThreadState.disconnect();
 
     this.dispatchEvent("Debugger:Unloaded");
     this._disconnect();
     this._isChromeDebugger && this._quitApp();
   },
--- a/browser/devtools/debugger/debugger-view.js
+++ b/browser/devtools/debugger/debugger-view.js
@@ -52,16 +52,24 @@ let DebuggerView = {
    * Removes the displayed panes and saves any necessary state.
    */
   destroyPanes: function DV_destroyPanes() {
     let stackframes = document.getElementById("stackframes+breakpoints");
     Prefs.stackframesWidth = stackframes.getAttribute("width");
 
     let variables = document.getElementById("variables");
     Prefs.variablesWidth = variables.getAttribute("width");
+
+    let bkps = document.getElementById("breakpoints");
+    let frames = document.getElementById("stackframes");
+    bkps.parentNode.removeChild(bkps);
+    frames.parentNode.removeChild(frames);
+
+    stackframes.parentNode.removeChild(stackframes);
+    variables.parentNode.removeChild(variables);
   },
 
   /**
    * Removes the SourceEditor instance and added breakpoints.
    */
   destroyEditor: function DV_destroyEditor() {
     DebuggerController.Breakpoints.destroy();
     this.editor = null;
@@ -539,16 +547,18 @@ ScriptsView.prototype = {
   /**
    * Destruction function, called when the debugger is shut down.
    */
   destroy: function DVS_destroy() {
     this._scripts.removeEventListener("select", this._onScriptsChange, false);
     this._searchbox.removeEventListener("select", this._onScriptsSearch, false);
     this._searchbox.removeEventListener("input", this._onScriptsSearch, false);
     this._searchbox.removeEventListener("keyup", this._onScriptsKeyUp, false);
+
+    this.empty();
     this._scripts = null;
     this._searchbox = null;
   }
 };
 
 /**
  * Functions handling the html stackframes UI.
  */
@@ -854,16 +864,17 @@ StackFramesView.prototype = {
     resume.removeEventListener("click", this._onResumeButtonClick, false);
     stepOver.removeEventListener("click", this._onStepOverClick, false);
     stepIn.removeEventListener("click", this._onStepInClick, false);
     stepOut.removeEventListener("click", this._onStepOutClick, false);
     frames.removeEventListener("click", this._onFramesClick, false);
     frames.removeEventListener("scroll", this._onFramesScroll, false);
     window.removeEventListener("resize", this._onFramesScroll, false);
 
+    this.empty();
     this._frames = null;
   }
 };
 
 /**
  * Functions handling the breakpoints view.
  */
 function BreakpointsView() {
@@ -873,16 +884,17 @@ function BreakpointsView() {
 
 BreakpointsView.prototype = {
 
   /**
    * Removes all elements from the breakpoints container, leaving it empty.
    */
   empty: function DVB_empty() {
     let firstChild;
+
     while (firstChild = this._breakpoints.firstChild) {
       this._destroyContextMenu(firstChild);
       this._breakpoints.removeChild(firstChild);
     }
   },
 
   /**
    * Removes all elements from the breakpoints container, and adds a child node
@@ -1282,18 +1294,18 @@ BreakpointsView.prototype = {
    *        An element representing a breakpoint.
    * @return string
    *         The popup id.
    */
   _createContextMenu: function DVB_createContextMenu(aBreakpoint) {
     let commandsetId = "breakpointMenuCommands-" + aBreakpoint.id;
     let menupopupId = "breakpointContextMenu-" + aBreakpoint.id;
 
-    let commandsset = document.createElement("commandsset");
-    commandsset.setAttribute("id", commandsetId);
+    let commandset = document.createElement("commandset");
+    commandset.setAttribute("id", commandsetId);
 
     let menupopup = document.createElement("menupopup");
     menupopup.setAttribute("id", menupopupId);
 
     /**
      * Creates a menu item specified by a name with the appropriate attributes
      * (label and command handler).
      *
@@ -1316,17 +1328,17 @@ BreakpointsView.prototype = {
       command.setAttribute("id", commandId);
       command.setAttribute("label", label);
       command.addEventListener("command", func.bind(this, aBreakpoint), true);
 
       menuitem.setAttribute("id", menuitemId);
       menuitem.setAttribute("command", commandId);
       menuitem.setAttribute("hidden", aHiddenFlag);
 
-      commandsset.appendChild(command);
+      commandset.appendChild(command);
       menupopup.appendChild(menuitem);
 
       aBreakpoint[aName] = {
         menuitem: menuitem,
         command: command
       };
     }
 
@@ -1349,40 +1361,40 @@ BreakpointsView.prototype = {
     createMenuSeparator();
     createMenuItem.call(this, "enableAll");
     createMenuItem.call(this, "disableAll");
     createMenuSeparator();
     createMenuItem.call(this, "deleteAll");
 
     let popupset = document.getElementById("debugger-popups");
     popupset.appendChild(menupopup);
-    document.documentElement.appendChild(commandsset);
+    document.documentElement.appendChild(commandset);
+
+    aBreakpoint.commandsetId = commandsetId;
+    aBreakpoint.menupopupId = menupopupId;
 
     return menupopupId;
   },
 
   /**
    * Destroys a breakpoint context menu.
    *
    * @param object aBreakpoint
    *        An element representing a breakpoint.
    */
   _destroyContextMenu: function DVB__destroyContextMenu(aBreakpoint) {
-    let commandsetId = "breakpointMenuCommands-" + aBreakpoint.id;
-    let menupopupId = "breakpointContextMenu-" + aBreakpoint.id;
-
-    let commandset = document.getElementById(commandsetId);
-    let menupopup = document.getElementById(menupopupId);
+    if (!aBreakpoint.commandsetId || !aBreakpoint.menupopupId) {
+      return;
+    }
 
-    if (commandset) {
-      commandset.parentNode.removeChild(commandset);
-    }
-    if (menupopup) {
-      menupopup.parentNode.removeChild(menupopup);
-    }
+    let commandset = document.getElementById(aBreakpoint.commandsetId);
+    let menupopup = document.getElementById(aBreakpoint.menupopupId);
+
+    commandset.parentNode.removeChild(commandset);
+    menupopup.parentNode.removeChild(menupopup);
   },
 
   /**
    * Initialization function, called when the debugger is initialized.
    */
   initialize: function DVB_initialize() {
     let breakpoints = document.getElementById("breakpoints");
     breakpoints.addEventListener("click", this._onBreakpointClick, false);
@@ -1393,16 +1405,17 @@ BreakpointsView.prototype = {
 
   /**
    * Destruction function, called when the debugger is shut down.
    */
   destroy: function DVB_destroy() {
     let breakpoints = this._breakpoints;
     breakpoints.removeEventListener("click", this._onBreakpointClick, false);
 
+    this.empty();
     this._breakpoints = null;
   }
 };
 
 /**
  * Functions handling the properties view.
  */
 function PropertiesView() {
@@ -2494,16 +2507,18 @@ PropertiesView.prototype = {
     this.emptyText();
     this.createHierarchyStore();
   },
 
   /**
    * Destruction function, called when the debugger is shut down.
    */
   destroy: function DVP_destroy() {
+    this.empty();
+
     this._currHierarchy = null;
     this._prevHierarchy = null;
     this._vars = null;
   }
 };
 
 /**
  * Preliminary setup for the DebuggerView object.
--- a/browser/devtools/debugger/test/Makefile.in
+++ b/browser/devtools/debugger/test/Makefile.in
@@ -6,16 +6,17 @@ DEPTH           = ../../../..
 topsrcdir       = @top_srcdir@
 srcdir          = @srcdir@
 VPATH           = @srcdir@
 relativesrcdir  = browser/devtools/debugger/test
 
 include $(DEPTH)/config/autoconf.mk
 
 MOCHITEST_BROWSER_TESTS = \
+	browser_dbg_leaktest.js \
 	browser_dbg_createRemote.js \
 	browser_dbg_createChrome.js \
 	browser_dbg_debugger-tab-switch.js \
 	browser_dbg_debugger-tab-switch-window.js \
 	browser_dbg_debuggerstatement.js \
 	browser_dbg_listtabs.js \
 	browser_dbg_tabactor-01.js \
 	browser_dbg_tabactor-02.js \
--- a/browser/devtools/debugger/test/browser_dbg_breakpoint-new-script.js
+++ b/browser/devtools/debugger/test/browser_dbg_breakpoint-new-script.js
@@ -44,47 +44,49 @@ function testAddBreakpoint()
     });
   }, false);
 
   gDebuggee.runDebuggerStatement();
 }
 
 function testResume()
 {
-  gDebugger.DebuggerController.activeThread.addOneTimeListener("resumed", function test() {
-    gDebugger.DebuggerController.activeThread.addOneTimeListener("paused", function test() {
+  let thread = gDebugger.DebuggerController.activeThread;
+  thread.addOneTimeListener("resumed", function() {
+    thread.addOneTimeListener("paused", function() {
       executeSoon(testBreakpointHit);
-    }, false);
+    });
 
     EventUtils.sendMouseEvent({ type: "click" },
-      content.document.querySelector("button"),
-      content.window);
+      content.document.querySelector("button"));
 
   });
 
-  gDebugger.DebuggerController.activeThread.resume();
+  thread.resume();
 }
 
 function testBreakpointHit()
 {
-  var frames = gDebugger.DebuggerView.StackFrames._frames;
-
   is(gDebugger.DebuggerController.activeThread.state, "paused",
     "The breakpoint was hit.");
 
   resumeAndFinish();
 }
 
 function resumeAndFinish() {
   let thread = gDebugger.DebuggerController.activeThread;
   thread.addOneTimeListener("paused", function test(aEvent, aPacket) {
+    thread.addOneTimeListener("resumed", function() {
+      executeSoon(closeDebuggerAndFinish);
+    });
+
     is(aPacket.why.type, "debuggerStatement", "Execution has advanced to the next line.");
     isnot(aPacket.why.type, "breakpoint", "No ghost breakpoint was hit.");
+    thread.resume();
 
-    closeDebuggerAndFinish();
   });
 
   thread.resume();
 }
 
 registerCleanupFunction(function() {
   removeTab(gTab);
   gPane = null;
--- a/browser/devtools/debugger/test/browser_dbg_bug723069_editor-breakpoints.js
+++ b/browser/devtools/debugger/test/browser_dbg_bug723069_editor-breakpoints.js
@@ -270,25 +270,31 @@ function test()
     ok(aEvent, "breakpoint2 removed from the editor");
     is(aEvent.added.length, 0, "no breakpoint was added to the editor");
     is(aEvent.removed.length, 1, "one breakpoint was removed from the editor");
     is(aEvent.removed[0].line, 4, "editor breakpoint line is correct");
 
     is(gEditor.getBreakpoints().length, 0, "editor.getBreakpoints().length is correct");
 
     executeSoon(function() {
-      gDebugger.DebuggerController.activeThread.resume(finish);
+      gDebugger.gClient.addOneTimeListener("resumed", function() {
+        finalCheck();
+        closeDebuggerAndFinish();
+      });
+      gDebugger.DebuggerController.activeThread.resume();
     });
   }
 
+  function finalCheck() {
+    is(Object.keys(gBreakpoints).length, 0, "no breakpoint in the debugger");
+    ok(!gPane.getBreakpoint(gScripts.scriptLocations[0], 5),
+       "getBreakpoint(scriptLocations[0], 5) returns no breakpoint");
+  }
+
   registerCleanupFunction(function() {
-    is(Object.keys(gBreakpoints).length, 0, "no breakpoint in the debugger");
-    ok(!gPane.getBreakpoint(gScripts.scriptLocations[0], 5),
-       "getBreakpoint(scriptLocations[0], 5) returns no breakpoint");
-
     removeTab(gTab);
     is(breakpointsAdded, 2, "correct number of breakpoints have been added");
     is(breakpointsRemoved, 1, "correct number of breakpoints have been removed");
     is(editorBreakpointChanges, 4, "correct number of editor breakpoint changes");
     gPane = null;
     gTab = null;
     gDebuggee = null;
     gDebugger = null;
--- a/browser/devtools/debugger/test/browser_dbg_bug723071_editor-breakpoints-pane.js
+++ b/browser/devtools/debugger/test/browser_dbg_bug723071_editor-breakpoints-pane.js
@@ -137,17 +137,23 @@ function test()
 
             is(gBreakpointsElement.childNodes.length, 1,
               "The breakpoints pane should be empty, but showing a " +
               "'no breakpoints' information message.");
             is(gBreakpointsElement.childNodes.length,
                gBreakpointsElement.querySelectorAll(".list-item.empty").length,
                "Found junk in the breakpoints container.");
 
-            finish();
+            executeSoon(function() {
+              gDebugger.gClient.addOneTimeListener("resumed", function() {
+                finalCheck();
+                closeDebuggerAndFinish();
+              });
+              gDebugger.DebuggerController.activeThread.resume();
+            });
           });
         });
       });
     }, true);
 
     function addBreakpoints(callback, increment)
     {
       let line;
@@ -256,21 +262,23 @@ function test()
       return label + ":" + line;
     }
 
     function getExpectedLineText(line) {
       return gDebugger.DebuggerController.SourceScripts.getLineText(line - 1);
     }
   }
 
-  registerCleanupFunction(function() {
+  function finalCheck() {
     is(Object.keys(gBreakpoints).length, 0, "no breakpoint in the debugger");
     ok(!gPane.getBreakpoint(gScripts.scriptLocations[0], 5),
        "getBreakpoint(scriptLocations[0], 5) returns no breakpoint");
+  }
 
+  registerCleanupFunction(function() {
     is(breakpointsAdded, 3, "correct number of breakpoints have been added");
     is(breakpointsDisabled, 3, "correct number of breakpoints have been disabled");
     is(breakpointsRemoved, 3, "correct number of breakpoints have been removed");
     removeTab(gTab);
     gPane = null;
     gTab = null;
     gDebuggee = null;
     gDebugger = null;
--- a/browser/devtools/debugger/test/browser_dbg_bug731394_editor-contextmenu.js
+++ b/browser/devtools/debugger/test/browser_dbg_bug731394_editor-contextmenu.js
@@ -108,17 +108,17 @@ function test()
     for (let id in commands) {
       let element = document.getElementById(id);
       is(element.hasAttribute("disabled"), commands[id],
          id + " hasAttribute('disabled') check");
     }
 
     executeSoon(function() {
       contextMenu.hidePopup();
-      gDebugger.DebuggerController.activeThread.resume(finish);
+      closeDebuggerAndFinish();
     });
   }
 
   registerCleanupFunction(function() {
     removeTab(gTab);
     gPane = null;
     gTab = null;
     gDebuggee = null;
new file mode 100644
--- /dev/null
+++ b/browser/devtools/debugger/test/browser_dbg_leaktest.js
@@ -0,0 +1,69 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/**
+ * This tests if the debugger leaks.
+ * If leaks happen here, there's something very, very fishy going on.
+ */
+
+const TAB_URL = EXAMPLE_URL + "browser_dbg_script-switching.html";
+
+let gPane = null;
+let gTab = null;
+let gDebuggee = null;
+let gDebugger = null;
+
+function test()
+{
+  let scriptShown = false;
+  let framesAdded = false;
+  let resumed = false;
+  let testStarted = false;
+
+  debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
+    gTab = aTab;
+    gDebuggee = aDebuggee;
+    gPane = aPane;
+    gDebugger = gPane.contentWindow;
+    resumed = true;
+
+    gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
+      framesAdded = true;
+      executeSoon(startTest);
+    });
+
+    executeSoon(function() {
+      gDebuggee.firstCall();
+    });
+  });
+
+  function onScriptShown(aEvent)
+  {
+    scriptShown = aEvent.detail.url.indexOf("-02.js") != -1;
+    executeSoon(startTest);
+  }
+
+  window.addEventListener("Debugger:ScriptShown", onScriptShown);
+
+  function startTest()
+  {
+    if (scriptShown && framesAdded && resumed && !testStarted) {
+      window.removeEventListener("Debugger:ScriptShown", onScriptShown);
+      testStarted = true;
+      Services.tm.currentThread.dispatch({ run: performTest }, 0);
+    }
+  }
+
+  function performTest()
+  {
+    closeDebuggerAndFinish();
+  }
+
+  registerCleanupFunction(function() {
+    removeTab(gTab);
+    gPane = null;
+    gTab = null;
+    gDebuggee = null;
+    gDebugger = null;
+  });
+}
--- a/browser/devtools/layoutview/view.css
+++ b/browser/devtools/layoutview/view.css
@@ -40,17 +40,17 @@ body[dir=rtl] > #header > #element-size 
 
 #header:focus {
   outline: none;
 }
 
 #main {
   margin: 0 10px 10px 10px;
   -moz-box-sizing: border-box;
-  width: -moz-calc(100% - 2 * 10px);
+  width: calc(100% - 2 * 10px);
   position: absolute;
   border-width: 1px;
   font: 10px/12px monospace;
 }
 
 #margins {
   padding: 28px;
 }
@@ -103,17 +103,17 @@ body[dir=rtl] > #header > #element-size 
 
 .border.right{
   bottom: 42px; right: 0;
   width: 56px;
   top: auto;
 }
 
 .top, .bottom {
-  width: -moz-calc(100% - 2px);
+  width: calc(100% - 2px);
   text-align: center;
 }
 
 .margin.top {
   top: 8px;
 }
 
 .margin.bottom {
@@ -133,17 +133,17 @@ body[dir=rtl] > #header > #element-size 
 .margin.right,
 .padding.left,
 .padding.right {
   top: 0;
   line-height: 132px;
 }
 
 .size {
-  width: -moz-calc(100% - 2px);
+  width: calc(100% - 2px);
 }
 
 .margin.right,
 .margin.left {
   width: 28px;
 }
 
 .padding.right,
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -657,8 +657,10 @@ toolbar button -->
 <!ENTITY social.notLoggedIn.label   "Not logged in">
 
 <!ENTITY social.sharePopup.undo.label     "Unshare">
 <!ENTITY social.sharePopup.undo.accesskey "U">
 <!ENTITY social.sharePopup.ok.label       "OK">
 <!ENTITY social.sharePopup.ok.accesskey   "O">
 <!ENTITY social.sharePopup.shared.label   "You shared this page.">
 <!ENTITY social.sharePopup.portrait.arialabel "User profile picture">
+<!ENTITY social.toggleSidebar.label "Show sidebar">
+<!ENTITY social.toggleSidebar.accesskey "s">
--- a/browser/modules/Social.jsm
+++ b/browser/modules/Social.jsm
@@ -29,22 +29,23 @@ let Social = {
     SocialService.getProviderList(function (providers) {
       if (providers.length)
         this.provider = providers[0];
       callback();
       Services.obs.notifyObservers(null, "test-social-ui-ready", "");
     }.bind(this));
   },
 
-  get enabled() {
-    return SocialService.enabled;
+  get uiVisible() {
+    return this.provider && this.provider.enabled && this.provider.port;
   },
 
-  get uiVisible() {
-    return this.provider && this.provider.enabled && this.provider.port;
+  toggleSidebar: function SocialSidebar_toggle() {
+    let prefValue = Services.prefs.getBoolPref("social.sidebar.open");
+    Services.prefs.setBoolPref("social.sidebar.open", !prefValue);
   },
 
   sendWorkerMessage: function Social_sendWorkerMessage(message) {
     // Responses aren't handled yet because there is no actions to perform
     // based on the response from the provider at this point.
     if (this.provider && this.provider.port)
       this.provider.port.postMessage(message);
   },
--- a/browser/themes/gnomestripe/browser.css
+++ b/browser/themes/gnomestripe/browser.css
@@ -1523,17 +1523,17 @@ richlistitem[type~="action"][actiontype=
 
 .tabbrowser-tab,
 .tabs-newtab-button {
   position: static;
   -moz-appearance: none;
   background: -moz-linear-gradient(hsla(0,0%,100%,.2), hsla(0,0%,45%,.2) 2px, hsla(0,0%,32%,.2) 80%);
   background-origin: border-box;
   background-position: 1px 2px;
-  background-size: 100% -moz-calc(100% - 2px);
+  background-size: 100% calc(100% - 2px);
   background-repeat: no-repeat;
   color: inherit;
   margin: 0;
   padding: 0;
   border-width: 4px 5px 3px 6px;
   border-style: solid;
   -moz-border-image: url(tabbrowser/tab.png) 4 5 3 6 fill repeat stretch;
   border-radius: 10px 8px 0 0;
@@ -2035,17 +2035,17 @@ toolbar[mode="text"] toolbarbutton.chevr
   border-radius: 3px;
   background: -moz-linear-gradient(hsl(209, 18%, 30%), hsl(210, 24%, 16%)) no-repeat padding-box;
 }
 
 /* Highlighter - Node Infobar - text */
 
 #highlighter-nodeinfobar-text {
   /* 100% - size of the buttons and margins */
-  max-width: -moz-calc(100% - 2 * (26px + 6px));
+  max-width: calc(100% - 2 * (26px + 6px));
   padding-bottom: 1px;
 }
 
 html|*#highlighter-nodeinfobar-tagname {
   color: white;
 }
 
 html|*#highlighter-nodeinfobar-id {
@@ -2100,17 +2100,17 @@ html|*#highlighter-nodeinfobar-pseudo-cl
   -moz-margin-start: -1px;
 }
 
 /* Highlighter - Node Infobar - box & arrow */
 
 .highlighter-nodeinfobar-arrow {
   width: 14px;
   height: 14px;
-  -moz-margin-start: -moz-calc(50% - 7px);
+  -moz-margin-start: calc(50% - 7px);
   transform: rotate(-45deg);
   border: 1px solid transparent;
   background-clip: padding-box;
   background-repeat: no-repeat;
 }
 
 #highlighter-nodeinfobar-arrow-top {
   margin-bottom: -8px;
--- a/browser/themes/gnomestripe/devtools/common.css
+++ b/browser/themes/gnomestripe/devtools/common.css
@@ -88,17 +88,17 @@
   -moz-padding-end: 12px;
   box-shadow: 0 1px 1px hsla(210,8%,5%,.3) inset,
               0 0 0 1px hsla(210,16%,76%,.1) inset,
               0 1px 0 hsla(210,16%,76%,.15);
   color: inherit;
 }
 
 .devtools-searchinput:-moz-locale-dir(rtl) {
-  background-position: -moz-calc(100% - 4px) 3px, top left, top left;
+  background-position: calc(100% - 4px) 3px, top left, top left;
 }
 
 .devtools-searchinput > .textbox-input-box > .textbox-search-icons {
   display: none;
 }
 
 .devtools-searchinput > .textbox-input-box > .textbox-input:-moz-placeholder {
   color: hsl(208,10%,66%);
--- a/browser/themes/pinstripe/browser.css
+++ b/browser/themes/pinstripe/browser.css
@@ -2791,17 +2791,17 @@ toolbarbutton.chevron > .toolbarbutton-m
   border-radius: 3px;
   background: -moz-linear-gradient(hsl(209, 18%, 30%), hsl(210, 24%, 16%)) no-repeat padding-box;
 }
 
 /* Highlighter - Node Infobar - text */
 
 #highlighter-nodeinfobar-text {
   /* 100% - size of the buttons + margins */
-  max-width: -moz-calc(100% - 2 * (26px + 6px));
+  max-width: calc(100% - 2 * (26px + 6px));
   padding-bottom: 1px;
 }
 
 html|*#highlighter-nodeinfobar-tagname {
   color: white;
 }
 
 html|*#highlighter-nodeinfobar-id {
@@ -2857,17 +2857,17 @@ html|*#highlighter-nodeinfobar-pseudo-cl
   -moz-margin-start: -1px;
 }
 
 /* Highlighter - Node Infobar - box & arrow */
 
 .highlighter-nodeinfobar-arrow {
   width: 14px;
   height: 14px;
-  -moz-margin-start: -moz-calc(50% - 7px);
+  -moz-margin-start: calc(50% - 7px);
   transform: rotate(-45deg);
   border: 1px solid transparent;
   background-clip: padding-box;
   background-repeat: no-repeat;
 }
 
 #highlighter-nodeinfobar-arrow-top {
   margin-bottom: -8px;
--- a/browser/themes/pinstripe/devtools/common.css
+++ b/browser/themes/pinstripe/devtools/common.css
@@ -94,17 +94,17 @@
   -moz-padding-end: 12px;
   box-shadow: 0 1px 1px hsla(210,8%,5%,.3) inset,
               0 0 0 1px hsla(210,16%,76%,.1) inset,
               0 1px 0 hsla(210,16%,76%,.15);
   color: inherit;
 }
 
 .devtools-searchinput:-moz-locale-dir(rtl) {
-  background-position: -moz-calc(100% - 4px) 3px, top left, top left;
+  background-position: calc(100% - 4px) 3px, top left, top left;
 }
 
 .devtools-searchinput > .textbox-input-box > .textbox-search-icons {
   display: none;
 }
 
 .devtools-searchinput > .textbox-input-box > .textbox-input:-moz-placeholder {
   color: hsl(208,10%,66%);
--- a/browser/themes/winstripe/browser.css
+++ b/browser/themes/winstripe/browser.css
@@ -343,17 +343,17 @@
 
   .appmenu-menuseparator {
     -moz-appearance: none;
     margin-top: 3px;
     margin-bottom: 3px;
 %ifdef WINSTRIPE_AERO
     -moz-margin-start: 30px;
 %else
-    -moz-margin-start: -moz-calc(1.45em + 4px);
+    -moz-margin-start: calc(1.45em + 4px);
 %endif
     padding: 0;
     border-top: 1px solid #d6e5f5;
     border-bottom: none;
   }
 
   .appmenu-edit-button:not([disabled]):hover {
     border: 1px solid #b8d6fb;
@@ -804,17 +804,17 @@ toolbar[mode=full] .toolbarbutton-1 > .t
 #TabsToolbar .toolbarbutton-1[open],
 #TabsToolbar .toolbarbutton-1 > .toolbarbutton-menubutton-button:not([disabled]):hover,
 .tabbrowser-arrowscrollbox > .scrollbutton-up:not([disabled]):hover,
 .tabbrowser-arrowscrollbox > .scrollbutton-down:not([disabled]):hover {
   background-image: -moz-linear-gradient(rgba(255,255,255,0), rgba(255,255,255,.5)),
                     -moz-linear-gradient(transparent, rgba(0,0,0,.25) 30%),
                     -moz-linear-gradient(transparent, rgba(0,0,0,.25) 30%);
   background-position: 1px -1px, 0 -1px, 100% -1px;
-  background-size: -moz-calc(100% - 2px) 100%, 1px 100%, 1px 100%;
+  background-size: calc(100% - 2px) 100%, 1px 100%, 1px 100%;
   background-repeat: no-repeat;
 }
 
 #addon-bar .toolbarbutton-1:not([disabled]):hover,
 #addon-bar .toolbarbutton-1[open],
 #addon-bar .toolbarbutton-1 > .toolbarbutton-menubutton-button:not([disabled]):hover {
   background-image: -moz-linear-gradient(bottom, transparent, rgba(0,0,0,.15)),
                     -moz-linear-gradient(bottom, transparent, rgba(0,0,0,.15) 30%),
@@ -1829,17 +1829,17 @@ richlistitem[type~="action"][actiontype=
 
 .tabbrowser-tab,
 .tabs-newtab-button {
   -moz-appearance: none;
   background: @toolbarShadowOnTab@, @bgTabTexture@,
               -moz-linear-gradient(-moz-dialog, -moz-dialog);
   background-origin: border-box;
   background-position: 1px 2px;
-  background-size: -moz-calc(100% - 2px) -moz-calc(100% - 2px);
+  background-size: calc(100% - 2px) calc(100% - 2px);
   background-repeat: no-repeat;
   margin: 0;
   padding: 2px 0 4px;
   border-width: 4px 3px 0;
   border-style: solid;
   -moz-border-image: url(tabbrowser/tab.png) 4 3 0 fill repeat stretch;
   border-radius: 0;
 }
@@ -1987,17 +1987,17 @@ richlistitem[type~="action"][actiontype=
     min-width: 8.1mozmm;
   }
 
   .tabs-newtab-button {
     min-width: 10mozmm;
   }
 
   .tab-content {
-    min-height: -moz-calc(6.8mozmm - 7px); /* subtract borders from the desired height */
+    min-height: calc(6.8mozmm - 7px); /* subtract borders from the desired height */
   }
 }
 
 .tabbrowser-arrowscrollbox > .scrollbutton-up,
 .tabbrowser-arrowscrollbox > .scrollbutton-down {
   list-style-image: url("chrome://browser/skin/tabbrowser/tab-arrow-left.png");
   margin: 0;
   padding-right: 2px;
@@ -2713,17 +2713,17 @@ toolbarbutton.bookmark-item[dragover="tr
   border-radius: 3px;
   background: -moz-linear-gradient(hsl(209, 18%, 30%), hsl(210, 24%, 16%)) no-repeat padding-box;
 }
 
 /* Highlighter - Node Infobar - text */
 
 #highlighter-nodeinfobar-text {
   /* 100% - size of the buttons and margins */
-  max-width: -moz-calc(100% - 2 * (26px + 6px));
+  max-width: calc(100% - 2 * (26px + 6px));
   padding-bottom: 1px;
 }
 
 html|*#highlighter-nodeinfobar-tagname {
   color: white;
 }
 
 html|*#highlighter-nodeinfobar-id {
@@ -2779,17 +2779,17 @@ html|*#highlighter-nodeinfobar-pseudo-cl
   -moz-margin-start: -1px;
 }
 
 /* Highlighter - Node Infobar - box & arrow */
 
 .highlighter-nodeinfobar-arrow {
   width: 14px;
   height: 14px;
-  -moz-margin-start: -moz-calc(50% - 7px);
+  -moz-margin-start: calc(50% - 7px);
   transform: rotate(-45deg);
   border: 1px solid transparent;
   background-clip: padding-box;
   background-repeat: no-repeat;
 }
 
 #highlighter-nodeinfobar-arrow-top {
   margin-bottom: -8px;
--- a/browser/themes/winstripe/devtools/common.css
+++ b/browser/themes/winstripe/devtools/common.css
@@ -101,17 +101,17 @@
 .devtools-searchinput[focused] {
   border-color: hsl(200,70%,40%) hsl(200,75%,37%) hsl(200,80%,35%);
   background-origin: padding-box;
   background-clip: padding-box;
   box-shadow: inset 0 0 0 1px hsla(211,68%,6%,.1);
 }
 
 .devtools-searchinput:-moz-locale-dir(rtl) {
-  background-position: -moz-calc(100% - 4px) 3px, top left, top left;
+  background-position: calc(100% - 4px) 3px, top left, top left;
 }
 
 .devtools-searchinput > .textbox-input-box > .textbox-search-icons {
   display: none;
 }
 
 .devtools-searchinput > .textbox-input-box > .textbox-input:-moz-placeholder {
   color: hsl(208,10%,66%);
new file mode 100644
--- /dev/null
+++ b/build/autoconf/ccache.m4
@@ -0,0 +1,36 @@
+dnl This Source Code Form is subject to the terms of the Mozilla Public
+dnl License, v. 2.0. If a copy of the MPL was not distributed with this
+dnl file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+dnl ======================================================
+dnl = Enable compiling with ccache
+dnl ======================================================
+AC_DEFUN([MOZ_CHECK_CCACHE],
+[
+MOZ_ARG_WITH_STRING(ccache,
+[  --with-ccache[=path/to/ccache]
+                          Enable compiling with ccache],
+    CCACHE=$withval, CCACHE="no")
+
+if test "$CCACHE" != "no"; then
+    if test -z "$CCACHE" -o "$CCACHE" = "yes"; then
+        CCACHE=
+    else
+        if test ! -e "$CCACHE"; then
+            AC_MSG_ERROR([$CCACHE not found])
+        fi
+    fi
+    MOZ_PATH_PROGS(CCACHE, $CCACHE ccache)
+    if test -z "$CCACHE" -o "$CCACHE" = ":"; then
+        AC_MSG_ERROR([ccache not found])
+    elif test -x "$CCACHE"; then
+        CC="$CCACHE $CC"
+        CXX="$CCACHE $CXX"
+        MOZ_USING_CCACHE=1
+    else
+        AC_MSG_ERROR([$CCACHE is not executable])
+    fi
+fi
+
+AC_SUBST(MOZ_USING_CCACHE)
+])
new file mode 100644
--- /dev/null
+++ b/build/autoconf/toolchain.m4
@@ -0,0 +1,62 @@
+dnl This Source Code Form is subject to the terms of the Mozilla Public
+dnl License, v. 2.0. If a copy of the MPL was not distributed with this
+dnl file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+AC_DEFUN([MOZ_TOOL_VARIABLES],
+[
+GNU_AS=
+GNU_LD=
+GNU_CC=
+GNU_CXX=
+CC_VERSION='N/A'
+CXX_VERSION='N/A'
+if test "$GCC" = "yes"; then
+    GNU_CC=1
+    CC_VERSION=`$CC -v 2>&1 | grep 'gcc version'`
+fi
+if test "$GXX" = "yes"; then
+    GNU_CXX=1
+    CXX_VERSION=`$CXX -v 2>&1 | grep 'gcc version'`
+fi
+if test "`echo | $AS -o conftest.out -v 2>&1 | grep -c GNU`" != "0"; then
+    GNU_AS=1
+fi
+rm -f conftest.out
+if test "`echo | $LD -v 2>&1 | grep -c GNU`" != "0"; then
+    GNU_LD=1
+fi
+if test "$GNU_CC"; then
+    if `$CC -print-prog-name=ld` -v 2>&1 | grep -c GNU >/dev/null; then
+        GCC_USE_GNU_LD=1
+    fi
+fi
+
+INTEL_CC=
+INTEL_CXX=
+if test "$GCC" = yes; then
+   if test "`$CC -help 2>&1 | grep -c 'Intel(R) C++ Compiler'`" != "0"; then
+     INTEL_CC=1
+   fi
+fi
+
+if test "$GXX" = yes; then
+   if test "`$CXX -help 2>&1 | grep -c 'Intel(R) C++ Compiler'`" != "0"; then
+     INTEL_CXX=1
+   fi
+fi
+
+CLANG_CC=
+CLANG_CXX=
+if test "$GCC" = yes; then
+   if test "`$CC -v 2>&1 | grep -c 'clang version'`" != "0"; then
+     CLANG_CC=1
+   fi
+fi
+
+if test "$GXX" = yes; then
+   if test "`$CXX -v 2>&1 | grep -c 'clang version'`" != "0"; then
+     CLANG_CXX=1
+   fi
+fi
+AC_SUBST(CLANG_CXX)
+])
--- a/build/automation.py.in
+++ b/build/automation.py.in
@@ -13,16 +13,17 @@ import re
 import select
 import shutil
 import signal
 import subprocess
 import sys
 import threading
 import tempfile
 import sqlite3
+from string import Template
 
 SCRIPT_DIR = os.path.abspath(os.path.realpath(os.path.dirname(sys.argv[0])))
 sys.path.insert(0, SCRIPT_DIR)
 import automationutils
 
 _DEFAULT_WEB_SERVER = "127.0.0.1"
 _DEFAULT_HTTP_PORT = 8888
 _DEFAULT_SSL_PORT = 4443
@@ -279,16 +280,73 @@ class Automation(object):
         c += 1
         cursor.execute("INSERT INTO moz_hosts values(?, ?, ?, ?, 0, 0)",
                        (c, host, perm, 1 if allow else 2))
 
     # Commit and close
     permDB.commit()
     cursor.close()
 
+  def setupTestApps(self, profileDir, apps):
+    webappJSONTemplate = Template(""""$name": {
+"origin": "$origin",
+"installOrigin": "$origin",
+"receipt": null,
+"installTime": 132333986000,
+"manifestURL": "$manifestURL",
+"localId": $localId
+}""")
+
+    manifestTemplate = Template("""{
+  "name": "$name",
+  "description": "$description",
+  "launch_path": "/",
+  "developer": {
+    "name": "Mozilla",
+    "url": "https://mozilla.org/"
+  },
+  "permissions": [
+  ],
+  "locales": {
+    "en-US": {
+      "name": "$name",
+      "description": "$description"
+    }
+  },
+  "default_locale": "en-US",
+  "icons": {
+  }
+}
+""")
+
+    # Create webapps/webapps.json
+    webappsDir = os.path.join(profileDir, "webapps")
+    os.mkdir(webappsDir);
+
+    webappsJSON = []
+    for localId, app in enumerate(apps):
+      app['localId'] = localId + 1 # Has to be 1..n
+      webappsJSON.append(webappJSONTemplate.substitute(app))
+    webappsJSON = '{\n' + ',\n'.join(webappsJSON) + '\n}\n'
+
+    webappsJSONFile = open(os.path.join(webappsDir, "webapps.json"), "a")
+    webappsJSONFile.write(webappsJSON)
+    webappsJSONFile.close()
+
+    # Create manifest file for each app.
+    for app in apps:
+      manifest = manifestTemplate.substitute(app)
+
+      manifestDir = os.path.join(webappsDir, app['name'])
+      os.mkdir(manifestDir)
+
+      manifestFile = open(os.path.join(manifestDir, "manifest.webapp"), "a")
+      manifestFile.write(manifest)
+      manifestFile.close()
+
   def initializeProfile(self, profileDir, extraPrefs = [], useServerLocations = False):
     " Sets up the standard testing profile."
 
     prefs = []
     # Start with a clean slate.
     shutil.rmtree(profileDir, True)
     os.mkdir(profileDir)
 
@@ -458,16 +516,50 @@ user_pref("camino.use_system_proxy_setti
       part = 'user_pref("%s", %s);\n' % (thispref[0], thispref[1])
       prefs.append(part)
 
     # write the preferences
     prefsFile = open(profileDir + "/" + "user.js", "a")
     prefsFile.write("".join(prefs))
     prefsFile.close()
 
+    apps = [
+      {
+        'name': 'http_example_org',
+        'origin': 'http://example.org',
+        'manifestURL': 'http://example.org/manifest.webapp',
+        'description': 'http://example.org App'
+      },
+      {
+        'name': 'https_example_com',
+        'origin': 'https://example.com',
+        'manifestURL': 'https://example.com/manifest.webapp',
+        'description': 'https://example.com App'
+      },
+      {
+        'name': 'http_test1_example_org',
+        'origin': 'http://test1.example.org',
+        'manifestURL': 'http://test1.example.org/manifest.webapp',
+        'description': 'http://test1.example.org App'
+      },
+      {
+        'name': 'http_test1_example_org_8000',
+        'origin': 'http://test1.example.org:8000',
+        'manifestURL': 'http://test1.example.org:8000/manifest.webapp',
+        'description': 'http://test1.example.org:8000 App'
+      },
+      {
+        'name': 'http_sub1_test1_example_org',
+        'origin': 'http://sub1.test1.example.org',
+        'manifestURL': 'http://sub1.test1.example.org/manifest.webapp',
+        'description': 'http://sub1.test1.example.org App'
+      },
+    ];
+    self.setupTestApps(profileDir, apps)
+
   def addCommonOptions(self, parser):
     "Adds command-line options which are common to mochitest and reftest."
 
     parser.add_option("--setpref",
                       action = "append", type = "string",
                       default = [],
                       dest = "extraPrefs", metavar = "PREF=VALUE",
                       help = "defines an extra user preference")  
--- a/build/macosx/common
+++ b/build/macosx/common
@@ -1,4 +1,11 @@
-export CC=$topsrcdir/clang/bin/clang
-export CXX=$topsrcdir/clang/bin/clang++
+if [ -d "$topsrcdir/clang" ]; then
+    # mozilla-central based build
+    export CC=$topsrcdir/clang/bin/clang
+    export CXX=$topsrcdir/clang/bin/clang++
+elif [ -d "$topsrcdir/../clang" ]; then
+    # comm-central based build
+    export CC=$topsrcdir/../clang/bin/clang
+    export CXX=$topsrcdir/../clang/bin/clang++
+fi
 
 ac_add_options --enable-stdcxx-compat
new file mode 100644
--- /dev/null
+++ b/build/mobile/b2gemulator.py
@@ -0,0 +1,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/.
+
+
+import os
+import platform
+
+from emulator import Emulator
+
+
+class B2GEmulator(Emulator):
+
+    def __init__(self, homedir=None, noWindow=False, logcat_dir=None, arch="x86",
+                 emulatorBinary=None, res='480x800', userdata=None,
+                 memory='512', partition_size='512'):
+        super(B2GEmulator, self).__init__(noWindow=noWindow, logcat_dir=logcat_dir,
+                                          arch=arch, emulatorBinary=emulatorBinary,
+                                          res=res, userdata=userdata,
+                                          memory=memory, partition_size=partition_size)
+        self.homedir = homedir
+        if self.homedir is not None:
+            self.homedir = os.path.expanduser(homedir)
+
+    def _check_file(self, filePath):
+        if not os.path.exists(filePath):
+            raise Exception(('File not found: %s; did you pass the B2G home '
+                             'directory as the homedir parameter, or set '
+                             'B2G_HOME correctly?') % filePath)
+
+    def _check_for_adb(self, host_dir):
+        self.adb = os.path.join(self.homedir, 'out', 'host', host_dir, 'bin', 'adb')
+        if not os.path.exists(self.adb):
+            self.adb = os.path.join(self.homedir, 'bin/adb')
+        super(B2GEmulator, self)._check_for_adb()
+
+    def _locate_files(self):
+        if self.homedir is None:
+            self.homedir = os.getenv('B2G_HOME')
+        if self.homedir is None:
+            raise Exception('Must define B2G_HOME or pass the homedir parameter')
+        self._check_file(self.homedir)
+
+        if self.arch not in ("x86", "arm"):
+            raise Exception("Emulator architecture must be one of x86, arm, got: %s" %
+                            self.arch)
+
+        host_dir = "linux-x86"
+        if platform.system() == "Darwin":
+            host_dir = "darwin-x86"
+
+        host_bin_dir = os.path.join("out", "host", host_dir, "bin")
+
+        if self.arch == "x86":
+            binary = os.path.join(host_bin_dir, "emulator-x86")
+            kernel = "prebuilts/qemu-kernel/x86/kernel-qemu"
+            sysdir = "out/target/product/generic_x86"
+            self.tail_args = []
+        else:
+            binary = os.path.join(host_bin_dir, "emulator")
+            kernel = "prebuilts/qemu-kernel/arm/kernel-qemu-armv7"
+            sysdir = "out/target/product/generic"
+            self.tail_args = ["-cpu", "cortex-a8"]
+
+        self._check_for_adb(host_dir)
+
+        if not self.binary:
+            self.binary = os.path.join(self.homedir, binary)
+
+        self._check_file(self.binary)
+
+        self.kernelImg = os.path.join(self.homedir, kernel)
+        self._check_file(self.kernelImg)
+
+        self.sysDir = os.path.join(self.homedir, sysdir)
+        self._check_file(self.sysDir)
+
+        if not self.dataImg:
+            self.dataImg = os.path.join(self.sysDir, 'userdata.img')
+        self._check_file(self.dataImg)
new file mode 100644
--- /dev/null
+++ b/build/mobile/emulator.py
@@ -0,0 +1,295 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+from abc import abstractmethod
+import datetime
+from mozprocess import ProcessHandlerMixin
+import multiprocessing
+import os
+import re
+import shutil
+import socket
+import subprocess
+from telnetlib import Telnet
+import tempfile
+import time
+
+from emulator_battery import EmulatorBattery
+
+
+class LogcatProc(ProcessHandlerMixin):
+    """Process handler for logcat which saves all output to a logfile.
+    """
+
+    def __init__(self, logfile, cmd, **kwargs):
+        self.logfile = logfile
+        kwargs.setdefault('processOutputLine', []).append(self.log_output)
+        ProcessHandlerMixin.__init__(self, cmd, **kwargs)
+
+    def log_output(self, line):
+        f = open(self.logfile, 'a')
+        f.write(line + "\n")
+        f.flush()
+
+
+class Emulator(object):
+
+    deviceRe = re.compile(r"^emulator-(\d+)(\s*)(.*)$")
+
+    def __init__(self, noWindow=False, logcat_dir=None, arch="x86",
+                 emulatorBinary=None, res='480x800', userdata=None,
+                 memory='512', partition_size='512'):
+        self.port = None
+        self._emulator_launched = False
+        self.proc = None
+        self.local_port = None
+        self.telnet = None
+        self._tmp_userdata = None
+        self._adb_started = False
+        self.logcat_dir = logcat_dir
+        self.logcat_proc = None
+        self.arch = arch
+        self.binary = emulatorBinary
+        self.memory = str(memory)
+        self.partition_size = str(partition_size)
+        self.res = res
+        self.battery = EmulatorBattery(self)
+        self.noWindow = noWindow
+        self.dataImg = userdata
+        self.copy_userdata = self.dataImg is None
+
+    def __del__(self):
+        if self.telnet:
+            self.telnet.write('exit\n')
+            self.telnet.read_all()
+
+    @property
+    def args(self):
+        qemuArgs = [self.binary,
+                    '-kernel', self.kernelImg,
+                    '-sysdir', self.sysDir,
+                    '-data', self.dataImg]
+        if self.noWindow:
+            qemuArgs.append('-no-window')
+        qemuArgs.extend(['-memory', self.memory,
+                         '-partition-size', self.partition_size,
+                         '-verbose',
+                         '-skin', self.res,
+                         '-gpu', 'on',
+                         '-qemu'] + self.tail_args)
+        return qemuArgs
+
+    @property
+    def is_running(self):
+        if self._emulator_launched:
+            return self.proc is not None and self.proc.poll() is None
+        else:
+            return self.port is not None
+
+    def _check_for_adb(self):
+        if not os.path.exists(self.adb):
+            adb = subprocess.Popen(['which', 'adb'],
+                                   stdout=subprocess.PIPE,
+                                   stderr=subprocess.STDOUT)
+            retcode = adb.wait()
+            if retcode:
+                raise Exception('adb not found!')
+            out = adb.stdout.read().strip()
+            if len(out) and out.find('/') > -1:
+                self.adb = out
+
+    def _run_adb(self, args):
+        args.insert(0, self.adb)
+        adb = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+        retcode = adb.wait()
+        if retcode:
+            raise Exception('adb terminated with exit code %d: %s'
+            % (retcode, adb.stdout.read()))
+        return adb.stdout.read()
+
+    def _get_telnet_response(self, command=None):
+        output = []
+        assert(self.telnet)
+        if command is not None:
+            self.telnet.write('%s\n' % command)
+        while True:
+            line = self.telnet.read_until('\n')
+            output.append(line.rstrip())
+            if line.startswith('OK'):
+                return output
+            elif line.startswith('KO:'):
+                raise Exception('bad telnet response: %s' % line)
+
+    def _run_telnet(self, command):
+        if not self.telnet:
+            self.telnet = Telnet('localhost', self.port)
+            self._get_telnet_response()
+        return self._get_telnet_response(command)
+
+    def close(self):
+        if self.is_running and self._emulator_launched:
+            self.proc.terminate()
+            self.proc.wait()
+        if self._adb_started:
+            self._run_adb(['kill-server'])
+            self._adb_started = False
+        if self.proc:
+            retcode = self.proc.poll()
+            self.proc = None
+            if self._tmp_userdata:
+                os.remove(self._tmp_userdata)
+                self._tmp_userdata = None
+            return retcode
+        if self.logcat_proc:
+            self.logcat_proc.kill()
+        return 0
+
+    def _get_adb_devices(self):
+        offline = set()
+        online = set()
+        output = self._run_adb(['devices'])
+        for line in output.split('\n'):
+            m = self.deviceRe.match(line)
+            if m:
+                if m.group(3) == 'offline':
+                    offline.add(m.group(1))
+                else:
+                    online.add(m.group(1))
+        return (online, offline)
+
+    def restart(self):
+        if not self._emulator_launched:
+            return
+        self.close()
+        self.start()
+
+    def start_adb(self):
+        result = self._run_adb(['start-server'])
+        # We keep track of whether we've started adb or not, so we know
+        # if we need to kill it.
+        if 'daemon started successfully' in result:
+            self._adb_started = True
+        else:
+            self._adb_started = False
+
+    def connect(self):
+        self._check_for_adb()
+        self.start_adb()
+
+        online, offline = self._get_adb_devices()
+        now = datetime.datetime.now()
+        while online == set([]):
+            time.sleep(1)
+            if datetime.datetime.now() - now > datetime.timedelta(seconds=60):
+                raise Exception('timed out waiting for emulator to be available')
+            online, offline = self._get_adb_devices()
+        self.port = int(list(online)[0])
+
+    @abstractmethod
+    def _locate_files(self):
+        pass
+
+    def start(self):
+        self._locate_files()
+        self.start_adb()
+
+        qemu_args = self.args[:]
+        if self.copy_userdata:
+            # Make a copy of the userdata.img for this instance of the emulator
+            # to use.
+            self._tmp_userdata = tempfile.mktemp(prefix='emulator')
+            shutil.copyfile(self.dataImg, self._tmp_userdata)
+            qemu_args[qemu_args.index('-data') + 1] = self._tmp_userdata
+
+        original_online, original_offline = self._get_adb_devices()
+
+        self.proc = subprocess.Popen(qemu_args,
+                                     stdout=subprocess.PIPE,
+                                     stderr=subprocess.PIPE)
+
+        online, offline = self._get_adb_devices()
+        now = datetime.datetime.now()
+        while online - original_online == set([]):
+            time.sleep(1)
+            if datetime.datetime.now() - now > datetime.timedelta(seconds=60):
+                raise Exception('timed out waiting for emulator to start')
+            online, offline = self._get_adb_devices()
+        self.port = int(list(online - original_online)[0])
+        self._emulator_launched = True
+
+        if self.logcat_dir:
+            self.save_logcat()
+
+        # setup DNS fix for networking
+        self._run_adb(['-s', 'emulator-%d' % self.port,
+                       'shell', 'setprop', 'net.dns1', '10.0.2.3'])
+
+    def _save_logcat_proc(self, filename, cmd):
+        self.logcat_proc = LogcatProc(filename, cmd)
+        self.logcat_proc.run()
+        self.logcat_proc.waitForFinish()
+        self.logcat_proc = None
+
+    def rotate_log(self, srclog, index=1):
+        """ Rotate a logfile, by recursively rotating logs further in the sequence,
+            deleting the last file if necessary.
+        """
+        destlog = os.path.join(self.logcat_dir, 'emulator-%d.%d.log' % (self.port, index))
+        if os.path.exists(destlog):
+            if index == 3:
+                os.remove(destlog)
+            else:
+                self.rotate_log(destlog, index + 1)
+        shutil.move(srclog, destlog)
+
+    def save_logcat(self):
+        """ Save the output of logcat to a file.
+        """
+        filename = os.path.join(self.logcat_dir, "emulator-%d.log" % self.port)
+        if os.path.exists(filename):
+            self.rotate_log(filename)
+        cmd = [self.adb, '-s', 'emulator-%d' % self.port, 'logcat']
+
+        # We do this in a separate process because we call mozprocess's
+        # waitForFinish method to process logcat's output, and this method
+        # blocks.
+        proc = multiprocessing.Process(target=self._save_logcat_proc, args=(filename, cmd))
+        proc.daemon = True
+        proc.start()
+
+    def setup_port_forwarding(self, remote_port):
+        """ Set up TCP port forwarding to the specified port on the device,
+            using any availble local port, and return the local port.
+        """
+
+        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        s.bind(("", 0))
+        local_port = s.getsockname()[1]
+        s.close()
+
+        output = self._run_adb(['-s', 'emulator-%d' % self.port,
+                                'forward',
+                                'tcp:%d' % local_port,
+                                'tcp:%d' % remote_port])
+
+        self.local_port = local_port
+
+        return local_port
+
+    def wait_for_port(self, timeout=300):
+        assert(self.local_port)
+        starttime = datetime.datetime.now()
+        while datetime.datetime.now() - starttime < datetime.timedelta(seconds=timeout):
+            try:
+                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+                sock.connect(('localhost', self.local_port))
+                data = sock.recv(16)
+                sock.close()
+                if '"from"' in data:
+                    return True
+            except:
+                import traceback
+                print traceback.format_exc()
+            time.sleep(1)
+        return False
new file mode 100644
--- /dev/null
+++ b/build/mobile/emulator_battery.py
@@ -0,0 +1,52 @@
+# 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/.
+
+class EmulatorBattery(object):
+
+    def __init__(self, emulator):
+        self.emulator = emulator
+
+    def get_state(self):
+        status = {}
+        state = {}
+
+        response = self.emulator._run_telnet('power display')
+        for line in response:
+            if ':' in line:
+                field, value = line.split(':')
+                value = value.strip()
+                if value == 'true':
+                    value = True
+                elif value == 'false':
+                    value = False
+                elif field == 'capacity':
+                    value = float(value)
+                status[field] = value
+
+        state['level'] = status.get('capacity', 0.0) / 100
+        if status.get('AC') == 'online':
+            state['charging'] = True
+        else:
+            state['charging'] = False
+
+        return state
+
+    def get_charging(self):
+        return self.get_state()['charging']
+
+    def get_level(self):
+        return self.get_state()['level']
+
+    def set_level(self, level):
+        self.emulator._run_telnet('power capacity %d' % (level * 100))
+
+    def set_charging(self, charging):
+        if charging:
+            cmd = 'power ac on'
+        else:
+            cmd = 'power ac off'
+        self.emulator._run_telnet(cmd)
+
+    charging = property(get_charging, set_charging)
+    level = property(get_level, set_level)
--- a/build/mobile/robocop/FennecTalosAssert.java.in
+++ b/build/mobile/robocop/FennecTalosAssert.java.in
@@ -28,24 +28,44 @@ public class FennecTalosAssert implement
     public void setLogFile(String filename) {
         FennecNativeDriver.setLogFile(filename);
     }
 
     public void setTestName(String testName) { }
 
     public void finalize() { }
 
-    public void ok(boolean condition, String name, String diag) { }
+    public void ok(boolean condition, String name, String diag) {
+        if (!condition) {
+            dumpLog("__FAIL" + name + ": " + diag + "__FAIL");
+        }
+    }
 
-    public void is(Object a, Object b, String name) { }
+    public void is(Object a, Object b, String name) {
+        boolean pass = (a == null ? b == null : a.equals(b));
+        ok(pass, name, "got " + a + ", expected " + b);
+    }
     
-    public void isnot(Object a, Object b, String name) { }
-
-    public void ispixel(int actual, int r, int g, int b, String name) { }
+    public void isnot(Object a, Object b, String name) {
+        boolean fail = (a == null ? b == null : a.equals(b));
+        ok(!fail, name, "got " + a + ", expected not " + b);
+    }
 
-    public void todo(boolean condition, String name, String diag) { }
+    public void ispixel(int actual, int r, int g, int b, String name) {
+        throw new UnsupportedOperationException();
+    }
 
-    public void todo_is(Object a, Object b, String name) { }
+    public void todo(boolean condition, String name, String diag) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void todo_is(Object a, Object b, String name) {
+        throw new UnsupportedOperationException();
+    }
     
-    public void todo_isnot(Object a, Object b, String name) { }
+    public void todo_isnot(Object a, Object b, String name) {
+        throw new UnsupportedOperationException();
+    }
 
-    public void info(String name, String message) { }
+    public void info(String name, String message) {
+        dumpLog(name + ": " + message);
+    }
 }
--- a/caps/idl/nsIPrincipal.idl
+++ b/caps/idl/nsIPrincipal.idl
@@ -16,17 +16,17 @@ struct JSPrincipals;
 
 interface nsIURI;
 interface nsIContentSecurityPolicy;
 
 [ptr] native JSContext(JSContext);
 [ptr] native JSPrincipals(JSPrincipals);
 [ptr] native PrincipalArray(nsTArray<nsCOMPtr<nsIPrincipal> >);
 
-[scriptable, uuid(42ba6a38-d619-49ab-8248-3d247e959d5e)]
+[scriptable, uuid(fbb93cc7-9a94-4743-8e89-9e6939cac083)]
 interface nsIPrincipal : nsISerializable
 {
     /**
      * Values of capabilities for each principal. Order is
      * significant: if an operation is performed on a set
      * of capabilities, the minimum is computed.
      */
     const short ENABLE_DENIED                = 1;
@@ -207,16 +207,49 @@ interface nsIPrincipal : nsISerializable
      * one, this will return null.  Getting this attribute never throws.
      */
     readonly attribute nsISupports certificate;
 
     /**
      * A Content Security Policy associated with this principal.
      */
     [noscript] attribute nsIContentSecurityPolicy csp;
+
+    /**
+     * Returns the extended origin of the principal.
+     * The extended origin is a string that has more information than the origin
+     * and can be used to isolate data or permissions between different
+     * principals while taking into account parameters like the app id or the
+     * fact that the principal is embedded in a mozbrowser.
+     * Some principals will return the origin for extendedOrigin.
+     * Some principals will assert if you try to access the extendedOrigin.
+     *
+     * The extendedOrigin is intended to be an opaque identifier. It is
+     * currently "human-readable" but no callers should assume it will stay
+     * as is and it might be crypto-hashed at some point.
+     */
+    readonly attribute AUTF8String extendedOrigin;
+
+    const short APP_STATUS_NOT_INSTALLED = 0;
+    const short APP_STATUS_INSTALLED     = 1;
+    const short APP_STATUS_TRUSTED       = 2;
+    const short APP_STATUS_CERTIFIED     = 3;
+
+    /**
+     * Shows the status of the app.
+     * Can be: APP_STATUS_NOT_INSTALLED, APP_STATUS_INSTALLED,
+     *         APP_STATUS_TRUSTED or APP_STATUS_CERTIFIED.
+     */
+    readonly attribute unsigned short appStatus;
+
+    /**
+     * Returns the app id the principal is in.
+     * Returns nsIAppsService::NO_APP_ID if this principal isn't part of an app.
+     */
+    readonly attribute unsigned long appId;
 };
 
 /**
  * If nsSystemPrincipal is too risky to use, but we want a principal to access 
  * more than one origin, nsExpandedPrincipals letting us define an array of 
  * principals it subsumes. So script with an nsExpandedPrincipals will gain
  * same origin access when at least one of its principals it contains gained 
  * sameorigin acccess. An nsExpandedPrincipal will be subsumed by the system
@@ -229,9 +262,9 @@ interface nsIPrincipal : nsISerializable
 interface nsIExpandedPrincipal : nsISupports
 {
   /**
    * An array of principals that the expanded principal subsumes.
    * Note: this list is not reference counted, it is shared, so 
    * should not be changed and should only be used ephemerally.
    */
   [notxpcom] readonly attribute PrincipalArray whiteList;
-};
\ No newline at end of file
+};
--- a/caps/idl/nsIScriptSecurityManager.idl
+++ b/caps/idl/nsIScriptSecurityManager.idl
@@ -3,18 +3,19 @@
  * 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"
 #include "nsIPrincipal.idl"
 #include "nsIXPCSecurityManager.idl"
 interface nsIURI;
 interface nsIChannel;
+interface nsIDocShell;
 
-[scriptable, uuid(cdb27711-492b-4973-938b-de81ac124658)]
+[scriptable, uuid(75a7afe3-d7c9-46fe-b305-ae686457bc7f)]
 interface nsIScriptSecurityManager : nsIXPCSecurityManager
 {
     ///////////////// Security Checks //////////////////
     /**
      * Checks whether the running script is allowed to access aProperty.
      */
     [noscript] void checkPropertyAccess(in JSContextPtr aJSContext,
                                         in JSObjectPtr aJSObject,
@@ -80,53 +81,29 @@ interface nsIScriptSecurityManager : nsI
      * @param uri the URI that is being loaded
      * @param flags the permission set, see above
      */
     void checkLoadURIWithPrincipal(in nsIPrincipal aPrincipal,
                                    in nsIURI uri,
                                    in unsigned long flags);
 
     /**
-     * Check that content from "from" can load "uri".
-     *
-     * Will return error code NS_ERROR_DOM_BAD_URI if the load request
-     * should be denied.
-     *
-     * @param from the URI causing the load
-     * @param uri the URI that is being loaded
-     * @param flags the permission set, see above
-     *
-     * @deprecated Use checkLoadURIWithPrincipal instead of this function.
-     */
-    [deprecated] void checkLoadURI(in nsIURI from, in nsIURI uri,
-                                   in unsigned long flags);
-
-    /**
      * Similar to checkLoadURIWithPrincipal but there are two differences:
      *
      * 1) The URI is a string, not a URI object.
      * 2) This function assumes that the URI may still be subject to fixup (and
      * hence will check whether fixed-up versions of the URI are allowed to
      * load as well); if any of the versions of this URI is not allowed, this
      * function will return error code NS_ERROR_DOM_BAD_URI.
      */
     void checkLoadURIStrWithPrincipal(in nsIPrincipal aPrincipal,
                                       in AUTF8String uri,
                                       in unsigned long flags);
 
     /**
-     * Same as CheckLoadURI but takes string arguments for ease of use
-     * by scripts
-     *
-     * @deprecated Use checkLoadURIStrWithPrincipal instead of this function.
-     */
-    [deprecated] void checkLoadURIStr(in AUTF8String from, in AUTF8String uri,
-                                      in unsigned long flags);
-
-    /**
      * Check that the function 'funObj' is allowed to run on 'targetObj'
      *
      * Will return error code NS_ERROR_DOM_SECURITY_ERR if the function
      * should not run
      *
      * @param cx The current active JavaScript context.
      * @param funObj The function trying to run..
      * @param targetObj The object the function will run on.
@@ -166,19 +143,46 @@ interface nsIScriptSecurityManager : nsI
          getCertificatePrincipal(in AUTF8String aCertFingerprint,
                                  in AUTF8String aSubjectName,
                                  in AUTF8String aPrettyName,
                                  in nsISupports aCert,
                                  in nsIURI aURI);
 
     /**
      * Return a principal that has the same origin as aURI.
+     * This principals should not be used for any data/permission check, it will
+     * have appId = UNKNOWN_APP_ID.
      */
     nsIPrincipal getCodebasePrincipal(in nsIURI aURI);
 
+    /**
+     * Returns a principal that has the given information.
+     * @param appId is the app id of the principal. It can't be UNKNOWN_APP_ID.
+     * @param inMozBrowser is true if the principal has to be considered as
+     * inside a mozbrowser frame.
+     */
+    nsIPrincipal getAppCodebasePrincipal(in nsIURI uri,
+                                         in unsigned long appId,
+                                         in boolean inMozBrowser);
+
+    /**
+     * Returns a principal that has the appId and inMozBrowser of the docshell
+     * inside a mozbrowser frame.
+     * @param docShell to get appId/inMozBrowser from.
+     */
+    nsIPrincipal getDocShellCodebasePrincipal(in nsIURI uri,
+                                              in nsIDocShell docShell);
+
+    /**
+     * Returns a principal with that has the same origin as uri and is not part
+     * of an appliction.
+     * The returned principal will have appId = NO_APP_ID.
+     */
+    nsIPrincipal getNoAppCodebasePrincipal(in nsIURI uri);
+
     ///////////////// Capabilities API /////////////////////
     /**
      * Request that 'capability' can be enabled by scripts or applets
      * running with 'principal'. Will prompt user if
      * necessary. Returns nsIPrincipal::ENABLE_GRANTED or
      * nsIPrincipal::ENABLE_DENIED based on user's choice.
      */
     [noscript] short requestCapability(in nsIPrincipal principal,
@@ -255,14 +259,27 @@ interface nsIScriptSecurityManager : nsI
      * Same as getSubjectPrincipal(), only faster. cx must *never* be
      * passed null, and it must be the context on the top of the
      * context stack. Does *not* reference count the returned
      * principal.
      */
     [noscript,notxpcom] nsIPrincipal getCxSubjectPrincipal(in JSContextPtr cx);
     [noscript,notxpcom] nsIPrincipal getCxSubjectPrincipalAndFrame(in JSContextPtr cx,
                                                                    out JSStackFramePtr fp);
+
+
+    const unsigned long NO_APP_ID = 0;
+    const unsigned long UNKNOWN_APP_ID = 4294967295; // PR_UINT32_MAX
+
+    /**
+     * Returns the extended origin for the uri.
+     * appId can be NO_APP_ID or a valid app id. appId should not be
+     * UNKNOWN_APP_ID.
+     * inMozBrowser has to be true if the uri is inside a mozbrowser iframe.
+     */
+    AUTF8String getExtendedOrigin(in nsIURI uri, in unsigned long appId,
+                                  in boolean inMozBrowser);
 };
 
 %{C++
 #define NS_SCRIPTSECURITYMANAGER_CONTRACTID "@mozilla.org/scriptsecuritymanager;1"
 #define NS_SCRIPTSECURITYMANAGER_CLASSNAME "scriptsecuritymanager"
 %}
--- a/caps/include/nsPrincipal.h
+++ b/caps/include/nsPrincipal.h
@@ -107,63 +107,82 @@ protected:
 
   nsCOMPtr<nsIContentSecurityPolicy> mCSP;
   bool mTrusted;
 };
 
 class nsPrincipal : public nsBasePrincipal
 {
 public:
-  nsPrincipal();
-
-protected:
-  virtual ~nsPrincipal();
-
-public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSISERIALIZABLE
   NS_IMETHOD Equals(nsIPrincipal* other, bool* _retval NS_OUTPARAM);
   NS_IMETHOD EqualsIgnoringDomain(nsIPrincipal* other, bool* _retval NS_OUTPARAM);
   NS_IMETHOD GetHashValue(PRUint32* aHashValue);
   NS_IMETHOD GetURI(nsIURI** aURI);
   NS_IMETHOD GetDomain(nsIURI** aDomain);
   NS_IMETHOD SetDomain(nsIURI* aDomain);
   NS_IMETHOD GetOrigin(char** aOrigin);
   NS_IMETHOD Subsumes(nsIPrincipal* other, bool* _retval NS_OUTPARAM);
   NS_IMETHOD SubsumesIgnoringDomain(nsIPrincipal* other, bool* _retval NS_OUTPARAM);
   NS_IMETHOD CheckMayLoad(nsIURI* uri, bool report);
+  NS_IMETHOD GetExtendedOrigin(nsACString& aExtendedOrigin);
+  NS_IMETHOD GetAppStatus(PRUint16* aAppStatus);
+  NS_IMETHOD GetAppId(PRUint32* aAppStatus);
 #ifdef DEBUG
   virtual void dumpImpl();
 #endif
+
+  nsPrincipal();
+
   // Either Init() or InitFromPersistent() must be called before
   // the principal is in a usable state.
   nsresult Init(const nsACString& aCertFingerprint,
                 const nsACString& aSubjectName,
                 const nsACString& aPrettyName,
                 nsISupports* aCert,
-                nsIURI* aCodebase);
+                nsIURI* aCodebase,
+                PRUint32 aAppId,
+                bool aInMozBrowser);
   nsresult InitFromPersistent(const char* aPrefName,
                               const nsCString& aFingerprint,
                               const nsCString& aSubjectName,
                               const nsACString& aPrettyName,
                               const char* aGrantedList,
                               const char* aDeniedList,
                               nsISupports* aCert,
                               bool aIsCert,
-                              bool aTrusted);
+                              bool aTrusted,
+                              PRUint32 aAppId,
+                              bool aInMozBrowser);
 
   virtual void GetScriptLocation(nsACString& aStr) MOZ_OVERRIDE;
   void SetURI(nsIURI* aURI);
 
+  /**
+   * Computes the puny-encoded origin of aURI.
+   */
+  static nsresult GetOriginForURI(nsIURI* aURI, char **aOrigin);
+
   nsCOMPtr<nsIURI> mDomain;
   nsCOMPtr<nsIURI> mCodebase;
+  PRUint32 mAppId;
+  bool mInMozBrowser;
   // If mCodebaseImmutable is true, mCodebase is non-null and immutable
   bool mCodebaseImmutable;
   bool mDomainImmutable;
   bool mInitialized;
+
+protected:
+  virtual ~nsPrincipal();
+
+  /**
+   * Returns the app status of the principal based on mAppId and mInMozBrowser.
+   */
+  PRUint16 GetAppStatus();
 };
 
 class nsExpandedPrincipal : public nsIExpandedPrincipal, public nsBasePrincipal
 {
 public:
   nsExpandedPrincipal(nsTArray< nsCOMPtr<nsIPrincipal> > &aWhiteList);
 
 protected:
@@ -178,16 +197,19 @@ public:
   NS_IMETHOD GetHashValue(PRUint32* aHashValue);
   NS_IMETHOD GetURI(nsIURI** aURI);
   NS_IMETHOD GetDomain(nsIURI** aDomain);
   NS_IMETHOD SetDomain(nsIURI* aDomain);
   NS_IMETHOD GetOrigin(char** aOrigin);
   NS_IMETHOD Subsumes(nsIPrincipal* other, bool* _retval NS_OUTPARAM);
   NS_IMETHOD SubsumesIgnoringDomain(nsIPrincipal* other, bool* _retval NS_OUTPARAM);
   NS_IMETHOD CheckMayLoad(nsIURI* uri, bool report);
+  NS_IMETHOD GetExtendedOrigin(nsACString& aExtendedOrigin);
+  NS_IMETHOD GetAppStatus(PRUint16* aAppStatus);
+  NS_IMETHOD GetAppId(PRUint32* aAppStatus);
 #ifdef DEBUG
   virtual void dumpImpl();
 #endif
   
   virtual void GetScriptLocation(nsACString &aStr) MOZ_OVERRIDE;
 
 private:
   nsTArray< nsCOMPtr<nsIPrincipal> > mPrincipals;
--- a/caps/include/nsScriptSecurityManager.h
+++ b/caps/include/nsScriptSecurityManager.h
@@ -431,17 +431,22 @@ private:
     nsresult
     LookupPolicy(nsIPrincipal* principal,
                  ClassInfoData& aClassData, jsid aProperty,
                  PRUint32 aAction,
                  ClassPolicy** aCachedClassPolicy,
                  SecurityLevel* result);
 
     nsresult
-    CreateCodebasePrincipal(nsIURI* aURI, nsIPrincipal** result);
+    GetCodebasePrincipalInternal(nsIURI* aURI, PRUint32 aAppId, bool aInMozBrowser,
+                         nsIPrincipal** result);
+
+    nsresult
+    CreateCodebasePrincipal(nsIURI* aURI, PRUint32 aAppId, bool aInMozBrowser,
+                            nsIPrincipal** result);
 
     // This is just like the API method, but it doesn't check that the subject
     // name is non-empty or aCertificate is non-null, and it doesn't change the
     // certificate in the table (if any) in any way if aModifyTable is false.
     nsresult
     DoGetCertificatePrincipal(const nsACString& aCertFingerprint,
                               const nsACString& aSubjectName,
                               const nsACString& aPrettyName,
@@ -591,9 +596,18 @@ public:
     nsSecurityNameSet();
     virtual ~nsSecurityNameSet();
     
     NS_DECL_ISUPPORTS
 
     NS_IMETHOD InitializeNameSet(nsIScriptContext* aScriptContext);
 };
 
+namespace mozilla {
+
+void
+GetExtendedOrigin(nsIURI* aURI, PRUint32 aAppid,
+                  bool aInMozBrowser,
+                  nsACString& aExtendedOrigin);
+
+} // namespace mozilla
+
 #endif // nsScriptSecurityManager_h__
--- a/caps/src/nsNullPrincipal.cpp
+++ b/caps/src/nsNullPrincipal.cpp
@@ -15,16 +15,17 @@
 #include "nsNullPrincipalURI.h"
 #include "nsMemory.h"
 #include "nsIUUIDGenerator.h"
 #include "nsID.h"
 #include "nsNetUtil.h"
 #include "nsIClassInfoImpl.h"
 #include "nsNetCID.h"
 #include "nsDOMError.h"
+#include "nsIScriptSecurityManager.h"
 #include "nsScriptSecurityManager.h"
 
 using namespace mozilla;
 
 NS_IMPL_CLASSINFO(nsNullPrincipal, NULL, nsIClassInfo::MAIN_THREAD_ONLY,
                   NS_NULLPRINCIPAL_CID)
 NS_IMPL_QUERY_INTERFACE2_CI(nsNullPrincipal,
                             nsIPrincipal,
@@ -309,16 +310,36 @@ nsNullPrincipal::GetSubjectName(nsACStri
 
 NS_IMETHODIMP
 nsNullPrincipal::GetCertificate(nsISupports** aCertificate)
 {
     *aCertificate = nsnull;
     return NS_OK;
 }
 
+NS_IMETHODIMP
+nsNullPrincipal::GetExtendedOrigin(nsACString& aExtendedOrigin)
+{
+  return GetOrigin(getter_Copies(aExtendedOrigin));
+}
+
+NS_IMETHODIMP
+nsNullPrincipal::GetAppStatus(PRUint16* aAppStatus)
+{
+  *aAppStatus = nsIPrincipal::APP_STATUS_NOT_INSTALLED;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsNullPrincipal::GetAppId(PRUint32* aAppId)
+{
+  *aAppId = nsIScriptSecurityManager::NO_APP_ID;
+  return NS_OK;
+}
+
 /**
  * nsISerializable implementation
  */
 NS_IMETHODIMP
 nsNullPrincipal::Read(nsIObjectInputStream* aStream)
 {
   // no-op: CID is sufficient to create a useful nsNullPrincipal, since the URI
   // is not really relevant.
--- a/caps/src/nsPrincipal.cpp
+++ b/caps/src/nsPrincipal.cpp
@@ -596,133 +596,148 @@ FreeAnnotationEntry(nsIObjectInputStream
   delete aKey;
 }
 
 #ifdef DEBUG
 void nsPrincipal::dumpImpl()
 {
   nsCAutoString str;
   GetScriptLocation(str);
-  fprintf(stderr, "nsPrincipal (%p) = %s\n", this, str.get());
+  fprintf(stderr, "nsPrincipal (%p) = %s\n", static_cast<void*>(this), str.get());
 }
 #endif 
 
 NS_IMPL_CLASSINFO(nsPrincipal, NULL, nsIClassInfo::MAIN_THREAD_ONLY,
                   NS_PRINCIPAL_CID)
 NS_IMPL_QUERY_INTERFACE2_CI(nsPrincipal,
                             nsIPrincipal,
                             nsISerializable)
 NS_IMPL_CI_INTERFACE_GETTER2(nsPrincipal,
                              nsIPrincipal,
                              nsISerializable)
 NS_IMPL_ADDREF_INHERITED(nsPrincipal, nsBasePrincipal)
 NS_IMPL_RELEASE_INHERITED(nsPrincipal, nsBasePrincipal)
 
 nsPrincipal::nsPrincipal()
-  : mCodebaseImmutable(false)
+  : mAppId(nsIScriptSecurityManager::UNKNOWN_APP_ID)
+  , mInMozBrowser(false)
+  , mCodebaseImmutable(false)
   , mDomainImmutable(false)
   , mInitialized(false)
 { }
 
 nsPrincipal::~nsPrincipal()
 { }
 
 nsresult
 nsPrincipal::Init(const nsACString& aCertFingerprint,
                   const nsACString& aSubjectName,
                   const nsACString& aPrettyName,
                   nsISupports* aCert,
-                  nsIURI *aCodebase)
+                  nsIURI *aCodebase,
+                  PRUint32 aAppId,
+                  bool aInMozBrowser)
 {
   NS_ENSURE_STATE(!mInitialized);
   NS_ENSURE_ARG(!aCertFingerprint.IsEmpty() || aCodebase); // better have one of these.
 
   mInitialized = true;
 
   mCodebase = NS_TryToMakeImmutable(aCodebase);
   mCodebaseImmutable = URIIsImmutable(mCodebase);
 
+  mAppId = aAppId;
+  mInMozBrowser = aInMozBrowser;
+
   if (aCertFingerprint.IsEmpty())
     return NS_OK;
 
   return SetCertificate(aCertFingerprint, aSubjectName, aPrettyName, aCert);
 }
 
 void
 nsPrincipal::GetScriptLocation(nsACString &aStr)
 {
   if (mCert) {
     aStr.Assign(mCert->fingerprint);
   } else {
     mCodebase->GetSpec(aStr);
   }
 }
 
-NS_IMETHODIMP
-nsPrincipal::GetOrigin(char **aOrigin)
+/* static */ nsresult
+nsPrincipal::GetOriginForURI(nsIURI* aURI, char **aOrigin)
 {
+  if (!aURI) {
+    return NS_ERROR_FAILURE;
+  }
+
   *aOrigin = nsnull;
 
-  nsCOMPtr<nsIURI> origin;
-  if (mCodebase) {
-    origin = NS_GetInnermostURI(mCodebase);
-  }
-  
+  nsCOMPtr<nsIURI> origin = NS_GetInnermostURI(aURI);
   if (!origin) {
-    NS_ASSERTION(mCert, "No Domain or Codebase for a non-cert principal");
     return NS_ERROR_FAILURE;
   }
 
   nsCAutoString hostPort;
 
   // chrome: URLs don't have a meaningful origin, so make
   // sure we just get the full spec for them.
   // XXX this should be removed in favor of the solution in
   // bug 160042.
   bool isChrome;
   nsresult rv = origin->SchemeIs("chrome", &isChrome);
   if (NS_SUCCEEDED(rv) && !isChrome) {
     rv = origin->GetAsciiHost(hostPort);
     // Some implementations return an empty string, treat it as no support
     // for asciiHost by that implementation.
-    if (hostPort.IsEmpty())
+    if (hostPort.IsEmpty()) {
       rv = NS_ERROR_FAILURE;
+    }
   }
 
   PRInt32 port;
   if (NS_SUCCEEDED(rv) && !isChrome) {
     rv = origin->GetPort(&port);
   }
 
   if (NS_SUCCEEDED(rv) && !isChrome) {
     if (port != -1) {
       hostPort.AppendLiteral(":");
       hostPort.AppendInt(port, 10);
     }
 
     nsCAutoString scheme;
     rv = origin->GetScheme(scheme);
     NS_ENSURE_SUCCESS(rv, rv);
+
     *aOrigin = ToNewCString(scheme + NS_LITERAL_CSTRING("://") + hostPort);
   }
   else {
     // Some URIs (e.g., nsSimpleURI) don't support asciiHost. Just
     // get the full spec.
     nsCAutoString spec;
     // XXX nsMozIconURI and nsJARURI don't implement this correctly, they
     // both fall back to GetSpec.  That needs to be fixed.
     rv = origin->GetAsciiSpec(spec);
     NS_ENSURE_SUCCESS(rv, rv);
+
     *aOrigin = ToNewCString(spec);
   }
 
   return *aOrigin ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
 }
 
 NS_IMETHODIMP
+nsPrincipal::GetOrigin(char **aOrigin)
+{
+  return GetOriginForURI(mCodebase, aOrigin);
+}
+
+NS_IMETHODIMP
 nsPrincipal::Equals(nsIPrincipal *aOther, bool *aResult)
 {
   if (!aOther) {
     NS_WARNING("Need a principal to compare this to!");
     *aResult = false;
     return NS_OK;
   }
 
@@ -917,18 +932,16 @@ nsPrincipal::CheckMayLoad(nsIURI* aURI, 
 
 void
 nsPrincipal::SetURI(nsIURI* aURI)
 {
   mCodebase = NS_TryToMakeImmutable(aURI);
   mCodebaseImmutable = URIIsImmutable(mCodebase);
 }
 
-
-
 NS_IMETHODIMP
 nsPrincipal::GetHashValue(PRUint32* aValue)
 {
   NS_PRECONDITION(mCert || mCodebase, "Need a cert or codebase");
 
   // If there is a certificate, it takes precendence over the codebase.
   if (mCert) {
     *aValue = HashString(mCert->fingerprint);
@@ -984,26 +997,31 @@ nsresult
 nsPrincipal::InitFromPersistent(const char* aPrefName,
                                 const nsCString& aToken,
                                 const nsCString& aSubjectName,
                                 const nsACString& aPrettyName,
                                 const char* aGrantedList,
                                 const char* aDeniedList,
                                 nsISupports* aCert,
                                 bool aIsCert,
-                                bool aTrusted)
+                                bool aTrusted,
+                                PRUint32 aAppId,
+                                bool aInMozBrowser)
 {
   NS_PRECONDITION(!mCapabilities || mCapabilities->Count() == 0,
                   "mCapabilities was already initialized?");
   NS_PRECONDITION(mAnnotations.Length() == 0,
                   "mAnnotations was already initialized?");
   NS_PRECONDITION(!mInitialized, "We were already initialized?");
 
   mInitialized = true;
 
+  mAppId = aAppId;
+  mInMozBrowser = aInMozBrowser;
+
   nsresult rv;
   if (aIsCert) {
     rv = SetCertificate(aToken, aSubjectName, aPrettyName, aCert);
     
     if (NS_FAILED(rv)) {
       return rv;
     }
   }
@@ -1040,16 +1058,47 @@ nsPrincipal::InitFromPersistent(const ch
   if (NS_SUCCEEDED(rv) && aDeniedList) {
     rv = SetCanEnableCapability(aDeniedList, nsIPrincipal::ENABLE_DENIED);
   }
 
   return rv;
 }
 
 NS_IMETHODIMP
+nsPrincipal::GetExtendedOrigin(nsACString& aExtendedOrigin)
+{
+  MOZ_ASSERT(mAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID);
+
+  mozilla::GetExtendedOrigin(mCodebase, mAppId, mInMozBrowser, aExtendedOrigin);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPrincipal::GetAppStatus(PRUint16* aAppStatus)
+{
+  MOZ_ASSERT(mAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID);
+
+  *aAppStatus = GetAppStatus();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPrincipal::GetAppId(PRUint32* aAppId)
+{
+  if (mAppId == nsIScriptSecurityManager::UNKNOWN_APP_ID) {
+    MOZ_ASSERT(false);
+    *aAppId = nsIScriptSecurityManager::NO_APP_ID;
+    return NS_OK;
+  }
+
+  *aAppId = mAppId;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsPrincipal::Read(nsIObjectInputStream* aStream)
 {
   bool hasCapabilities;
   nsresult rv = aStream->ReadBoolean(&hasCapabilities);
   if (NS_SUCCEEDED(rv) && hasCapabilities) {
     mCapabilities = new nsHashtable(aStream, ReadAnnotationEntry,
                                     FreeAnnotationEntry, &rv);
     NS_ENSURE_TRUE(mCapabilities, NS_ERROR_OUT_OF_MEMORY);
@@ -1105,17 +1154,25 @@ nsPrincipal::Read(nsIObjectInputStream* 
   }
 
   nsCOMPtr<nsIURI> codebase;
   rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(codebase));
   if (NS_FAILED(rv)) {
     return rv;
   }
 
-  rv = Init(fingerprint, subjectName, prettyName, cert, codebase);
+  PRUint32 appId;
+  rv = aStream->Read32(&appId);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  bool inMozBrowser;
+  rv = aStream->ReadBoolean(&inMozBrowser);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = Init(fingerprint, subjectName, prettyName, cert, codebase, appId, inMozBrowser);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIURI> domain;
   rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(domain));
   if (NS_FAILED(rv)) {
     return rv;
   }
 
@@ -1201,27 +1258,42 @@ nsPrincipal::Write(nsIObjectOutputStream
   }
 
   rv = NS_WriteOptionalCompoundObject(aStream, mDomain, NS_GET_IID(nsIURI),
                                       true);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
+  aStream->Write32(mAppId);
+  aStream->WriteBoolean(mInMozBrowser);
+
   rv = aStream->Write8(mTrusted);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   // mCodebaseImmutable and mDomainImmutable will be recomputed based
   // on the deserialized URIs in Read().
 
   return NS_OK;
 }
 
+PRUint16
+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;
+}
 
 /************************************************************************************************************************/
 
 static const char EXPANDED_PRINCIPAL_SPEC[] = "[Expanded Principal]";
 
 NS_IMPL_CLASSINFO(nsExpandedPrincipal, NULL, nsIClassInfo::MAIN_THREAD_ONLY,
                   NS_EXPANDEDPRINCIPAL_CID)
 NS_IMPL_QUERY_INTERFACE2_CI(nsExpandedPrincipal,
@@ -1381,31 +1453,49 @@ nsExpandedPrincipal::GetURI(nsIURI** aUR
 
 NS_IMETHODIMP 
 nsExpandedPrincipal::GetWhiteList(nsTArray<nsCOMPtr<nsIPrincipal> >** aWhiteList)
 {
   *aWhiteList = &mPrincipals;
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsExpandedPrincipal::GetExtendedOrigin(nsACString& aExtendedOrigin)
+{
+  return NS_ERROR_NOT_AVAILABLE;
+}
+
+NS_IMETHODIMP
+nsExpandedPrincipal::GetAppStatus(PRUint16* aAppStatus)
+{
+  return NS_ERROR_NOT_AVAILABLE;
+}
+
+NS_IMETHODIMP
+nsExpandedPrincipal::GetAppId(PRUint32* aAppId)
+{
+  return NS_ERROR_NOT_AVAILABLE;
+}
+
 void
 nsExpandedPrincipal::GetScriptLocation(nsACString& aStr)
 {
   if (mCert) {
     aStr.Assign(mCert->fingerprint);
   } else {
     // Is that a good idea to list it's principals?
     aStr.Assign(EXPANDED_PRINCIPAL_SPEC);
   }
 }
 
 #ifdef DEBUG
 void nsExpandedPrincipal::dumpImpl()
 {
-  fprintf(stderr, "nsExpandedPrincipal (%p)\n", this);
+  fprintf(stderr, "nsExpandedPrincipal (%p)\n", static_cast<void*>(this));
 }
 #endif 
 
 //////////////////////////////////////////
 // Methods implementing nsISerializable //
 //////////////////////////////////////////
 
 NS_IMETHODIMP
--- a/caps/src/nsScriptSecurityManager.cpp
+++ b/caps/src/nsScriptSecurityManager.cpp
@@ -323,17 +323,29 @@ nsScriptSecurityManager::GetChannelPrinc
     }
 
     // OK, get the principal from the URI.  Make sure this does the same thing
     // as nsDocument::Reset and nsXULDocument::StartDocumentLoad.
     nsCOMPtr<nsIURI> uri;
     nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
     NS_ENSURE_SUCCESS(rv, rv);
 
-    return GetCodebasePrincipal(uri, aPrincipal);
+    PRUint32 appId = UNKNOWN_APP_ID;
+    bool isInBrowserElement = false;
+
+    nsCOMPtr<nsIDocShell> docShell;
+    NS_QueryNotificationCallbacks(aChannel, docShell);
+
+    if (docShell) {
+        docShell->GetAppId(&appId);
+        docShell->GetIsInBrowserElement(&isInBrowserElement);
+    }
+
+    return GetCodebasePrincipalInternal(uri, appId, isInBrowserElement,
+                                        aPrincipal);
 }
 
 NS_IMETHODIMP
 nsScriptSecurityManager::IsSystemPrincipal(nsIPrincipal* aPrincipal,
                                            bool* aIsSystem)
 {
     *aIsSystem = (aPrincipal == mSystemPrincipal);
     return NS_OK;
@@ -1257,35 +1269,16 @@ nsScriptSecurityManager::CheckLoadURIFro
         return NS_ERROR_FAILURE;
     nsCAutoString msg("Access to '");
     msg.Append(spec);
     msg.AppendLiteral("' from script denied");
     SetPendingException(cx, msg.get());
     return NS_ERROR_DOM_BAD_URI;
 }
 
-NS_IMETHODIMP
-nsScriptSecurityManager::CheckLoadURI(nsIURI *aSourceURI, nsIURI *aTargetURI,
-                                      PRUint32 aFlags)
-{
-    // FIXME: bug 327244 -- this function should really die...  Really truly.
-    NS_PRECONDITION(aSourceURI, "CheckLoadURI called with null source URI");
-    NS_ENSURE_ARG_POINTER(aSourceURI);
-
-    // Note: this is not _quite_ right if aSourceURI has
-    // NS_NULLPRINCIPAL_SCHEME, but we'll just extract the scheme in
-    // CheckLoadURIWithPrincipal anyway, so this is good enough.  This method
-    // really needs to go away....
-    nsCOMPtr<nsIPrincipal> sourcePrincipal;
-    nsresult rv = CreateCodebasePrincipal(aSourceURI,
-                                          getter_AddRefs(sourcePrincipal));
-    NS_ENSURE_SUCCESS(rv, rv);
-    return CheckLoadURIWithPrincipal(sourcePrincipal, aTargetURI, aFlags);
-}
-
 /**
  * Helper method to handle cases where a flag passed to
  * CheckLoadURIWithPrincipal means denying loading if the given URI has certain
  * nsIProtocolHandler flags set.
  * @return if success, access is allowed. Otherwise, deny access
  */
 static nsresult
 DenyAccessIfURIHasFlags(nsIURI* aURI, PRUint32 aURIFlags)
@@ -1583,40 +1576,16 @@ nsScriptSecurityManager::ReportError(JSC
 #ifdef DEBUG
         fprintf(stderr, "%s\n", NS_LossyConvertUTF16toASCII(message).get());
 #endif
     }
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsScriptSecurityManager::CheckLoadURIStr(const nsACString& aSourceURIStr,
-                                         const nsACString& aTargetURIStr,
-                                         PRUint32 aFlags)
-{
-    // FIXME: bug 327244 -- this function should really die...  Really truly.
-    nsCOMPtr<nsIURI> source;
-    nsresult rv = NS_NewURI(getter_AddRefs(source), aSourceURIStr,
-                            nsnull, nsnull, sIOService);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    // Note: this is not _quite_ right if aSourceURI has
-    // NS_NULLPRINCIPAL_SCHEME, but we'll just extract the scheme in
-    // CheckLoadURIWithPrincipal anyway, so this is good enough.  This method
-    // really needs to go away....
-    nsCOMPtr<nsIPrincipal> sourcePrincipal;
-    rv = CreateCodebasePrincipal(source,
-                                 getter_AddRefs(sourcePrincipal));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    return CheckLoadURIStrWithPrincipal(sourcePrincipal, aTargetURIStr,
-                                        aFlags);
-}
-
-NS_IMETHODIMP
 nsScriptSecurityManager::CheckLoadURIStrWithPrincipal(nsIPrincipal* aPrincipal,
                                                       const nsACString& aTargetURIStr,
                                                       PRUint32 aFlags)
 {
     nsresult rv;
     nsCOMPtr<nsIURI> target;
     rv = NS_NewURI(getter_AddRefs(target), aTargetURIStr,
                    nsnull, nsnull, sIOService);
@@ -1901,17 +1870,18 @@ nsScriptSecurityManager::DoGetCertificat
     // Create a certificate principal out of the certificate ID
     // and URI given to us.  We will use this principal to test
     // equality when doing our hashtable lookups below.
     nsRefPtr<nsPrincipal> certificate = new nsPrincipal();
     if (!certificate)
         return NS_ERROR_OUT_OF_MEMORY;
 
     nsresult rv = certificate->Init(aCertFingerprint, aSubjectName,
-                                    aPrettyName, aCertificate, aURI);
+                                    aPrettyName, aCertificate, aURI,
+                                    UNKNOWN_APP_ID, false);
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Check to see if we already have this principal.
     nsCOMPtr<nsIPrincipal> fromTable;
     mPrincipals.Get(certificate, getter_AddRefs(fromTable));
     if (fromTable) {
         // Bingo.  We found the certificate in the table, which means
         // that it has escalated privileges.
@@ -1962,32 +1932,35 @@ nsScriptSecurityManager::DoGetCertificat
                 certificate = new nsPrincipal();
                 if (!certificate)
                     return NS_ERROR_OUT_OF_MEMORY;
 
                 rv = certificate->InitFromPersistent(prefName, id,
                                                      subjectName, aPrettyName,
                                                      granted, denied,
                                                      aCertificate,
-                                                     true, false);
+                                                     true, false,
+                                                     UNKNOWN_APP_ID, false);
                 if (NS_FAILED(rv))
                     return rv;
                 
                 certificate->SetURI(aURI);
             }
         }
     }
 
     NS_ADDREF(*result = certificate);
 
     return rv;
 }
 
 nsresult
-nsScriptSecurityManager::CreateCodebasePrincipal(nsIURI* aURI, nsIPrincipal **result)
+nsScriptSecurityManager::CreateCodebasePrincipal(nsIURI* aURI, PRUint32 aAppId,
+                                                 bool aInMozBrowser,
+                                                 nsIPrincipal **result)
 {
     // I _think_ it's safe to not create null principals here based on aURI.
     // At least all the callers would do the right thing in those cases, as far
     // as I can tell.  --bz
 
     nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(aURI);
     if (uriPrinc) {
         nsCOMPtr<nsIPrincipal> principal;
@@ -2001,43 +1974,91 @@ nsScriptSecurityManager::CreateCodebaseP
         return NS_OK;
     }
 
     nsRefPtr<nsPrincipal> codebase = new nsPrincipal();
     if (!codebase)
         return NS_ERROR_OUT_OF_MEMORY;
 
     nsresult rv = codebase->Init(EmptyCString(), EmptyCString(),
-                                 EmptyCString(), nsnull, aURI);
+                                 EmptyCString(), nsnull, aURI, aAppId,
+                                 aInMozBrowser);
     if (NS_FAILED(rv))
         return rv;
 
     NS_ADDREF(*result = codebase);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsScriptSecurityManager::GetCodebasePrincipal(nsIURI *aURI,
+nsScriptSecurityManager::GetCodebasePrincipal(nsIURI* aURI,
+                                                    nsIPrincipal** aPrincipal)
+{
+  return GetCodebasePrincipalInternal(aURI, nsIScriptSecurityManager::UNKNOWN_APP_ID,
+                              false, aPrincipal);
+}
+
+NS_IMETHODIMP
+nsScriptSecurityManager::GetNoAppCodebasePrincipal(nsIURI* aURI,
+                                                   nsIPrincipal** aPrincipal)
+{
+  return GetCodebasePrincipalInternal(aURI,  nsIScriptSecurityManager::NO_APP_ID,
+                              false, aPrincipal);
+}
+
+NS_IMETHODIMP
+nsScriptSecurityManager::GetAppCodebasePrincipal(nsIURI* aURI,
+                                                 PRUint32 aAppId,
+                                                 bool aInMozBrowser,
+                                                 nsIPrincipal** aPrincipal)
+{
+  NS_ENSURE_TRUE(aAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID,
+                 NS_ERROR_INVALID_ARG);
+
+  return GetCodebasePrincipalInternal(aURI, aAppId, aInMozBrowser, aPrincipal);
+}
+
+NS_IMETHODIMP
+nsScriptSecurityManager::GetDocShellCodebasePrincipal(nsIURI* aURI,
+                                                      nsIDocShell* aDocShell,
+                                                      nsIPrincipal** aPrincipal)
+{
+  MOZ_ASSERT(aDocShell);
+
+  PRUint32 appId;
+  bool isInBrowserElement;
+  aDocShell->GetAppId(&appId);
+  aDocShell->GetIsInBrowserElement(&isInBrowserElement);
+
+  return GetCodebasePrincipalInternal(aURI, appId, isInBrowserElement,
+                                      aPrincipal);
+}
+
+nsresult
+nsScriptSecurityManager::GetCodebasePrincipalInternal(nsIURI *aURI,
+                                              PRUint32 aAppId,
+                                              bool aInMozBrowser,
                                               nsIPrincipal **result)
 {
     NS_ENSURE_ARG(aURI);
-    
+
     bool inheritsPrincipal;
     nsresult rv =
         NS_URIChainHasFlags(aURI,
                             nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
                             &inheritsPrincipal);
     if (NS_FAILED(rv) || inheritsPrincipal) {
         return CallCreateInstance(NS_NULLPRINCIPAL_CONTRACTID, result);
     }
-    
+
     nsCOMPtr<nsIPrincipal> principal;
-    rv = CreateCodebasePrincipal(aURI, getter_AddRefs(principal));
-    if (NS_FAILED(rv)) return rv;
+    rv = CreateCodebasePrincipal(aURI, aAppId, aInMozBrowser,
+                                 getter_AddRefs(principal));
+    NS_ENSURE_SUCCESS(rv, rv);
 
     if (mPrincipals.Count() > 0)
     {
         //-- Check to see if we already have this principal.
         nsCOMPtr<nsIPrincipal> fromTable;
         mPrincipals.Get(principal, getter_AddRefs(fromTable));
         if (fromTable) {
             // We found an existing codebase principal.  But it might have a
@@ -2062,20 +2083,21 @@ nsScriptSecurityManager::GetCodebasePrin
                 nsRefPtr<nsPrincipal> codebase = new nsPrincipal();
                 if (!codebase)
                     return NS_ERROR_OUT_OF_MEMORY;
 
                 rv = codebase->InitFromPersistent(prefName, id,
                                                   subjectName, EmptyCString(),
                                                   granted, denied,
                                                   nsnull, false,
-                                                  isTrusted);
-                if (NS_FAILED(rv))
-                    return rv;
-                
+                                                  isTrusted,
+                                                  aAppId,
+                                                  aInMozBrowser);
+                NS_ENSURE_SUCCESS(rv, rv);
+
                 codebase->SetURI(aURI);
                 principal = codebase;
             }
 
         }
     }
 
     NS_IF_ADDREF(*result = principal);
@@ -3531,17 +3553,18 @@ nsScriptSecurityManager::InitPrincipals(
 
         nsRefPtr<nsPrincipal> newPrincipal = new nsPrincipal();
         if (!newPrincipal)
             return NS_ERROR_OUT_OF_MEMORY;
 
         rv = newPrincipal->InitFromPersistent(aPrefNames[c], id, subjectName,
                                               EmptyCString(),
                                               grantedList, deniedList, nsnull, 
-                                              isCert, isTrusted);
+                                              isCert, isTrusted, UNKNOWN_APP_ID,
+                                              false);
         if (NS_SUCCEEDED(rv))
             mPrincipals.Put(newPrincipal, newPrincipal);
     }
     return NS_OK;
 }
 
 inline void
 nsScriptSecurityManager::ScriptSecurityPrefChanged()
@@ -3589,16 +3612,61 @@ nsScriptSecurityManager::InitPrefs()
         rv = InitPrincipals(prefCount, (const char**)prefNames);
         NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(prefCount, prefNames);
         NS_ENSURE_SUCCESS(rv, rv);
     }
 
     return NS_OK;
 }
 
+namespace mozilla {
+
+void
+GetExtendedOrigin(nsIURI* aURI, PRUint32 aAppId, bool aInMozBrowser,
+                  nsACString& aExtendedOrigin)
+{
+  MOZ_ASSERT(aURI);
+  MOZ_ASSERT(aAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID);
+
+  if (aAppId == nsIScriptSecurityManager::UNKNOWN_APP_ID) {
+    aAppId = nsIScriptSecurityManager::NO_APP_ID;
+  }
+
+  nsCAutoString origin;
+  nsPrincipal::GetOriginForURI(aURI, getter_Copies(origin));
+
+  // Fallback.
+  if (aAppId == nsIScriptSecurityManager::NO_APP_ID && !aInMozBrowser) {
+    aExtendedOrigin.Assign(origin);
+    return;
+  }
+
+  // aExtendedOrigin = origin + "@" + aAppId + { 't', 'f' }
+  aExtendedOrigin.Assign(origin + NS_LITERAL_CSTRING("@"));
+  aExtendedOrigin.AppendInt(aAppId);
+  aExtendedOrigin.Append(aInMozBrowser ? NS_LITERAL_CSTRING("t")
+                                       : NS_LITERAL_CSTRING("f"));
+
+  return;
+}
+
+} // namespace mozilla
+
+NS_IMETHODIMP
+nsScriptSecurityManager::GetExtendedOrigin(nsIURI* aURI,
+                                           PRUint32 aAppId,
+                                           bool aInMozBrowser,
+                                           nsACString& aExtendedOrigin)
+{
+  MOZ_ASSERT(aAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID);
+
+  mozilla::GetExtendedOrigin(aURI, aAppId, aInMozBrowser, aExtendedOrigin);
+  return NS_OK;
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 // The following code prints the contents of the policy DB to the console.
 #ifdef DEBUG_CAPS_HACKER
 
 //typedef PLDHashOperator
 //(* PLDHashEnumerator)(PLDHashTable *table, PLDHashEntryHdr *hdr,
 //                      PRUint32 number, void *arg);
 static PLDHashOperator
--- a/caps/src/nsSystemPrincipal.cpp
+++ b/caps/src/nsSystemPrincipal.cpp
@@ -11,16 +11,17 @@
 #include "nsIServiceManager.h"
 #include "nsIURL.h"
 #include "nsCOMPtr.h"
 #include "nsXPIDLString.h"
 #include "nsReadableUtils.h"
 #include "nsCRT.h"
 #include "nsString.h"
 #include "nsIClassInfoImpl.h"
+#include "nsIScriptSecurityManager.h"
 
 NS_IMPL_CLASSINFO(nsSystemPrincipal, NULL,
                   nsIClassInfo::SINGLETON | nsIClassInfo::MAIN_THREAD_ONLY,
                   NS_SYSTEMPRINCIPAL_CID)
 NS_IMPL_QUERY_INTERFACE2_CI(nsSystemPrincipal,
                             nsIPrincipal,
                             nsISerializable)
 NS_IMPL_CI_INTERFACE_GETTER2(nsSystemPrincipal,
@@ -232,16 +233,35 @@ nsSystemPrincipal::GetSecurityPolicy(voi
 }
 
 NS_IMETHODIMP
 nsSystemPrincipal::SetSecurityPolicy(void* aSecurityPolicy)
 {
     return NS_OK;
 }
 
+NS_IMETHODIMP
+nsSystemPrincipal::GetExtendedOrigin(nsACString& aExtendedOrigin)
+{
+  return GetOrigin(getter_Copies(aExtendedOrigin));
+}
+
+NS_IMETHODIMP
+nsSystemPrincipal::GetAppStatus(PRUint16* aAppStatus)
+{
+  *aAppStatus = nsIPrincipal::APP_STATUS_NOT_INSTALLED;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSystemPrincipal::GetAppId(PRUint32* aAppId)
+{
+  *aAppId = nsIScriptSecurityManager::NO_APP_ID;
+  return NS_OK;
+}
 
 //////////////////////////////////////////
 // Methods implementing nsISerializable //
 //////////////////////////////////////////
 
 NS_IMETHODIMP
 nsSystemPrincipal::Read(nsIObjectInputStream* aStream)
 {
--- a/caps/tests/mochitest/Makefile.in
+++ b/caps/tests/mochitest/Makefile.in
@@ -13,15 +13,19 @@ include $(DEPTH)/config/autoconf.mk
 
 MOCHITEST_FILES = 	test_bug423375.html \
                 test_bug246699.html \
                 test_bug292789.html \
                 test_bug470804.html \
                 test_disallowInheritPrincipal.html \
                 $(NULL)
 
+# Temporarily disabled for orange
+# MOCHITEST_CHROME_FILES = test_principal_extendedorigin_appid_appstatus.html \
+#                          $(NULL)
+
 test_bug292789.html : % : %.in
 	$(PYTHON) $(topsrcdir)/config/Preprocessor.py \
 	     $(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $< > $@
 
 GARBAGE += test_bug292789.html
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/caps/tests/mochitest/test_principal_extendedorigin_appid_appstatus.html
@@ -0,0 +1,241 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=758258
+-->
+<head>
+  <meta charset="utf-8">
+  <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">
+
+/** Test for Bug 758258 **/
+
+var Ci = Components.interfaces;
+
+SimpleTest.waitForExplicitFinish();
+
+/*
+ * gData is an array of objects. Each object represents a test case.
+ * - app: gives the app manifest URL, will set mozapp to it on the iframe;
+ * - origin: gives the origin of the iframe. This is the URL thas is going to
+ *           to be passed as iframe.src but also the expected principal's
+ *           origin.
+ * - isapp: tells if the iframe is really a mozapp. If the manifest url isn't
+ *          valid, the iframe will not be considered as a mozapp.
+ * - browser: say if the iframe should be a mozbrowser. This is implicit when
+ *            app is set.
+ * - test: an array of tests to run for this test case:
+ *   - eo-unique: the extendedOrigin of the prinicpal must be unique in the
+ *                current list.
+ *   - eo-as-last: the extendedOrigin of the principal must be the same as the
+ *                 last added to the list.
+ */
+var gData = [
+  {
+    app: "http://example.org/manifest.webapp",
+    src: "http://example.org/",
+    isapp: true,
+    test: [ "eo-unique" ],
+  },
+  {
+    app: "https://example.com/manifest.webapp",
+    src: "https://example.com/",
+    isapp: true,
+    test: [ "eo-unique" ],
+  },
+  {
+    app: "http://test1.example.org/manifest.webapp",
+    src: "http://test1.example.org/",
+    isapp: true,
+    test: [ "eo-unique" ],
+  },
+  {
+    app: "http://test1.example.org:8000/manifest.webapp",
+    src: "http://test1.example.org:8000/",
+    isapp: true,
+    test: [ "eo-unique" ],
+  },
+  {
+    app: "http://sub1.test1.example.org/manifest.webapp",
+    src: "http://sub1.test1.example.org/",
+    isapp: true,
+    test: [ "eo-unique" ],
+  },
+// WebApps implementation doesn't allow apps with the same origin. Sad...
+//  {
+//    app: "http://example.org/foo/manifest.webapp",
+//    src: "http://example.org/",
+//    isapp: true,
+//    test: [ "eo-unique" ],
+//  },
+//  {
+//    app: "http://example.org/bar/manifest.webapp",
+//    src: "http://example.org/",
+//    isapp: true,
+//    test: [ "eo-unique" ],
+//  },
+  {
+    src: "http://example.org/",
+    isapp: false,
+    test: [ "eo-unique" ],
+  },
+  {
+    browser: true,
+    src: "http://example.org/",
+    isapp: false,
+    test: [ "eo-unique" ],
+  },
+  {
+    app: "http://example.org/wedonthaveanyappinthatdirectory/manifest.webapp",
+    src: "http://example.org/",
+    isapp: false,
+    // TODO: this is a browser because we need apps to be browser and it's not
+    // an app because the manifest is invalid. Ideally, it should not be a
+    // browser.
+    browser: true,
+    test: [ "eo-as-last" ],
+  },
+/*
+//  {
+//    app: "http://example.org/manifest.webapp",
+//    src: "data:text/html,foobar",
+//    test: [ "todo-src" ],
+//  },
+//  {
+//    app: "http://example.org/manifest.webapp",
+//    src: "data:text/html,foobar2",
+//    test: [ "todo-src" ],
+//  },
+*/
+  {
+    src: "file:///",
+    isapp: false,
+    test: [ "eo-unique" ],
+  },
+  {
+    src: "file:///tmp",
+    isapp: false,
+    test: [ "eo-unique" ],
+  },
+  {
+    app: "http://example.org/manifest.webapp",
+    src: "file:///",
+    isapp: true,
+    test: [ "eo-unique" ],
+  },
+  {
+    app: "http://example.org/manifest.webapp",
+    src: "file:///tmp",
+    isapp: true,
+    test: [ "eo-unique" ],
+  },
+];
+
+// The list of all data ids generated by this test.
+var eoList = [];
+
+var content = document.getElementById('content');
+var checkedCount = 0;
+var checksTodo = gData.length;
+
+function checkPrincipalForIFrame(aFrame, data) {
+  var principal = aFrame.contentDocument.nodePrincipal;
+
+  if (!data.test) {
+    data.test = [];
+  }
+
+// Temporarily disable that check.
+//  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");
+  } 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) {
+    is(principal.extendedOrigin, principal.origin,
+       'extendedOrigin should return the origin for non-app and non-browsers principals');
+  } else {
+    isnot(principal.extendedOrigin, principal.origin,
+          'extendedOrigin should not return the origin for apps or mozbrowsers');
+  }
+
+  if (data.test.indexOf("eo-unique") != -1) {
+    is(eoList.indexOf(principal.extendedOrigin), -1,
+       "extendedOrigin should be unique");
+  }
+  if (data.test.indexOf("eo-as-last") != -1) {
+    is(principal.extendedOrigin, eoList[eoList.length-1],
+       "extendedOrigin should be the same as the last inserted one");
+  }
+
+  eoList.push(principal.extendedOrigin);
+
+  checkedCount++;
+  if (checkedCount == checksTodo) {
+    SimpleTest.finish();
+  }
+}
+
+is('appStatus' in document.nodePrincipal, true,
+   'appStatus should be present in nsIPrincipal');
+is('extendedOrigin' in document.nodePrincipal, true,
+   'extendedOrigin should be present in nsIPrincipal');
+is('appId' in document.nodePrincipal, true,
+   'appId should be present in nsIPrincipal');
+
+SpecialPowers.pushPrefEnv({'set': [["dom.mozBrowserFramesEnabled", true]]}, function() {
+
+// For some unknown reasons, this test this to always timeout on Windows.
+if (navigator.platform.indexOf("Win") != -1) {
+  SimpleTest.finish();
+  return;
+}
+
+gData.forEach(function(data) {
+  var iframe = document.createElement('iframe');
+  iframe.checkPrincipal = function() {
+    checkPrincipalForIFrame(this, data);
+  };
+
+  if (data.app) {
+    iframe.setAttribute('mozapp', data.app);
+    iframe.setAttribute('mozbrowser', '');
+  } else if (data.browser) {
+    iframe.setAttribute('mozbrowser', '');
+  }
+
+  iframe.src = data.src;
+
+  iframe.addEventListener('load', iframe.checkPrincipal.bind(iframe));
+
+  content.appendChild(iframe);
+});
+
+});
+
+</script>
+</pre>
+</body>
+</html>
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -79,16 +79,18 @@ MOZ_JPROF       = @MOZ_JPROF@
 MOZ_SHARK       = @MOZ_SHARK@
 MOZ_CALLGRIND   = @MOZ_CALLGRIND@
 MOZ_VALGRIND    = @MOZ_VALGRIND@
 MOZ_VTUNE       = @MOZ_VTUNE@
 MOZ_ETW         = @MOZ_ETW@
 MOZ_TRACE_JSCALLS = @MOZ_TRACE_JSCALLS@
 DEHYDRA_PATH    = @DEHYDRA_PATH@
 
+MOZ_USING_CCACHE = @MOZ_USING_CCACHE@
+CLANG_CXX = @CLANG_CXX@
 MOZ_LINKER = @MOZ_LINKER@
 MOZ_OLD_LINKER = @MOZ_OLD_LINKER@
 MOZ_ENABLE_SZIP = @MOZ_ENABLE_SZIP@
 NS_TRACE_MALLOC = @NS_TRACE_MALLOC@
 USE_ELF_DYNSTR_GC = @USE_ELF_DYNSTR_GC@
 USE_ELF_HACK = @USE_ELF_HACK@
 STDCXX_COMPAT = @STDCXX_COMPAT@
 MOZ_LIBSTDCXX_TARGET_VERSION=@MOZ_LIBSTDCXX_TARGET_VERSION@
--- a/config/config.mk
+++ b/config/config.mk
@@ -557,16 +557,23 @@ endif # NEXT_ROOT
 PBBUILD_SETTINGS = GCC_VERSION="$(GCC_VERSION)" SYMROOT=build ARCHS="$(OS_TEST)"
 ifdef MACOS_SDK_DIR
 PBBUILD_SETTINGS += SDKROOT="$(MACOS_SDK_DIR)"
 endif # MACOS_SDK_DIR
 ifdef MACOSX_DEPLOYMENT_TARGET
 export MACOSX_DEPLOYMENT_TARGET
 PBBUILD_SETTINGS += MACOSX_DEPLOYMENT_TARGET="$(MACOSX_DEPLOYMENT_TARGET)"
 endif # MACOSX_DEPLOYMENT_TARGET
+
+ifdef MOZ_USING_CCACHE
+ifdef CLANG_CXX
+export CCACHE_CPP2=1
+endif
+endif
+
 ifdef MOZ_OPTIMIZE
 ifeq (2,$(MOZ_OPTIMIZE))
 # Only override project defaults if the config specified explicit settings
 PBBUILD_SETTINGS += GCC_MODEL_TUNING= OPTIMIZATION_CFLAGS="$(MOZ_OPTIMIZE_FLAGS)"
 endif # MOZ_OPTIMIZE=2
 endif # MOZ_OPTIMIZE
 endif # OS_ARCH=Darwin
 
--- a/config/makefiles/mochitest.mk
+++ b/config/makefiles/mochitest.mk
@@ -10,17 +10,17 @@ ifndef INCLUDED_TESTS_MOCHITEST_MK #{
 ifdef relativesrcdir
   mochitestdir = $(DEPTH)/_tests/testing/mochitest/$1/$(relativesrcdir)
 else
   mochitestdir = $(DEPTH)/_tests/testing/mochitest/$1/$(subst $(topsrcdir),,$(srcdir))
 endif
 
 define mochitest-libs-rule-template
 libs:: $$($(1))
-	$$(INSTALL) $$(foreach f,$$^,"$$(f)") $$(call mochitestdir,$(2))
+	$$(call install_cmd,$$(foreach f,$$^,"$$(f)") $$(call mochitestdir,$(2)))
 endef
 
 # Provide support for modules with such a large number of tests that
 # installing them with a single $(INSTALL) invocation would overflow
 # command-line length limits on some operating systems.
 ifdef MOCHITEST_FILES_PARTS
 ifdef MOCHITEST_FILES
 $(error You must define only one of MOCHITEST_FILES_PARTS or MOCHITEST_FILES)
--- a/configure.in
+++ b/configure.in
@@ -358,70 +358,17 @@ else
     if test -z "$HOST_AR"; then
         HOST_AR='$(AR)'
     fi
     if test -z "$HOST_AR_FLAGS"; then
         HOST_AR_FLAGS='$(AR_FLAGS)'
     fi
 fi
 
-GNU_AS=
-GNU_LD=
-GNU_CC=
-GNU_CXX=
-CC_VERSION='N/A'
-CXX_VERSION='N/A'
-if test "$GCC" = "yes"; then
-    GNU_CC=1
-    CC_VERSION=`$CC -v 2>&1 | grep 'gcc version'`
-fi
-if test "$GXX" = "yes"; then
-    GNU_CXX=1
-    CXX_VERSION=`$CXX -v 2>&1 | grep 'gcc version'`
-fi
-if test "`echo | $AS -o conftest.out -v 2>&1 | grep -c GNU`" != "0"; then
-    GNU_AS=1
-fi
-rm -f conftest.out
-if test "`echo | $LD -v 2>&1 | grep -c GNU`" != "0"; then
-    GNU_LD=1
-fi
-if test "$GNU_CC"; then
-    if `$CC -print-prog-name=ld` -v 2>&1 | grep -c GNU >/dev/null; then
-        GCC_USE_GNU_LD=1
-    fi
-fi
-
-INTEL_CC=
-INTEL_CXX=
-if test "$GCC" = yes; then
-   if test "`$CC -help 2>&1 | grep -c 'Intel(R) C++ Compiler'`" != "0"; then
-     INTEL_CC=1
-   fi
-fi
-
-if test "$GXX" = yes; then
-   if test "`$CXX -help 2>&1 | grep -c 'Intel(R) C++ Compiler'`" != "0"; then
-     INTEL_CXX=1
-   fi
-fi
-
-CLANG_CC=
-CLANG_CXX=
-if test "$GCC" = yes; then
-   if test "`$CC -v 2>&1 | grep -c 'clang version'`" != "0"; then
-     CLANG_CC=1
-   fi
-fi
-
-if test "$GXX" = yes; then
-   if test "`$CXX -v 2>&1 | grep -c 'clang version'`" != "0"; then
-     CLANG_CXX=1
-   fi
-fi
+MOZ_TOOL_VARIABLES
 
 dnl ========================================================
 dnl Special win32 checks
 dnl ========================================================
 
 # With win8, sdk target=602, WINVER=602
 MOZ_ARG_ENABLE_BOOL(metro,
 [  --enable-metro           Enable Windows Metro build targets],
@@ -7162,42 +7109,17 @@ MOZ_ARG_ENABLE_BOOL(js-diagnostics,
 [  --enable-js-diagnostics
                           Enable JS diagnostic assertions and breakpad data],
     JS_CRASH_DIAGNOSTICS=1,
     JS_CRASH_DIAGNOSTICS= )
 if test -n "$JS_CRASH_DIAGNOSTICS"; then
     AC_DEFINE(JS_CRASH_DIAGNOSTICS)
 fi
 
-dnl ======================================================
-dnl = Enable compiling with ccache
-dnl ======================================================
-MOZ_ARG_WITH_STRING(ccache,
-[  --with-ccache[=path/to/ccache]
-                          Enable compiling with ccache],
-    CCACHE=$withval, CCACHE="no")
-
-if test "$CCACHE" != "no"; then
-    if test -z "$CCACHE" -o "$CCACHE" = "yes"; then
-        CCACHE=
-    else
-        if test ! -e "$CCACHE"; then
-            AC_MSG_ERROR([$CCACHE not found])
-        fi
-    fi
-    MOZ_PATH_PROGS(CCACHE, $CCACHE ccache)
-    if test -z "$CCACHE" -o "$CCACHE" = ":"; then
-        AC_MSG_ERROR([ccache not found])
-    elif test -x "$CCACHE"; then
-        CC="$CCACHE $CC"
-        CXX="$CCACHE $CXX"
-    else
-        AC_MSG_ERROR([$CCACHE is not executable])
-    fi
-fi
+MOZ_CHECK_CCACHE
 
 dnl ========================================================
 dnl = Enable static checking using gcc-dehydra
 dnl ========================================================
 
 MOZ_ARG_WITH_STRING(static-checking,
 [  --with-static-checking=path/to/gcc_dehydra.so
                           Enable static checking of code using GCC-dehydra],
@@ -8747,24 +8669,26 @@ HAVE_WCRTOMB
 "
 
 AC_CONFIG_HEADER(
 netwerk/necko-config.h
 xpcom/xpcom-config.h
 xpcom/xpcom-private.h
 )
 
-# Hack around an Apple bug that effects the egrep that comes with OS X 10.7.
-# "arch -arch i386 egrep" always uses the 32-bit Intel part of the egrep fat
-# binary, even on 64-bit systems. We (apparently) only need this hack when
-# egrep's "pattern" is particularly long (as in the following code).
-# See bug 655339.
+# Hack around an Apple bug that affects the egrep that comes with OS X 10.7.
+# "env ARCHPREFERENCE=i386,x86_64 arch egrep" first tries to use the 32-bit
+# Intel part of the egrep fat binary, even on 64-bit systems, and falls back on
+# the 64-bit part if it's not a fat binary, as can happen with MacPorts. We
+# (apparently) only need this hack when egrep's "pattern" is particularly long
+# (as in the following code) and the first egrep on our $PATH is Apple's.  See
+# bug 655339.
 case "$host" in
 *-apple-darwin11*)
-    FIXED_EGREP="arch -arch i386 egrep"
+    FIXED_EGREP="env ARCHPREFERENCE=i386,x86_64 arch egrep"
     ;;
 *)
     FIXED_EGREP="egrep"
     ;;
 esac
 
 # Save the defines header file before autoconf removes it.
 # (Do not add AC_DEFINE calls after this line.)
--- a/content/base/src/contentAreaDropListener.js
+++ b/content/base/src/contentAreaDropListener.js
@@ -61,39 +61,39 @@ ContentAreaDropListener.prototype =
 
     // Strip leading and trailing whitespace, then try to create a
     // URI from the dropped string. If that succeeds, we're
     // dropping a URI and we need to do a security check to make
     // sure the source document can load the dropped URI.
     uriString = uriString.replace(/^\s*|\s*$/g, '');
 
     let uri;
+    let ioService = Cc["@mozilla.org/network/io-service;1"]
+                      .getService(Components.interfaces.nsIIOService);
     try {
       // Check that the uri is valid first and return an empty string if not.
       // It may just be plain text and should be ignored here
-      uri = Cc["@mozilla.org/network/io-service;1"].
-              getService(Components.interfaces.nsIIOService).
-              newURI(uriString, null, null);
+      uri = ioService.newURI(uriString, null, null);
     } catch (ex) { }
     if (!uri)
       return uriString;
 
     // uriString is a valid URI, so do the security check.
     let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].
                    getService(Ci.nsIScriptSecurityManager);
     let sourceNode = dataTransfer.mozSourceNode;
     let flags = secMan.STANDARD;
     if (disallowInherit)
       flags |= secMan.DISALLOW_INHERIT_PRINCIPAL;
 
     // Use file:/// as the default uri so that drops of file URIs are always allowed
-    if (sourceNode)
-      secMan.checkLoadURIStrWithPrincipal(sourceNode.nodePrincipal, uriString, flags);
-    else
-      secMan.checkLoadURIStr("file:///", uriString, flags);
+    let principal = sourceNode ? sourceNode.nodePrincipal
+                               : secMan.getCodebasePrincipal(ioService.newURI("file:///", null, null));
+
+    secMan.checkLoadURIStrWithPrincipal(principal, uriString, flags);
 
     return uriString;
   },
 
   canDropLink: function(aEvent, aAllowSameDocument)
   {
     let dataTransfer = aEvent.dataTransfer;
     let types = dataTransfer.types;
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -2186,20 +2186,31 @@ nsDocument::ResetToURI(nsIURI *aURI, nsI
 
   // Now get our new principal
   if (aPrincipal) {
     SetPrincipal(aPrincipal);
   } else {
     nsIScriptSecurityManager *securityManager =
       nsContentUtils::GetSecurityManager();
     if (securityManager) {
+      nsCOMPtr<nsIDocShell> docShell = do_QueryReferent(mDocumentContainer);
+
+      if (!docShell && aLoadGroup) {
+        nsCOMPtr<nsIInterfaceRequestor> cbs;
+        aLoadGroup->GetNotificationCallbacks(getter_AddRefs(cbs));
+        docShell = do_GetInterface(cbs);
+      }
+
+      MOZ_ASSERT(docShell,
+                 "must be in a docshell or pass in an explicit principal");
+
       nsCOMPtr<nsIPrincipal> principal;
-      nsresult rv =
-        securityManager->GetCodebasePrincipal(mDocumentURI,
-                                              getter_AddRefs(principal));
+      nsresult rv = securityManager->
+        GetDocShellCodebasePrincipal(mDocumentURI, docShell,
+                                     getter_AddRefs(principal));
       if (NS_SUCCEEDED(rv)) {
         SetPrincipal(principal);
       }
     }
   }
 
   // Refresh the principal on the compartment.
   nsPIDOMWindow* win = GetInnerWindow();
@@ -3082,17 +3093,17 @@ nsDocument::SetHeaderData(nsIAtom* aHead
     // our container via mDocumentContainer.
     nsCOMPtr<nsIRefreshURI> refresher = do_QueryReferent(mDocumentContainer);
     if (refresher) {
       // Note: using mDocumentURI instead of mBaseURI here, for consistency
       // (used to just use the current URI of our webnavigation, but that
       // should really be the same thing).  Note that this code can run
       // before the current URI of the webnavigation has been updated, so we
       // can't assert equality here.
-      refresher->SetupRefreshURIFromHeader(mDocumentURI,
+      refresher->SetupRefreshURIFromHeader(mDocumentURI, NodePrincipal(),
                                            NS_ConvertUTF16toUTF8(aData));
     }
   }
 
   if (aHeaderField == nsGkAtoms::headerDNSPrefetchControl &&
       mAllowDNSPrefetch) {
     // Chromium treats any value other than 'on' (case insensitive) as 'off'.
     mAllowDNSPrefetch = aData.IsEmpty() || aData.LowerCaseEqualsLiteral("on");
--- a/content/base/src/nsFrameLoader.cpp
+++ b/content/base/src/nsFrameLoader.cpp
@@ -75,16 +75,17 @@
 
 #include "ContentParent.h"
 #include "TabParent.h"
 #include "mozilla/GuardObjects.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/unused.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/layout/RenderFrameParent.h"
+#include "nsIAppsService.h"
 
 #include "jsapi.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::layers;
 using namespace mozilla::layout;
 typedef FrameMetrics::ViewID ViewID;
@@ -1104,24 +1105,39 @@ nsFrameLoader::SwapWithOtherLoader(nsFra
   NS_ASSERTION(otherDoc == otherParentDocument, "Unexpected parent document");
 
   nsIPresShell* ourShell = ourDoc->GetShell();
   nsIPresShell* otherShell = otherDoc->GetShell();
   if (!ourShell || !otherShell) {
     return NS_ERROR_NOT_IMPLEMENTED;
   }
 
-  bool weAreBrowserFrame = false;
-  bool otherIsBrowserFrame = false;
-  ourDocshell->GetIsBrowserFrame(&weAreBrowserFrame);
-  otherDocshell->GetIsBrowserFrame(&otherIsBrowserFrame);
-  if (weAreBrowserFrame != otherIsBrowserFrame) {
+  bool ourContentBoundary, otherContentBoundary;
+  ourDocshell->GetIsContentBoundary(&ourContentBoundary);
+  otherDocshell->GetIsContentBoundary(&otherContentBoundary);
+  if (ourContentBoundary != otherContentBoundary) {
     return NS_ERROR_NOT_IMPLEMENTED;
   }
 
+  if (ourContentBoundary) {
+    bool ourIsBrowser, otherIsBrowser;
+    ourDocshell->GetIsBrowserElement(&ourIsBrowser);
+    otherDocshell->GetIsBrowserElement(&otherIsBrowser);
+    if (ourIsBrowser != otherIsBrowser) {
+      return NS_ERROR_NOT_IMPLEMENTED;
+    }
+
+    bool ourIsApp, otherIsApp;
+    ourDocshell->GetIsApp(&ourIsApp);
+    otherDocshell->GetIsApp(&otherIsApp);
+    if (ourIsApp != otherIsApp) {
+      return NS_ERROR_NOT_IMPLEMENTED;
+    }
+  }
+
   if (mInSwap || aOther->mInSwap) {
     return NS_ERROR_NOT_IMPLEMENTED;
   }
   mInSwap = aOther->mInSwap = true;
 
   // Fire pageshow events on still-loading pages, and then fire pagehide
   // events.  Note that we do NOT fire these in the normal way, but just fire
   // them on the chrome event handlers.
@@ -1456,16 +1472,34 @@ nsFrameLoader::MaybeCreateDocShell()
     doc->GetContainer();
   nsCOMPtr<nsIWebNavigation> parentAsWebNav = do_QueryInterface(container);
   NS_ENSURE_STATE(parentAsWebNav);
 
   // Create the docshell...
   mDocShell = do_CreateInstance("@mozilla.org/docshell;1");
   NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
 
+  if (OwnerIsBrowserFrame() &&
+      mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::mozapp)) {
+    nsCOMPtr<nsIAppsService> appsService =
+      do_GetService(APPS_SERVICE_CONTRACTID);
+    if (!appsService) {
+      NS_ERROR("Apps Service is not available!");
+      return NS_ERROR_FAILURE;
+    }
+
+    nsAutoString manifest;
+    mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::mozapp, manifest);
+
+    PRUint32 appId;
+    appsService->GetAppLocalIdByManifestURL(manifest, &appId);
+
+    mDocShell->SetAppId(appId);
+  }
+
   if (!mNetworkCreated) {
     nsCOMPtr<nsIDocShellHistory> history = do_QueryInterface(mDocShell);
     if (history) {
       history->SetCreatedDynamically(true);
     }
   }
 
   // Get the frame name and tell the docshell about it.
@@ -1558,17 +1592,17 @@ nsFrameLoader::MaybeCreateDocShell()
     // Do not call Destroy() here. See bug 472312.
     NS_WARNING("Something wrong when creating the docshell for a frameloader!");
     return NS_ERROR_FAILURE;
   }
 
   EnsureMessageManager();
 
   if (OwnerIsBrowserFrame()) {
-    mDocShell->SetIsBrowserFrame(true);
+    mDocShell->SetIsBrowser();
 
     nsCOMPtr<nsIObserverService> os = services::GetObserverService();
     if (os) {
       os->NotifyObservers(NS_ISUPPORTS_CAST(nsIFrameLoader*, this),
                           "in-process-browser-frame-shown", NULL);
     }
 
     if (mMessageManager) {
--- a/content/events/src/nsEventStateManager.cpp
+++ b/content/events/src/nsEventStateManager.cpp
@@ -1739,16 +1739,17 @@ CrossProcessSafeEvent(const nsEvent& aEv
   }
 }
 
 bool
 nsEventStateManager::HandleCrossProcessEvent(nsEvent *aEvent,
                                              nsIFrame* aTargetFrame,
                                              nsEventStatus *aStatus) {
   if (*aStatus == nsEventStatus_eConsumeNoDefault ||
+      aEvent->flags & NS_EVENT_FLAG_DONT_FORWARD_CROSS_PROCESS ||
       !CrossProcessSafeEvent(*aEvent)) {
     return false;
   }
 
   // Collect the remote event targets we're going to forward this
   // event to.
   //
   // NB: the elements of |targets| must be unique, for correctness.
--- a/content/events/test/Makefile.in
+++ b/content/events/test/Makefile.in
@@ -80,38 +80,33 @@ MOCHITEST_FILES = \
 		test_bug689564.html \
 		test_bug698929.html \
 		test_eventctors.html \
 		test_bug635465.html \
 		test_bug741666.html \
 		test_dom_keyboard_event.html \
 		test_dom_mouse_event.html \
 		test_bug742376.html \
+		test_bug603008.html \
 		$(NULL)
 
 #bug 585630
 ifneq (mobile,$(MOZ_BUILD_APP))
 MOCHITEST_FILES += \
 		test_dragstart.html \
 		$(NULL)
 endif
 
 # bug 565245
 ifneq (Linux,$(OS_ARCH))
 MOCHITEST_FILES += \
 		test_bug493251.html \
 		$(NULL)
 endif
 
-ifeq (android,$(MOZ_WIDGET_TOOLKIT))
-MOCHITEST_FILES += \
-		test_bug603008.html \
-		$(NULL)
-endif
-
 MOCHITEST_CHROME_FILES = \
 		test_bug336682_2.xul \
 		test_bug336682.js \
 		test_bug350471.xul \
 		test_bug586961.xul \
 		test_bug415498.xul \
 		bug415498-doc1.html \
 		bug415498-doc2.html \
--- a/content/media/nsBuiltinDecoderStateMachine.cpp
+++ b/content/media/nsBuiltinDecoderStateMachine.cpp
@@ -216,17 +216,17 @@ public:
   // Returns true if aStateMachine has a pending request for a
   // decode thread.
   bool IsQueued(nsBuiltinDecoderStateMachine* aStateMachine);
 #endif
 
 private:
   // Holds global instance of StateMachineTracker.
   // Writable on main thread only.
-  static StateMachineTracker* mInstance;
+  static StateMachineTracker* sInstance;
 
   // Reentrant monitor that must be obtained to access
   // the decode thread count member and methods.
   ReentrantMonitor mMonitor;
 
   // Number of instances of nsBuiltinDecoderStateMachine
   // that are currently instantiated. Access on the
   // main thread only.
@@ -242,25 +242,25 @@ private:
   // the mMonitor.
   nsIThread* mStateMachineThread;
 
   // Queue of state machines waiting for decode threads. Entries at the front
   // get their threads first.
   nsDeque mPending;
 };
 
-StateMachineTracker* StateMachineTracker::mInstance = nsnull;
+StateMachineTracker* StateMachineTracker::sInstance = nsnull;
 
 StateMachineTracker& StateMachineTracker::Instance()
 {
-  if (!mInstance) {
+  if (!sInstance) {
     NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-    mInstance = new StateMachineTracker();
+    sInstance = new StateMachineTracker();
   }
-  return *mInstance;
+  return *sInstance;
 }
 
 void StateMachineTracker::EnsureGlobalStateMachine() 
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
   ReentrantMonitorAutoEnter mon(mMonitor);
   if (mStateMachineCount == 0) {
     NS_ASSERTION(!mStateMachineThread, "Should have null state machine thread!");
@@ -298,17 +298,17 @@ void StateMachineTracker::CleanupGlobalS
     {
       ReentrantMonitorAutoEnter mon(mMonitor);
       nsCOMPtr<nsIRunnable> event = new ShutdownThreadEvent(mStateMachineThread);
       NS_RELEASE(mStateMachineThread);
       mStateMachineThread = nsnull;
       NS_DispatchToMainThread(event);
 
       NS_ASSERTION(mDecodeThreadCount == 0, "Decode thread count must be zero.");
-      mInstance = nsnull;
+      sInstance = nsnull;
     }
     delete this;
   }
 }
 
 void StateMachineTracker::NoteDecodeThreadDestroyed()
 {
   ReentrantMonitorAutoEnter mon(mMonitor);
--- a/content/media/nsDOMMediaStream.h
+++ b/content/media/nsDOMMediaStream.h
@@ -6,16 +6,23 @@
 #ifndef NSDOMMEDIASTREAM_H_
 #define NSDOMMEDIASTREAM_H_
 
 #include "nsIDOMMediaStream.h"
 #include "MediaStreamGraph.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsIPrincipal.h"
 
+// GetCurrentTime is defined in winbase.h as zero argument macro forwarding to
+// GetTickCount() and conflicts with NS_DECL_NSIDOMMEDIASTREAM, containing
+// currentTime getter.
+#ifdef GetCurrentTime
+#undef GetCurrentTime
+#endif
+
 /**
  * DOM wrapper for MediaStreams.
  */
 class nsDOMMediaStream : public nsIDOMMediaStream
 {
   typedef mozilla::MediaStream MediaStream;
 
 public:
--- a/content/smil/nsSMILCSSProperty.cpp
+++ b/content/smil/nsSMILCSSProperty.cpp
@@ -12,17 +12,17 @@
 #include "nsStyleAnimation.h"
 #include "mozilla/dom/Element.h"
 #include "nsIDOMElement.h"
 
 using namespace mozilla::dom;
 
 // Helper function
 static bool
-GetCSSComputedValue(nsIContent* aElem,
+GetCSSComputedValue(Element* aElem,
                     nsCSSProperty aPropID,
                     nsAString& aResult)
 {
   NS_ABORT_IF_FALSE(!nsCSSProps::IsShorthand(aPropID),
                     "Can't look up computed value of shorthand property");
   NS_ABORT_IF_FALSE(nsSMILCSSProperty::IsPropertyAnimatable(aPropID),
                     "Shouldn't get here for non-animatable properties");
 
@@ -35,26 +35,21 @@ GetCSSComputedValue(nsIContent* aElem,
   }
 
   nsIPresShell* shell = doc->GetShell();
   if (!shell) {
     NS_WARNING("Unable to look up computed style -- no pres shell");
     return false;
   }
 
-  nsRefPtr<nsComputedDOMStyle> computedStyle;
-  nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(aElem));
-  nsresult rv = NS_NewComputedDOMStyle(domElement, EmptyString(), shell,
-                                       getter_AddRefs(computedStyle));
+  nsRefPtr<nsComputedDOMStyle> computedStyle =
+    NS_NewComputedDOMStyle(aElem, EmptyString(), shell);
 
-  if (NS_SUCCEEDED(rv)) {
-    computedStyle->GetPropertyValue(aPropID, aResult);
-    return true;
-  }
-  return false;
+  computedStyle->GetPropertyValue(aPropID, aResult);
+  return true;
 }
 
 // Class Methods
 nsSMILCSSProperty::nsSMILCSSProperty(nsCSSProperty aPropID,
                                      Element* aElement)
   : mPropID(aPropID), mElement(aElement)
 {
   NS_ABORT_IF_FALSE(IsPropertyAnimatable(mPropID),
--- a/content/xslt/src/xslt/txMozillaXMLOutput.cpp
+++ b/content/xslt/src/xslt/txMozillaXMLOutput.cpp
@@ -236,16 +236,17 @@ txMozillaXMLOutput::endDocument(nsresult
 
     if (!mRefreshString.IsEmpty()) {
         nsPIDOMWindow *win = mDocument->GetWindow();
         if (win) {
             nsCOMPtr<nsIRefreshURI> refURI =
                 do_QueryInterface(win->GetDocShell());
             if (refURI) {
                 refURI->SetupRefreshURIFromHeader(mDocument->GetDocBaseURI(),
+                                                  mDocument->NodePrincipal(),
                                                   mRefreshString);
             }
         }
     }
 
     if (mNotifier) {
         mNotifier->OnTransformEnd();
     }
--- a/docshell/base/nsDSURIContentListener.cpp
+++ b/docshell/base/nsDSURIContentListener.cpp
@@ -306,19 +306,19 @@ bool nsDSURIContentListener::CheckOneFra
 
         // Traverse up the parent chain and stop when we see a docshell whose
         // parent has a system principal, or a docshell corresponding to
         // <iframe mozbrowser>.
         while (NS_SUCCEEDED(curDocShellItem->GetParent(getter_AddRefs(parentDocShellItem))) &&
                parentDocShellItem) {
 
             nsCOMPtr<nsIDocShell> curDocShell = do_QueryInterface(curDocShellItem);
-            bool browserFrame = false;
-            curDocShell->GetIsBrowserFrame(&browserFrame);
-            if (browserFrame) {
+            bool isContentBoundary;
+            curDocShell->GetIsContentBoundary(&isContentBoundary);
+            if (isContentBoundary) {
               break;
             }
 
             bool system = false;
             topDoc = do_GetInterface(parentDocShellItem);
             if (topDoc) {
                 if (NS_SUCCEEDED(ssm->IsSystemPrincipal(topDoc->NodePrincipal(),
                                                         &system)) && system) {
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* vim: set ts=4 sw=4 tw=80 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/. */
 
 #include "mozilla/dom/ContentChild.h"
+#include "mozilla/dom/TabChild.h"
 #include "mozilla/Util.h"
 
 #ifdef MOZ_LOGGING
 // so we can get logging even in release builds (but only for some things)
 #define FORCE_PR_LOG 1
 #endif
 
 #include "nsIBrowserDOMWindow.h"
@@ -196,16 +197,17 @@ static NS_DEFINE_CID(kDOMScriptObjectFac
 static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
 
 #if defined(DEBUG_bryner) || defined(DEBUG_chb)
 //#define DEBUG_DOCSHELL_FOCUS
 #define DEBUG_PAGE_CACHE
 #endif
 
 using namespace mozilla;
+using namespace mozilla::dom;
 
 // Number of documents currently loading
 static PRInt32 gNumberOfDocumentsLoading = 0;
 
 // Global count of existing docshells.
 static PRInt32 gDocShellCount = 0;
 
 // Global count of docshells with the private attribute set
@@ -758,16 +760,17 @@ nsDocShell::nsDocShell():
     mURIResultedInDocument(false),
     mIsBeingDestroyed(false),
     mIsExecutingOnLoadHandler(false),
     mIsPrintingOrPP(false),
     mSavingOldViewer(false),
 #ifdef DEBUG
     mInEnsureScriptEnv(false),
 #endif
+    mAppId(nsIScriptSecurityManager::NO_APP_ID),
     mParentCharsetSource(0)
 {
     mHistoryID = ++gDocshellIDCounter;
     if (gDocShellCount++ == 0) {
         NS_ASSERTION(sURIFixup == nsnull,
                      "Huh, sURIFixup not null in first nsDocShell ctor!");
 
         CallGetService(NS_URIFIXUP_CONTRACTID, &sURIFixup);
@@ -5523,16 +5526,17 @@ nsDocShell::ForceRefreshURI(nsIURI * aUR
      */
     LoadURI(aURI, loadInfo, nsIWebNavigation::LOAD_FLAGS_NONE, true);
 
     return NS_OK;
 }
 
 nsresult
 nsDocShell::SetupRefreshURIFromHeader(nsIURI * aBaseURI,
+                                      nsIPrincipal* aPrincipal,
                                       const nsACString & aHeader)
 {
     // Refresh headers are parsed with the following format in mind
     // <META HTTP-EQUIV=REFRESH CONTENT="5; URL=http://uri">
     // By the time we are here, the following is true:
     // header = "REFRESH"
     // content = "5; URL=http://uri" // note the URL attribute is
     // optional, if it is absent, the currently loaded url is used.
@@ -5564,16 +5568,18 @@ nsDocShell::SetupRefreshURIFromHeader(ns
     // "go.html;" since ';' and ',' are valid uri characters.
     // 
     // Note that we need to remove any tokens wrapping the URI.
     // These tokens currently include spaces, double and single
     // quotes.
 
     // when done, seconds is 0 or the given number of seconds
     //            uriAttrib is empty or the URI specified
+    MOZ_ASSERT(aPrincipal);
+
     nsCAutoString uriAttrib;
     PRInt32 seconds = 0;
     bool specifiesSeconds = false;
 
     nsACString::const_iterator iter, tokenStart, doneIterating;
 
     aHeader.BeginReading(iter);
     aHeader.EndReading(doneIterating);
@@ -5728,19 +5734,18 @@ nsDocShell::SetupRefreshURIFromHeader(ns
     }
 
     if (NS_SUCCEEDED(rv)) {
         nsCOMPtr<nsIScriptSecurityManager>
             securityManager(do_GetService
                             (NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv));
         if (NS_SUCCEEDED(rv)) {
             rv = securityManager->
-                CheckLoadURI(aBaseURI, uri,
-                             nsIScriptSecurityManager::
-                             LOAD_IS_AUTOMATIC_DOCUMENT_REPLACEMENT);
+                CheckLoadURIWithPrincipal(aPrincipal, uri,
+                                          nsIScriptSecurityManager::LOAD_IS_AUTOMATIC_DOCUMENT_REPLACEMENT);
 
             if (NS_SUCCEEDED(rv)) {
                 bool isjs = true;
                 rv = NS_URIChainHasFlags(uri,
                   nsIProtocolHandler::URI_OPENING_EXECUTES_SCRIPT, &isjs);
                 NS_ENSURE_SUCCESS(rv, rv);
 
                 if (isjs) {
@@ -5766,18 +5771,26 @@ NS_IMETHODIMP nsDocShell::SetupRefreshUR
     nsresult rv;
     nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(aChannel, &rv));
     if (NS_SUCCEEDED(rv)) {
         nsCAutoString refreshHeader;
         rv = httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("refresh"),
                                             refreshHeader);
 
         if (!refreshHeader.IsEmpty()) {
+            nsCOMPtr<nsIScriptSecurityManager> secMan =
+                do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
+            NS_ENSURE_SUCCESS(rv, rv);
+
+            nsCOMPtr<nsIPrincipal> principal;
+            rv = secMan->GetChannelPrincipal(aChannel, getter_AddRefs(principal));
+            NS_ENSURE_SUCCESS(rv, rv);
+
             SetupReferrerFromChannel(aChannel);
-            rv = SetupRefreshURIFromHeader(mCurrentURI, refreshHeader);
+            rv = SetupRefreshURIFromHeader(mCurrentURI, principal, refreshHeader);
             if (NS_SUCCEEDED(rv)) {
                 return NS_REFRESHURI_HEADER_FOUND;
             }
         }
     }
     return rv;
 }
 
@@ -12008,57 +12021,161 @@ nsDocShell::GetCanExecuteScripts(bool *a
 #endif // DEBUG
       } while (treeItem && docshell);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDocShell::GetIsBrowserFrame(bool *aOut)
-{
-  NS_ENSURE_ARG_POINTER(aOut);
-  *aOut = mIsBrowserFrame;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDocShell::SetIsBrowserFrame(bool aValue)
-{
-  // Disallow transitions from browser frame to not-browser-frame.  Once a
-  // browser frame, always a browser frame.  (Otherwise, observers of
-  // docshell-marked-as-browser-frame would have to distinguish between
-  // newly-created browser frames and frames which went from true to false back
-  // to true.)
-  NS_ENSURE_STATE(!mIsBrowserFrame || aValue);
-
-  bool wasBrowserFrame = mIsBrowserFrame;
-  mIsBrowserFrame = aValue;
-  if (aValue && !wasBrowserFrame) {
+nsDocShell::SetIsBrowser()
+{
+    if (mIsBrowserFrame) {
+        NS_ERROR("You should not call SetIsBrowser() more than once.");
+        return NS_OK;
+    }
+
+    mIsBrowserFrame = true;
+
     nsCOMPtr<nsIObserverService> os = services::GetObserverService();
     if (os) {
-      os->NotifyObservers(GetAsSupports(this),
-                          "docshell-marked-as-browser-frame", NULL);
-    }
-  }
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDocShell::GetContainedInBrowserFrame(bool *aOut)
-{
-    *aOut = false;
-
-    if (mIsBrowserFrame) {
-        *aOut = true;
-        return NS_OK;
+        os->NotifyObservers(GetAsSupports(this),
+                            "docshell-marked-as-browser-frame", NULL);
+    }
+
+    return NS_OK;
+}
+
+nsDocShell::FrameType
+nsDocShell::GetInheritedFrameType()
+{
+    FrameType type = GetFrameType();
+
+    if (type != eFrameTypeRegular) {
+        return type;
     }
 
     nsCOMPtr<nsIDocShellTreeItem> parentAsItem;
     GetSameTypeParent(getter_AddRefs(parentAsItem));
 
     nsCOMPtr<nsIDocShell> parent = do_QueryInterface(parentAsItem);
-    if (parent) {
-        return parent->GetContainedInBrowserFrame(aOut);
-    }
-
-    return NS_OK;
-}
+    if (!parent) {
+        return eFrameTypeRegular;
+    }
+
+    return static_cast<nsDocShell*>(parent.get())->GetInheritedFrameType();
+}
+
+nsDocShell::FrameType
+nsDocShell::GetFrameType()
+{
+    if (mAppId != nsIScriptSecurityManager::NO_APP_ID) {
+        return eFrameTypeApp;
+    }
+
+    return mIsBrowserFrame ? eFrameTypeBrowser : eFrameTypeRegular;
+}
+
+NS_IMETHODIMP
+nsDocShell::GetIsBrowserElement(bool* aIsBrowser)
+{
+    *aIsBrowser = (GetFrameType() == eFrameTypeBrowser);
+
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocShell::GetIsApp(bool* aIsApp)
+{
+    *aIsApp = (GetFrameType() == eFrameTypeApp);
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocShell::GetIsContentBoundary(bool* aIsContentBoundary)
+{
+    switch (GetFrameType()) {
+        case eFrameTypeRegular:
+            *aIsContentBoundary = false;
+            break;
+        case eFrameTypeBrowser:
+        case eFrameTypeApp:
+            *aIsContentBoundary = true;
+            break;
+    }
+
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocShell::GetIsInBrowserElement(bool* aIsInBrowserElement)
+{
+    *aIsInBrowserElement = (GetInheritedFrameType() == eFrameTypeBrowser);
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocShell::GetIsInApp(bool* aIsInApp)
+{
+    *aIsInApp = (GetInheritedFrameType() == eFrameTypeApp);
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocShell::GetIsBelowContentBoundary(bool* aIsInContentBoundary)
+{
+    switch (GetInheritedFrameType()) {
+        case eFrameTypeRegular:
+            *aIsInContentBoundary = false;
+            break;
+        case eFrameTypeBrowser:
+        case eFrameTypeApp:
+            *aIsInContentBoundary = true;
+            break;
+    }
+
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocShell::SetAppId(PRUint32 aAppId)
+{
+    MOZ_ASSERT(mAppId == nsIScriptSecurityManager::NO_APP_ID);
+    MOZ_ASSERT(aAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID);
+
+    mAppId = aAppId;
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocShell::GetAppId(PRUint32* aAppId)
+{
+    if (mAppId != nsIScriptSecurityManager::NO_APP_ID) {
+        MOZ_ASSERT(GetFrameType() == eFrameTypeApp);
+
+        *aAppId = mAppId;
+        return NS_OK;
+    }
+
+    MOZ_ASSERT(GetFrameType() != eFrameTypeApp);
+
+    nsCOMPtr<nsIDocShellTreeItem> parentAsItem;
+    GetSameTypeParent(getter_AddRefs(parentAsItem));
+
+    nsCOMPtr<nsIDocShell> parent = do_QueryInterface(parentAsItem);
+    if (!parent) {
+        *aAppId = nsIScriptSecurityManager::NO_APP_ID;
+        return NS_OK;
+    }
+
+    return parent->GetAppId(aAppId);
+}
+
+NS_IMETHODIMP
+nsDocShell::GetAsyncPanZoomEnabled(bool* aOut)
+{
+    if (TabChild* tabChild = GetTabChildFrom(this)) {
+        *aOut = tabChild->IsAsyncPanZoomEnabled();
+        return NS_OK;
+    }
+    *aOut = false;
+    return NS_OK;
+}
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -659,16 +659,25 @@ protected:
         RestorePresentationEvent(nsDocShell *ds) : mDocShell(ds) {}
         void Revoke() { mDocShell = nsnull; }
     private:
         nsRefPtr<nsDocShell> mDocShell;
     };
 
     bool JustStartedNetworkLoad();
 
+    enum FrameType {
+        eFrameTypeRegular  = 0x0, // 0000
+        eFrameTypeBrowser  = 0x1, // 0001
+        eFrameTypeApp      = 0x2  // 0010
+    };
+
+    FrameType GetInheritedFrameType();
+    FrameType GetFrameType();
+
     // hash of session storages, keyed by domain
     nsInterfaceHashtable<nsCStringHashKey, nsIDOMStorage> mStorages;
 
     // Dimensions of the docshell
     nsIntRect                  mBounds;
     nsString                   mName;
     nsString                   mTitle;
 
@@ -810,16 +819,18 @@ protected:
     bool                       mInEnsureScriptEnv;
 #endif
     PRUint64                   mHistoryID;
 
     static nsIURIFixup *sURIFixup;
 
     nsRefPtr<nsDOMNavigationTiming> mTiming;
 
+    PRUint32 mAppId;
+
 private:
     nsCOMPtr<nsIAtom> mForcedCharset;
     nsCOMPtr<nsIAtom> mParentCharset;
     nsTObserverArray<nsWeakPtr> mPrivacyObservers;
     PRInt32           mParentCharsetSource;
     nsCString         mOriginalUriString;
 
 #ifdef DEBUG
--- a/docshell/base/nsIDocShell.idl
+++ b/docshell/base/nsIDocShell.idl
@@ -34,17 +34,17 @@ interface nsISHEntry;
 interface nsILayoutHistoryState;
 interface nsISecureBrowserUI;
 interface nsIDOMStorage;
 interface nsIPrincipal;
 interface nsIWebBrowserPrint;
 interface nsIVariant;
 interface nsIPrivacyTransitionObserver;
 
-[scriptable, builtinclass, uuid(89ea9f32-18ec-413b-9e2c-ce9a4c851b1c)]
+[scriptable, builtinclass, uuid(05802c0d-3315-4245-b72e-cf92eb3118a3)]
 interface nsIDocShell : nsISupports
 {
   /**
    * Loads a given URI.  This will give priority to loading the requested URI
    * in the object implementing	this interface.  If it can't be loaded here
    * however, the URL dispatcher will go through its normal process of content
    * loading.
    *
@@ -584,26 +584,75 @@ interface nsIDocShell : nsISupports
   attribute PRInt32 parentCharsetSource;
 
   /**
    * Add an observer to the list of parties to be notified when this docshell's
    * private browsing status is changed. |obs| must support weak references.
    */
   void addWeakPrivacyTransitionObserver(in nsIPrivacyTransitionObserver obs);
 
-  /*
-   * Is this docshell a browser frame (i.e., does it correspond to an <iframe
-   * mozbrowser>)?  The frameloader is responsible for setting this property
-   * when it initializes the docshell.
-   *
-   * If so, this docshell should act like a chrome/content boundary for the
-   * purposes of window.top and window.parent.
+  /**
+   * Mark the docshell as a browser frame.
+   * This should be used for <iframe mozbrowser> but not for <iframe mozapp>.
    *
-   * See also nsIMozBrowserFrame.
+   * This method should not be called more than once.
+   */
+  void setIsBrowser();
+
+  /**
+   * Returns true iff the docshell is marked as a browser frame.
+   */
+  readonly attribute boolean isBrowserElement;
+
+  /**
+   * Returns true iif the docshell is marked as an app frame.
    */
-  attribute bool isBrowserFrame;
+  readonly attribute boolean isApp;
+
+  /**
+   * Returns true iif the docshell is marked as a type that behaves like a
+   * content boundary.
+   */
+  readonly attribute boolean isContentBoundary;
+
+  /**
+   * Returns true iif the docshell is inside a browser element.
+   */
+  readonly attribute boolean isInBrowserElement;
+
+  /**
+   * Returns true iif the docshell is inside an application.
+   * However, it will return false if the docshell is inside a browser element
+   * that is inside an application.
+   */
+  readonly attribute boolean isInApp;
 
-  /*
-   * Is this docshell contained in an <iframe mozbrowser>, either directly or
-   * indirectly?
+  /**
+   * Returns if the docshell has a docshell that behaves as a content boundary
+   * in his parent hierarchy.
    */
-  readonly attribute bool containedInBrowserFrame;
+  readonly attribute boolean isBelowContentBoundary;
+
+  /**
+   * Set the app id this docshell is associated with. The id has to be a valid
+   * app id. If the docshell isn't associated with any app, the value should be
+   * nsIScriptSecurityManager::NO_APP_ID. However, this is the default value if
+   * nothing is et.
+   *
+   * This method is [noscript] to reduce the scope. It should be used at very
+   * specific moments.
+   *
+   * Calling setAppId() will mark the frame as an app frame.
+   */
+  [noscript] void setAppId(in unsigned long appId);
+
+  /**
+   * Returns the app id of the app the docshell is in. Returns
+   * nsIScriptSecurityManager::NO_APP_ID if the docshell is not in an app.
+   */
+  readonly attribute unsigned long appId;
+
+  /** 
+   * True iff asynchronous panning and zooming is enabled for this
+   * docshell.
+   */
+  readonly attribute bool asyncPanZoomEnabled;
 };
--- a/docshell/base/nsIRefreshURI.idl
+++ b/docshell/base/nsIRefreshURI.idl
@@ -2,18 +2,19 @@
  *
  * 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"
 #include "nsIURI.idl"
 interface nsIChannel;
+interface nsIPrincipal;
 
-[scriptable, uuid(cb0ad623-6b46-4c09-a473-c1d6ca63d3c7)]
+[scriptable, uuid(a5e61a3c-51bd-45be-ac0c-e87b71860656)]
 interface nsIRefreshURI : nsISupports {
     /**
       * Load a uri after waiting for aMillis milliseconds. If the docshell
       * is busy loading a page currently, the refresh request will be
       * queued and executed when the current load finishes. 
       *
       * @param aUri The uri to refresh.
       * @param aMillis The number of milliseconds to wait.
@@ -50,20 +51,21 @@ interface nsIRefreshURI : nsISupports {
 
     /**
       * Parses the passed in header string and sets up a refreshURI if
       * a "refresh" header is found. If docshell is busy loading a page 
       * currently, the request will be queued and executed when 
       * the current page finishes loading. 
       *
       * @param aBaseURI base URI to resolve refresh uri with.
+      * @param principal the associated principal
       * @param aHeader  The meta refresh header string.
       */
-    void setupRefreshURIFromHeader(in nsIURI aBaseURI, in ACString aHeader);
-      
+    void setupRefreshURIFromHeader(in nsIURI aBaseURI, in nsIPrincipal principal, in ACString aHeader);
+
     /**
       * Cancels all timer loads.
       */
     void cancelRefreshURITimers();
 
    /**
      * True when there are pending refreshes, false otherwise.
      */
--- a/dom/apps/src/Webapps.jsm
+++ b/dom/apps/src/Webapps.jsm
@@ -312,17 +312,18 @@ let DOMApplicationRegistry = {
       cacheUpdate.addObserver(new AppcacheObserver(appObject), false);
       if (aOfflineCacheObserver) {
         cacheUpdate.addObserver(aOfflineCacheObserver, false);
       }
     }
   },
 
   _nextLocalId: function() {
-    let maxLocalId = 0;
+    let maxLocalId = Ci.nsIScriptSecurityManager.NO_APP_ID;
+
     for (let id in this.webapps) {
       if (this.webapps[id].localId > maxLocalId) {
         maxLocalId = this.webapps[id].localId;
       }
     }
 
     return maxLocalId + 1;
   },
@@ -630,17 +631,17 @@ let DOMApplicationRegistry = {
 
   getAppLocalIdByManifestURL: function(aManifestURL) {
     for (let id in this.webapps) {
       if (this.webapps[id].manifestURL == aManifestURL) {
         return this.webapps[id].localId;
       }
     }
 
-    return 0;
+    return Ci.nsIScriptSecurityManager.NO_APP_ID;
   },
 
   getAllWithoutManifests: function(aCallback) {
     let result = {};
     for (let id in this.webapps) {
       let app = this._cloneAppObject(this.webapps[id]);
       result[id] = app;
     }
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -2960,19 +2960,19 @@ nsGlobalWindow::GetScriptableParent(nsID
 {
   FORWARD_TO_OUTER(GetScriptableParent, (aParent), NS_ERROR_NOT_INITIALIZED);
 
   *aParent = NULL;
   if (!mDocShell) {
     return NS_OK;
   }
 
-  bool isMozBrowser = false;
-  mDocShell->GetIsBrowserFrame(&isMozBrowser);
-  if (isMozBrowser) {
+  bool isContentBoundary = false;
+  mDocShell->GetIsContentBoundary(&isContentBoundary);
+  if (isContentBoundary) {
     nsCOMPtr<nsIDOMWindow> parent = static_cast<nsIDOMWindow*>(this);
     parent.swap(*aParent);
     return NS_OK;
   }
 
   return GetRealParent(aParent);
 }
 
@@ -4562,16 +4562,21 @@ nsGlobalWindow::Dump(const nsAString& aS
   while (c < cEnd) {
     if (*c == '\r')
       *c = '\n';
     c++;
   }
 #endif
 
   if (cstr) {
+#ifdef XP_WIN
+    if (IsDebuggerPresent()) {
+      OutputDebugStringA(cstr);
+    }
+#endif
 #ifdef ANDROID
     __android_log_write(ANDROID_LOG_INFO, "GeckoDump", cstr);
 #endif
     FILE *fp = gDumpFile ? gDumpFile : stdout;
     fputs(cstr, fp);
     fflush(fp);
     nsMemory::Free(cstr);
   }
@@ -6441,22 +6446,23 @@ nsGlobalWindow::CanClose()
   return true;
 }
 
 NS_IMETHODIMP
 nsGlobalWindow::Close()
 {
   FORWARD_TO_OUTER(Close, (), NS_ERROR_NOT_INITIALIZED);
 
-  bool isMozBrowser = false;
+  bool isContentBoundary = false;
   if (mDocShell) {
-    mDocShell->GetIsBrowserFrame(&isMozBrowser);
-  }
-
-  if ((!isMozBrowser && IsFrame()) || !mDocShell || IsInModalState()) {
+    mDocShell->GetIsContentBoundary(&isContentBoundary);
+  }
+
+  if ((!isContentBoundary && IsFrame()) ||
+      !mDocShell || IsInModalState()) {
     // window.close() is called on a frame in a frameset, on a window
     // that's already closed, or on a window for which there's
     // currently a modal dialog open. Ignore such calls.
 
     return NS_OK;
   }
 
   if (mHavePendingClose) {
@@ -6975,19 +6981,19 @@ nsGlobalWindow::GetScriptableFrameElemen
 {
   FORWARD_TO_OUTER(GetScriptableFrameElement, (aFrameElement), NS_ERROR_NOT_INITIALIZED);
   *aFrameElement = NULL;
 
   if (!mDocShell) {
     return NS_OK;
   }
 
-  bool isMozBrowser = false;
-  mDocShell->GetIsBrowserFrame(&isMozBrowser);
-  if (isMozBrowser) {
+  bool isContentBoundary = false;
+  mDocShell->GetIsContentBoundary(&isContentBoundary);
+  if (isContentBoundary) {
     return NS_OK;
   }
 
   return GetFrameElement(aFrameElement);
 }
 
 /**
  * nsIGlobalWindow::GetFrameElement (when called from C++) is just a wrapper
@@ -8171,20 +8177,20 @@ nsGlobalWindow::GetComputedStyle(nsIDOME
 
   nsCOMPtr<nsIPresShell> presShell;
   mDocShell->GetPresShell(getter_AddRefs(presShell));
 
   if (!presShell) {
     return NS_OK;
   }
 
-  nsRefPtr<nsComputedDOMStyle> compStyle;
-  nsresult rv = NS_NewComputedDOMStyle(aElt, aPseudoElt, presShell,
-                                       getter_AddRefs(compStyle));
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsCOMPtr<dom::Element> element = do_QueryInterface(aElt);
+  NS_ENSURE_TRUE(element, NS_ERROR_FAILURE);
+  nsRefPtr<nsComputedDOMStyle> compStyle =
+    NS_NewComputedDOMStyle(element, aPseudoElt, presShell);
 
   *aReturn = compStyle.forget().get();
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsGlobalWindow::GetSessionStorage(nsIDOMStorage ** aSessionStorage)
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -3750,17 +3750,17 @@ SetMemoryGCSliceTimePrefChangedCallback(
 }
 
 static int
 SetMemoryGCPrefChangedCallback(const char* aPrefName, void* aClosure)
 {
   PRInt32 pref = Preferences::GetInt(aPrefName, -1);
   // handle overflow and negative pref values
   if (pref > 0 && pref < 10000)
-    JS_SetGCParameter(nsJSRuntime::sRuntime, (JSGCParamKey)(long)aClosure, pref);
+    JS_SetGCParameter(nsJSRuntime::sRuntime, (JSGCParamKey)(intptr_t)aClosure, pref);
   return 0;
 }
 
 static int
 SetMemoryGCDynamicHeapGrowthPrefChangedCallback(const char* aPrefName, void* aClosure)
 {
   bool pref = Preferences::GetBool(aPrefName);
   JS_SetGCParameter(nsJSRuntime::sRuntime, JSGC_DYNAMIC_HEAP_GROWTH, pref);
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -10,21 +10,24 @@
 #
 # Valid fields for all descriptors:
 #   * nativeType - The native type (concrete class or XPCOM interface) that
 #                  instances of this interface will unwrap to (required).
 #   * 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).
+#                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
 #                their primary interface (defaults to True).
 #   * prefable - Indicates whether this binding is subject to the about:config
 #                pref, or whether it's always enabled (defaults to False).
+#                Cannot be set on external interfaces.
 #   * workers - Indicates whether the descriptor is intended to be used for
 #               worker threads (defaults to false).
 #   * customTrace - The native class will use a custom trace hook (defaults to
 #                   true for workers, false otherwise).
 #   * customFinalize - The native class will use a custom finalize hook
 #                      (defaults to true for workers, false otherwise).
 #   * notflattened - The native type does not have nsIClassInfo, so when
 #                    wrapping it the right IID needs to be passed in.
@@ -50,24 +53,21 @@
 #                         that do not AddRef the return value
 
 DOMInterfaces = {
 
 'Blob': [
 {
     'nativeType': 'nsIDOMBlob',
     'headerFile': 'nsIDOMFile.h',
-    'prefable': True,
-    'castable': False
 },
 {
     'workers': True,
     'nativeType': 'JSObject',
     'headerFile': 'jsapi.h',
-    'castable': False
 }],
 
 '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,
@@ -80,37 +80,31 @@ DOMInterfaces = {
         'mozImageSmoothingEnabled': 'imageSmoothingEnabled',
         'mozFillRule': 'fillRule'
     }
 }],
 
 'Document': [
 {
     'nativeType': 'nsIDocument',
-    'prefable': True,
-    'castable': False
 },
 {
     'workers': True,
     'nativeType': 'JSObject',
     'headerFile': 'jsapi.h',
-    'castable': False
 }],
 
 'Event': [
 {
     'nativeType': 'nsIDOMEvent',
-    'prefable': True,
-    'castable': False
 },
 {
     'workers': True,
     'nativeType': 'JSObject',
     'headerFile': 'jsapi.h',
-    'castable': False
 }],
 
 'EventListener': [
 {
     'nativeType': 'nsIDOMEventListener',
     'prefable': True
 },
 {
@@ -131,66 +125,54 @@ DOMInterfaces = {
     'nativeType': 'mozilla::dom::workers::EventTarget',
     'headerFile': 'mozilla/dom/workers/bindings/EventTarget.h',
     'concrete': False
 }],
 
 'FormData': [
 {
     'nativeType': 'nsIDOMFormData',
-    'prefable': True,
-    'castable': False
 },
 {
     'workers': True,
     'nativeType': 'JSObject',
     'headerFile': 'jsapi.h',
-    'castable': False
 }],
 
 'IID': [
 {
     'nativeType': 'nsIJSIID',
     'headerFile': 'xpcjsid.h',
-    'prefable': True,
-    'castable': False
 },
 {
     'workers': True,
     'nativeType': 'JSObject',
     'headerFile': 'jsapi.h',
-    'castable': False
 }],
 
 'InputStream': [
 {
     'nativeType': 'nsIInputStream',
-    'prefable': True,
-    'castable': False,
     'notflattened': True
 },
 {
     'workers': True,
     'nativeType': 'JSObject',
     'headerFile': 'jsapi.h',
-    'castable': False
 }],
 
 'MozChannel': [
 {
     'nativeType': 'nsIChannel',
-    'prefable': True,
-    'castable': False,
     'notflattened': True
 },
 {
     'workers': True,
     'nativeType': 'JSObject',
     'headerFile': 'jsapi.h',
-    'castable': False
 }],
 
 'Performance': {
     'nativeType': 'nsPerformance',
     'resultNotAddRefed': [ 'timing', 'navigation' ]
 },
 
 'PerformanceTiming': {
@@ -261,16 +243,20 @@ DOMInterfaces = {
 # 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',
                                'receiveWeakNullableCastableObjectSequence',
                                'receiveWeakCastableObjectNullableSequence',
                                'receiveWeakNullableCastableObjectNullableSequence' ],
         'binaryNames': { 'methodRenamedFrom': 'methodRenamedTo',
                          'attributeGetterRenamedFrom': 'attributeGetterRenamedTo',
                          'attributeRenamedFrom': 'attributeRenamedTo' }
         },
@@ -280,36 +266,48 @@ DOMInterfaces = {
         'headerFile': 'TestBindingHeader.h',
         'register': False,
         'castable': False
         },
 
 'TestExternalInterface' : {
         'nativeType': 'mozilla::dom::TestExternalInterface',
         'headerFile': 'TestBindingHeader.h',
-        'register': False,
-        'castable': False
+        '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
+        },
 }
 
 # 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,
-        'castable': False
+        'concrete': False
     }
     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):
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -1831,16 +1831,20 @@ for (uint32_t i = 0; i < length; ++i) {
 
         templateBody = ""
         if descriptor.castable:
             if descriptor.prefable:
                 raise TypeError("We don't support prefable castable object "
                                 "arguments (like %s), because we don't know "
                                 "how to handle them being preffed off" %
                                 descriptor.interface.identifier.name)
+            if descriptor.interface.isConsequential():
+                raise TypeError("Consequential interface %s being used as an "
+                                "argument but flagged as castable" %
+                                descriptor.interface.identifier.name)
             if failureCode is not None:
                 templateBody += str(CastableObjectUnwrapper(
                         descriptor,
                         "&${val}.toObject()",
                         "${declName}",
                         failureCode))
             else:
                 templateBody += str(FailureFatalCastableObjectUnwrapper(
@@ -2359,33 +2363,38 @@ for (uint32_t i = 0; i < length; ++i) {
     if type.isGeckoInterface():
         descriptor = descriptorProvider.getDescriptor(type.unroll().inner.identifier.name)
         if type.nullable():
             wrappingCode = ("if (!%s) {\n" % (result) +
                             CGIndenter(CGGeneric(setValue("JSVAL_NULL"))).define() + "\n" +
                             "}\n")
         else:
             wrappingCode = ""
-        if descriptor.castable and not type.unroll().inner.isExternal():
+        if (not descriptor.interface.isExternal() and
+            not descriptor.interface.isCallback()):
             if descriptor.wrapperCache:
                 wrapMethod = "WrapNewBindingObject"
             else:
                 if not isCreator:
                     raise MethodNotCreatorError(descriptor.interface.identifier.name)
                 wrapMethod = "WrapNewBindingNonWrapperCachedObject"
             wrap = "%s(cx, ${obj}, %s, ${jsvalPtr})" % (wrapMethod, result)
             # We don't support prefable stuff in workers.
             assert(not descriptor.prefable or not descriptor.workers)
             if not descriptor.prefable:
                 # Non-prefable bindings can only fail to wrap as a new-binding object
                 # if they already threw an exception.  Same thing for
                 # non-prefable bindings.
                 failed = ("MOZ_ASSERT(JS_IsExceptionPending(cx));\n" +
                           "return false;")
             else:
+                if descriptor.notflattened:
+                    raise TypeError("%s is prefable but not flattened; "
+                                    "fallback won't work correctly" %
+                                    descriptor.interface.identifier.name)
                 # Try old-style wrapping for bindings which might be preffed off.
                 failed = wrapAndSetPtr("HandleNewBindingWrappingFailure(cx, ${obj}, %s, ${jsvalPtr})" % result)
             wrappingCode += wrapAndSetPtr(wrap, failed)
         else:
             if descriptor.notflattened:
                 getIID = "&NS_GET_IID(%s), " % descriptor.nativeType
             else:
                 getIID = ""
@@ -3058,31 +3067,43 @@ class CGSetterCall(CGGetterSetterCall):
                     "jsval undef = JS::UndefinedValue();\n"
                     "if (argc == 0) {\n"
                     "  argv = &undef;\n"
                     "  argc = 1;\n"
                     "}")
         # We just get our stuff from vp
         return ""
 
+class FakeCastableDescriptor():
+    def __init__(self, descriptor):
+        self.castable = True
+        self.workers = descriptor.workers
+        self.nativeType = descriptor.nativeType
+        self.name = descriptor.name
+
 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.
     """
     def __init__(self, descriptor, name, args):
         CGAbstractStaticMethod.__init__(self, descriptor, name, "JSBool", args)
 
     def definition_body(self):
+        # Our descriptor might claim that we're not castable, simply because
+        # we're someone's consequential interface.  But for this-unwrapping, we
+        # know that we're the real deal.  So fake a descriptor here for
+        # consumption by FailureFatalCastableObjectUnwrapper.
         unwrapThis = CGIndenter(CGGeneric(
-            str(FailureFatalCastableObjectUnwrapper(self.descriptor,
-                                                    "obj", "self"))))
+            str(FailureFatalCastableObjectUnwrapper(
+                        FakeCastableDescriptor(self.descriptor),
+                        "obj", "self"))))
         return CGList([ self.getThis(), unwrapThis,
                         self.generate_code() ], "\n").define()
 
     def getThis(self):
         return CGIndenter(
             CGGeneric("JSObject* obj = JS_THIS_OBJECT(cx, vp);\n"
                       "if (!obj) {\n"
                       "  return false;\n"
@@ -3920,17 +3941,17 @@ class CGDescriptor(CGThing):
             # Always have a finalize hook, regardless of whether the class wants a
             # custom hook.
             cgThings.append(CGClassFinalizeHook(descriptor))
 
             # Only generate a trace hook if the class wants a custom hook.
             if (descriptor.customTrace):
                 cgThings.append(CGClassTraceHook(descriptor))
 
-        if descriptor.concrete or descriptor.interface.hasInterfacePrototypeObject():
+        if descriptor.interface.hasInterfacePrototypeObject():
             cgThings.append(CGNativePropertyHooks(descriptor))
         if descriptor.concrete:
             cgThings.append(CGDOMJSClass(descriptor))
 
         if descriptor.interface.hasInterfaceObject():
             cgThings.append(CGClassConstructHook(descriptor))
             cgThings.append(CGClassHasInstanceHook(descriptor))
             cgThings.append(CGInterfaceObjectJSClass(descriptor))
@@ -3943,18 +3964,17 @@ class CGDescriptor(CGThing):
         cgThings.append(CGCreateInterfaceObjectsMethod(descriptor, properties))
         if descriptor.interface.hasInterfacePrototypeObject():
             cgThings.append(CGIndenter(CGGetProtoObjectMethod(descriptor)))
         else:
             cgThings.append(CGIndenter(CGGetConstructorObjectMethod(descriptor)))
 
         # Set up our Xray callbacks as needed.  Note that we don't need to do
         # it in workers.
-        if ((descriptor.concrete or
-             descriptor.interface.hasInterfacePrototypeObject()) and
+        if (descriptor.interface.hasInterfacePrototypeObject() and
             not descriptor.workers):
             cgThings.append(CGResolveProperty(descriptor, properties))
             cgThings.append(CGEnumerateProperties(descriptor, properties))
 
         if descriptor.interface.hasInterfaceObject():
             cgThings.append(CGDefineDOMInterfaceMethod(descriptor))
 
         if descriptor.concrete:
--- a/dom/bindings/Configuration.py
+++ b/dom/bindings/Configuration.py
@@ -129,31 +129,39 @@ class Descriptor(DescriptorProvider):
         # Read the desc, and fill in the relevant defaults.
         self.nativeType = desc['nativeType']
         self.hasInstanceInterface = desc.get('hasInstanceInterface', None)
 
         headerDefault = self.nativeType
         headerDefault = headerDefault.replace("::", "/") + ".h"
         self.headerFile = desc.get('headerFile', headerDefault)
 
-        castableDefault = not self.interface.isCallback()
-        self.castable = desc.get('castable', castableDefault)
+        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)
 
         # If we're concrete, we need to crawl our ancestor interfaces and mark
         # them as having a concrete descendant.
         self.concrete = desc.get('concrete', True)
         if self.concrete:
             iface = self.interface
             while iface:
                 iface.setUserData('hasConcreteDescendant', True)
                 iface = iface.parent
 
+        if self.interface.isExternal() and 'prefable' in desc:
+            raise TypeError("%s is external but has a prefable setting" %
+                            self.interface.identifier.name)
         self.prefable = desc.get('prefable', False)
 
         self.nativeIsISupports = not self.workers
         self.customTrace = desc.get('customTrace', self.workers)
         self.customFinalize = desc.get('customFinalize', self.workers)
         self.wrapperCache = self.workers or desc.get('wrapperCache', True)
 
         if not self.wrapperCache and self.prefable:
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -572,17 +572,17 @@ class IDLInterface(IDLObjectWithScope):
         return any(m.isConst() for m in self.members)
 
     def hasInterfaceObject(self):
         if self.isCallback():
             return self.hasConstants()
         return not hasattr(self, "_noInterfaceObject")
 
     def hasInterfacePrototypeObject(self):
-        return not self.isCallback()
+        return not self.isCallback() and self.getUserData('hasConcreteDescendant', False)
 
     def addExtendedAttributes(self, attrs):
         self._extendedAttrDict = {}
         for attr in attrs:
             attrlist = list(attr)
             identifier = attrlist.pop(0)
 
             # Special cased attrs
--- a/dom/bindings/test/Makefile.in
+++ b/dom/bindings/test/Makefile.in
@@ -44,33 +44,37 @@ bindinggen_dependencies := \
   ../Configuration.py \
   ../Codegen.py \
   ../parser/WebIDL.py \
   ../ParserResults.pkl \
   ../Makefile \
   $(GLOBAL_DEPS) \
   $(NULL)
 
+# Include rules.mk before any of our targets so our first target is coming from
+# rules.mk and running make with no target in this dir does the right thing.
+include $(topsrcdir)/config/rules.mk
+
 $(CPPSRCS): ../%Binding.cpp: $(bindinggen_dependencies) \
                              ../%.webidl \
                              $(NULL)
 	$(MAKE) -C .. $*Binding.h
 	$(MAKE) -C .. $*Binding.cpp
 
 MOCHITEST_FILES = \
   test_enums.html \
   test_integers.html \
   test_interfaceToString.html \
   test_lookupGetter.html \
   test_InstanceOf.html \
   test_traceProtos.html \
+  test_forOf.html \
+  forOf_iframe.html \
   $(NULL)
 
 
-include $(topsrcdir)/config/rules.mk
-
 check::
 	PYTHONDONTWRITEBYTECODE=1 $(PYTHON) $(topsrcdir)/config/pythonpath.py \
 	  $(PLY_INCLUDE) $(srcdir)/../parser/runtests.py
 
 check-interactive:
 	PYTHONDONTWRITEBYTECODE=1 $(PYTHON) $(topsrcdir)/config/pythonpath.py \
 	  $(PLY_INCLUDE) $(srcdir)/../parser/runtests.py -q
--- a/dom/bindings/test/TestBindingHeader.h
+++ b/dom/bindings/test/TestBindingHeader.h
@@ -30,27 +30,58 @@ class TestNonCastableInterface : public 
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_TEST_NONCASTABLE_INTERFACE_IID)
   NS_DECL_ISUPPORTS
 
   // We need a GetParentObject to make binding codegen happy
   virtual nsISupports* GetParentObject();
 };
 
+// IID for the IndirectlyImplementedInterface
+#define NS_INDIRECTLY_IMPLEMENTED_INTERFACE_IID \
+{ 0xfed55b69, 0x7012, 0x4849, \
+ { 0xaf, 0x56, 0x4b, 0xa9, 0xee, 0x41, 0x30, 0x89 } }
+
+class IndirectlyImplementedInterface : public nsISupports,
+                                       public nsWrapperCache
+{
+public:
+  NS_DECLARE_STATIC_IID_ACCESSOR(NS_INDIRECTLY_IMPLEMENTED_INTERFACE_IID)
+  NS_DECL_ISUPPORTS
+
+  // We need a GetParentObject to make binding codegen happy
+  virtual nsISupports* GetParentObject();
+
+  bool GetIndirectlyImplementedProperty(ErrorResult&);
+  void SetIndirectlyImplementedProperty(bool, ErrorResult&);
+  void IndirectlyImplementedMethod(ErrorResult&);
+};
+
 // IID for the TestExternalInterface
 #define NS_TEST_EXTERNAL_INTERFACE_IID \
 { 0xd5ba0c99, 0x9b1d, 0x4e71, \
  { 0x8a, 0x94, 0x56, 0x38, 0x6c, 0xa3, 0xda, 0x3d } }
 class TestExternalInterface : public nsISupports
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_TEST_EXTERNAL_INTERFACE_IID)
   NS_DECL_ISUPPORTS
 };
 
+// IID for the TestCallbackInterface
+#define NS_TEST_CALLBACK_INTERFACE_IID \
+{ 0xbf711ba4, 0xc8f6, 0x46cf, \
+ { 0xba, 0x5b, 0xaa, 0xe2, 0x78, 0x18, 0xe6, 0x4a } }
+class TestCallbackInterface : public nsISupports
+{
+public:
+  NS_DECLARE_STATIC_IID_ACCESSOR(NS_TEST_CALLBACK_INTERFACE_IID)
+  NS_DECL_ISUPPORTS
+};
+
 class TestNonWrapperCacheInterface : public nsISupports
 {
 public:
   NS_DECL_ISUPPORTS
 
   virtual JSObject* WrapObject(JSContext* cx, JSObject* scope);
 };
 
@@ -197,16 +228,34 @@ public:
   already_AddRefed<TestExternalInterface> GetNonNullExternal(ErrorResult&);
   void SetNonNullExternal(TestExternalInterface*, ErrorResult&);
   already_AddRefed<TestExternalInterface> GetNullableExternal(ErrorResult&);
   void SetNullableExternal(TestExternalInterface*, ErrorResult&);
   void PassOptionalExternal(const Optional<TestExternalInterface*>&, ErrorResult&);
   void PassOptionalNonNullExternal(const Optional<TestExternalInterface*>&, ErrorResult&);
   void PassOptionalExternalWithDefault(TestExternalInterface*, ErrorResult&);
 
+  already_AddRefed<TestCallbackInterface> ReceiveCallbackInterface(ErrorResult&);
+  already_AddRefed<TestCallbackInterface> ReceiveNullableCallbackInterface(ErrorResult&);
+  TestCallbackInterface* ReceiveWeakCallbackInterface(ErrorResult&);
+  TestCallbackInterface* ReceiveWeakNullableCallbackInterface(ErrorResult&);
+  void PassCallbackInterface(TestCallbackInterface&, ErrorResult&);
+  void PassCallbackInterface2(OwningNonNull<TestCallbackInterface>, ErrorResult&);
+  void PassNullableCallbackInterface(TestCallbackInterface*, ErrorResult&);
+  already_AddRefed<TestCallbackInterface> GetNonNullCallbackInterface(ErrorResult&);
+  void SetNonNullCallbackInterface(TestCallbackInterface&, ErrorResult&);
+  already_AddRefed<TestCallbackInterface> GetNullableCallbackInterface(ErrorResult&);
+  void SetNullableCallbackInterface(TestCallbackInterface*, ErrorResult&);
+  void PassOptionalCallbackInterface(const Optional<nsRefPtr<TestCallbackInterface> >&, ErrorResult&);
+  void PassOptionalNonNullCallbackInterface(const Optional<OwningNonNull<TestCallbackInterface> >&, ErrorResult&);
+  void PassOptionalCallbackInterfaceWithDefault(TestCallbackInterface*, ErrorResult&);
+
+  already_AddRefed<IndirectlyImplementedInterface> ReceiveConsequentialInterface(ErrorResult&);
+  void PassConsequentialInterface(IndirectlyImplementedInterface&, ErrorResult&);
+
   // Sequence types
   void ReceiveSequence(nsTArray<int32_t>&, ErrorResult&);
   void ReceiveNullableSequence(Nullable< nsTArray<int32_t> >&, ErrorResult&);
   void ReceiveSequenceOfNullableInts(nsTArray< Nullable<int32_t> >&, ErrorResult&);
   void ReceiveNullableSequenceOfNullableInts(Nullable< nsTArray< Nullable<int32_t> > >&, ErrorResult&);
   void PassSequence(const Sequence<int32_t> &, ErrorResult&);
   void PassNullableSequence(const Nullable< Sequence<int32_t> >&, ErrorResult&);
   void PassSequenceOfNullableInts(const Sequence<Nullable<int32_t> >&, ErrorResult&);
@@ -215,18 +264,16 @@ public:
   void PassOptionalNullableSequenceOfNullableInts(const Optional<Nullable<Sequence<Nullable<int32_t> > > > &,
                                                   ErrorResult&);
   void ReceiveCastableObjectSequence(nsTArray< nsRefPtr<TestInterface> > &,
                                      ErrorResult&);
   void ReceiveNullableCastableObjectSequence(nsTArray< nsRefPtr<TestInterface> > &,
                                              ErrorResult&);
   void ReceiveCastableObjectNullableSequence(Nullable< nsTArray< nsRefPtr<TestInterface> > >&,
                                              ErrorResult&);
-  void ReceiveWeakNullableCastableObjectNullableSequence(Nullable< nsTArray< nsRefPtr<TestInterface> > >&,
-                                                         ErrorResult&);
   void ReceiveNullableCastableObjectNullableSequence(Nullable< nsTArray< nsRefPtr<TestInterface> > >&,
                                              ErrorResult&);
   void ReceiveWeakCastableObjectSequence(nsTArray<TestInterface*> &,
                                          ErrorResult&);
   void ReceiveWeakNullableCastableObjectSequence(nsTArray<TestInterface*> &,
                                                  ErrorResult&);
   void ReceiveWeakCastableObjectNullableSequence(Nullable< nsTArray<TestInterface*> >&,
                                                  ErrorResult&);
--- a/dom/bindings/test/TestCodeGen.webidl
+++ b/dom/bindings/test/TestCodeGen.webidl
@@ -4,16 +4,21 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
 interface TestExternalInterface;
 
 interface TestNonCastableInterface {
 };
 
+callback interface TestCallbackInterface {
+  readonly attribute long foo;
+  void doSomething();
+};
+
 enum TestEnum {
   "a",
   "b"
 };
 
 callback TestCallback = void();
 
 TestInterface implements ImplementedInterface;
@@ -145,16 +150,37 @@ interface TestInterface {
   void passNullableExternal(TestExternalInterface? arg);
   attribute TestExternalInterface nonNullExternal;
   attribute TestExternalInterface? nullableExternal;
   // Optional arguments
   void passOptionalExternal(optional TestExternalInterface? arg);
   void passOptionalNonNullExternal(optional TestExternalInterface arg);
   void passOptionalExternalWithDefault(optional TestExternalInterface? arg = null);
 
+  // Callback interface types
+  TestCallbackInterface receiveCallbackInterface();
+  TestCallbackInterface? receiveNullableCallbackInterface();
+  TestCallbackInterface receiveWeakCallbackInterface();
+  TestCallbackInterface? receiveWeakNullableCallbackInterface();
+  // A verstion to test for casting to TestCallbackInterface&
+  void passCallbackInterface(TestCallbackInterface arg);
+  // A version we can use to test for the exact type passed in
+  void passCallbackInterface2(TestCallbackInterface arg);
+  void passNullableCallbackInterface(TestCallbackInterface? arg);
+  attribute TestCallbackInterface nonNullCallbackInterface;
+  attribute TestCallbackInterface? nullableCallbackInterface;
+  // Optional arguments
+  void passOptionalCallbackInterface(optional TestCallbackInterface? arg);
+  void passOptionalNonNullCallbackInterface(optional TestCallbackInterface arg);
+  void passOptionalCallbackInterfaceWithDefault(optional TestCallbackInterface? arg = null);
+
+  // Miscellaneous interface tests
+  IndirectlyImplementedInterface receiveConsequentialInterface();
+  void passConsequentialInterface(IndirectlyImplementedInterface arg);
+
   // Sequence types
   sequence<long> receiveSequence();
   sequence<long>? receiveNullableSequence();
   sequence<long?> receiveSequenceOfNullableInts();
   sequence<long?>? receiveNullableSequenceOfNullableInts();
   void passSequence(sequence<long> arg);
   void passNullableSequence(sequence<long>? arg);
   void passSequenceOfNullableInts(sequence<long?> arg);
@@ -275,16 +301,17 @@ interface ImplementedInterfaceParent {
   void implementedParentMethod();
   attribute boolean implementedParentProperty;
 
   const long implementedParentConstant = 8;
 };
 
 ImplementedInterfaceParent implements IndirectlyImplementedInterface;
 
+[NoInterfaceObject]
 interface IndirectlyImplementedInterface {
   void indirectlyImplementedMethod();
   attribute boolean indirectlyImplementedProperty;
 
   const long indirectlyImplementedConstant = 9;
 };
 
 interface ImplementedInterface : ImplementedInterfaceParent {
new file mode 100644
--- /dev/null
+++ b/dom/bindings/test/forOf_iframe.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>iframe content for test_forOf_iframe.html</title>
+</head>
+<body>
+  <div id="basket">
+    <span id="egg0"></span>
+    <span id="egg1"><span id="duckling1"></span></span>
+    <span id="egg2"></span>
+  </div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/bindings/test/test_forOf.html
@@ -0,0 +1,94 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=725907
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 725907</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=725907">Mozilla Bug 725907</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<div id="basket">
+  <span id="egg0"></span>
+  <span id="egg1"><span id="duckling1"></span></span>
+  <span id="egg2"></span>
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 725907 **/
+
+function runTestsForDocument(document, msgSuffix) {
+    function is(a, b, msg) { SimpleTest.is(a, b, msg + msgSuffix); }
+    function isnot(a, b, msg) { SimpleTest.isnot(a, b, msg + msgSuffix); }
+
+    var basket = document.getElementById("basket");
+    var egg3 = document.createElement("span");
+    egg3.id = "egg3";
+
+    var log = '';
+    for (var x of basket.childNodes) {
+        if (x.nodeType != x.TEXT_NODE)
+            log += x.id + ";";
+    }
+    is(log, "egg0;egg1;egg2;", "'for (x of div.childNodes)' should iterate over child nodes");
+
+    log = '';
+    for (var x of basket.childNodes) {
+        if (x.nodeType != x.TEXT_NODE) {
+            log += x.id + ";";
+            if (x.id == "egg1")
+                basket.appendChild(egg3);
+        }
+    }
+    is(log, "egg0;egg1;egg2;egg3;", "'for (x of div.childNodes)' should see elements added during iteration");
+
+    var iter1 = basket.childNodes.iterator();
+    var iter2 = basket.childNodes.iterator();
+    isnot(iter1, iter2, "nodelist.iterator() returns a new iterator each time");
+
+    log = '';
+    basket.appendChild(document.createTextNode("some text"));
+    for (var x of basket.children)
+        log += x.id + ";";
+    is(log, "egg0;egg1;egg2;egg3;", "'for (x of div.children)' should iterate over child elements");
+
+    var iter1 = basket.children.iterator();
+    var iter2 = basket.children.iterator();
+    isnot(iter1, iter2, ".iterator() returns a new iterator each time");
+
+    var count = 0;
+    for (var x of document.getElementsByClassName("hazardous-materials"))
+        count++;
+    is(count, 0, "'for (x of emptyNodeList)' loop should run zero times");
+
+    var log = '';
+    for (var x of document.querySelectorAll("span"))
+        log += x.id + ";";
+    is(log, "egg0;egg1;duckling1;egg2;egg3;", "for-of loop should work with a querySelectorAll() NodeList");
+}
+
+/* All the tests run twice. First, in this document, so without any wrappers. */
+runTestsForDocument(document, "");
+
+/* And once using the document of an iframe, so working with cross-compartment wrappers. */
+SimpleTest.waitForExplicitFinish();
+function iframeLoaded(iframe) {
+    runTestsForDocument(iframe.contentWindow.document, " (in iframe)");
+    SimpleTest.finish();
+}
+
+</script>
+
+<iframe src="forOf_iframe.html" onload="iframeLoaded(this)"></iframe>
+
+</pre>
+</body>
+</html>
--- a/dom/bluetooth/Makefile.in
+++ b/dom/bluetooth/Makefile.in
@@ -1,11 +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/.
+# Copyright 2012 Mozilla Foundation and Mozilla contributors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
 
 DEPTH            = ../..
 topsrcdir        = @top_srcdir@
 srcdir           = @srcdir@
 VPATH            = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
--- a/dom/bluetooth/gonk/BluetoothGonkService.cpp
+++ b/dom/bluetooth/gonk/BluetoothGonkService.cpp
@@ -1,13 +1,24 @@
 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
 /* vim: set ts=2 et sw=2 tw=40: */
-/* 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/. */
+/* Copyright 2012 Mozilla Foundation and Mozilla contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 #include "BluetoothGonkService.h"
 #include "BluetoothDBusService.h"
 
 #include "nsDebug.h"
 #include "nsError.h"
 #include <dlfcn.h>
 
--- a/dom/bluetooth/gonk/BluetoothGonkService.h
+++ b/dom/bluetooth/gonk/BluetoothGonkService.h
@@ -1,13 +1,24 @@
 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
 /* vim: set ts=2 et sw=2 tw=40: */
-/* 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/. */
+/* Copyright 2012 Mozilla Foundation and Mozilla contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 #ifndef mozilla_dom_bluetooth_bluetoothgonkservice_h__
 #define mozilla_dom_bluetooth_bluetoothgonkservice_h__
 
 #include "BluetoothCommon.h"
 #include "BluetoothDBusService.h"
 
 BEGIN_BLUETOOTH_NAMESPACE
--- a/dom/bluetooth/gonk/BluetoothGonkServiceFactory.cpp
+++ b/dom/bluetooth/gonk/BluetoothGonkServiceFactory.cpp
@@ -1,13 +1,24 @@
 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
 /* vim: set ts=2 et sw=2 tw=40: */
-/* 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/. */
+/* Copyright 2012 Mozilla Foundation and Mozilla contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 #include "BluetoothGonkService.h"
 
 USING_BLUETOOTH_NAMESPACE
 
 BluetoothService*
 BluetoothService::Create()
 {
--- a/dom/browser-element/BrowserElementChild.js
+++ b/dom/browser-element/BrowserElementChild.js
@@ -1,21 +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/. */
 
 "use strict";
 
-let Cu = Components.utils;
-let Ci = Components.interfaces;
-let Cc = Components.classes;
-let Cr = Components.results;
-
+let { classes: Cc, interfaces: Ci, results: Cr, utils: Cu }  = Components;
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/Geometry.jsm");
 Cu.import("resource://gre/modules/BrowserElementPromptService.jsm");
 
 // Event whitelisted for bubbling.
 let whitelistedEvents = [
   Ci.nsIDOMKeyEvent.DOM_VK_ESCAPE,   // Back button.
   Ci.nsIDOMKeyEvent.DOM_VK_SLEEP,    // Power button.
   Ci.nsIDOMKeyEvent.DOM_VK_CONTEXT_MENU,
   Ci.nsIDOMKeyEvent.DOM_VK_F5,       // Search button.
@@ -57,17 +54,17 @@ function BrowserElementChild() {
 
 BrowserElementChild.prototype = {
   _init: function() {
     debug("Starting up.");
     sendAsyncMsg("hello");
 
     BrowserElementPromptService.mapWindowToBrowserElementChild(content, this);
 
-    docShell.isBrowserFrame = true;
+    docShell.setIsBrowser();
     docShell.QueryInterface(Ci.nsIWebProgress)
             .addProgressListener(this._progressListener,
                                  Ci.nsIWebProgress.NOTIFY_LOCATION |
                                  Ci.nsIWebProgress.NOTIFY_SECURITY |
                                  Ci.nsIWebProgress.NOTIFY_STATE_WINDOW);
 
     // This is necessary to get security web progress notifications.
     var securityUI = Cc['@mozilla.org/secure_browser_ui;1']
@@ -570,8 +567,15 @@ BrowserElementChild.prototype = {
 
     onStatusChange: function(webProgress, request, status, message) {},
     onProgressChange: function(webProgress, request, curSelfProgress,
                                maxSelfProgress, curTotalProgress, maxTotalProgress) {},
   },
 };
 
 var api = new BrowserElementChild();
+
+// FIXME/bug 775438: use a JSM?
+//
+// The code in this included file depends on the |addEventListener|,
+// |addMessageListener|, |content|, |Geometry| and |Services| symbols
+// being "exported" from here.
+#include BrowserElementScrolling.js
--- a/dom/browser-element/BrowserElementParent.js
+++ b/dom/browser-element/BrowserElementParent.js
@@ -131,17 +131,22 @@ function BrowserElementParent(frameLoade
 
   this._mm = frameLoader.messageManager;
 
   // Messages we receive are handed to functions which take a (data) argument,
   // where |data| is the message manager's data object.
 
   let self = this;
   function addMessageListener(msg, handler) {
-    self._mm.addMessageListener('browser-element-api:' + msg, handler.bind(self));
+    function checkedHandler() {
+      if (self._isAlive()) {
+        handler.apply(self, arguments);
+      }
+    }
+    self._mm.addMessageListener('browser-element-api:' + msg, checkedHandler);
   }
 
   addMessageListener("hello", this._recvHello);
   addMessageListener("contextmenu", this._fireCtxMenuEvent);
   addMessageListener("locationchange", this._fireEventFromMsg);
   addMessageListener("loadstart", this._fireEventFromMsg);
   addMessageListener("loadend", this._fireEventFromMsg);
   addMessageListener("titlechange", this._fireEventFromMsg);
@@ -152,35 +157,53 @@ function BrowserElementParent(frameLoade
   addMessageListener("get-mozapp-manifest-url", this._sendMozAppManifestURL);
   addMessageListener("keyevent", this._fireKeyEvent);
   addMessageListener("showmodalprompt", this._handleShowModalPrompt);
   addMessageListener('got-screenshot', this._gotDOMRequestResult);
   addMessageListener('got-can-go-back', this._gotDOMRequestResult);
   addMessageListener('got-can-go-forward', this._gotDOMRequestResult);
 
   function defineMethod(name, fn) {
-    XPCNativeWrapper.unwrap(self._frameElement)[name] = fn.bind(self);
+    XPCNativeWrapper.unwrap(self._frameElement)[name] = function() {
+      if (self._isAlive()) {
+        return fn.apply(self, arguments);
+      }
+    };
   }
 
   function defineDOMRequestMethod(domName, msgName) {
-    XPCNativeWrapper.unwrap(self._frameElement)[domName] = self._sendDOMRequest.bind(self, msgName);
+    XPCNativeWrapper.unwrap(self._frameElement)[domName] = function() {
+      if (self._isAlive()) {
+        return self._sendDOMRequest(msgName);
+      }
+    };
   }
 
   // Define methods on the frame element.
   defineMethod('setVisible', this._setVisible);
   defineMethod('goBack', this._goBack);
   defineMethod('goForward', this._goForward);
   defineMethod('reload', this._reload);
   defineMethod('stop', this._stop);
   defineDOMRequestMethod('getScreenshot', 'get-screenshot');
   defineDOMRequestMethod('getCanGoBack', 'get-can-go-back');
   defineDOMRequestMethod('getCanGoForward', 'get-can-go-forward');
 }
 
 BrowserElementParent.prototype = {
+  /**
+   * You shouldn't touch this._frameElement or this._window if _isAlive is
+   * false.  (You'll likely get an exception if you do.)
+   */
+  _isAlive: function() {
+    return !Cu.isDeadWrapper(this._frameElement) &&
+           !Cu.isDeadWrapper(this._frameElement.ownerDocument) &&
+           !Cu.isDeadWrapper(this._frameElement.ownerDocument.defaultView);
+  },
+
   get _window() {
     return this._frameElement.ownerDocument.defaultView;
   },
 
   _sendAsyncMsg: function(msg, data) {
     this._frameElement.QueryInterface(Ci.nsIFrameLoaderOwner)
                       .frameLoader
                       .messageManager
rename from b2g/chrome/content/webapi.js
rename to dom/browser-element/BrowserElementScrolling.js
--- a/b2g/chrome/content/webapi.js
+++ b/dom/browser-element/BrowserElementScrolling.js
@@ -1,28 +1,19 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
-/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
 /* 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';
-
-dump('======================= webapi.js ======================= \n');
-
-let { classes: Cc, interfaces: Ci, utils: Cu }  = Components;
-Cu.import('resource://gre/modules/XPCOMUtils.jsm');
-Cu.import('resource://gre/modules/Services.jsm');
-Cu.import('resource://gre/modules/Geometry.jsm');
-
 const ContentPanning = {
   init: function cp_init() {
     ['mousedown', 'mouseup', 'mousemove'].forEach(function(type) {
       addEventListener(type, ContentPanning, true);
     });
+
+    addMessageListener("Viewport:Change", this._recvViewportChange.bind(this));
   },
 
   handleEvent: function cp_handleEvent(evt) {
     switch (evt.type) {
       case 'mousedown':
         this.onTouchStart(evt);
         break;
       case 'mousemove':
@@ -119,19 +110,19 @@ const ContentPanning = {
     if (!this.dragging)
       this.scrollCallback = null;
   },
 
   getPannable: function cp_getPannable(node) {
     if (!(node instanceof Ci.nsIDOMHTMLElement) || node.tagName == 'HTML')
       return [null, null];
 
-    let content = node.ownerDocument.defaultView;
+    let nodeContent = node.ownerDocument.defaultView;
     while (!(node instanceof Ci.nsIDOMHTMLBodyElement)) {
-      let style = content.getComputedStyle(node, null);
+      let style = nodeContent.getComputedStyle(node, null);
 
       let overflow = [style.getPropertyValue('overflow'),
                       style.getPropertyValue('overflow-x'),
                       style.getPropertyValue('overflow-y')];
 
       let rect = node.getBoundingClientRect();
       let isAuto = (overflow.indexOf('auto') != -1 &&
                    (rect.height < node.scrollHeight ||
@@ -139,17 +130,23 @@ const ContentPanning = {
 
       let isScroll = (overflow.indexOf('scroll') != -1);
       if (isScroll || isAuto)
         return [node, this._generateCallback(node)];
 
       node = node.parentNode;
     }
 
-    return [content, this._generateCallback(content)];
+    if (ContentPanning._asyncPanZoomForViewportFrame &&
+        nodeContent === content)
+      // The parent context is asynchronously panning and zooming our
+      // root scrollable frame, so don't use our synchronous fallback.
+      return [null, null];
+
+    return [nodeContent, this._generateCallback(nodeContent)];
   },
 
   _generateCallback: function cp_generateCallback(content) {
     function scroll(delta) {
       if (content instanceof Ci.nsIDOMHTMLElement) {
         let oldX = content.scrollLeft, oldY = content.scrollTop;
         content.scrollLeft += delta.x;
         content.scrollTop += delta.y;
@@ -171,16 +168,49 @@ const ContentPanning = {
                               .getService(Ci.inIDOMUtils);
   },
 
   _resetActive: function cp_resetActive() {
     let root = this.target.ownerDocument || this.target.document;
 
     const kStateActive = 0x00000001;
     this._domUtils.setContentState(root.documentElement, kStateActive);
+  },
+
+  get _asyncPanZoomForViewportFrame() {
+    return docShell.asyncPanZoomEnabled;
+  },
+
+  _recvViewportChange: function(data) {
+    let viewport = data.json;
+    let displayPort = viewport.displayPort;
+
+    let screenWidth = viewport.screenSize.width;
+    let screenHeight = viewport.screenSize.height;
+
+    let x = viewport.x;
+    let y = viewport.y;
+
+    let cwu = content.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
+    cwu.setCSSViewport(screenWidth, screenHeight);
+
+    // Set scroll position
+    cwu.setScrollPositionClampingScrollPortSize(
+      screenWidth / viewport.zoom, screenHeight / viewport.zoom);
+    content.scrollTo(x, y);
+    cwu.setResolution(displayPort.resolution, displayPort.resolution);
+
+    let element = null;
+    if (content.document && (element = content.document.documentElement)) {
+      cwu.setDisplayPortForElement(displayPort.left,
+                                   displayPort.top,
+                                   displayPort.width,
+                                   displayPort.height,
+                                   element);
+    }
   }
 };
 
 ContentPanning.init();
 
 // Min/max velocity of kinetic panning. This is in pixels/millisecond.
 const kMinVelocity = 0.4;
 const kMaxVelocity = 6;
@@ -344,9 +374,8 @@ const KineticPanning = {
       }
 
       content.mozRequestAnimationFrame(callback);
     }).bind(this);
 
     content.mozRequestAnimationFrame(callback);
   }
 };
-
--- a/dom/imptests/writeMakefile.py
+++ b/dom/imptests/writeMakefile.py
@@ -12,25 +12,23 @@ topsrcdir = @top_srcdir@
 srcdir = @srcdir@
 VPATH = @srcdir@
 relativesrcdir = ${relativesrcdir}
 
 DIRS = \\
 ${dirs}
 
 include $$(DEPTH)/config/autoconf.mk
-include $$(topsrcdir)/config/rules.mk
 """
 
 filesTemplate = """
-_FILES = \\
+MOCHITEST_FILES := \\
 ${files}
 
-libs:: $$(_FILES)
-\t$$(INSTALL) $$(foreach f,$$^,"$$f") $$(DEPTH)/_tests/testing/mochitest/tests/$$(relativesrcdir)
+include $$(topsrcdir)/config/rules.mk
 """
 
 def makefileString(entries):
   if not len(entries):
     return "  $(NULL)"
   return "\n".join(["  %s \\" % (entry, ) for entry in entries]) + "\n  $(NULL)"
 
 def substMakefile(caller, path, subdirs, files):
--- a/dom/interfaces/apps/nsIAppsService.idl
+++ b/dom/interfaces/apps/nsIAppsService.idl
@@ -10,14 +10,21 @@ interface mozIDOMApplication;
 #define APPS_SERVICE_CID { 0x05072afa, 0x92fe, 0x45bf, { 0xae, 0x22, 0x39, 0xb6, 0x9c, 0x11, 0x70, 0x58 } }
 #define APPS_SERVICE_CONTRACTID "@mozilla.org/AppsService;1"
 %}
 
 /*
  * This service allows accessing some DOMApplicationRegistry methods from
  * non-javascript code.
  */
-[scriptable, uuid(40e580e7-8891-4eb8-b514-0b5796af4df1)]
+[scriptable, uuid(1210a0f3-add3-4381-b892-9c102e3afc42)]
 interface nsIAppsService : nsISupports
 {
   mozIDOMApplication getAppByManifestURL(in DOMString manifestURL);
+
+  /**
+   * Returns the |localId| of the app associated with the |manifestURL| passed
+   * in parameter.
+   * Returns nsIScriptSecurityManager::NO_APP_ID if |manifestURL| isn't a valid
+   * installed manifest URL.
+   */
   unsigned long getAppLocalIdByManifestURL(in DOMString manifestURL);
 };
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -8,28 +8,33 @@
 include protocol PContent;
 include protocol PContentDialog;
 include protocol PDocumentRenderer;
 include protocol PContentPermissionRequest;
 include protocol PRenderFrame;
 include protocol POfflineCacheUpdate;
 include protocol PIndexedDB;
 
+include "gfxMatrix.h";
+include "IPC/nsGUIEventIPC.h";
 include "mozilla/dom/TabMessageUtils.h";
-include "gfxMatrix.h";
+include "mozilla/layout/RenderFrameUtils.h";
 include "mozilla/net/NeckoMessageUtils.h";
-include "IPC/nsGUIEventIPC.h";
 
 using IPC::URI;
 using gfxMatrix;
+using gfxSize;
 using mozilla::layers::LayersBackend;
+using mozilla::layout::ScrollingBehavior;
 using mozilla::WindowsHandle;
 using nscolor;
 using nsCompositionEvent;
 using nsIMEUpdatePreference;
+using nsIntPoint;
+using nsIntRect;
 using nsIntSize;
 using nsKeyEvent;
 using nsMouseEvent;
 using nsMouseScrollEvent;
 using nsQueryContentEvent;
 using nsRect;
 using nsSelectionEvent;
 using nsTextEvent;
@@ -171,17 +176,18 @@ parent:
     PContentDialog(PRUint32 aType, nsCString aName, nsCString aFeatures,
                    PRInt32[] aIntParams, nsString[] aStringParams);
 
     /**
      * Create a layout frame (encapsulating a remote layer tree) for
      * the page that is currently loaded in the <browser>.
      */
     sync PRenderFrame()
-        returns (LayersBackend backend, int32_t maxTextureSize, uint64_t layersId);
+        returns (ScrollingBehavior scrolling,
+                 LayersBackend backend, int32_t maxTextureSize, uint64_t layersId);
 
     /** 
      * Starts an offline application cache update.
      * @param manifestURI
      *   URI of the manifest to fetch, the application cache group ID
      * @param documentURI
      *   URI of the document that referred the manifest
      * @param clientID
@@ -236,16 +242,21 @@ child:
      * point.
      */
     Show(nsIntSize size);
 
     LoadURL(nsCString uri);
 
     UpdateDimensions(nsRect rect, nsIntSize size);
 
+    UpdateFrame(nsIntRect displayPort,
+                nsIntPoint scrollOffset,
+                gfxSize resolution,
+                nsIntRect screenSize);
+
     /**
      * Sending an activate message moves focus to the child.
      */
     Activate();
 
     Deactivate();
 
     /**
--- a/dom/ipc/PCOMContentPermissionRequestChild.h
+++ b/dom/ipc/PCOMContentPermissionRequestChild.h
@@ -7,20 +7,29 @@
 
 #include "mozilla/dom/PContentPermissionRequestChild.h"
 // Microsoft's API Name hackery sucks
 #undef CreateEvent
 
 /*
   PContentPermissionRequestChild implementations also are
   XPCOM objects.  Addref() is called on their implementation
-  before SendPCOntentPermissionRequestConstructor is called.
+  before SendPContentPermissionRequestConstructor is called.
   When Dealloc is called, IPDLRelease() is called.
   Implementations of this method are expected to call
   Release() on themselves.  See Bug 594261 for more
   information.
  */
 class PCOMContentPermissionRequestChild : public mozilla::dom::PContentPermissionRequestChild {
 public:
   virtual void IPDLRelease() = 0;
+#ifdef DEBUG
+  PCOMContentPermissionRequestChild() : mIPCOpen(false) {}
+  virtual ~PCOMContentPermissionRequestChild() {
+    // mIPCOpen is set to true in TabChild::SendPContentPermissionRequestConstructor
+    // and set to false in TabChild::DeallocPContentPermissionRequest
+    MOZ_ASSERT(!mIPCOpen, "Protocol must not be open when PCOMContentPermissionRequestChild is destroyed.");
+  }
+  bool mIPCOpen;
+#endif /* DEBUG */
 };
 
 #endif
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -47,16 +47,17 @@
 #include "nsIWebBrowserFocus.h"
 #include "nsIWebBrowserSetup.h"
 #include "nsIWebProgress.h"
 #include "nsIXPCSecurityManager.h"
 #include "nsInterfaceHashtable.h"
 #include "nsPIDOMWindow.h"
 #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 "TabChild.h"
 #include "xpcpublic.h"
 
@@ -332,22 +333,22 @@ TabChild::ProvideWindow(nsIDOMWindow* aP
                         nsIDOMWindow** aReturn)
 {
     *aReturn = nsnull;
 
     // If aParent is inside an <iframe mozbrowser> and this isn't a request to
     // open a modal-type window, we're going to create a new <iframe mozbrowser>
     // and return its window here.
     nsCOMPtr<nsIDocShell> docshell = do_GetInterface(aParent);
-    bool inBrowserFrame = false;
+    bool isInContentBoundary = false;
     if (docshell) {
-      docshell->GetContainedInBrowserFrame(&inBrowserFrame);
+      docshell->GetIsBelowContentBoundary(&isInContentBoundary);
     }
 
-    if (inBrowserFrame &&
+    if (isInContentBoundary &&
         !(aChromeFlags & (nsIWebBrowserChrome::CHROME_MODAL |
                           nsIWebBrowserChrome::CHROME_OPENAS_DIALOG |
                           nsIWebBrowserChrome::CHROME_OPENAS_CHROME))) {
 
       // Note that BrowserFrameProvideWindow may return NS_ERROR_ABORT if the
       // open window call was canceled.  It's important that we pass this error
       // code back to our caller.
       return BrowserFrameProvideWindow(aParent, aURI, aName, aFeatures,
@@ -621,16 +622,47 @@ TabChild::RecvUpdateDimensions(const nsR
     nsCOMPtr<nsIBaseWindow> baseWin = do_QueryInterface(mWebNav);
     baseWin->SetPositionAndSize(0, 0, size.width, size.height,
                                 true);
 
     return true;
 }
 
 bool
+TabChild::RecvUpdateFrame(const nsIntRect& aDisplayPort,
+                          const nsIntPoint& aScrollOffset,
+                          const gfxSize& aResolution,
+                          const nsIntRect& aScreenSize)
+{
+    nsCString data;
+    data += nsPrintfCString("{ \"x\" : %d", aScrollOffset.x);
+    data += nsPrintfCString(", \"y\" : %d", aScrollOffset.y);
+    // We don't treat the x and y scales any differently for this
+    // semi-platform-specific code.
+    data += nsPrintfCString(", \"zoom\" : %f", aResolution.width);
+    data += nsPrintfCString(", \"displayPort\" : ");
+        data += nsPrintfCString("{ \"left\" : %d", aDisplayPort.X());
+        data += nsPrintfCString(", \"top\" : %d", aDisplayPort.Y());
+        data += nsPrintfCString(", \"width\" : %d", aDisplayPort.Width());
+        data += nsPrintfCString(", \"height\" : %d", aDisplayPort.Height());
+        data += nsPrintfCString(", \"resolution\" : %f", aResolution.width);
+        data += nsPrintfCString(" }");
+    data += nsPrintfCString(", \"screenSize\" : ");
+        data += nsPrintfCString("{ \"width\" : %d", aScreenSize.width);
+        data += nsPrintfCString(", \"height\" : %d", aScreenSize.height);
+        data += nsPrintfCString(" }");
+    data += nsPrintfCString(" }");
+
+    // Let the BrowserElementScrolling helper (if it exists) for this
+    // content manipulate the frame state.
+    return RecvAsyncMessage(NS_LITERAL_STRING("Viewport:Change"),
+                            NS_ConvertUTF8toUTF16(data));
+}
+
+bool
 TabChild::RecvActivate()
 {
   nsCOMPtr<nsIWebBrowserFocus> browser = do_QueryInterface(mWebNav);
   browser->Activate();
   return true;
 }
 
 bool TabChild::RecvDeactivate()
@@ -852,17 +884,22 @@ TabChild::AllocPContentPermissionRequest
 {
   NS_RUNTIMEABORT("unused");
   return nsnull;
 }
 
 bool
 TabChild::DeallocPContentPermissionRequest(PContentPermissionRequestChild* actor)
 {
-    static_cast<PCOMContentPermissionRequestChild*>(actor)->IPDLRelease();
+    PCOMContentPermissionRequestChild* child =
+        static_cast<PCOMContentPermissionRequestChild*>(actor);
+#ifdef DEBUG
+    child->mIPCOpen = false;
+#endif /* DEBUG */
+    child->IPDLRelease();
     return true;
 }
 
 bool
 TabChild::RecvActivateFrameEvent(const nsString& aType, const bool& capture)
 {
   nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(mWebNav);
   NS_ENSURE_TRUE(window, true);
@@ -957,17 +994,18 @@ TabChild::RecvDestroy()
 
   // XXX what other code in ~TabChild() should we be running here?
   DestroyWindow();
 
   return Send__delete__(this);
 }
 
 PRenderFrameChild*
-TabChild::AllocPRenderFrame(LayersBackend* aBackend,
+TabChild::AllocPRenderFrame(ScrollingBehavior* aScrolling,
+                            LayersBackend* aBackend,
                             int32_t* aMaxTextureSize,
                             uint64_t* aLayersId)
 {
     return new RenderFrameChild();
 }
 
 bool
 TabChild::DeallocPRenderFrame(PRenderFrameChild* aFrame)
@@ -1030,17 +1068,17 @@ TabChild::InitWidget(const nsIntSize& si
         nsnull                  // nsDeviceContext
         );
 
     LayersBackend be;
     uint64_t id;
     int32_t maxTextureSize;
     RenderFrameChild* remoteFrame =
         static_cast<RenderFrameChild*>(SendPRenderFrameConstructor(
-                                           &be, &maxTextureSize, &id));
+                                           &mScrolling, &be, &maxTextureSize, &id));
     if (!remoteFrame) {
       NS_WARNING("failed to construct RenderFrame");
       return false;
     }
 
     PLayersChild* shadowManager = nsnull;
     if (id != 0) {
         // Pushing layers transactions directly to a separate
@@ -1093,16 +1131,22 @@ TabChild::NotifyPainted()
         // thread in the parent process.  It's wasteful but won't
         // result in unnecessary repainting or even composites
         // (usually, unless timing is unlucky), since they're
         // throttled.
         mRemoteFrame->SendNotifyCompositorTransaction();
     }
 }
 
+bool
+TabChild::IsAsyncPanZoomEnabled()
+{
+    return mScrolling == ASYNC_PAN_ZOOM;
+}
+
 NS_IMETHODIMP
 TabChild::GetMessageManager(nsIContentFrameMessageManager** aResult)
 {
   if (mTabChildGlobal) {
     NS_ADDREF(*aResult = mTabChildGlobal);
     return NS_OK;
   }
   *aResult = nsnull;
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -5,16 +5,19 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_TabChild_h
 #define mozilla_dom_TabChild_h
 
 #ifndef _IMPL_NS_LAYOUT
 #include "mozilla/dom/PBrowserChild.h"
 #endif
+#ifdef DEBUG
+#include "PCOMContentPermissionRequestChild.h"
+#endif /* DEBUG */
 #include "nsIWebNavigation.h"
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
 #include "nsIWebBrowserChrome2.h"
 #include "nsIEmbeddingSiteWindow.h"
 #include "nsIWebBrowserChromeFocus.h"
 #include "nsIWidget.h"
 #include "nsIDOMEventListener.h"
@@ -35,16 +38,17 @@
 #include "nsIScriptContext.h"
 #include "nsDOMEventTargetHelper.h"
 #include "nsIDialogCreator.h"
 #include "nsIDialogParamBlock.h"
 #include "nsIPresShell.h"
 #include "nsIPrincipal.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsIScriptContext.h"
+#include "nsPIDOMWindow.h"
 #include "nsWeakReference.h"
 #include "nsITabChild.h"
 #include "mozilla/Attributes.h"
 
 struct gfxMatrix;
 
 namespace mozilla {
 namespace layout {
@@ -158,16 +162,20 @@ public:
     NS_DECL_NSIINTERFACEREQUESTOR
     NS_DECL_NSIWINDOWPROVIDER
     NS_DECL_NSIDIALOGCREATOR
     NS_DECL_NSITABCHILD
 
     virtual bool RecvLoadURL(const nsCString& uri);
     virtual bool RecvShow(const nsIntSize& size);
     virtual bool RecvUpdateDimensions(const nsRect& rect, const nsIntSize& size);
+    virtual bool RecvUpdateFrame(const nsIntRect& aDisplayPort,
+                                      const nsIntPoint& aScrollOffset,
+                                      const gfxSize& aResolution,
+                                      const nsIntRect& aScreenSize);
     virtual bool RecvActivate();
     virtual bool RecvDeactivate();
     virtual bool RecvMouseEvent(const nsString& aType,
                                 const float&    aX,
                                 const float&    aY,
                                 const PRInt32&  aButton,
                                 const PRInt32&  aClickCount,
                                 const PRInt32&  aModifiers,
@@ -211,16 +219,28 @@ public:
     virtual bool DeallocPContentDialog(PContentDialogChild* aDialog);
     static void ParamsToArrays(nsIDialogParamBlock* aParams,
                                InfallibleTArray<int>& aIntParams,
                                InfallibleTArray<nsString>& aStringParams);
     static void ArraysToParams(const InfallibleTArray<int>& aIntParams,
                                const InfallibleTArray<nsString>& aStringParams,
                                nsIDialogParamBlock* aParams);
 
+#ifdef DEBUG
+    virtual PContentPermissionRequestChild* SendPContentPermissionRequestConstructor(PContentPermissionRequestChild* aActor,
+                                                                                     const nsCString& aType,
+                                                                                     const URI& aUri)
+    {
+      PCOMContentPermissionRequestChild* child = static_cast<PCOMContentPermissionRequestChild*>(aActor);
+      PContentPermissionRequestChild* request = PBrowserChild::SendPContentPermissionRequestConstructor(aActor, aType, aUri);
+      child->mIPCOpen = true;
+      return request;
+    }
+#endif /* DEBUG */
+
     virtual PContentPermissionRequestChild* AllocPContentPermissionRequest(const nsCString& aType, const IPC::URI& uri);
     virtual bool DeallocPContentPermissionRequest(PContentPermissionRequestChild* actor);
 
     virtual POfflineCacheUpdateChild* AllocPOfflineCacheUpdate(const URI& manifestURI,
             const URI& documentURI,
             const nsCString& clientID,
             const bool& stickDocument);
     virtual bool DeallocPOfflineCacheUpdate(POfflineCacheUpdateChild* offlineCacheUpdate);
@@ -229,19 +249,23 @@ public:
 
     JSContext* GetJSContext() { return mCx; }
 
     nsIPrincipal* GetPrincipal() { return mPrincipal; }
 
     void SetBackgroundColor(const nscolor& aColor);
 
     void NotifyPainted();
+
+    bool IsAsyncPanZoomEnabled();
+
 protected:
     NS_OVERRIDE
-    virtual PRenderFrameChild* AllocPRenderFrame(LayersBackend* aBackend,
+    virtual PRenderFrameChild* AllocPRenderFrame(ScrollingBehavior* aScrolling,
+                                                 LayersBackend* aBackend,
                                                  int32_t* aMaxTextureSize,
                                                  uint64_t* aLayersId);
     NS_OVERRIDE
     virtual bool DeallocPRenderFrame(PRenderFrameChild* aFrame);
     NS_OVERRIDE
     virtual bool RecvDestroy();
 
     nsEventStatus DispatchWidgetEvent(nsGUIEvent& event);
@@ -273,16 +297,17 @@ private:
 
     nsCOMPtr<nsIWebNavigation> mWebNav;
     nsCOMPtr<nsIWidget> mWidget;
     RenderFrameChild* mRemoteFrame;
     nsRefPtr<TabChildGlobal> mTabChildGlobal;
     PRUint32 mChromeFlags;
     nsIntRect mOuterRect;
     nscolor mLastBackgroundColor;
+    ScrollingBehavior mScrolling;
     bool mDidFakeShow;
     bool mIsBrowserFrame;
 
     DISALLOW_EVIL_CONSTRUCTORS(TabChild);
 };
 
 inline TabChild*
 GetTabChildFrom(nsIDocShell* aDocShell)
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -1,54 +1,58 @@
 /* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8; -*- */
 /* vim: set sw=2 ts=8 et tw=80 : */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "TabParent.h"
+#include "base/basictypes.h"
 
+#include "IDBFactory.h"
+#include "IndexedDBParent.h"
+#include "mozilla/BrowserElementParent.h"
+#include "mozilla/docshell/OfflineCacheUpdateParent.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/ipc/DocumentRendererParent.h"
+#include "mozilla/layers/CompositorParent.h"
 #include "mozilla/layout/RenderFrameParent.h"
-#include "mozilla/docshell/OfflineCacheUpdateParent.h"
-
-#include "nsIURI.h"
+#include "mozilla/Preferences.h"
+#include "mozilla/unused.h"
+#include "nsCOMPtr.h"
+#include "nsContentPermissionHelper.h"
+#include "nsContentUtils.h"
+#include "nsDebug.h"
+#include "nsEventDispatcher.h"
 #include "nsFocusManager.h"
-#include "nsCOMPtr.h"
-#include "nsServiceManagerUtils.h"
+#include "nsFrameLoader.h"
+#include "nsIContent.h"
 #include "nsIDOMElement.h"
-#include "nsEventDispatcher.h"
+#include "nsIDOMEvent.h"
 #include "nsIDOMEventTarget.h"
-#include "nsIWindowWatcher.h"
+#include "nsIDOMHTMLFrameElement.h"
 #include "nsIDOMWindow.h"
-#include "nsPIDOMWindow.h"
-#include "TabChild.h"
-#include "nsIDOMEvent.h"
-#include "nsFrameLoader.h"
+#include "nsIDialogCreator.h"
+#include "nsIPromptFactory.h"
+#include "nsIURI.h"
+#include "nsIMozBrowserFrame.h"
+#include "nsIViewManager.h"
+#include "nsIWidget.h"
+#include "nsIWindowWatcher.h"
 #include "nsNetUtil.h"
-#include "nsContentUtils.h"
-#include "nsContentPermissionHelper.h"
-#include "nsIDOMHTMLFrameElement.h"
-#include "nsIDialogCreator.h"
-#include "nsThreadUtils.h"
+#include "nsPIDOMWindow.h"
+#include "nsPrintfCString.h"
 #include "nsSerializationHelper.h"
-#include "nsIPromptFactory.h"
-#include "nsIContent.h"
-#include "nsIWidget.h"
-#include "nsIViewManager.h"
-#include "mozilla/unused.h"
-#include "nsDebug.h"
-#include "nsPrintfCString.h"
-#include "mozilla/BrowserElementParent.h"
-#include "IndexedDBParent.h"
-#include "IDBFactory.h"
+#include "nsServiceManagerUtils.h"
+#include "nsThreadUtils.h"
+#include "TabChild.h"
+#include "TabParent.h"
 
 using namespace mozilla::dom;
 using namespace mozilla::ipc;
+using namespace mozilla::layers;
 using namespace mozilla::layout;
 using namespace mozilla::widget;
 using namespace mozilla::dom::indexedDB;
 
 // The flags passed by the webProgress notifications are 16 bits shifted
 // from the ones registered by webProgressListeners.
 #define NOTIFY_FLAG_SHIFT 16
 
@@ -87,20 +91,18 @@ TabParent::SetOwnerElement(nsIDOMElement
 void
 TabParent::Destroy()
 {
   // If this fails, it's most likely due to a content-process crash,
   // and auto-cleanup will kick in.  Otherwise, the child side will
   // destroy itself and send back __delete__().
   unused << SendDestroy();
 
-  for (size_t i = 0; i < ManagedPRenderFrameParent().Length(); ++i) {
-    RenderFrameParent* rfp =
-      static_cast<RenderFrameParent*>(ManagedPRenderFrameParent()[i]);
-    rfp->Destroy();
+  if (RenderFrameParent* frame = GetRenderFrame()) {
+    frame->Destroy();
   }
 }
 
 bool
 TabParent::Recv__delete__()
 {
   ContentParent* cp = static_cast<ContentParent*>(Manager());
   cp->NotifyTabDestroyed(this);
@@ -198,17 +200,29 @@ TabParent::Show(const nsIntSize& size)
     // sigh
     mShown = true;
     unused << SendShow(size);
 }
 
 void
 TabParent::UpdateDimensions(const nsRect& rect, const nsIntSize& size)
 {
-    unused << SendUpdateDimensions(rect, size);
+  unused << SendUpdateDimensions(rect, size);
+  if (RenderFrameParent* rfp = GetRenderFrame()) {
+    rfp->NotifyDimensionsChanged(size.width, size.height);
+  }
+}
+
+void
+TabParent::UpdateFrame(const FrameMetrics& aFrameMetrics)
+{
+  unused << SendUpdateFrame(aFrameMetrics.mDisplayPort,
+                            aFrameMetrics.mViewportScrollOffset,
+                            aFrameMetrics.mResolution,
+                            aFrameMetrics.mViewport);
 }
 
 void
 TabParent::Activate()
 {
     mActive = true;
     unused << SendActivate();
 }
@@ -297,32 +311,40 @@ TabParent::SendKeyEvent(const nsAString&
                         bool aPreventDefault)
 {
   unused << PBrowserParent::SendKeyEvent(nsString(aType), aKeyCode, aCharCode,
                                          aModifiers, aPreventDefault);
 }
 
 bool TabParent::SendRealMouseEvent(nsMouseEvent& event)
 {
-  return PBrowserParent::SendRealMouseEvent(event);
+  nsMouseEvent e(event);
+  MaybeForwardEventToRenderFrame(event, &e);
+  return PBrowserParent::SendRealMouseEvent(e);
 }
 
 bool TabParent::SendMouseScrollEvent(nsMouseScrollEvent& event)
 {
-  return PBrowserParent::SendMouseScrollEvent(event);
+  nsMouseScrollEvent e(event);
+  MaybeForwardEventToRenderFrame(event, &e);
+  return PBrowserParent::SendMouseScrollEvent(e);
 }
 
 bool TabParent::SendRealKeyEvent(nsKeyEvent& event)
 {
-  return PBrowserParent::SendRealKeyEvent(event);
+  nsKeyEvent e(event);
+  MaybeForwardEventToRenderFrame(event, &e);
+  return PBrowserParent::SendRealKeyEvent(e);
 }
 
 bool TabParent::SendRealTouchEvent(nsTouchEvent& event)
 {
-  return PBrowserParent::SendRealTouchEvent(event);
+  nsTouchEvent e(event);
+  MaybeForwardEventToRenderFrame(event, &e);
+  return PBrowserParent::SendRealTouchEvent(e);
 }
 
 bool
 TabParent::RecvSyncMessage(const nsString& aMessage,
                            const nsString& aJSON,
                            InfallibleTArray<nsString>* aJSONRetVal)
 {
   return ReceiveMessage(aMessage, true, aJSON, aJSONRetVal);
@@ -343,20 +365,18 @@ TabParent::RecvSetCursor(const PRUint32&
     widget->SetCursor((nsCursor) aCursor);
   }
   return true;
 }
 
 bool
 TabParent::RecvSetBackgroundColor(const nscolor& aColor)
 {
-  if (nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader()) {
-    if (RenderFrameParent* frame = frameLoader->GetCurrentRemoteFrame()) {
-      frame->SetBackgroundColor(aColor);
-    }
+  if (RenderFrameParent* frame = GetRenderFrame()) {
+    frame->SetBackgroundColor(aColor);
   }
   return true;
 }
 
 bool
 TabParent::RecvNotifyIMEFocus(const bool& aFocus,
                               nsIMEUpdatePreference* aPreference,
                               PRUint32* aSeqno)
@@ -552,16 +572,25 @@ TabParent::GetFrom(nsIContent* aContent)
   nsCOMPtr<nsIFrameLoaderOwner> loaderOwner = do_QueryInterface(aContent);
   if (!loaderOwner) {
     return nsnull;
   }
   nsRefPtr<nsFrameLoader> frameLoader = loaderOwner->GetFrameLoader();
   return GetFrom(frameLoader);
 }
 
+RenderFrameParent*
+TabParent::GetRenderFrame()
+{
+  if (ManagedPRenderFrameParent().IsEmpty()) {
+    return nsnull;
+  }
+  return static_cast<RenderFrameParent*>(ManagedPRenderFrameParent()[0]);
+}
+
 bool
 TabParent::RecvEndIMEComposition(const bool& aCancel,
                                  nsString* aComposition)
 {
   nsCOMPtr<nsIWidget> widget = GetWidget();
   if (!widget)
     return true;
 
@@ -841,22 +870,27 @@ TabParent::HandleDelayedDialogs()
   if (ShouldDelayDialogs() && mDelayedDialogs.Length()) {
     nsContentUtils::DispatchTrustedEvent(frame->OwnerDoc(), frame,
                                          NS_LITERAL_STRING("MozDelayedModalDialog"),
                                          true, true);
   }
 }
 
 PRenderFrameParent*
-TabParent::AllocPRenderFrame(LayersBackend* aBackend,
+TabParent::AllocPRenderFrame(ScrollingBehavior* aScrolling,
+                             LayersBackend* aBackend,
                              int32_t* aMaxTextureSize,
                              uint64_t* aLayersId)
 {
+  MOZ_ASSERT(ManagedPRenderFrameParent().IsEmpty());
+
   nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
+  *aScrolling = UseAsyncPanZoom() ? ASYNC_PAN_ZOOM : DEFAULT_SCROLLING;
   return new RenderFrameParent(frameLoader,
+                               *aScrolling,
                                aBackend, aMaxTextureSize, aLayersId);
 }
 
 bool
 TabParent::DeallocPRenderFrame(PRenderFrameParent* aFrame)
 {
   delete aFrame;
   return true;
@@ -956,16 +990,50 @@ TabParent::GetWidget() const
   if (!frame)
     return nsnull;
 
   nsCOMPtr<nsIWidget> widget = frame->GetNearestWidget();
   return widget.forget();
 }
 
 bool
+TabParent::IsForMozBrowser()
+{
+  nsCOMPtr<nsIContent> content = do_QueryInterface(mFrameElement);
+  nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(content);
+  if (browserFrame) {
+    bool isBrowser = false;
+    browserFrame->GetReallyIsBrowser(&isBrowser);
+    return isBrowser;
+  }
+  return false;
+}
+
+bool
+TabParent::UseAsyncPanZoom()
+{
+  bool usingOffMainThreadCompositing = !!CompositorParent::CompositorLoop();
+  bool asyncPanZoomEnabled =
+    Preferences::GetBool("layers.async-pan-zoom.enabled", false);
+  ContentParent* cp = static_cast<ContentParent*>(Manager());
+  return (usingOffMainThreadCompositing &&
+          !cp->IsForApp() && IsForMozBrowser() &&
+          asyncPanZoomEnabled);
+}
+
+void
+TabParent::MaybeForwardEventToRenderFrame(const nsInputEvent& aEvent,
+                                          nsInputEvent* aOutEvent)
+{
+  if (RenderFrameParent* rfp = GetRenderFrame()) {
+    rfp->NotifyInputEvent(aEvent, aOutEvent);
+  }
+}
+
+bool
 TabParent::RecvBrowserFrameOpenWindow(PBrowserParent* aOpener,
                                       const nsString& aURL,
                                       const nsString& aName,
                                       const nsString& aFeatures,
                                       bool* aOutWindowOpened)
 {
   *aOutWindowOpened =
     BrowserElementParent::OpenWindowOOP(static_cast<TabParent*>(aOpener),
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -24,16 +24,25 @@
 struct gfxMatrix;
 struct JSContext;
 struct JSObject;
 class nsFrameLoader;
 class nsIDOMElement;
 class nsIURI;
 
 namespace mozilla {
+
+namespace layers {
+struct FrameMetrics;
+}
+
+namespace layout {
+class RenderFrameParent;
+}
+
 namespace dom {
 
 class ContentDialogParent : public PContentDialogParent {};
 
 class TabParent : public PBrowserParent 
                 , public nsITabParent 
                 , public nsIAuthPromptProvider
                 , public nsISecureBrowserUI
@@ -100,16 +109,17 @@ public:
 
 
     void LoadURL(nsIURI* aURI);
     // XXX/cjones: it's not clear what we gain by hiding these
     // message-sending functions under a layer of indirection and
     // eating the return values
     void Show(const nsIntSize& size);
     void UpdateDimensions(const nsRect& rect, const nsIntSize& size);
+    void UpdateFrame(const layers::FrameMetrics& aFrameMetrics);
     void Activate();
     void Deactivate();
 
     /**
      * Is this object active?  That is, was Activate() called more recently than
      * Deactivate()?
      */
     bool Active();
@@ -198,17 +208,18 @@ protected:
       nsCOMPtr<nsIDialogParamBlock> mParams;
     };
     InfallibleTArray<DelayedDialogData*> mDelayedDialogs;
 
     bool ShouldDelayDialogs();
     bool AllowContentIME();
 
     NS_OVERRIDE
-    virtual PRenderFrameParent* AllocPRenderFrame(LayersBackend* aBackend,
+    virtual PRenderFrameParent* AllocPRenderFrame(ScrollingBehavior* aScrolling,
+                                                  LayersBackend* aBackend,
                                                   int32_t* aMaxTextureSize,
                                                   uint64_t* aLayersId);
     NS_OVERRIDE
     virtual bool DeallocPRenderFrame(PRenderFrameParent* aFrame);
 
     // IME
     static TabParent *mIMETabParent;
     nsString mIMECacheText;
@@ -224,15 +235,28 @@ protected:
 
     float mDPI;
     bool mActive;
     bool mShown;
 
 private:
     already_AddRefed<nsFrameLoader> GetFrameLoader() const;
     already_AddRefed<nsIWidget> GetWidget() const;
+    layout::RenderFrameParent* GetRenderFrame();
     void TryCacheDPI();
+    // Return true iff this TabParent was created for a mozbrowser
+    // frame.
+    bool IsForMozBrowser();
+    // When true, we create a pan/zoom controller for our frame and
+    // notify it of input events targeting us.
+    bool UseAsyncPanZoom();
+    // If we have a render frame currently, notify it that we're about
+    // to dispatch |aEvent| to our child.  If there's a relevant
+    // transform in place, |aOutEvent| is the transformed |aEvent| to
+    // dispatch to content.
+    void MaybeForwardEventToRenderFrame(const nsInputEvent& aEvent,
+                                        nsInputEvent* aOutEvent);
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif
--- a/dom/ipc/jar.mn
+++ b/dom/ipc/jar.mn
@@ -1,8 +1,8 @@
 # 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/.
 
 toolkit.jar:
         content/global/test-ipc.xul (test.xul)
         content/global/remote-test-ipc.js (remote-test.js)
-        content/global/BrowserElementChild.js (../browser-element/BrowserElementChild.js)
+*       content/global/BrowserElementChild.js (../browser-element/BrowserElementChild.js)
--- a/dom/mms/src/ril/MmsPduHelper.jsm
+++ b/dom/mms/src/ril/MmsPduHelper.jsm
@@ -967,17 +967,24 @@ let PduHelper = {
     let header;
     while (data.offset < data.array.length) {
       // There is no `header length` information in MMS PDU. If we just got
       // something wrong in parsing header fields, we might not be able to
       // determine the correct header-content boundary.
       header = HeaderField.decode(data, headers);
 
       if (header) {
-        headers[header.name] = header.value;
+        let orig = headers[header.name];
+        if (Array.isArray(orig)) {
+          headers[header.name].push(header.value);
+        } else if (orig) {
+          headers[header.name] = [orig, header.value];
+        } else {
+          headers[header.name] = header.value;
+        }
         if (header.name == "content-type") {
           // `... if the PDU contains a message body the Content Type MUST be
           // the last header field, followed by message body.` See
           // OMA-TS-MMS_ENC-V1_3-20110913-A section 7.
           break;
         }
       }
     }
--- a/dom/mms/tests/test_mms_pdu_helper.js
+++ b/dom/mms/tests/test_mms_pdu_helper.js
@@ -545,8 +545,51 @@ add_test(function test_StatusValue_encod
     } else {
       wsp_encode_test(MMS.StatusValue, i, null, "CodeError");
     }
   }
 
   run_next_test();
 });
 
+//
+// Test target: PduHelper
+//
+
+//// PduHelper.parseHeaders ////
+
+add_test(function test_PduHelper_parseHeaders() {
+  function parse(input, expect, exception) {
+    let data = {array: input, offset: 0};
+    do_check_throws(wsp_test_func.bind(null, MMS.PduHelper.parseHeaders, data, expect),
+                    exception);
+  }
+
+  // Parse ends with Content-Type
+  let expect = {};
+  expect["x-mms-mms-version"] = MMS_VERSION;
+  expect["content-type"] = {
+    media: "application/vnd.wap.multipart.related",
+    params: null,
+  };
+  parse([0x80 | 0x0D, 0x80 | MMS_VERSION,   // X-Mms-Mms-Version: 1.3
+         0x80 | 0x04, 0x80 | 0x33,          // Content-Type: application/vnd.wap.multipart.related
+	 0x80 | 0x0C, MMS_PDU_TYPE_SEND_REQ // X-Mms-Message-Type: M-Send.req
+        ], expect);
+
+  // Parse header fields with multiple entries
+  expect = {
+    to: [
+      { address: "+123", type: "PLMN" },
+      { address: "+456", type: "num" },
+    ],
+  };
+  expect["content-type"] = {
+    media: "application/vnd.wap.multipart.related",
+    params: null,
+  };
+  parse(Array.concat([0x80 | 0x17]).concat(strToCharCodeArray("+123/TYPE=PLMN"))
+             .concat([0x80 | 0x17]).concat(strToCharCodeArray("+456"))
+             .concat([0x80 | 0x04, 0x80 | 0x33]),
+        expect);
+
+  run_next_test();
+});
--- a/dom/plugins/base/nsJSNPRuntime.cpp
+++ b/dom/plugins/base/nsJSNPRuntime.cpp
@@ -1145,33 +1145,38 @@ nsJSObjWrapper::GetNewOrUsed(NPP npp, JS
   }
 
   return wrapper;
 }
 
 // Climb the prototype chain, unwrapping as necessary until we find an NP object
 // wrapper.
 //
-// Note that the returned value is not necessarily in the same compartment as cx.
-// Callers should use it in very limited ways (checking the private is fine).
+// Because this function unwraps, its return value must be wrapped for the cx
+// compartment for callers that plan to hold onto the result or do anything
+// substantial with it.
 static JSObject *
-GetNPObjectWrapper(JSContext *cx, JSObject *obj)
+GetNPObjectWrapper(JSContext *cx, JSObject *obj, bool wrapResult = true)
 {
   while (obj && (obj = js::UnwrapObjectChecked(cx, obj))) {
-    if (JS_GetClass(obj) == &sNPObjectJSWrapperClass)
+    if (JS_GetClass(obj) == &sNPObjectJSWrapperClass) {
+      if (wrapResult && !JS_WrapObject(cx, &obj)) {
+        return NULL;
+      }
       return obj;
+    }
     obj = ::JS_GetPrototype(obj);
   }
   return NULL;
 }
 
 static NPObject *
 GetNPObject(JSContext *cx, JSObject *obj)
 {
-  obj = GetNPObjectWrapper(cx, obj);
+  obj = GetNPObjectWrapper(cx, obj, /* wrapResult = */ false);
   if (!obj) {
     return nsnull;
   }
 
   return (NPObject *)::JS_GetPrivate(obj);
 }
 
 
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -3868,17 +3868,17 @@ CheckForDisabledWindows()
     nsCOMPtr<nsISupports> supportsWindow;
     windowList->GetNext(getter_AddRefs(supportsWindow));
     nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(supportsWindow));
     if (baseWin) {
       bool aFlag;
       nsCOMPtr<nsIWidget> widget;
       baseWin->GetMainWidget(getter_AddRefs(widget));
       if (widget && !widget->GetParent() &&
-          NS_SUCCEEDED(widget->IsVisible(aFlag)) && aFlag == true &&
+          widget->IsVisible() &&
           NS_SUCCEEDED(widget->IsEnabled(&aFlag)) && aFlag == false) {
         nsIWidget * child = widget->GetFirstChild();
         bool enable = true;
         while (child)  {
           nsWindowType aType;
           if (NS_SUCCEEDED(child->GetWindowType(aType)) &&
               aType == eWindowType_dialog) {
             enable = false;
--- a/dom/system/gonk/AudioManager.cpp
+++ b/dom/system/gonk/AudioManager.cpp
@@ -1,11 +1,22 @@
-/* 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/. */
+/* Copyright 2012 Mozilla Foundation and Mozilla contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 #include <android/log.h> 
 
 #include "mozilla/Hal.h"
 #include "AudioManager.h"
 #include "gonk/AudioSystem.h"
 
 using namespace mozilla::dom::gonk;
--- a/dom/system/gonk/AudioManager.h
+++ b/dom/system/gonk/AudioManager.h
@@ -1,11 +1,22 @@
-/* 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/. */
+/* Copyright 2012 Mozilla Foundation and Mozilla contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 #ifndef mozilla_dom_system_b2g_audiomanager_h__
 #define mozilla_dom_system_b2g_audiomanager_h__
 
 #include "mozilla/Observer.h"
 #include "nsAutoPtr.h"
 #include "nsIAudioManager.h"
 
--- a/dom/system/gonk/GonkGPSGeolocationProvider.cpp
+++ b/dom/system/gonk/GonkGPSGeolocationProvider.cpp
@@ -1,12 +1,23 @@
 /* -*- 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/. */
+/* Copyright 2012 Mozilla Foundation and Mozilla contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 #include <pthread.h>
 #include <hardware/gps.h>
 
 #include "GonkGPSGeolocationProvider.h"
 #include "SystemWorkerManager.h"
 #include "mozilla/Preferences.h"
 #include "nsGeoPosition.h"
--- a/dom/system/gonk/GonkGPSGeolocationProvider.h
+++ b/dom/system/gonk/GonkGPSGeolocationProvider.h
@@ -1,12 +1,24 @@
 /* -*- 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/. */
+/* Copyright 2012 Mozilla Foundation and Mozilla contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 #ifndef GonkGPSGeolocationProvider_h
 #define GonkGPSGeolocationProvider_h
 
 #include <hardware/gps.h> // for GpsInterface
 #include "nsCOMPtr.h"
 #include "nsIGeolocationProvider.h"
 #include "nsIRadioInterfaceLayer.h"
 #include "nsString.h"
--- a/dom/system/gonk/Makefile.in
+++ b/dom/system/gonk/Makefile.in
@@ -1,11 +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/.
+# Copyright 2012 Mozilla Foundation and Mozilla contributors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
 
 DEPTH            = ../../..
 topsrcdir        = @top_srcdir@
 srcdir           = @srcdir@
 VPATH            = @srcdir@
 
 relativesrcdir   = dom/system/gonk
 
--- a/dom/system/gonk/RILContentHelper.js
+++ b/dom/system/gonk/RILContentHelper.js
@@ -1,11 +1,22 @@
-/* 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/. */
+/* Copyright 2012 Mozilla Foundation and Mozilla contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 "use strict";
 
 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
--- a/dom/system/gonk/RadioInterfaceLayer.js
+++ b/dom/system/gonk/RadioInterfaceLayer.js
@@ -1,11 +1,22 @@
-/* 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/. */
+/* Copyright 2012 Mozilla Foundation and Mozilla contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 "use strict";
 
 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
@@ -341,17 +352,17 @@ RadioInterfaceLayer.prototype = {
         return;
       case "sms-delivered":
         this.handleSmsDelivered(message);
         return;
       case "sms-send-failed":
         this.handleSmsSendFailed(message);
         return;
       case "datacallstatechange":
-        this.handleDataCallState(message.datacall);
+        this.handleDataCallState(message);
         break;
       case "datacalllist":
         this.handleDataCallList(message);
         break;
       case "nitzTime":
         // TODO bug 714349
         // Send information to time manager to decide what to do with it
         // Message contains networkTimeInSeconds, networkTimeZoneInMinutes,
@@ -465,17 +476,17 @@ RadioInterfaceLayer.prototype = {
       voiceInfo.connected = false;
       voiceInfo.emergencyCallsOnly = false;
       voiceInfo.roaming = false;
       voiceInfo.network = null;
       voiceInfo.type = null;
       voiceInfo.signalStrength = null;
       voiceInfo.relSignalStrength = null;
       ppmm.sendAsyncMessage("RIL:VoiceInfoChanged", voiceInfo);
-      return;
+      return false;
     }
 
     let isRoaming = regState == RIL.NETWORK_CREG_STATE_REGISTERED_ROAMING;
     let isHome = regState == RIL.NETWORK_CREG_STATE_REGISTERED_HOME;
     let isConnected = isRoaming || isHome;
     let radioTech = RIL.GECKO_RADIO_TECH[state.radioTech] || null;
 
     // Ensure that we check for changes before sending the message
@@ -520,17 +531,17 @@ RadioInterfaceLayer.prototype = {
       data.connected = false;
       data.emergencyCallsOnly = false;
       data.roaming = false;
       data.network = null;
       data.type = null;
       data.signalStrength = null;
       data.relSignalStrength = null;
       ppmm.sendAsyncMessage("RIL:DataInfoChanged", data);
-      return;
+      return false;
     }
     data.roaming =
       (state.regState == RIL.NETWORK_CREG_STATE_REGISTERED_ROAMING);
     data.type = RIL.GECKO_RADIO_TECH[state.radioTech] || null;
     ppmm.sendAsyncMessage("RIL:DataInfoChanged", data);
 
     if (!this._isDataEnabled()) {
       return false;
--- a/dom/system/gonk/RadioInterfaceLayer.manifest
+++ b/dom/system/gonk/RadioInterfaceLayer.manifest
@@ -1,7 +1,21 @@
+# Copyright 2012 Mozilla Foundation and Mozilla contributors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
 # RadioInterfaceLayer.js
 component {2d831c8d-6017-435b-a80c-e5d422810cea} RadioInterfaceLayer.js
 
 # RILContentHelper.js
 component {472816e1-1fd6-4405-996c-806f9ea68174} RILContentHelper.js
 contract @mozilla.org/ril/content-helper;1 {472816e1-1fd6-4405-996c-806f9ea68174}
 category profile-after-change RILContentHelper @mozilla.org/ril/content-helper;1
--- a/dom/system/gonk/SystemWorkerManager.cpp
+++ b/dom/system/gonk/SystemWorkerManager.cpp
@@ -1,13 +1,24 @@
 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
 /* 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/. */
+/* Copyright 2012 Mozilla Foundation and Mozilla contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 #include "SystemWorkerManager.h"
 
 #include "nsIObserverService.h"
 #include "nsIJSContextStack.h"
 #include "nsIRadioInterfaceLayer.h"
 #include "nsIWifi.h"
 #include "nsIWorkerHolder.h"
--- a/dom/system/gonk/SystemWorkerManager.h
+++ b/dom/system/gonk/SystemWorkerManager.h
@@ -1,13 +1,24 @@
 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
 /* vim: set ts=2 et sw=2 tw=40: */
-/* 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/. */
+/* Copyright 2012 Mozilla Foundation and Mozilla contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 #ifndef mozilla_dom_system_b2g_systemworkermanager_h__
 #define mozilla_dom_system_b2g_systemworkermanager_h__
 
 #include "nsIInterfaceRequestor.h"
 #include "nsIObserver.h"
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
--- a/dom/system/gonk/net_worker.js
+++ b/dom/system/gonk/net_worker.js
@@ -1,11 +1,22 @@
-/* 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/. */
+/* Copyright 2012 Mozilla Foundation and Mozilla contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 "use strict";
 
 const DEBUG = true;
 
 importScripts("systemlibs.js");
 
 /**
--- a/dom/system/gonk/ril_consts.js
+++ b/dom/system/gonk/ril_consts.js
@@ -1,11 +1,22 @@
-/* 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/. */
+/* Copyright 2012 Mozilla Foundation and Mozilla contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 // Set to true to debug all RIL layers
 const DEBUG_ALL = false;
 
 // Set individually to debug specific layers
 const DEBUG_WORKER = false || DEBUG_ALL;
 const DEBUG_CONTENT_HELPER = false || DEBUG_ALL;
 const DEBUG_RIL = false || DEBUG_ALL;
--- a/dom/system/gonk/ril_worker.js
+++ b/dom/system/gonk/ril_worker.js
@@ -1,11 +1,22 @@
-/* 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/. */
+/* Copyright 2012 Mozilla Foundation and Mozilla contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 /**
  * This file implements the RIL worker thread. It communicates with
  * the main thread to provide a high-level API to the phone's RIL
  * stack, and with the RIL IPC thread to communicate with the RIL
  * device itself. These communication channels use message events as
  * known from Web Workers:
  *
@@ -1396,17 +1407,17 @@ let RIL = {
 
   /**
    * Request various states about the network.
    */
   requestNetworkInfo: function requestNetworkInfo() {
     if (this._processingNetworkInfo) {
       if (DEBUG) {
         debug("Already requesting network info: " +
-              JSON.stringify(this._pendingNetworkInfo))
+              JSON.stringify(this._pendingNetworkInfo));
       }
       return;
     }
 
     if (DEBUG) debug("Requesting network info");
 
     this._processingNetworkInfo = true;
     this.getVoiceRegistrationState();
@@ -1787,18 +1798,17 @@ let RIL = {
 
     let token = Buf.newParcel(REQUEST_DEACTIVATE_DATA_CALL);
     Buf.writeUint32(2);
     Buf.writeString(options.cid);
     Buf.writeString(options.reason || DATACALL_DEACTIVATE_NO_REASON);
     Buf.sendParcel();
 
     datacall.state = GECKO_NETWORK_STATE_DISCONNECTING;
-    this.sendDOMMessage({type: "datacallstatechange",
-                         datacall: datacall});
+    this.sendDOMMessage(datacall);
   },
 
   /**
    * Get a list of data calls.
    */
   getDataCallList: function getDataCallList() {
     Buf.simpleRequest(REQUEST_DATA_CALL_LIST);
   },
@@ -2335,47 +2345,58 @@ let RIL = {
         if (this.currentCallsLength == 1) {
           return true;
         } else {
           return false;
         }
     }
   },
 
-  _processDataCallList: function _processDataCallList(datacalls) {
+  _processDataCallList: function _processDataCallList(datacalls, newDataCallOptions) {
     for each (let currentDataCall in this.currentDataCalls) {
       let updatedDataCall;
       if (datacalls) {
         updatedDataCall = datacalls[currentDataCall.cid];
         delete datacalls[currentDataCall.cid];
       }
 
       if (!updatedDataCall) {
         delete this.currentDataCalls[currentDataCall.callIndex];
         currentDataCall.state = GECKO_NETWORK_STATE_DISCONNECTED;
-        this.sendDOMMessage({type: "datacallstatechange",
-                             datacall: currentDataCall});
+        currentDataCall.type = "datacallstatechange";
+        this.sendDOMMessage(currentDataCall);
         continue;
       }
 
       this._setDataCallGeckoState(updatedDataCall);
       if (updatedDataCall.state != currentDataCall.state) {
         currentDataCall.status = updatedDataCall.status;
         currentDataCall.active = updatedDataCall.active;
         currentDataCall.state = updatedDataCall.state;
-        this.sendDOMMessage({type: "datacallstatechange",
-                             datacall: currentDataCall});
+        currentDataCall.type = "datacallstatechange";
+        this.sendDOMMessage(currentDataCall);
       }
     }
 
     for each (let newDataCall in datacalls) {
       this.currentDataCalls[newDataCall.cid] = newDataCall;
       this._setDataCallGeckoState(newDataCall);
-      this.sendDOMMessage({type: "datacallstatechange",
-                           datacall: newDataCall});
+      if (newDataCallOptions) {
+        newDataCall.radioTech = newDataCallOptions.radioTech;
+        newDataCall.apn = newDataCallOptions.apn;
+        newDataCall.user = newDataCallOptions.user;
+        newDataCall.passwd = newDataCallOptions.passwd;
+        newDataCall.chappap = newDataCallOptions.chappap;
+        newDataCall.pdptype = newDataCallOptions.pdptype;
+        newDataCallOptions = null;
+      } else if (DEBUG) {
+        debug("Unexpected new data call: " + JSON.stringify(newDataCall));
+      }
+      newDataCall.type = "datacallstatechange";
+      this.sendDOMMessage(newDataCall);
     }
   },
 
   _setDataCallGeckoState: function _setDataCallGeckoState(datacall) {
     switch (datacall.active) {
       case DATACALL_INACTIVE:
         datacall.state = GECKO_NETWORK_STATE_DISCONNECTED;
         break;
@@ -3118,31 +3139,35 @@ RIL.readSetupDataCall_v5 = function read
   options.gw = gw;
   options.active = DATACALL_ACTIVE_UNKNOWN;
   options.state = GECKO_NETWORK_STATE_CONNECTING;
   return options;
 };
 
 RIL[REQUEST_SETUP_DATA_CALL] = function REQUEST_SETUP_DATA_CALL(length, options) {
   if (options.rilRequestError) {
-    // On Data Call error, we shall notify caller
-    this.sendDOMMessage({type: "datacallerror"});
+    options.type = "datacallerror";
+    this.sendDOMMessage(options);
     return;
   }
 
   if (RILQUIRKS_V5_LEGACY) {
+    // Populate the `options` object with the data call information. That way
+    // we retain the APN and other info about how the data call was set up.
     this.readSetupDataCall_v5(options);
     this.currentDataCalls[options.cid] = options;
-    this.sendDOMMessage({type: "datacallstatechange",
-                         datacall: options});
+    options.type = "datacallstatechange";
+    this.sendDOMMessage(options);
     // Let's get the list of data calls to ensure we know whether it's active
     // or not.
     this.getDataCallList();
     return;
   }
+  // Pass `options` along. That way we retain the APN and other info about
+  // how the data call was set up.
   this[REQUEST_DATA_CALL_LIST](length, options);
 };
 RIL[REQUEST_SIM_IO] = function REQUEST_SIM_IO(length, options) {
   if (options.rilRequestError) {
     return;
   }
 
   let sw1 = Buf.readUint32();
@@ -3200,18 +3225,18 @@ RIL[REQUEST_ANSWER] = null;
 RIL[REQUEST_DEACTIVATE_DATA_CALL] = function REQUEST_DEACTIVATE_DATA_CALL(length, options) {
   if (options.rilRequestError) {
     return;
   }
 
   let datacall = this.currentDataCalls[options.cid];
   delete this.currentDataCalls[options.cid];
   datacall.state = GECKO_NETWORK_STATE_DISCONNECTED;
-  this.sendDOMMessage({type: "datacallstatechange",
-                       datacall: datacall});
+  datacall.type = "datacallstatechange";
+  this.sendDOMMessage(datacall);
 };
 RIL[REQUEST_QUERY_FACILITY_LOCK] = function REQUEST_QUERY_FACILITY_LOCK(length, options) {
   if (options.rilRequestError) {
     return;
   }
 
   let response = Buf.readUint32List()[0];
   this.sendDOMMessage({type: "iccgetcardlock",
@@ -3296,25 +3321,25 @@ RIL[REQUEST_BASEBAND_VERSION] = function
   if (DEBUG) debug("Baseband version: " + this.basebandVersion);
 };
 RIL[REQUEST_SEPARATE_CONNECTION] = null;
 RIL[REQUEST_SET_MUTE] = null;
 RIL[REQUEST_GET_MUTE] = null;
 RIL[REQUEST_QUERY_CLIP] = null;
 RIL[REQUEST_LAST_DATA_CALL_FAIL_CAUSE] = null;
 
-RIL.readDataCall_v5 = function readDataCall_v5() {
+RIL.readDataCall_v5 = function readDataCall_v5(options) {
   if (!options) {
     options = {};
   }
-  cid = Buf.readUint32().toString();
-  active = Buf.readUint32(); // DATACALL_ACTIVE_*
-  type = Buf.readString();
-  apn = Buf.readString();
-  address = Buf.readString();
+  options.cid = Buf.readUint32().toString();
+  options.active = Buf.readUint32(); // DATACALL_ACTIVE_*
+  options.type = Buf.readString();
+  options.apn = Buf.readString();
+  options.address = Buf.readString();
   return options;
 };
 
 RIL.readDataCall_v6 = function readDataCall_v6(options) {
   if (!options) {
     options = {};
   }
   options.status = Buf.readUint32();  // DATACALL_FAIL_*
@@ -3354,24 +3379,28 @@ RIL[REQUEST_DATA_CALL_LIST] = function R
   if (!RILQUIRKS_V5_LEGACY) {
     version = Buf.readUint32();
   }
   let num = num = Buf.readUint32();
   let datacalls = {};
   for (let i = 0; i < num; i++) {
     let datacall;
     if (version < 6) {
-      datacall = this.readDataCall_v5(options);
+      datacall = this.readDataCall_v5();
     } else {
-      datacall = this.readDataCall_v6(options);
+      datacall = this.readDataCall_v6();
     }
     datacalls[datacall.cid] = datacall;
   }
 
-  this._processDataCallList(datacalls);
+  let newDataCallOptions = null;
+  if (options.rilRequestType == REQUEST_SETUP_DATA_CALL) {
+    newDataCallOptions = options;
+  }
+  this._processDataCallList(datacalls, newDataCallOptions);
 };
 RIL[REQUEST_RESET_RADIO] = null;
 RIL[REQUEST_OEM_HOOK_RAW] = null;
 RIL[REQUEST_OEM_HOOK_STRINGS] = null;
 RIL[REQUEST_SCREEN_STATE] = null;
 RIL[REQUEST_SET_SUPP_SVC_NOTIFICATION] = null;
 RIL[REQUEST_WRITE_SMS_TO_SIM] = null;
 RIL[REQUEST_DELETE_SMS_ON_SIM] = null;
--- a/dom/system/gonk/systemlibs.js
+++ b/dom/system/gonk/systemlibs.js
@@ -1,11 +1,22 @@
-/* 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/. */
+/* Copyright 2012 Mozilla Foundation and Mozilla contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 const SYSTEM_PROPERTY_KEY_MAX = 32;
 const SYSTEM_PROPERTY_VALUE_MAX = 92;
 
 // We leave this as 'undefined' instead of setting it to 'false'. That
 // way a file that includes us can have it defined already without us
 // overriding the value here.
 let DEBUG;
--- a/editor/libeditor/html/Makefile.in
+++ b/editor/libeditor/html/Makefile.in
@@ -43,18 +43,21 @@ CPPSRCS  = \
 ifdef ENABLE_EDITOR_API_LOG
 CPPSRCS += nsHTMLEditorLog.cpp             \
            nsEditorTxnLog.cpp              \
            $(NULL)
 
 DEFINES += -DENABLE_EDITOR_API_LOG
 endif
 
+DEFINES += -D_IMPL_NS_LAYOUT
+
 # don't want the shared lib; force the creation of a static lib.
 FORCE_STATIC_LIB = 1
 
 include $(topsrcdir)/config/rules.mk
 
 INCLUDES        += -I$(topsrcdir)/editor/libeditor/base \
                    -I$(topsrcdir)/editor/libeditor/text \
                    -I$(topsrcdir)/editor/txmgr/src \
                    -I$(topsrcdir)/content/base/src \
+                   -I$(topsrcdir)/layout/style \
                    $(NULL)
--- a/editor/libeditor/html/nsHTMLAbsPosition.cpp
+++ b/editor/libeditor/html/nsHTMLAbsPosition.cpp
@@ -7,16 +7,17 @@
 #include "mozilla/Preferences.h"
 #include "mozilla/Selection.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/mozalloc.h"
 #include "nsAString.h"
 #include "nsAlgorithm.h"
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
+#include "nsComputedDOMStyle.h"
 #include "nsDebug.h"
 #include "nsEditProperty.h"
 #include "nsEditRules.h"
 #include "nsEditor.h"
 #include "nsEditorUtils.h"
 #include "nsError.h"
 #include "nsGkAtoms.h"
 #include "nsHTMLCSSUtils.h"
@@ -651,23 +652,19 @@ nsHTMLEditor::CheckPositionedElementBGan
   if (bgImageStr.EqualsLiteral("none")) {
     nsAutoString bgColorStr;
     res =
       mHTMLCSSUtils->GetComputedProperty(aElement,
                                          nsEditProperty::cssBackgroundColor,
                                          bgColorStr);
     NS_ENSURE_SUCCESS(res, res);
     if (bgColorStr.EqualsLiteral("transparent")) {
-      nsCOMPtr<nsIDOMWindow> window;
-      res = mHTMLCSSUtils->GetDefaultViewCSS(aElement, getter_AddRefs(window));
-      NS_ENSURE_SUCCESS(res, res);
-
-      nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl;
-      res = window->GetComputedStyle(aElement, EmptyString(), getter_AddRefs(cssDecl));
-      NS_ENSURE_SUCCESS(res, res);
+      nsRefPtr<nsComputedDOMStyle> cssDecl =
+        mHTMLCSSUtils->GetComputedStyle(aElement);
+      NS_ENSURE_STATE(cssDecl);
 
       // from these declarations, get the one we want and that one only
       nsCOMPtr<nsIDOMCSSValue> colorCssValue;
       res = cssDecl->GetPropertyCSSValue(NS_LITERAL_STRING("color"), getter_AddRefs(colorCssValue));
       NS_ENSURE_SUCCESS(res, res);
 
       PRUint16 type;
       res = colorCssValue->GetCssValueType(&type);
--- a/editor/libeditor/html/nsHTMLAnonymousUtils.cpp
+++ b/editor/libeditor/html/nsHTMLAnonymousUtils.cpp
@@ -3,16 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/Attributes.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/mozalloc.h"
 #include "nsAString.h"
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
+#include "nsComputedDOMStyle.h"
 #include "nsContentUtils.h"
 #include "nsDebug.h"
 #include "nsEditProperty.h"
 #include "nsError.h"
 #include "nsHTMLCSSUtils.h"
 #include "nsHTMLEditor.h"
 #include "nsIAtom.h"
 #include "nsIContent.h"
@@ -415,24 +416,20 @@ nsHTMLEditor::GetPositionAndDimensions(n
                                        positionStr);
     isPositioned = positionStr.EqualsLiteral("absolute");
   }
 
   if (isPositioned) {
     // Yes, it is absolutely positioned
     mResizedObjectIsAbsolutelyPositioned = true;
 
-    nsCOMPtr<nsIDOMWindow> window;
-    res = mHTMLCSSUtils->GetDefaultViewCSS(aElement, getter_AddRefs(window));
-    NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
-
-    nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl;
     // Get the all the computed css styles attached to the element node
-    res = window->GetComputedStyle(aElement, EmptyString(), getter_AddRefs(cssDecl));
-    NS_ENSURE_SUCCESS(res, res);
+    nsRefPtr<nsComputedDOMStyle> cssDecl =
+      mHTMLCSSUtils->GetComputedStyle(aElement);
+    NS_ENSURE_STATE(cssDecl);
 
     aBorderLeft = GetCSSFloatValue(cssDecl, NS_LITERAL_STRING("border-left-width"));
     aBorderTop  = GetCSSFloatValue(cssDecl, NS_LITERAL_STRING("border-top-width"));
     aMarginLeft = GetCSSFloatValue(cssDecl, NS_LITERAL_STRING("margin-left"));
     aMarginTop  = GetCSSFloatValue(cssDecl, NS_LITERAL_STRING("margin-top"));
 
     aX = GetCSSFloatValue(cssDecl, NS_LITERAL_STRING("left")) +
          aMarginLeft + aBorderLeft;
--- a/editor/libeditor/html/nsHTMLCSSUtils.cpp
+++ b/editor/libeditor/html/nsHTMLCSSUtils.cpp
@@ -2,22 +2,25 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ChangeCSSInlineStyleTxn.h"
 #include "EditTxn.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/css/Declaration.h"
+#include "mozilla/css/StyleRule.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/mozalloc.h"
 #include "nsAString.h"
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsColor.h"
+#include "nsComputedDOMStyle.h"
 #include "nsContentUtils.h"
 #include "nsDebug.h"
 #include "nsDependentSubstring.h"
 #include "nsEditProperty.h"
 #include "nsError.h"
 #include "nsGkAtoms.h"
 #include "nsHTMLCSSUtils.h"
 #include "nsHTMLEditor.h"
@@ -565,104 +568,96 @@ nsHTMLCSSUtils::CreateCSSPropertyTxn(nsI
   NS_ADDREF(*aTxn);
   return (*aTxn)->Init(mHTMLEditor, aElement, aAttribute, aValue, aRemoveProperty);
 }
 
 nsresult
 nsHTMLCSSUtils::GetSpecifiedProperty(nsIDOMNode *aNode, nsIAtom *aProperty,
                                      nsAString & aValue)
 {
-  return GetCSSInlinePropertyBase(aNode, aProperty, aValue, nsnull, SPECIFIED_STYLE_TYPE);
+  return GetCSSInlinePropertyBase(aNode, aProperty, aValue, eSpecified);
 }
 
 nsresult
 nsHTMLCSSUtils::GetComputedProperty(nsIDOMNode *aNode, nsIAtom *aProperty,
                                     nsAString & aValue)
 {
-  nsCOMPtr<nsIDOMWindow> window;
-  nsresult res = GetDefaultViewCSS(aNode, getter_AddRefs(window));
-  NS_ENSURE_SUCCESS(res, res);
+  return GetCSSInlinePropertyBase(aNode, aProperty, aValue, eComputed);
+}
 
-  return GetCSSInlinePropertyBase(aNode, aProperty, aValue, window, COMPUTED_STYLE_TYPE);
+nsresult
+nsHTMLCSSUtils::GetCSSInlinePropertyBase(nsIDOMNode* aNode, nsIAtom* aProperty,
+                                         nsAString& aValue,
+                                         StyleType aStyleType)
+{
+  nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
+  return GetCSSInlinePropertyBase(node, aProperty, aValue, aStyleType);
 }
 
 nsresult
 nsHTMLCSSUtils::GetCSSInlinePropertyBase(nsINode* aNode, nsIAtom* aProperty,
                                          nsAString& aValue,
-                                         nsIDOMWindow* aWindow,
-                                         PRUint8 aStyleType)
+                                         StyleType aStyleType)
 {
-  nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aNode);
-  return GetCSSInlinePropertyBase(node, aProperty, aValue, aWindow, aStyleType);
-}
+  MOZ_ASSERT(aNode && aProperty);
+  aValue.Truncate();
 
-nsresult
-nsHTMLCSSUtils::GetCSSInlinePropertyBase(nsIDOMNode *aNode, nsIAtom *aProperty,
-                                         nsAString& aValue,
-                                         nsIDOMWindow* aWindow,
-                                         PRUint8 aStyleType)
-{
-  aValue.Truncate();
-  NS_ENSURE_TRUE(aProperty, NS_ERROR_NULL_POINTER);
-
-  nsCOMPtr<nsIDOMElement> element = GetElementContainerOrSelf(aNode);
+  nsCOMPtr<dom::Element> element = GetElementContainerOrSelf(aNode);
   NS_ENSURE_TRUE(element, NS_ERROR_NULL_POINTER);
 
-  switch (aStyleType) {
-    case COMPUTED_STYLE_TYPE:
-      if (element && aWindow) {
-        nsAutoString value, propString;
-        nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl;
-        aProperty->ToString(propString);
-        // Get the all the computed css styles attached to the element node
-        nsresult res = aWindow->GetComputedStyle(element, EmptyString(), getter_AddRefs(cssDecl));
-        if (NS_FAILED(res) || !cssDecl)
-          return res;
-        // from these declarations, get the one we want and that one only
-        res = cssDecl->GetPropertyValue(propString, value);
-        NS_ENSURE_SUCCESS(res, res);
-        aValue.Assign(value);
-      }
-      break;
-    case SPECIFIED_STYLE_TYPE:
-      if (element) {
-        nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl;
-        PRUint32 length;
-        nsresult res = GetInlineStyles(element, getter_AddRefs(cssDecl), &length);
-        if (NS_FAILED(res) || !cssDecl) return res;
-        nsAutoString value, propString;
-        aProperty->ToString(propString);
-        res = cssDecl->GetPropertyValue(propString, value);
-        NS_ENSURE_SUCCESS(res, res);
-        aValue.Assign(value);
-      }
-      break;
+  if (aStyleType == eComputed) {
+    // Get the all the computed css styles attached to the element node
+    nsRefPtr<nsComputedDOMStyle> cssDecl = GetComputedStyle(element);
+    NS_ENSURE_STATE(cssDecl);
+
+    // from these declarations, get the one we want and that one only
+    MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
+      cssDecl->GetPropertyValue(nsDependentAtomString(aProperty), aValue)));
+
+    return NS_OK;
   }
+
+  MOZ_ASSERT(aStyleType == eSpecified);
+  nsRefPtr<css::StyleRule> rule = element->GetInlineStyleRule();
+  if (!rule) {
+    return NS_OK;
+  }
+  nsCSSProperty prop =
+    nsCSSProps::LookupProperty(nsDependentAtomString(aProperty),
+                               nsCSSProps::eEnabled);
+  MOZ_ASSERT(prop != eCSSProperty_UNKNOWN);
+  rule->GetDeclaration()->GetValue(prop, aValue);
+
   return NS_OK;
 }
 
-nsresult
-nsHTMLCSSUtils::GetDefaultViewCSS(nsIDOMNode *aNode, nsIDOMWindow **aViewCSS)
+already_AddRefed<nsComputedDOMStyle>
+nsHTMLCSSUtils::GetComputedStyle(nsIDOMElement* aElement)
 {
-  nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
-  NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER);
-  return GetDefaultViewCSS(node, aViewCSS);
+  nsCOMPtr<dom::Element> element = do_QueryInterface(aElement);
+  return GetComputedStyle(element);
 }
 
-nsresult
-nsHTMLCSSUtils::GetDefaultViewCSS(nsINode* aNode, nsIDOMWindow** aViewCSS)
+already_AddRefed<nsComputedDOMStyle>
+nsHTMLCSSUtils::GetComputedStyle(dom::Element* aElement)
 {
-  MOZ_ASSERT(aNode);
-  dom::Element* element = GetElementContainerOrSelf(aNode);
-  NS_ENSURE_TRUE(element, NS_ERROR_NULL_POINTER);
+  MOZ_ASSERT(aElement);
+
+  nsIDocument* doc = aElement->GetCurrentDoc();
+  NS_ASSERTION(doc, "Trying to compute style of detached element");
+  NS_ENSURE_TRUE(doc, nsnull);
 
-  nsCOMPtr<nsIDOMWindow> window = element->OwnerDoc()->GetWindow();
-  NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
-  window.forget(aViewCSS);
-  return NS_OK;
+  nsIPresShell* presShell = doc->GetShell();
+  NS_ASSERTION(presShell, "Trying to compute style without PresShell");
+  NS_ENSURE_TRUE(presShell, nsnull);
+
+  nsRefPtr<nsComputedDOMStyle> style =
+    NS_NewComputedDOMStyle(aElement, EmptyString(), presShell);
+
+  return style.forget();
 }
 
 // remove the CSS style "aProperty : aPropertyValue" and possibly remove the whole node
 // if it is a span and if its only attribute is _moz_dirty
 nsresult
 nsHTMLCSSUtils::RemoveCSSInlineStyle(nsIDOMNode *aNode, nsIAtom *aProperty, const nsAString & aPropertyValue)
 {
   nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(aNode);
@@ -1061,46 +1056,40 @@ nsHTMLCSSUtils::RemoveCSSEquivalentToHTM
 // the HTML style aHTMLProperty/aAttribute/aValueString for the node aNode;
 // the value of aStyleType controls the styles we retrieve : specified or
 // computed.
 nsresult
 nsHTMLCSSUtils::GetCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode,
                                                      nsIAtom *aHTMLProperty,
                                                      const nsAString *aAttribute,
                                                      nsAString & aValueString,
-                                                     PRUint8 aStyleType)
+                                                     StyleType aStyleType)
 {
   aValueString.Truncate();
   nsCOMPtr<dom::Element> theElement = GetElementContainerOrSelf(aNode);
   NS_ENSURE_TRUE(theElement, NS_ERROR_NULL_POINTER);
 
   if (!theElement || !IsCSSEditableProperty(theElement, aHTMLProperty,
                                             aAttribute, &aValueString)) {
     return NS_OK;
   }
 
   // Yes, the requested HTML style has a CSS equivalence in this implementation
-  // Retrieve the default ViewCSS if we are asked for computed styles
-  nsCOMPtr<nsIDOMWindow> window;
-  if (COMPUTED_STYLE_TYPE == aStyleType) {
-    nsresult res = GetDefaultViewCSS(theElement, getter_AddRefs(window));
-    NS_ENSURE_SUCCESS(res, res);
-  }
   nsTArray<nsIAtom*> cssPropertyArray;
   nsTArray<nsString> cssValueArray;
   // get the CSS equivalence with last param true indicating we want only the
   // "gettable" properties
   GenerateCSSDeclarationsFromHTMLStyle(theElement, aHTMLProperty, aAttribute, nsnull,
                                        cssPropertyArray, cssValueArray, true);
   PRInt32 count = cssPropertyArray.Length();
   for (PRInt32 index = 0; index < count; index++) {
     nsAutoString valueString;
     // retrieve the specified/computed value of the property
     nsresult res = GetCSSInlinePropertyBase(theElement, cssPropertyArray[index],
-                                            valueString, window, aStyleType);
+                                            valueString, aStyleType);
     NS_ENSURE_SUCCESS(res, res);
     // append the value to aValueString (possibly with a leading whitespace)
     if (index) {
       aValueString.Append(PRUnichar(' '));
     }
     aValueString.Append(valueString);
   }
   return NS_OK;
@@ -1113,38 +1102,36 @@ nsHTMLCSSUtils::GetCSSEquivalentToHTMLIn
 //
 // The nsIContent variant returns aIsSet instead of using an out parameter, and
 // does not modify aValue.
 bool
 nsHTMLCSSUtils::IsCSSEquivalentToHTMLInlineStyleSet(nsIContent* aContent,
                                                     nsIAtom* aProperty,
                                                     const nsAString* aAttribute,
                                                     const nsAString& aValue,
-                                                    PRUint8 aStyleType)
+                                                    StyleType aStyleType)
 {
   MOZ_ASSERT(aContent && aProperty);
-  MOZ_ASSERT(aStyleType == SPECIFIED_STYLE_TYPE ||
-             aStyleType == COMPUTED_STYLE_TYPE);
   bool isSet;
   nsAutoString value(aValue);
   nsresult res = IsCSSEquivalentToHTMLInlineStyleSet(aContent->AsDOMNode(),
                                                      aProperty, aAttribute,
                                                      isSet, value, aStyleType);
   NS_ASSERTION(NS_SUCCEEDED(res), "IsCSSEquivalentToHTMLInlineStyleSet failed");
   NS_ENSURE_SUCCESS(res, false);
   return isSet;
 }
 
 nsresult
 nsHTMLCSSUtils::IsCSSEquivalentToHTMLInlineStyleSet(nsIDOMNode *aNode,
                                                     nsIAtom *aHTMLProperty,
                                                     const nsAString *aHTMLAttribute,
                                                     bool& aIsSet,
                                                     nsAString& valueString,
-                                                    PRUint8 aStyleType)
+                                                    StyleType aStyleType)
 {
   NS_ENSURE_TRUE(aNode, NS_ERROR_NULL_POINTER);
 
   nsAutoString htmlValueString(valueString);
   aIsSet = false;
   nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
   do {
     valueString.Assign(htmlValueString);
--- a/editor/libeditor/html/nsHTMLCSSUtils.h
+++ b/editor/libeditor/html/nsHTMLCSSUtils.h
@@ -7,32 +7,30 @@
 #define nsHTMLCSSUtils_h__
 
 #include "nsCOMPtr.h"                   // for already_AddRefed
 #include "nsTArray.h"                   // for nsTArray
 #include "nscore.h"                     // for nsAString, nsresult, nsnull
 #include "prtypes.h"                    // for PRUint8, PRInt32, PRUint32
 
 class ChangeCSSInlineStyleTxn;
+class nsComputedDOMStyle;
 class nsIAtom;
 class nsIContent;
 class nsIDOMCSSStyleDeclaration;
 class nsIDOMElement;
 class nsIDOMNode;
 class nsINode;
 class nsString;
 namespace mozilla {
 namespace dom {
 class Element;
 }  // namespace dom
 }  // namespace mozilla
 
-#define SPECIFIED_STYLE_TYPE    1
-#define COMPUTED_STYLE_TYPE     2
-
 class nsHTMLEditor;
 class nsIDOMWindow;
 
 typedef void (*nsProcessValueFunc)(const nsAString * aInputString, nsAString & aOutputString,
                                    const char * aDefaultValueString,
                                    const char * aPrependString, const char* aAppendString);
 
 class nsHTMLCSSUtils
@@ -59,16 +57,18 @@ public:
     eCSSEditableProperty_margin_right,
     eCSSEditableProperty_text_align,
     eCSSEditableProperty_text_decoration,
     eCSSEditableProperty_vertical_align,
     eCSSEditableProperty_whitespace,
     eCSSEditableProperty_width
   };
 
+  enum StyleType { eSpecified, eComputed };
+
 
   struct CSSEquivTable {
     nsCSSEditableProperty cssProperty;
     nsProcessValueFunc processValueFunctor;
     const char * defaultValue;
     const char * prependValue;
     const char * appendValue;
     bool gettable;
@@ -171,50 +171,48 @@ public:
 
   /** returns the list of values for the CSS equivalences to
     * the passed HTML style for the passed node
     *
     * @param aNode          [IN] a DOM node
     * @param aHTMLProperty  [IN] an atom containing an HTML property
     * @param aAttribute     [IN] a pointer to an attribute name or nsnull if irrelevant
     * @param aValueString   [OUT] the list of css values
-    * @param aStyleType     [IN] SPECIFIED_STYLE_TYPE to query the specified style values
-                                 COMPUTED_STYLE_TYPE  to query the computed style values
+    * @param aStyleType     [IN] eSpecified or eComputed
     */
   nsresult    GetCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode,
                                                    nsIAtom * aHTMLProperty,
                                                    const nsAString * aAttribute,
                                                    nsAString & aValueString,
-                                                   PRUint8 aStyleType);
+                                                   StyleType aStyleType);
 
   /** Does the node aNode (or his parent if it is not an element node) carries
     * the CSS equivalent styles to the HTML style for this node ?
     *
     * @param aNode          [IN] a DOM node
     * @param aHTMLProperty  [IN] an atom containing an HTML property
     * @param aAttribute     [IN] a pointer to an attribute name or nsnull if irrelevant
     * @param aIsSet         [OUT] a boolean being true if the css properties are set
     * @param aValueString   [IN/OUT] the attribute value (in) the list of css values (out)
-    * @param aStyleType     [IN] SPECIFIED_STYLE_TYPE to query the specified style values
-    *                            COMPUTED_STYLE_TYPE  to query the computed style values
+    * @param aStyleType     [IN] eSpecified or eComputed
     *
     * The nsIContent variant returns aIsSet instead of using an out parameter.
     */
   bool IsCSSEquivalentToHTMLInlineStyleSet(nsIContent* aContent,
                                            nsIAtom* aProperty,
                                            const nsAString* aAttribute,
                                            const nsAString& aValue,
-                                           PRUint8 aStyleType);
+                                           StyleType aStyleType);
 
   nsresult    IsCSSEquivalentToHTMLInlineStyleSet(nsIDOMNode * aNode,
                                                   nsIAtom * aHTMLProperty,
                                                   const nsAString * aAttribute,
                                                   bool & aIsSet,
                                                   nsAString & aValueString,
-                                                  PRUint8 aStyleType);
+                                                  StyleType aStyleType);
 
   /** Adds to the node the CSS inline styles equivalent to the HTML style
     * and return the number of CSS properties set by the call
     *
     * @param aNode          [IN] a DOM node
     * @param aHTMLProperty  [IN] an atom containing an HTML property
     * @param aAttribute     [IN] a pointer to an attribute name or nsnull if irrelevant
     * @param aValue         [IN] the attribute value
@@ -302,23 +300,22 @@ public:
     *
     * @param aNode           [IN] a node
     * @param aElement        [OUT] the deepest element node containing aNode (possibly aNode itself)
     */
   mozilla::dom::Element* GetElementContainerOrSelf(nsINode* aNode);
   already_AddRefed<nsIDOMElement> GetElementContainerOrSelf(nsIDOMNode* aNode);
 
   /**
-   * Gets the default Window for a given node.
-   *
-   * @param aNode    the node we want the default Window for
-   * @param aWindow  [OUT] the default Window
+   * Gets the computed sty