Merge from mozilla-central.
authorDavid Anderson <danderson@mozilla.com>
Fri, 20 Jul 2012 12:02:04 -0700
changeset 106593 a21ef9ee88f4d0168b073a98cc9c7b9283cf8649
parent 106592 f2faee47a80ff0f75e336056f5c7beb6628e9173 (current diff)
parent 99912 eea94a9b40a1c5d88913adf597f5b84dd89fd4fc (diff)
child 106594 23a84dbb258f6d7221ae270708ef3ed42395cd71
push id1075
push uservporof@mozilla.com
push dateThu, 13 Sep 2012 10:46:49 +0000
treeherderfx-team@f39786e8364d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone17.0a1
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 style for a given element.  Can return null.
    */
-  nsresult GetDefaultViewCSS(nsINode* aNode, nsIDOMWindow** aWindow);
-  nsresult GetDefaultViewCSS(nsIDOMNode* aNode, nsIDOMWindow** aWindow);
+  already_AddRefed<nsComputedDOMStyle>
+    GetComputedStyle(nsIDOMElement* aElement);
+  already_AddRefed<nsComputedDOMStyle>
+    GetComputedStyle(mozilla::dom::Element* aElement);
 
 
 private:
 
   /** retrieves the css property atom from an enum
     *
     * @param aProperty          [IN] the enum value for the property
     * @param aAtom              [OUT] the corresponding atom
@@ -378,26 +375,22 @@ private:
                                    ChangeCSSInlineStyleTxn ** aTxn,
                                    bool aRemoveProperty);
 
   /** back-end for GetSpecifiedProperty and GetComputedProperty
    *
    * @param aNode               [IN] a DOM node
    * @param aProperty           [IN] a CSS property
    * @param aValue              [OUT] the retrieved value for this property
-   * @param aWindow             [IN] the window we need in case we query computed styles
-   * @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 GetCSSInlinePropertyBase(nsINode* aNode, nsIAtom* aProperty,
-                                    nsAString& aValue, nsIDOMWindow* aWindow,
-                                    PRUint8 aStyleType);
+                                    nsAString& aValue, StyleType aStyleType);
   nsresult GetCSSInlinePropertyBase(nsIDOMNode* aNode, nsIAtom* aProperty,
-                                    nsAString& aValue, nsIDOMWindow* aWindow,
-                                    PRUint8 aStyleType);
+                                    nsAString& aValue, StyleType aStyleType);
 
 
 private:
   nsHTMLEditor            *mHTMLEditor;
   bool                    mIsCSSPrefChecked; 
 };
 
 #define NS_EDITOR_INDENT_INCREMENT_IN        0.4134f
--- a/editor/libeditor/html/nsHTMLEditRules.cpp
+++ b/editor/libeditor/html/nsHTMLEditRules.cpp
@@ -831,17 +831,17 @@ nsHTMLEditRules::GetAlignment(bool *aMix
     if (blockParentContent && 
         mHTMLEditor->mHTMLCSSUtils->IsCSSEditableProperty(blockParentContent, dummyProperty, &typeAttrName))
     {
       // we are in CSS mode and we know how to align this element with CSS
       nsAutoStri