Merge from mozilla-central.
authorDavid Anderson <danderson@mozilla.com>
Tue, 21 Aug 2012 15:59:12 -0700
changeset 113571 c797118c02a869e2eda77a380f0f646b84fe6679
parent 113570 32dd9f9afa382cc0b340f78837dd117b3a80ad63 (current diff)
parent 108909 9315dc9bb36f4c0c7c11f4eb639861b272645fa8 (diff)
child 113572 d6599c909132ffa2e368233d7cc730d8137ef9bc
push id239
push userakeybl@mozilla.com
push dateThu, 03 Jan 2013 21:54:43 +0000
treeherdermozilla-release@3a7b66445659 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone17.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge from mozilla-central.
accessible/src/html/HTMLTableAccessible.cpp
b2g/chrome/jar.mn
browser/app/profile/firefox.js
browser/base/content/browser.js
browser/base/content/browser.xul
browser/base/jar.mn
browser/components/sessionstore/test/Makefile.in
browser/locales/en-US/chrome/browser/browser.properties
browser/themes/winstripe/browser.css
caps/include/nsPrincipal.h
caps/src/nsNullPrincipal.cpp
caps/src/nsPrincipal.cpp
caps/src/nsScriptSecurityManager.cpp
caps/src/nsSystemPrincipal.cpp
configure.in
content/base/public/nsContentUtils.h
content/base/public/nsDeprecatedOperationList.h
content/base/public/nsIDocument.h
content/base/public/nsLineBreaker.h
content/base/src/Makefile.in
content/base/src/nsContentSink.cpp
content/base/src/nsContentUtils.cpp
content/base/src/nsCrossSiteListenerProxy.cpp
content/base/src/nsDocument.cpp
content/base/src/nsDocument.h
content/base/src/nsFrameLoader.cpp
content/base/src/nsFrameLoader.h
content/base/src/nsGkAtomList.h
content/base/src/nsLineBreaker.cpp
content/base/src/nsNodeInfo.cpp
content/base/src/nsNodeInfo.h
content/base/src/nsNodeInfoManager.cpp
content/base/src/nsObjectLoadingContent.cpp
content/base/src/nsObjectLoadingContent.h
content/base/src/nsScriptLoader.cpp
content/base/src/nsXMLHttpRequest.cpp
content/canvas/src/WebGLContext.cpp
content/canvas/test/test_canvas.html
content/events/src/nsDOMNotifyAudioAvailableEvent.cpp
content/events/src/nsDOMPopupBlockedEvent.cpp
content/events/src/nsDOMPopupBlockedEvent.h
content/events/src/nsEventListenerManager.cpp
content/events/src/nsEventStateManager.cpp
content/events/src/nsEventStateManager.h
content/events/src/nsIMEStateManager.cpp
content/events/test/Makefile.in
content/events/test/test_bug422132.html
content/html/content/public/nsHTMLMediaElement.h
content/html/content/src/nsHTMLCanvasElement.cpp
content/html/content/src/nsHTMLFormElement.cpp
content/html/content/src/nsHTMLIFrameElement.cpp
content/html/content/src/nsHTMLInputElement.cpp
content/html/content/src/nsHTMLInputElement.h
content/html/content/src/nsHTMLMediaElement.cpp
content/html/content/src/nsHTMLVideoElement.cpp
content/html/document/src/nsHTMLDocument.cpp
content/media/MediaResource.cpp
content/media/MediaResource.h
content/media/nsAudioStream.cpp
content/media/nsBuiltinDecoder.cpp
content/media/nsBuiltinDecoder.h
content/media/nsBuiltinDecoderReader.cpp
content/media/nsBuiltinDecoderReader.h
content/media/nsBuiltinDecoderStateMachine.cpp
content/media/nsBuiltinDecoderStateMachine.h
content/media/nsMediaDecoder.h
content/media/ogg/nsOggDecoderStateMachine.cpp
content/media/ogg/nsOggDecoderStateMachine.h
content/media/ogg/nsOggReader.cpp
content/xbl/src/nsXBLBinding.cpp
content/xbl/src/nsXBLPrototypeHandler.cpp
content/xbl/src/nsXBLService.cpp
content/xml/document/src/nsXMLContentSink.cpp
content/xml/document/src/nsXMLDocument.cpp
content/xul/document/src/nsXULDocument.cpp
content/xul/templates/src/nsXULTemplateBuilder.cpp
docshell/base/nsDocShell.cpp
docshell/base/nsDocShell.h
docshell/test/browser/browser_bug435325.js
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfoClasses.h
dom/base/nsGlobalWindow.cpp
dom/base/nsPluginArray.cpp
dom/bluetooth/BluetoothDeviceEvent.cpp
dom/bluetooth/BluetoothDeviceEvent.h
dom/indexedDB/IDBTransaction.cpp
dom/ipc/ContentChild.cpp
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/PBrowser.ipdl
dom/ipc/PContent.ipdl
dom/ipc/TabChild.cpp
dom/ipc/TabChild.h
dom/ipc/TabParent.cpp
dom/ipc/TabParent.h
dom/locales/en-US/chrome/dom/dom.properties
dom/plugins/base/nsNPAPIPlugin.cpp
dom/plugins/base/nsNPAPIPluginInstance.cpp
dom/plugins/base/nsNPAPIPluginInstance.h
dom/plugins/base/nsPluginInstanceOwner.cpp
dom/plugins/base/nsPluginsDirUnix.cpp
dom/plugins/ipc/PluginInstanceChild.cpp
dom/plugins/ipc/PluginInstanceParent.cpp
dom/plugins/ipc/PluginInstanceParent.h
dom/plugins/ipc/PluginModuleChild.cpp
dom/plugins/test/reftest/reftest.list
dom/src/jsurl/nsJSProtocolHandler.cpp
dom/wifi/WifiWorker.js
dom/workers/ScriptLoader.cpp
dom/workers/WorkerPrivate.cpp
dom/workers/XMLHttpRequest.cpp
editor/composer/src/nsComposerDocumentCommands.cpp
editor/composer/src/nsEditingSession.cpp
editor/libeditor/html/nsHTMLEditor.cpp
embedding/android/GeckoAppShell.java
embedding/android/GeckoSurfaceView.java
embedding/browser/webBrowser/nsWebBrowserContentPolicy.cpp
embedding/components/windowwatcher/src/nsWindowWatcher.cpp
embedding/components/windowwatcher/src/nsWindowWatcher.h
extensions/permissions/nsContentBlocker.cpp
gfx/gl/GLContext.cpp
gfx/gl/GLContext.h
gfx/gl/GLContextProviderGLX.cpp
gfx/gl/GLXLibrary.h
gfx/harfbuzz/src/hb-fallback-shape-private.hh
gfx/harfbuzz/src/hb-graphite2-private.hh
gfx/harfbuzz/src/hb-ot-shape.cc
gfx/harfbuzz/src/hb-ot-shape.h
gfx/harfbuzz/src/hb-uniscribe-private.hh
gfx/layers/ImageLayers.h
gfx/layers/Layers.cpp
gfx/layers/Layers.h
gfx/layers/basic/BasicBuffers.h
gfx/layers/basic/BasicCanvasLayer.cpp
gfx/layers/basic/BasicImageLayer.cpp
gfx/layers/basic/BasicImages.cpp
gfx/layers/basic/BasicLayerManager.cpp
gfx/layers/basic/BasicLayers.h
gfx/layers/basic/BasicLayersImpl.h
gfx/layers/d3d10/CanvasLayerD3D10.cpp
gfx/layers/d3d10/CanvasLayerD3D10.h
gfx/layers/d3d10/ImageLayerD3D10.cpp
gfx/layers/d3d10/ImageLayerD3D10.h
gfx/layers/d3d9/CanvasLayerD3D9.cpp
gfx/layers/d3d9/CanvasLayerD3D9.h
gfx/layers/d3d9/ImageLayerD3D9.cpp
gfx/layers/d3d9/ImageLayerD3D9.h
gfx/layers/d3d9/ThebesLayerD3D9.cpp
gfx/layers/ipc/PLayers.ipdl
gfx/layers/ipc/ShadowLayerUtilsX11.cpp
gfx/layers/ipc/ShadowLayersParent.cpp
gfx/layers/opengl/CanvasLayerOGL.cpp
gfx/layers/opengl/CanvasLayerOGL.h
gfx/layers/opengl/ImageLayerOGL.cpp
gfx/layers/opengl/ImageLayerOGL.h
gfx/thebes/gfxBlur.h
gfx/thebes/gfxDrawable.cpp
gfx/thebes/gfxUtils.h
gfx/thebes/gfxXlibSurface.h
image/src/RasterImage.cpp
js/jsd/jsd_scpt.c
js/src/Makefile.in
js/src/configure.in
js/src/frontend/BytecodeCompiler.cpp
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/frontend/SemanticAnalysis.cpp
js/src/frontend/TreeContext-inl.h
js/src/frontend/TreeContext.cpp
js/src/frontend/TreeContext.h
js/src/gc/Statistics.h
js/src/ion/CodeGenerator.cpp
js/src/jitstats.tbl
js/src/js.msg
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jsarray.cpp
js/src/jsbool.cpp
js/src/jscntxt.cpp
js/src/jscntxt.h
js/src/jscompartment.h
js/src/jsdate.cpp
js/src/jsexn.cpp
js/src/jsfriendapi.cpp
js/src/jsfriendapi.h
js/src/jsfun.cpp
js/src/jsfun.h
js/src/jsgc.cpp
js/src/jsgc.h
js/src/jsinfer.cpp
js/src/jsinfer.h
js/src/jsinterpinlines.h
js/src/jsiter.cpp
js/src/jsnum.cpp
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jsopcode.cpp
js/src/jsopcode.h
js/src/jsopcode.tbl
js/src/jsproto.tbl
js/src/jsreflect.cpp
js/src/jsscript.cpp
js/src/jsscript.h
js/src/jsscriptinlines.h
js/src/jsstr.cpp
js/src/jsstr.h
js/src/jstypedarray.cpp
js/src/jsweakmap.cpp
js/src/jsxml.cpp
js/src/methodjit/BaseAssembler.h
js/src/methodjit/Compiler.cpp
js/src/methodjit/FastOps.cpp
js/src/methodjit/MonoIC.cpp
js/src/methodjit/PolyIC.cpp
js/src/shell/js.cpp
js/src/vm/Debugger.cpp
js/src/vm/GlobalObject.cpp
js/src/vm/SPSProfiler.cpp
js/src/vm/ScopeObject.h
js/src/vm/Stack.cpp
js/src/vm/Stack.h
js/src/vm/String.h
js/xpconnect/idl/xpccomponents.idl
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/tests/chrome/test_bug758563.xul
js/xpconnect/tests/mochitest/file_bug758563.html
js/xpconnect/wrappers/AccessCheck.cpp
js/xpconnect/wrappers/WrapperFactory.cpp
layout/base/FrameLayerBuilder.cpp
layout/base/FrameLayerBuilder.h
layout/base/nsCSSRendering.cpp
layout/base/nsDisplayList.cpp
layout/base/nsDisplayList.h
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
layout/base/nsPresContext.cpp
layout/base/nsPresContext.h
layout/base/nsPresShell.cpp
layout/forms/nsTextControlFrame.cpp
layout/generic/nsColumnSetFrame.cpp
layout/generic/nsFrame.cpp
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsHTMLCanvasFrame.cpp
layout/generic/nsHTMLReflowState.cpp
layout/generic/nsHTMLReflowState.h
layout/generic/nsImageFrame.cpp
layout/generic/nsObjectFrame.cpp
layout/generic/nsObjectFrame.h
layout/generic/nsSubDocumentFrame.cpp
layout/generic/nsSubDocumentFrame.h
layout/generic/nsTextFrameThebes.cpp
layout/generic/nsVideoFrame.cpp
layout/ipc/RenderFrameParent.cpp
layout/ipc/RenderFrameParent.h
layout/mathml/nsMathMLChar.cpp
layout/mathml/nsMathMLChar.h
layout/reftests/bugs/reftest.list
layout/reftests/css-namespace/LICENSE
layout/reftests/css-namespace/README
layout/reftests/css-namespace/prefix-001.xml
layout/reftests/css-namespace/prefix-002.xml
layout/reftests/css-namespace/prefix-003.xml
layout/reftests/css-namespace/prefix-004.xml
layout/reftests/css-namespace/prefix-005.xml
layout/reftests/css-namespace/prefix-006.xml
layout/reftests/css-namespace/ref-lime-1-block.xml
layout/reftests/css-namespace/ref-lime-1-generic.xml
layout/reftests/css-namespace/ref-lime-1.xml
layout/reftests/css-namespace/ref-lime-2-generic.xml
layout/reftests/css-namespace/ref-lime-2.xml
layout/reftests/css-namespace/ref-lime-3.xml
layout/reftests/css-namespace/ref-lime-5.xml
layout/reftests/css-namespace/ref-lime-6.xml
layout/reftests/css-namespace/reftest.list
layout/reftests/css-namespace/scope-001.xml
layout/reftests/css-namespace/scope-002.xml
layout/reftests/css-namespace/support/fail.css
layout/reftests/css-namespace/support/scope-002a.css
layout/reftests/css-namespace/support/scope-002b.css
layout/reftests/css-namespace/support/syntax-007.css
layout/reftests/css-namespace/syntax-001.xml
layout/reftests/css-namespace/syntax-002.xml
layout/reftests/css-namespace/syntax-003.xml
layout/reftests/css-namespace/syntax-004.xml
layout/reftests/css-namespace/syntax-005.xml
layout/reftests/css-namespace/syntax-006.xml
layout/reftests/css-namespace/syntax-007.xml
layout/reftests/css-namespace/syntax-008.xml
layout/reftests/css-namespace/syntax-009.xml
layout/reftests/css-namespace/syntax-010.xml
layout/reftests/css-namespace/syntax-011.xml
layout/reftests/css-namespace/syntax-012.xml
layout/reftests/css-namespace/syntax-013.xml
layout/reftests/css-namespace/syntax-014.xml
layout/reftests/css-namespace/syntax-015.xml
layout/reftests/reftest.list
layout/reftests/text/reftest.list
layout/style/Loader.cpp
layout/style/nsAnimationManager.cpp
layout/style/nsAnimationManager.h
layout/style/nsCSSParser.cpp
layout/style/nsRuleNode.cpp
layout/style/nsStyleStruct.cpp
layout/style/nsStyleStruct.h
layout/style/test/property_database.js
layout/xul/base/src/nsImageBoxFrame.cpp
media/omx-plugin/include/ics/OMX.h
media/omx-plugin/lib/ics/libstagefright_omx/Makefile.in
media/omx-plugin/lib/ics/libstagefright_omx/libstagefright_omx.cpp
mobile/android/base/GeckoApp.java
mobile/android/base/GeckoAppShell.java
mobile/android/base/Makefile.in
mobile/android/base/resources/drawable-hdpi-v11/ic_menu_clear_site_settings.png
mobile/android/base/resources/drawable-hdpi/abouthome_sync_bg.9.png
mobile/android/base/resources/drawable-hdpi/abouthome_sync_pressed_bg.9.png
mobile/android/base/resources/drawable-mdpi-v11/ic_menu_clear_site_settings.png
mobile/android/base/resources/drawable-xhdpi-v11/ic_menu_clear_site_settings.png
mobile/android/base/resources/drawable-xhdpi/abouthome_sync_bg.9.png
mobile/android/base/resources/drawable-xhdpi/abouthome_sync_pressed_bg.9.png
mobile/android/base/resources/drawable/abouthome_sync_bg.9.png
mobile/android/base/resources/drawable/abouthome_sync_box.xml
mobile/android/base/resources/drawable/abouthome_sync_pressed_bg.9.png
mobile/android/chrome/content/browser.js
mobile/android/themes/core/aboutReader.css
mobile/android/themes/core/images/reader-dark-bg.png
mobile/android/themes/core/images/reader-light-bg.png
mobile/android/themes/core/images/reader-sepia-bg.png
mobile/xul/installer/package-manifest.in
modules/libpref/src/init/all.js
netwerk/cache/nsCacheEntryDescriptor.cpp
netwerk/cache/nsCacheEntryDescriptor.h
netwerk/cache/nsCacheService.cpp
netwerk/cache/nsCacheService.h
netwerk/cache/nsDiskCacheMap.cpp
netwerk/cache/nsDiskCacheMap.h
netwerk/protocol/ftp/nsFtpConnectionThread.cpp
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/protocol/http/nsHttpHandler.cpp
netwerk/protocol/http/nsHttpTransaction.cpp
netwerk/protocol/http/nsHttpTransaction.h
parser/html/nsHtml5Parser.cpp
parser/html/nsHtml5StreamParser.cpp
parser/html/nsHtml5TreeOpExecutor.cpp
rdf/base/src/nsRDFXMLDataSource.cpp
rdf/tests/rdfcat/rdfcat.cpp
rdf/tests/triplescat/triplescat.cpp
security/manager/ssl/src/nsNSSComponent.cpp
security/manager/ssl/src/nsPKCS12Blob.cpp
testing/jetpack/jetpack-location.txt
testing/mochitest/tests/SimpleTest/setup.js
toolkit/components/startup/nsAppStartup.cpp
toolkit/components/telemetry/TelemetryHistograms.h
toolkit/components/telemetry/TelemetryPing.js
toolkit/components/telemetry/tests/unit/test_TelemetryPing.js
toolkit/content/license.html
toolkit/mozapps/extensions/AddonRepository.jsm
toolkit/mozapps/extensions/XPIProvider.jsm
toolkit/mozapps/extensions/content/extensions.js
toolkit/mozapps/extensions/test/browser/browser_inlinesettings.js
toolkit/mozapps/installer/packager.mk
toolkit/webapps/WebappsInstaller.jsm
view/src/nsView.cpp
view/src/nsView.h
view/src/nsViewManager.cpp
widget/android/AndroidBridge.cpp
widget/android/AndroidBridge.h
widget/android/nsAppShell.cpp
widget/android/nsWindow.cpp
widget/cocoa/nsChildView.mm
widget/cocoa/nsNativeThemeCocoa.mm
widget/nsGUIEvent.h
widget/nsIWidget.h
widget/qt/nsWindow.cpp
widget/windows/nsNativeThemeWin.cpp
widget/windows/nsWindow.cpp
widget/windows/nsWindowDefs.h
widget/xpwidgets/PuppetWidget.cpp
widget/xpwidgets/nsBaseFilePicker.cpp
widget/xpwidgets/nsBaseFilePicker.h
widget/xpwidgets/nsBaseWidget.cpp
xpcom/io/nsLocalFileCommon.cpp
xpcom/tests/TestDeadlockDetector.cpp
--- a/accessible/src/html/HTMLTableAccessible.cpp
+++ b/accessible/src/html/HTMLTableAccessible.cpp
@@ -1208,23 +1208,23 @@ HTMLTableAccessible::IsProbablyLayoutTab
     RETURN_LAYOUT_ANSWER(false, ">=5 columns");
   }
 
   // Now we know there are 2-4 columns and 2 or more rows
   // Check to see if there are visible borders on the cells
   // XXX currently, we just check the first cell -- do we really need to do more?
   nsCOMPtr<nsIDOMElement> cellElement;
   nsresult rv = GetCellAt(0, 0, *getter_AddRefs(cellElement));
-  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
+  NS_ENSURE_SUCCESS(rv, false);
 
   nsCOMPtr<nsIContent> cellContent(do_QueryInterface(cellElement));
-  NS_ENSURE_TRUE(cellContent, NS_ERROR_FAILURE);
+  NS_ENSURE_TRUE(cellContent, false);
   nsIFrame *cellFrame = cellContent->GetPrimaryFrame();
   if (!cellFrame) {
-    return NS_OK;
+    RETURN_LAYOUT_ANSWER(false, "Could not get frame for cellContent");
   }
   nsMargin border;
   cellFrame->GetBorder(border);
   if (border.top && border.bottom && border.left && border.right) {
     RETURN_LAYOUT_ANSWER(false, "Has nonzero border-width on table cell");
   }
 
   /**
--- a/accessible/src/jsat/AccessFu.css
+++ b/accessible/src/jsat/AccessFu.css
@@ -1,22 +1,30 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#virtual-cursor-box { 
+#virtual-cursor-box {
   position: fixed;
   border: 1px solid orange;
   pointer-events: none;
   display: none;
   border-radius: 2px;
   box-shadow: 1px 1px 1px #444;
 }
 
-#virtual-cursor-inset { 
+#virtual-cursor-inset {
   border-radius: 1px;
   box-shadow: inset 1px 1px 1px #444;
   display: block;
   box-sizing: border-box;
   width: 100%;
   height: 100%;
   pointer-events: none;
-}
\ No newline at end of file
+}
+
+#accessfu-glass {
+  width: 100%;
+  height: 100%;
+  position: fixed;
+  top: 0px;
+  left: 0px;
+}
--- a/accessible/src/jsat/AccessFu.jsm
+++ b/accessible/src/jsat/AccessFu.jsm
@@ -11,16 +11,17 @@ const Cr = Components.results;
 
 var EXPORTED_SYMBOLS = ['AccessFu'];
 
 Cu.import('resource://gre/modules/Services.jsm');
 
 Cu.import('resource://gre/modules/accessibility/Utils.jsm');
 Cu.import('resource://gre/modules/accessibility/Presenters.jsm');
 Cu.import('resource://gre/modules/accessibility/VirtualCursorController.jsm');
+Cu.import('resource://gre/modules/accessibility/TouchAdapter.jsm');
 
 const ACCESSFU_DISABLE = 0;
 const ACCESSFU_ENABLE = 1;
 const ACCESSFU_AUTO = 2;
 
 var AccessFu = {
   /**
    * Attach chrome-layer accessibility functionality to the given chrome window.
@@ -39,32 +40,55 @@ var AccessFu = {
     this.chromeWin = aWindow;
     this.presenters = [];
 
     this.prefsBranch = Cc['@mozilla.org/preferences-service;1']
       .getService(Ci.nsIPrefService).getBranch('accessibility.accessfu.');
     this.prefsBranch.addObserver('activate', this, false);
     this.prefsBranch.addObserver('explorebytouch', this, false);
 
-    if (Utils.MozBuildApp == 'mobile/android')
-      Services.obs.addObserver(this, 'Accessibility:Settings', false);
+    this.touchAdapter = TouchAdapter;
+
+    switch(Utils.MozBuildApp) {
+      case 'mobile/android':
+        Services.obs.addObserver(this, 'Accessibility:Settings', false);
+        this.touchAdapter = AndroidTouchAdapter;
+        break;
+      case 'b2g':
+        aWindow.addEventListener(
+          'ContentStart',
+          (function(event) {
+             let content = aWindow.shell.contentBrowser.contentWindow;
+             content.addEventListener('mozContentEvent', this, false, true);
+           }).bind(this), false);
+        break;
+      default:
+        break;
+    }
 
     this._processPreferences();
   },
 
   /**
    * Start AccessFu mode, this primarily means controlling the virtual cursor
    * with arrow keys.
    */
   _enable: function _enable() {
     if (this._enabled)
       return;
     this._enabled = true;
 
     Logger.info('enable');
+
+    // Add stylesheet
+    let stylesheetURL = 'chrome://global/content/accessibility/AccessFu.css';
+    this.stylesheet = this.chromeWin.document.createProcessingInstruction(
+      'xml-stylesheet', 'href="' + stylesheetURL + '" type="text/css"');
+    this.chromeWin.document.insertBefore(this.stylesheet, this.chromeWin.document.firstChild);
+
     this.addPresenter(new VisualPresenter());
 
     // Implicitly add the Android presenter on Android.
     if (Utils.MozBuildApp == 'mobile/android')
       this.addPresenter(new AndroidPresenter());
     else if (Utils.MozBuildApp == 'b2g')
       this.addPresenter(new SpeechPresenter());
 
@@ -83,16 +107,18 @@ var AccessFu = {
    */
   _disable: function _disable() {
     if (!this._enabled)
       return;
     this._enabled = false;
 
     Logger.info('disable');
 
+    this.chromeWin.document.removeChild(this.stylesheet);
+
     this.presenters.forEach(function(p) { p.detach(); });
     this.presenters = [];
 
     VirtualCursorController.detach();
 
     Services.obs.removeObserver(this, 'accessible-event');
     this.chromeWin.removeEventListener('DOMActivate', this, true);
     this.chromeWin.removeEventListener('resize', this, true);
@@ -125,18 +151,20 @@ var AccessFu = {
       }
     }
 
     if (accessPref == ACCESSFU_ENABLE)
       this._enable();
     else
       this._disable();
 
-    VirtualCursorController.exploreByTouch = ebtPref == ACCESSFU_ENABLE;
-    Logger.info('Explore by touch:', VirtualCursorController.exploreByTouch);
+    if (ebtPref == ACCESSFU_ENABLE)
+      this.touchAdapter.attach(this.chromeWin);
+    else
+      this.touchAdapter.detach(this.chromeWin);
   },
 
   addPresenter: function addPresenter(presenter) {
     this.presenters.push(presenter);
     presenter.attach(this.chromeWin);
   },
 
   handleEvent: function handleEvent(aEvent) {
@@ -187,16 +215,24 @@ var AccessFu = {
         break;
       }
       case 'scroll':
       case 'resize':
       {
         this.presenters.forEach(function(p) { p.viewportChanged(); });
         break;
       }
+      case 'mozContentEvent':
+      {
+        if (aEvent.detail.type == 'accessibility-screenreader') {
+          let pref = aEvent.detail.enabled + 0;
+          this._processPreferences(pref, pref);
+        }
+        break;
+      }
     }
   },
 
   observe: function observe(aSubject, aTopic, aData) {
     switch (aTopic) {
       case 'Accessibility:Settings':
         this._processPreferences(JSON.parse(aData).enabled + 0,
                                  JSON.parse(aData).exploreByTouch + 0);
--- a/accessible/src/jsat/Presenters.jsm
+++ b/accessible/src/jsat/Presenters.jsm
@@ -112,38 +112,31 @@ VisualPresenter.prototype = {
   /**
    * The padding in pixels between the object and the highlight border.
    */
   BORDER_PADDING: 2,
 
   attach: function VisualPresenter_attach(aWindow) {
     this.chromeWin = aWindow;
 
-    // Add stylesheet
-    let stylesheetURL = 'chrome://global/content/accessibility/AccessFu.css';
-    this.stylesheet = aWindow.document.createProcessingInstruction(
-      'xml-stylesheet', 'href="' + stylesheetURL + '" type="text/css"');
-    aWindow.document.insertBefore(this.stylesheet, aWindow.document.firstChild);
-
     // Add highlight box
     this.highlightBox = this.chromeWin.document.
       createElementNS('http://www.w3.org/1999/xhtml', 'div');
     this.chromeWin.document.documentElement.appendChild(this.highlightBox);
     this.highlightBox.id = 'virtual-cursor-box';
 
     // Add highlight inset for inner shadow
     let inset = this.chromeWin.document.
       createElementNS('http://www.w3.org/1999/xhtml', 'div');
     inset.id = 'virtual-cursor-inset';
 
     this.highlightBox.appendChild(inset);
   },
 
   detach: function VisualPresenter_detach() {
-    this.chromeWin.document.removeChild(this.stylesheet);
     this.highlightBox.parentNode.removeChild(this.highlightBox);
     this.highlightBox = this.stylesheet = null;
   },
 
   viewportChanged: function VisualPresenter_viewportChanged() {
     if (this._currentObject)
       this._highlight(this._currentObject);
   },
new file mode 100644
--- /dev/null
+++ b/accessible/src/jsat/TouchAdapter.jsm
@@ -0,0 +1,402 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+'use strict';
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+const Cr = Components.results;
+
+var EXPORTED_SYMBOLS = ['TouchAdapter', 'AndroidTouchAdapter'];
+
+Cu.import('resource://gre/modules/accessibility/Utils.jsm');
+
+// We should not be emitting explore events more than 10 times a second.
+// It is granular enough to feel natural, and it does not hammer the CPU.
+const EXPLORE_THROTTLE = 100;
+
+var TouchAdapter = {
+  // minimal swipe distance in inches
+  SWIPE_MIN_DISTANCE: 0.4,
+
+  // maximum duration of swipe
+  SWIPE_MAX_DURATION: 400,
+
+  // how straight does a swipe need to be
+  SWIPE_DIRECTNESS: 1.2,
+
+  // maximum consecutive
+  MAX_CONSECUTIVE_GESTURE_DELAY: 400,
+
+  // delay before tap turns into dwell
+  DWELL_THRESHOLD: 500,
+
+  // delay before distinct dwell events
+  DWELL_REPEAT_DELAY: 300,
+
+  // maximum distance the mouse could move during a tap in inches
+  TAP_MAX_RADIUS: 0.2,
+
+  attach: function TouchAdapter_attach(aWindow) {
+    if (this.chromeWin)
+      return;
+
+    Logger.info('TouchAdapter.attach');
+
+    this.chromeWin = aWindow;
+    this._touchPoints = {};
+    this._dwellTimeout = 0;
+    this._prevGestures = {};
+    this._lastExploreTime = 0;
+    this._dpi = this.chromeWin.QueryInterface(Ci.nsIInterfaceRequestor).
+      getInterface(Ci.nsIDOMWindowUtils).displayDPI;
+
+    this.glass = this.chromeWin.document.
+      createElementNS('http://www.w3.org/1999/xhtml', 'div');
+    this.glass.id = 'accessfu-glass';
+    this.chromeWin.document.documentElement.appendChild(this.glass);
+
+    this.glass.addEventListener('touchend', this, true, true);
+    this.glass.addEventListener('touchmove', this, true, true);
+    this.glass.addEventListener('touchstart', this, true, true);
+
+    if (Utils.OS != 'Android')
+      Mouse2Touch.attach(aWindow);
+  },
+
+  detach: function TouchAdapter_detach(aWindow) {
+    if (!this.chromeWin)
+      return;
+
+    Logger.info('TouchAdapter.detach');
+
+    this.glass.removeEventListener('touchend', this, true, true);
+    this.glass.removeEventListener('touchmove', this, true, true);
+    this.glass.removeEventListener('touchstart', this, true, true);
+    this.glass.parentNode.removeChild(this.glass);
+
+    if (Utils.OS != 'Android')
+      Mouse2Touch.detach(aWindow);
+
+    delete this.chromeWin;
+  },
+
+  handleEvent: function TouchAdapter_handleEvent(aEvent) {
+    let touches = aEvent.changedTouches;
+    switch (aEvent.type) {
+      case 'touchstart':
+        for (var i = 0; i < touches.length; i++) {
+          let touch = touches[i];
+          let touchPoint = new TouchPoint(touch, aEvent.timeStamp, this._dpi);
+          this._touchPoints[touch.identifier] = touchPoint;
+          this._lastExploreTime = aEvent.timeStamp + this.SWIPE_MAX_DURATION;
+        }
+        this._dwellTimeout = this.chromeWin.setTimeout(
+          (function () {
+             this.compileAndEmit(aEvent.timeStamp + this.DWELL_THRESHOLD);
+           }).bind(this), this.DWELL_THRESHOLD);
+        break;
+      case 'touchmove':
+        for (var i = 0; i < touches.length; i++) {
+          let touch = touches[i];
+          let touchPoint = this._touchPoints[touch.identifier];
+          touchPoint.update(touch, aEvent.timeStamp);
+        }
+        if (aEvent.timeStamp - this._lastExploreTime >= EXPLORE_THROTTLE) {
+          this.compileAndEmit(aEvent.timeStamp);
+          this._lastExploreTime = aEvent.timeStamp;
+        }
+        break;
+      case 'touchend':
+        for (var i = 0; i < touches.length; i++) {
+          let touch = touches[i];
+          let touchPoint = this._touchPoints[touch.identifier];
+          touchPoint.update(touch, aEvent.timeStamp);
+          touchPoint.finish();
+        }
+        this.compileAndEmit(aEvent.timeStamp);
+        break;
+    }
+  },
+
+  cleanupTouches: function cleanupTouches() {
+    for (var identifier in this._touchPoints) {
+      if (!this._touchPoints[identifier].done)
+        continue;
+
+      delete this._touchPoints[identifier];
+    }
+  },
+
+  compile: function TouchAdapter_compile(aTime) {
+    let multiDetails = {};
+
+    // Compound multiple simultaneous touch gestures.
+    for (let identifier in this._touchPoints) {
+      let touchPoint = this._touchPoints[identifier];
+      let details = touchPoint.compile(aTime);
+
+      if (!details)
+        continue;
+
+      details.touches = [identifier];
+
+      let otherTouches = multiDetails[details.type];
+      if (otherTouches) {
+        otherTouches.touches.push(identifier);
+        otherTouches.startTime =
+          Math.min(otherTouches.startTime, touchPoint.startTime);
+      } else {
+        details.startTime = touchPoint.startTime;
+        details.endTime = aTime;
+        multiDetails[details.type] = details;
+      }
+    }
+
+    // Compound multiple consecutive touch gestures.
+    for each (let details in multiDetails) {
+      let idhash = details.touches.slice().sort().toString();
+      let prevGesture = this._prevGestures[idhash];
+
+      if (prevGesture) {
+        // The time delta is calculated as the period between the end of the
+        // last gesture and the start of this one.
+        let timeDelta = details.startTime - prevGesture.endTime;
+        if (timeDelta > this.MAX_CONSECUTIVE_GESTURE_DELAY) {
+          delete this._prevGestures[idhash];
+        } else {
+          if (details.type == 'tap' && prevGesture.type == 'tap')
+            details.type = 'doubletap';
+          if (details.type == 'tap' && prevGesture.type == 'doubletap')
+            details.type = 'tripletap';
+          if (details.type == 'dwell' && prevGesture.type == 'tap')
+            details.type = 'taphold';
+        }
+      }
+
+      this._prevGestures[idhash] = details;
+    }
+
+    this.chromeWin.clearTimeout(this._dwellTimeout);
+    this.cleanupTouches();
+
+    return multiDetails;
+  },
+
+  emitGesture: function TouchAdapter_emitGesture(aDetails) {
+    let evt = this.chromeWin.document.createEvent('CustomEvent');
+    evt.initCustomEvent('mozAccessFuGesture', true, true, aDetails);
+    this.chromeWin.dispatchEvent(evt);
+  },
+
+  compileAndEmit: function TouchAdapter_compileAndEmit(aTime) {
+    for each (let details in this.compile(aTime)) {
+      this.emitGesture(details);
+    }
+  }
+};
+
+/***
+ * A TouchPoint represents a single touch from the moment of contact until it is
+ * lifted from the surface. It is capable of compiling gestures from the scope
+ * of one single touch.
+ */
+function TouchPoint(aTouch, aTime, aDPI) {
+  this.startX = aTouch.screenX;
+  this.startY = aTouch.screenY;
+  this.startTime = aTime;
+  this.distanceTraveled = 0;
+  this.dpi = aDPI;
+  this.done = false;
+}
+
+TouchPoint.prototype = {
+  update: function TouchPoint_update(aTouch, aTime) {
+    let lastX = this.x;
+    let lastY = this.y;
+    this.x = aTouch.screenX;
+    this.y = aTouch.screenY;
+    this.time = aTime;
+
+    if (lastX != undefined && lastY != undefined)
+      this.distanceTraveled += this.getDistanceToCoord(lastX, lastY);
+  },
+
+  getDistanceToCoord: function TouchPoint_getDistanceToCoord(aX, aY) {
+    return Math.sqrt(Math.pow(this.x - aX, 2) + Math.pow(this.y - aY, 2));
+  },
+
+  finish: function TouchPoint_finish() {
+    this.done = true;
+  },
+
+  /**
+   * Compile a gesture from an individual touch point. This is used by the
+   * TouchAdapter to compound multiple single gestures in to higher level
+   * gestures.
+   */
+  compile: function TouchPoint_compile(aTime) {
+    let directDistance = this.directDistanceTraveled;
+    let duration = aTime - this.startTime;
+
+    // To be considered a tap/dwell...
+    if ((this.distanceTraveled / this.dpi) < TouchAdapter.TAP_MAX_RADIUS) { // Didn't travel
+      if (duration < TouchAdapter.DWELL_THRESHOLD) {
+        // Mark it as done so we don't use this touch for another gesture.
+        this.finish();
+        return {type: 'tap', x: this.startX, y: this.startY};
+      } else if (!this.done && duration == TouchAdapter.DWELL_THRESHOLD) {
+        return {type: 'dwell', x: this.startX, y: this.startY};
+      }
+    }
+
+    // To be considered a swipe...
+    if (duration <= TouchAdapter.SWIPE_MAX_DURATION && // Quick enough
+        (directDistance / this.dpi) >= TouchAdapter.SWIPE_MIN_DISTANCE && // Traveled far
+        (directDistance * 1.2) >= this.distanceTraveled) { // Direct enough
+
+      let swipeGesture = {x1: this.startX, y1: this.startY,
+                          x2: this.x, y2: this.y};
+      let deltaX = this.x - this.startX;
+      let deltaY = this.y - this.startY;
+
+      if (Math.abs(deltaX) > Math.abs(deltaY)) {
+        // Horizontal swipe.
+        if (deltaX > 0)
+          swipeGesture.type = 'swiperight';
+        else
+          swipeGesture.type = 'swipeleft';
+      } else if (Math.abs(deltaX) < Math.abs(deltaY)) {
+        // Vertical swipe.
+        if (deltaY > 0)
+          swipeGesture.type = 'swipedown';
+        else
+          swipeGesture.type = 'swipeup';
+      } else {
+        // A perfect 45 degree swipe?? Not in our book.
+          return null;
+      }
+
+      this.finish();
+
+      return swipeGesture;
+    }
+
+    // To be considered an explore...
+    if (!this.done &&
+        duration > TouchAdapter.SWIPE_MAX_DURATION &&
+        (this.distanceTraveled / this.dpi) > TouchAdapter.TAP_MAX_RADIUS) {
+      return {type: 'explore', x: this.x, y: this.y};
+    }
+
+    return null;
+  },
+
+  get directDistanceTraveled() {
+    return this.getDistanceToCoord(this.startX, this.startY);
+  }
+};
+
+var Mouse2Touch = {
+  _MouseToTouchMap: {
+    mousedown: 'touchstart',
+    mouseup: 'touchend',
+    mousemove: 'touchmove'
+  },
+
+  attach: function Mouse2Touch_attach(aWindow) {
+    this.chromeWin = aWindow;
+    this.chromeWin.addEventListener('mousedown', this, true, true);
+    this.chromeWin.addEventListener('mouseup', this, true, true);
+    this.chromeWin.addEventListener('mousemove', this, true, true);
+  },
+
+  detach: function Mouse2Touch_detach(aWindow) {
+    this.chromeWin.removeEventListener('mousedown', this, true, true);
+    this.chromeWin.removeEventListener('mouseup', this, true, true);
+    this.chromeWin.removeEventListener('mousemove', this, true, true);
+  },
+
+  handleEvent: function Mouse2Touch_handleEvent(aEvent) {
+    if (aEvent.buttons == 0)
+      return;
+
+    let name = this._MouseToTouchMap[aEvent.type];
+    let evt = this.chromeWin.document.createEvent("touchevent");
+    let points = [this.chromeWin.document.createTouch(
+                    this.chromeWin, aEvent.target, 0,
+                    aEvent.pageX, aEvent.pageY, aEvent.screenX, aEvent.screenY,
+                    aEvent.clientX, aEvent.clientY, 1, 1, 0, 0)];
+
+    // Simulate another touch point at a 5px offset when ctrl is pressed.
+    if (aEvent.ctrlKey)
+      points.push(this.chromeWin.document.createTouch(
+                    this.chromeWin, aEvent.target, 1,
+                    aEvent.pageX + 5, aEvent.pageY + 5,
+                    aEvent.screenX + 5, aEvent.screenY + 5,
+                    aEvent.clientX + 5, aEvent.clientY + 5,
+                    1, 1, 0, 0));
+
+    // Simulate another touch point at a -5px offset when alt is pressed.
+    if (aEvent.altKey)
+      points.push(this.chromeWin.document.createTouch(
+                    this.chromeWin, aEvent.target, 2,
+                    aEvent.pageX - 5, aEvent.pageY - 5,
+                    aEvent.screenX - 5, aEvent.screenY - 5,
+                    aEvent.clientX - 5, aEvent.clientY - 5,
+                    1, 1, 0, 0));
+
+    let touches = this.chromeWin.document.createTouchList(points);
+    if (name == "touchend") {
+      let empty = this.chromeWin.document.createTouchList();
+      evt.initTouchEvent(name, true, true, this.chromeWin, 0,
+                         false, false, false, false, empty, empty, touches);
+    } else {
+      evt.initTouchEvent(name, true, true, this.chromeWin, 0,
+                         false, false, false, false, touches, touches, touches);
+    }
+    aEvent.target.dispatchEvent(evt);
+    aEvent.preventDefault();
+    aEvent.stopImmediatePropagation();
+  }
+};
+
+var AndroidTouchAdapter = {
+  attach: function AndroidTouchAdapter_attach(aWindow) {
+    if (this.chromeWin)
+      return;
+
+    Logger.info('AndroidTouchAdapter.attach');
+
+    this.chromeWin = aWindow;
+    this.chromeWin.addEventListener('mousemove', this, true, true);
+    this._lastExploreTime = 0;
+  },
+
+  detach: function AndroidTouchAdapter_detach(aWindow) {
+    if (!this.chromeWin)
+      return;
+
+    Logger.info('AndroidTouchAdapter.detach');
+
+    this.chromeWin.removeEventListener('mousemove', this, true, true);
+    delete this.chromeWin;
+  },
+
+  handleEvent: function AndroidTouchAdapter_handleEvent(aEvent) {
+    // On non-Android we use the shift key to simulate touch.
+    if (Utils.MozBuildApp != 'mobile/android' && !aEvent.shiftKey)
+      return;
+
+    if (aEvent.timeStamp - this._lastExploreTime >= EXPLORE_THROTTLE) {
+      let evt = this.chromeWin.document.createEvent('CustomEvent');
+      evt.initCustomEvent(
+        'mozAccessFuGesture', true, true,
+        {type: 'explore', x: aEvent.screenX, y: aEvent.screenY});
+      this.chromeWin.dispatchEvent(evt);
+      this._lastExploreTime = aEvent.timeStamp;
+    }
+  }
+};
\ No newline at end of file
--- a/accessible/src/jsat/Utils.jsm
+++ b/accessible/src/jsat/Utils.jsm
@@ -66,16 +66,30 @@ var Utils = {
   },
 
   getCurrentContentDoc: function getCurrentContentDoc(aWindow) {
     if (this.MozBuildApp == "b2g")
       return this.getBrowserApp(aWindow).contentBrowser.contentDocument;
     return this.getBrowserApp(aWindow).selectedBrowser.contentDocument;
   },
 
+  getAllDocuments: function getAllDocuments(aWindow) {
+    let doc = gAccRetrieval.
+      getAccessibleFor(this.getCurrentContentDoc(aWindow)).
+      QueryInterface(Ci.nsIAccessibleDocument);
+    let docs = [];
+    function getAllDocuments(aDocument) {
+      docs.push(aDocument.DOMDocument);
+      for (let i = 0; i < aDocument.childDocumentCount; i++)
+        getAllDocuments(aDocument.getChildDocumentAt(i));
+    }
+    getAllDocuments(doc);
+    return docs;
+  },
+
   getViewport: function getViewport(aWindow) {
     switch (this.MozBuildApp) {
       case 'mobile/android':
         return aWindow.BrowserApp.selectedTab.getViewport();
       default:
         return null;
     }
   },
@@ -98,16 +112,93 @@ var Utils = {
       try {
         return doc.QueryInterface(Ci.nsIAccessibleCursorable).virtualCursor;
       } catch (x) {
         doc = doc.parentDocument;
       }
     }
 
     return null;
+  },
+
+  scroll: function scroll(aWindow, aPage, aHorizontal) {
+    for each (let doc in this.getAllDocuments(aWindow)) {
+      // First see if we could scroll a window.
+      let win = doc.defaultView;
+      if (!aHorizontal && win.scrollMaxY &&
+          ((aPage > 0 && win.scrollY < win.scrollMaxY) ||
+           (aPage < 0 && win.scrollY > 0))) {
+        win.scroll(0, win.innerHeight);
+        return true;
+      } else if (aHorizontal && win.scrollMaxX &&
+                 ((aPage > 0 && win.scrollX < win.scrollMaxX) ||
+                  (aPage < 0 && win.scrollX > 0))) {
+        win.scroll(win.innerWidth, 0);
+        return true;
+      }
+
+      // Second, try to scroll main section or current target if there is no
+      // main section.
+      let main = doc.querySelector('[role=main]') ||
+        doc.querySelector(':target');
+
+      if (main) {
+        if ((!aHorizontal && main.clientHeight < main.scrollHeight) ||
+          (aHorizontal && main.clientWidth < main.scrollWidth)) {
+          let s = win.getComputedStyle(main);
+          if (!aHorizontal) {
+            if (s.overflowY == 'scroll' || s.overflowY == 'auto') {
+              main.scrollTop += aPage * main.clientHeight;
+              return true;
+            }
+          } else {
+            if (s.overflowX == 'scroll' || s.overflowX == 'auto') {
+              main.scrollLeft += aPage * main.clientWidth;
+              return true;
+            }
+          }
+        }
+      }
+    }
+
+    return false;
+  },
+
+  changePage: function changePage(aWindow, aPage) {
+    for each (let doc in this.getAllDocuments(aWindow)) {
+      // Get current main section or active target.
+      let main = doc.querySelector('[role=main]') ||
+        doc.querySelector(':target');
+      if (!main)
+        continue;
+
+      let mainAcc = gAccRetrieval.getAccessibleFor(main);
+      if (!mainAcc)
+        continue;
+
+      let controllers = mainAcc.
+        getRelationByType(Ci.nsIAccessibleRelation.RELATION_CONTROLLED_BY);
+
+      for (var i=0; controllers.targetsCount > i; i++) {
+        let controller = controllers.getTarget(i);
+        // If the section has a controlling slider, it should be considered
+        // the page-turner.
+        if (controller.role == Ci.nsIAccessibleRole.ROLE_SLIDER) {
+          // Sliders are controlled with ctrl+right/left. I just decided :)
+          let evt = doc.createEvent("KeyboardEvent");
+          evt.initKeyEvent('keypress', true, true, null,
+                           true, false, false, false,
+                           (aPage > 0) ? evt.DOM_VK_RIGHT : evt.DOM_VK_LEFT, 0);
+          controller.DOMNode.dispatchEvent(evt);
+          return true;
+        }
+      }
+    }
+
+    return false;
   }
 };
 
 var Logger = {
   DEBUG: 0,
   INFO: 1,
   WARNING: 2,
   ERROR: 3,
--- a/accessible/src/jsat/VirtualCursorController.jsm
+++ b/accessible/src/jsat/VirtualCursorController.jsm
@@ -192,68 +192,91 @@ var TraversalRules = {
 
 var VirtualCursorController = {
   exploreByTouch: false,
   editableState: 0,
 
   attach: function attach(aWindow) {
     this.chromeWin = aWindow;
     this.chromeWin.document.addEventListener('keypress', this, true);
-    this.chromeWin.document.addEventListener('mousemove', this, true);
+    this.chromeWin.addEventListener('mozAccessFuGesture', this, true);
   },
 
   detach: function detach() {
     this.chromeWin.document.removeEventListener('keypress', this, true);
-    this.chromeWin.document.removeEventListener('mousemove', this, true);
+    this.chromeWin.removeEventListener('mozAccessFuGesture', this, true);
   },
 
   handleEvent: function VirtualCursorController_handleEvent(aEvent) {
     switch (aEvent.type) {
       case 'keypress':
         this._handleKeypress(aEvent);
         break;
-      case 'mousemove':
-        this._handleMousemove(aEvent);
+      case 'mozAccessFuGesture':
+        this._handleGesture(aEvent);
         break;
     }
   },
 
-  _handleMousemove: function _handleMousemove(aEvent) {
-    // Explore by touch is disabled.
-    if (!this.exploreByTouch)
-      return;
+  _handleGesture: function _handleGesture(aEvent) {
+    let document = Utils.getCurrentContentDoc(this.chromeWin);
+    let detail = aEvent.detail;
+    Logger.info('Gesture', detail.type,
+                '(fingers: ' + detail.touches.length + ')');
 
-    // On non-Android we use the shift key to simulate touch.
-    if (Utils.OS != 'Android' && !aEvent.shiftKey)
-      return;
-
-    // We should not be calling moveToPoint more than 10 times a second.
-    // It is granular enough to feel natural, and it does not hammer the CPU.
-    if (!this._handleMousemove._lastEventTime ||
-        aEvent.timeStamp - this._handleMousemove._lastEventTime >= 100) {
-      this.moveToPoint(Utils.getCurrentContentDoc(this.chromeWin),
-                       aEvent.screenX, aEvent.screenY);
-      this._handleMousemove._lastEventTime = aEvent.timeStamp;
+    if (detail.touches.length == 1) {
+      switch (detail.type) {
+        case 'swiperight':
+          this.moveForward(document, aEvent.shiftKey);
+          break;
+        case 'swipeleft':
+          this.moveBackward(document, aEvent.shiftKey);
+          break;
+        case 'doubletap':
+          this.activateCurrent(document);
+          break;
+        case 'explore':
+          this.moveToPoint(document, detail.x, detail.y);
+          break;
+      }
     }
 
-    aEvent.preventDefault();
-    aEvent.stopImmediatePropagation();
+    if (detail.touches.length == 3) {
+      switch (detail.type) {
+        case 'swiperight':
+          if (!Utils.scroll(this.chromeWin, -1, true))
+            Utils.changePage(this.chromeWin, -1);
+          break;
+        case 'swipedown':
+          Utils.scroll(this.chromeWin, -1);
+          break;
+        case 'swipeleft':
+          if (!Utils.scroll(this.chromeWin, 1, true))
+            Utils.changePage(this.chromeWin, 1);
+        case 'swipeup':
+          Utils.scroll(this.chromeWin, 1);
+          break;
+      }
+    }
   },
 
   _handleKeypress: function _handleKeypress(aEvent) {
     let document = Utils.getCurrentContentDoc(this.chromeWin);
     let target = aEvent.target;
 
+    // Ignore keys with modifiers so the content could take advantage of them.
+    if (aEvent.ctrlKey || aEvent.altKey || aEvent.metaKey)
+      return;
+
     switch (aEvent.keyCode) {
       case 0:
         // an alphanumeric key was pressed, handle it separately.
         // If it was pressed with either alt or ctrl, just pass through.
         // If it was pressed with meta, pass the key on without the meta.
-        if (this.editableState ||
-            aEvent.ctrlKey || aEvent.altKey || aEvent.metaKey)
+        if (this.editableState)
           return;
 
         let key = String.fromCharCode(aEvent.charCode);
         let methodName = '', rule = {};
         try {
           [methodName, rule] = this.keyMap[key];
         } catch (x) {
           return;
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -483,16 +483,23 @@ pref("dom.experimental_forms", true);
 pref("gfx.gralloc.enabled", false);
 
 // XXXX REMOVE FOR PRODUCTION. Turns on GC and CC logging 
 pref("javascript.options.mem.log", true);
 
 // Increase mark slice time from 10ms to 30ms
 pref("javascript.options.mem.gc_incremental_slice_ms", 30);
 
+pref("javascript.options.mem.gc_high_frequency_heap_growth_max", 120);
+pref("javascript.options.mem.gc_high_frequency_heap_growth_min", 101);
+pref("javascript.options.mem.gc_high_frequency_high_limit_mb", 40);
+pref("javascript.options.mem.gc_high_frequency_low_limit_mb", 10);
+pref("javascript.options.mem.gc_low_frequency_heap_growth", 105);
+pref("javascript.options.mem.high_water_mark", 16);
+
 // Show/Hide scrollbars when active/inactive
 pref("ui.showHideScrollbars", 1);
 
 // Enable the ProcessPriorityManager, and give processes with no visible
 // documents a 1s grace period before they're eligible to be marked as
 // background.
 pref("dom.ipc.processPriorityManager.enabled", true);
 pref("dom.ipc.processPriorityManager.gracePeriodMS", 1000);
@@ -503,8 +510,11 @@ pref("hal.processPriorityManager.gonk.ma
 pref("hal.processPriorityManager.gonk.foregroundNice", 0);
 pref("hal.processPriorityManager.gonk.backgroundNice", 10);
 
 // Enable pre-launching content processes for improved startup time
 // (hiding latency).
 pref("dom.ipc.processPrelauch.enabled", true);
 // Wait this long before pre-launching a new subprocess.
 pref("dom.ipc.processPrelauch.delayMs", 1000);
+
+// Ignore the "dialog=1" feature in window.open.
+pref("dom.disable_window_open_dialog_feature", true);
new file mode 100644
--- /dev/null
+++ b/b2g/chrome/content/runapp.js
@@ -0,0 +1,93 @@
+// runapp.js:
+// Provide a --runapp APPNAME command-line option.
+
+window.addEventListener('load', function() {
+  // Get the command line arguments that were passed to the b2g client
+  let args = window.arguments[0].QueryInterface(Ci.nsICommandLine);
+  let appname;
+
+  // - Check if the argument is present before doing any work.
+  try {
+    // Returns null if the argument was not specified.  Throws
+    // NS_ERROR_INVALID_ARG if there is no parameter specified (because
+    // it was the last argument or the next argument starts with '-').
+    // However, someone could still explicitly pass an empty argument!
+    appname = args.handleFlagWithParam('runapp', false);
+  }
+  catch(e) {
+    // treat a missing parameter like an empty parameter (=> show usage)
+    appname = '';
+  }
+
+  // not specified, bail.
+  if (appname === null)
+    return;
+
+  // - Get the list of apps since the parameter was specified
+  let appsReq = navigator.mozApps.mgmt.getAll();
+  appsReq.onsuccess = function() {
+    let apps = appsReq.result;
+    function findAppWithName(name) {
+      let normalizedSearchName = name.replace(/[- ]+/g, '').toLowerCase();
+
+      for (let i = 0; i < apps.length; i++) {
+        let app = apps[i];
+        let normalizedAppName =
+              app.manifest.name.replace(/[- ]+/g, '').toLowerCase();
+        if (normalizedSearchName === normalizedAppName) {
+          return app;
+        }
+      }
+      return null;
+    }
+
+    function usageAndDie(justApps) {
+      if (!justApps)
+        dump(
+          'The --runapp argument specifies an app to automatically run at\n'+
+          'startup.  We match against app names per their manifest and \n' +
+          'ignoring capitalization, dashes, and whitespace.\n' +
+          '\nThe system will load as usual except the lock screen will be ' +
+          'automatically be disabled.\n\n' +
+          'Known apps:\n');
+
+      for (let i = 0; i < apps.length; i++) {
+        dump('  ' + apps[i].manifest.name + '\n');
+      }
+
+      // Exit the b2g client
+      Services.startup.quit(Ci.nsIAppStartup.eAttemptQuit);
+    }
+
+    if (appname === '') {
+      usageAndDie();
+      return;
+    }
+
+    let app = findAppWithName(appname);
+    if (!app) {
+      dump('Could not find app: "' + appname + '". Maybe you meant one of:\n');
+      usageAndDie(true);
+      return;
+    }
+
+    let setReq =
+      navigator.mozSettings.getLock().set({'lockscreen.enabled': false});
+    setReq.onsuccess = function() {
+      // give the event loop another turn to disable the lock screen
+      window.setTimeout(function() {
+        dump('--runapp launching app: ' + app.manifest.name + '\n');
+        app.launch();
+      }, 0);
+    };
+    setReq.onerror = function() {
+      dump('--runapp failed to disable lock-screen.  Giving up.\n');
+    };
+
+    dump('--runapp found app: ' + app.manifest.name +
+         ', disabling lock screen...\n');
+ };
+ appsReq.onerror = function() {
+   dump('Problem getting the list of all apps!');
+ };
+});
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -11,16 +11,18 @@ const Cr = Components.results;
 
 Cu.import('resource://gre/modules/XPCOMUtils.jsm');
 Cu.import('resource://gre/modules/Services.jsm');
 Cu.import('resource://gre/modules/ContactService.jsm');
 Cu.import('resource://gre/modules/SettingsChangeNotifier.jsm');
 Cu.import('resource://gre/modules/Webapps.jsm');
 Cu.import('resource://gre/modules/AlarmService.jsm');
 Cu.import('resource://gre/modules/ActivitiesService.jsm');
+Cu.import('resource://gre/modules/PermissionPromptHelper.jsm');
+Cu.import('resource://gre/modules/ObjectWrapper.jsm');
 
 XPCOMUtils.defineLazyServiceGetter(Services, 'env',
                                    '@mozilla.org/process/environment;1',
                                    'nsIEnvironment');
 
 XPCOMUtils.defineLazyServiceGetter(Services, 'ss',
                                    '@mozilla.org/content/style-sheet-service;1',
                                    'nsIStyleSheetService');
@@ -309,17 +311,18 @@ var shell = {
 
   sendEvent: function shell_sendEvent(content, type, details) {
     let event = content.document.createEvent('CustomEvent');
     event.initCustomEvent(type, true, true, details ? details : {});
     content.dispatchEvent(event);
   },
 
   sendChromeEvent: function shell_sendChromeEvent(details) {
-    this.sendEvent(getContentWindow(), "mozChromeEvent", details);
+    this.sendEvent(getContentWindow(), "mozChromeEvent",
+                   ObjectWrapper.wrap(details, getContentWindow()));
   },
 
   receiveMessage: function shell_receiveMessage(message) {
     if (message.name != 'content-handler') {
       return;
     }
     let handler = message.json;
     new MozActivity({
@@ -367,24 +370,24 @@ nsBrowserAccess.prototype = {
 Services.obs.addObserver(function onSystemMessage(subject, topic, data) {
   let msg = JSON.parse(data);
   let origin = Services.io.newURI(msg.manifest, null, null).prePath;
   shell.sendChromeEvent({
     type: 'open-app',
     url: msg.uri,
     origin: origin,
     manifest: msg.manifest,
+    isActivity: (msg.type == 'activity'),
     target: msg.target
   });
 }, 'system-messages-open-app', false);
 
 Services.obs.addObserver(function(aSubject, aTopic, aData) {
-  shell.sendEvent(shell.contentBrowser.contentWindow,
-                  "mozChromeEvent", { type: "fullscreenoriginchange",
-                                      fullscreenorigin: aData } );
+  shell.sendChromeEvent({ type: "fullscreenoriginchange",
+                          fullscreenorigin: aData });
 }, "fullscreen-origin-change", false);
 
 (function Repl() {
   if (!Services.prefs.getBoolPref('b2g.remote-js.enabled')) {
     return;
   }
   const prompt = 'JS> ';
   let output;
@@ -641,8 +644,29 @@ window.addEventListener('ContentStart', 
     if (gGeolocationActiveCount + oldCount == 1) {
       shell.sendChromeEvent({
         type: 'geolocation-status',
         active: (gGeolocationActiveCount == 1)
       });
     }
 }, "geolocation-device-events", false);
 })();
+
+(function recordingStatusTracker() {
+  let gRecordingActiveCount = 0;
+
+  Services.obs.addObserver(function(aSubject, aTopic, aData) {
+    let oldCount = gRecordingActiveCount;
+    if (aData == "starting") {
+      gRecordingActiveCount += 1;
+    } else if (aData == "shutdown") {
+      gRecordingActiveCount -= 1;
+    }
+
+    // We need to track changes from 1 <-> 0
+    if (gRecordingActiveCount + oldCount == 1) {
+      shell.sendChromeEvent({
+        type: 'recording-status',
+        active: (gRecordingActiveCount == 1)
+      });
+    }
+}, "recording-device-events", false);
+})();
--- a/b2g/chrome/content/shell.xul
+++ b/b2g/chrome/content/shell.xul
@@ -15,11 +15,13 @@
         onunload="shell.stop();">
 
   <script type="application/javascript" src="chrome://browser/content/settings.js"/>
   <script type="application/javascript" src="chrome://browser/content/shell.js"/>
 
 #ifndef ANDROID
   <!-- this script handles the screen argument for desktop builds -->
   <script type="application/javascript" src="chrome://browser/content/screen.js"/>
+  <!-- this script handles the "runapp" argument for desktop builds -->
+  <script type="application/javascript" src="chrome://browser/content/runapp.js"/>
 #endif
   <!-- The html:iframe containing the UI is created here. -->
 </window>
--- a/b2g/chrome/jar.mn
+++ b/b2g/chrome/jar.mn
@@ -11,16 +11,17 @@ chrome.jar:
   content/arrow.svg                     (content/arrow.svg)
   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)
+  content/runapp.js                     (content/runapp.js)
 #endif
   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
 
--- a/b2g/components/ActivitiesGlue.js
+++ b/b2g/components/ActivitiesGlue.js
@@ -28,35 +28,34 @@ ActivitiesDialog.prototype = {
     });
 
 
     // Keep up the frond-end of an activity choice. The messages contains
     // a list of {names, icons} for applications able to handle this particular
     // activity. The front-end should display a UI to pick one.
     let browser = Services.wm.getMostRecentWindow("navigator:browser");
     let content = browser.getContentWindow();
-    let event = content.document.createEvent("CustomEvent");
-    event.initCustomEvent("mozChromeEvent", true, true, {
+    let detail = {
       type: "activity-choice",
       id: id,
       name: activity.name,
       choices: choices
-    });
+    };
 
     // Listen the resulting choice from the front-end. If there is no choice,
     // let's return -1, which means the user has cancelled the dialog.
     content.addEventListener("mozContentEvent", function act_getChoice(evt) {
       if (evt.detail.id != id)
         return;
 
       content.removeEventListener("mozContentEvent", act_getChoice);
       activity.callback.handleEvent(evt.detail.value ? evt.detail.value : -1);
     });
 
-    content.dispatchEvent(event);
+    browser.shell.sendChromeEvent(detail);
   },
 
   chooseActivity: function ap_chooseActivity(aName, aActivities, aCallback) {
     this.activities.push({
       name: aName,
       list: aActivities,
       callback: aCallback
     });
--- a/b2g/components/ContentPermissionPrompt.js
+++ b/b2g/components/ContentPermissionPrompt.js
@@ -53,19 +53,17 @@ ContentPermissionPrompt.prototype = {
     });
 
     let details = {
       "type": "permission-prompt",
       "permission": request.type,
       "id": requestId,
       "url": request.principal.URI.spec
     };
-    let event = content.document.createEvent("CustomEvent");
-    event.initCustomEvent("mozChromeEvent", true, true, details);
-    content.dispatchEvent(event);
+    browser.shell.sendChromeEvent(details);
   },
 
   classID: Components.ID("{8c719f03-afe0-4aac-91ff-6c215895d467}"),
 
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionPrompt])
 };
 
 
--- a/b2g/components/MozKeyboard.js
+++ b/b2g/components/MozKeyboard.js
@@ -6,16 +6,17 @@
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 const kFormsFrameScript = "chrome://browser/content/forms.js";
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/ObjectWrapper.jsm");
 
 const messageManager = Cc["@mozilla.org/globalmessagemanager;1"]
                          .getService(Ci.nsIChromeFrameMessageManager);
 
 
 // -----------------------------------------------------------------------
 // MozKeyboard
 // -----------------------------------------------------------------------
@@ -98,17 +99,18 @@ MozKeyboard.prototype = {
     let handler = this._focusHandler;
     if (!handler || !(handler instanceof Ci.nsIDOMEventListener))
       return;
 
     let detail = {
       "detail": msg.json
     };
 
-    let evt = new this._window.CustomEvent("focuschanged", detail);
+    let evt = new this._window.CustomEvent("focuschanged",
+                                           ObjectWrapper.wrap(detail, this._window));
     handler.handleEvent(evt);
   },
 
   observe: function mozKeyboardObserve(subject, topic, data) {
     switch (topic) {
     case "inner-window-destroyed": {
       let wId = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
       if (wId == this.innerWindowID) {
--- a/b2g/config/mozconfigs/macosx64_gecko/nightly
+++ b/b2g/config/mozconfigs/macosx64_gecko/nightly
@@ -1,8 +1,10 @@
+. $topsrcdir/build/macosx/common
+
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 ac_add_options --enable-codesighs
 ac_add_options --enable-signmar
 
 # Nightlies only since this has a cost in performance
 ac_add_options --enable-js-diagnostics
 
@@ -11,17 +13,16 @@ export MOZILLA_OFFICIAL=1
 
 export MOZ_TELEMETRY_REPORTING=1
 mk_add_options MOZ_MAKE_FLAGS="-j12"
 
 #ac_add_options --with-macbundlename-prefix=Firefox
 
 # Treat warnings as errors in directories with FAIL_ON_WARNINGS.
 ac_add_options --enable-warnings-as-errors
-ac_add_options --with-ccache
 
 # B2G Stuff
 ac_add_options --enable-application=b2g
 ac_add_options --enable-debug-symbols
 ac_add_options --with-ccache
 ac_add_options --enable-marionette
 
 export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
copy from browser/config/tooltool-manifests/macosx64/releng.manifest
copy to b2g/config/tooltool-manifests/macosx64/releng.manifest
--- a/browser/app/blocklist.xml
+++ b/browser/app/blocklist.xml
@@ -1,227 +1,100 @@
 <?xml version="1.0"?>
-<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1344613852000">
+<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1345147390000">
   <emItems>
       <emItem  blockID="i58" id="webmaster@buzzzzvideos.info">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
-      <emItem  blockID="i86" id="{45147e67-4020-47e2-8f7a-55464fb535aa}">
-                        <versionRange  minVersion="0" maxVersion="*">
-                    </versionRange>
-                  </emItem>
       <emItem  blockID="i41" id="{99079a25-328f-4bd4-be04-00955acaa0a7}">
                         <versionRange  minVersion="0.1" maxVersion="4.3.1.00" severity="1">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i71" id="youtube@2youtube.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i8" id="{B13721C7-F507-4982-B2E5-502A71474FED}">
                         <versionRange  minVersion=" " severity="1">
                     </versionRange>
                   </emItem>
-      <emItem  blockID="i43" id="supportaccessplugin@gmail.com">
-                        </emItem>
-      <emItem  blockID="i82" id="{8f42fb8b-b6f6-45de-81c0-d6d39f54f971}">
-                        <versionRange  minVersion="0" maxVersion="*">
-                    </versionRange>
-                  </emItem>
       <emItem  blockID="i107" os="WINNT" id="{ABDE892B-13A8-4d1b-88E6-365A6E755758}">
                         <versionRange  minVersion="0" maxVersion="15.0.5" severity="1">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i88" id="anttoolbar@ant.com">
                         <versionRange  minVersion="2.4.6.4" maxVersion="2.4.6.4" severity="1">
                     </versionRange>
                   </emItem>
-      <emItem  blockID="i17" id="{3252b9ae-c69a-4eaf-9502-dc9c1f6c009e}">
-                        <versionRange  minVersion="2.2" maxVersion="2.2">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i98" id="youtubeeing@youtuberie.com">
-                        <versionRange  minVersion="0" maxVersion="*">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i46" id="{841468a1-d7f4-4bd3-84e6-bb0f13a06c64}">
-                        <versionRange  minVersion="0.1" maxVersion="*">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="9.0a1" maxVersion="9.0" />
-                          </targetApplication>
-                    </versionRange>
-                  </emItem>
       <emItem  blockID="i65" id="activity@facebook.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i66" id="youtubeer@youtuber.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
-      <emItem  blockID="i54" id="applebeegifts@mozilla.doslash.org">
-                        <versionRange  minVersion="0" maxVersion="*">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i16" id="{27182e60-b5f3-411c-b545-b44205977502}">
-                        <versionRange  minVersion="1.0" maxVersion="1.0">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i39" id="{c2d64ff7-0ab8-4263-89c9-ea3b0f8f050c}">
-                        <versionRange  minVersion="0.1" maxVersion="4.3.1.00" severity="1">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i92" id="play5@vide04flash.com">
-                        <versionRange  minVersion="0" maxVersion="*">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i108" id="{28bfb930-7620-11e1-b0c4-0800200c9a66}">
-                        <versionRange  minVersion="0" maxVersion="*">
-                    </versionRange>
-                  </emItem>
       <emItem  blockID="i105" id="{95ff02bc-ffc6-45f0-a5c8-619b8226a9de}">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
-      <emItem  blockID="i93" id="{68b8676b-99a5-46d1-b390-22411d8bcd61}">
-                        <versionRange  minVersion="0" maxVersion="*">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i61" id="youtube@youtube3.com">
-                        <versionRange  minVersion="0" maxVersion="*">
-                    </versionRange>
-                                <versionRange  minVersion="0" maxVersion="*">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i10" id="{8CE11043-9A15-4207-A565-0C94C42D590D}">
-                        </emItem>
-      <emItem  blockID="i1" id="mozilla_cc@internetdownloadmanager.com">
-                        <versionRange  minVersion="2.1" maxVersion="3.3">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.0a1" maxVersion="*" />
-                          </targetApplication>
-                    </versionRange>
-                                <versionRange  minVersion=" " maxVersion="6.9.8">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.7a1pre" maxVersion="*" />
-                          </targetApplication>
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i63" id="youtube@youtuber.com">
-                        <versionRange  minVersion="0" maxVersion="*">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i101" id="{3a12052a-66ef-49db-8c39-e5b0bd5c83fa}">
-                        <versionRange  minVersion="0" maxVersion="*">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i18" id="msntoolbar@msn.com">
-                        <versionRange  minVersion=" " maxVersion="6.*">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i13" id="{E8E88AB0-7182-11DF-904E-6045E0D72085}">
-                        </emItem>
       <emItem  blockID="i117" id="{ce7e73df-6a44-4028-8079-5927a588c948}">
                         <versionRange  minVersion="0" maxVersion="1.0.8" severity="1">
                     </versionRange>
                   </emItem>
-      <emItem  blockID="i24" id="{6E19037A-12E3-4295-8915-ED48BC341614}">
-                        <versionRange  minVersion="0.1" maxVersion="1.3.328.4" severity="1">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.7a1pre" maxVersion="*" />
-                          </targetApplication>
+      <emItem  blockID="i100" id="{394DCBA4-1F92-4f8e-8EC9-8D2CB90CB69B}">
+                        <versionRange  minVersion="2.5.0" maxVersion="2.5.0" severity="1">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i64" id="royal@facebook.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i72" os="WINNT" id="{4ED1F68A-5463-4931-9384-8FFF5ED91D92}">
                         <versionRange  minVersion="3.4.1" maxVersion="3.4.1.194" severity="1">
                     </versionRange>
                   </emItem>
-      <emItem  blockID="i97" id="support3_en@adobe122.com">
-                        <versionRange  minVersion="0" maxVersion="*">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i4" id="{4B3803EA-5230-4DC3-A7FC-33638F3D3542}">
-                        <versionRange  minVersion="1.2" maxVersion="1.2">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.0a1" maxVersion="*" />
-                          </targetApplication>
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i75" os="Darwin,Linux" id="firebug@software.joehewitt.com">
-                        <versionRange  minVersion="1.9.0" maxVersion="1.9.0" severity="1">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="9.0a1" maxVersion="9.*" />
-                          </targetApplication>
-                    </versionRange>
-                  </emItem>
       <emItem  blockID="i40" id="{28387537-e3f9-4ed7-860c-11e69af4a8a0}">
                         <versionRange  minVersion="0.1" maxVersion="4.3.1.00" severity="1">
                     </versionRange>
                   </emItem>
-      <emItem  blockID="i100" id="{394DCBA4-1F92-4f8e-8EC9-8D2CB90CB69B}">
-                        <versionRange  minVersion="2.5.0" maxVersion="2.5.0" severity="1">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i83" id="flash@adobee.com">
-                        <versionRange  minVersion="0" maxVersion="*">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i59" id="ghostviewer@youtube2.com">
-                        <versionRange  minVersion="0" maxVersion="*">
-                    </versionRange>
-                  </emItem>
       <emItem  blockID="i78" id="socialnetworktools@mozilla.doslash.org">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
-      <emItem  blockID="i53" id="{a3a5c777-f583-4fef-9380-ab4add1bc2a8}">
-                        <versionRange  minVersion="2.0.3" maxVersion="2.0.3">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i51" id="admin@youtubeplayer.com">
+      <emItem  blockID="i101" id="{3a12052a-66ef-49db-8c39-e5b0bd5c83fa}">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
-      <emItem  blockID="i68" id="flashupdate@adobe.com">
-                        <versionRange  minVersion="0" maxVersion="*">
+      <emItem  blockID="i5" id="support@daemon-tools.cc">
+                        <versionRange  minVersion=" " maxVersion="1.0.0.5">
                     </versionRange>
                   </emItem>
-      <emItem  blockID="i7" id="{2224e955-00e9-4613-a844-ce69fccaae91}">
-                        </emItem>
-      <emItem  blockID="i90" id="videoplugin@player.com">
+      <emItem  blockID="i97" id="support3_en@adobe122.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
-      <emItem  blockID="i91" id="crossriderapp4926@crossrider.com">
-                        <versionRange  minVersion="0" maxVersion="0.81.43" severity="1">
+      <emItem  blockID="i11" id="yslow@yahoo-inc.com">
+                        <versionRange  minVersion="2.0.5" maxVersion="2.0.5">
+                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+                              <versionRange  minVersion="3.5.7" maxVersion="*" />
+                          </targetApplication>
                     </versionRange>
                   </emItem>
-      <emItem  blockID="i84" id="pink@rosaplugin.info">
+      <emItem  blockID="i62" id="jid0-EcdqvFOgWLKHNJPuqAnawlykCGZ@jetpack">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
-      <emItem  blockID="i42" id="{D19CA586-DD6C-4a0a-96F8-14644F340D60}">
-                        <versionRange  minVersion="0.1" maxVersion="14.4.0" severity="1">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i67" id="youtube2@youtube2.com">
+      <emItem  blockID="i99" id="pfzPXmnzQRXX6@2iABkVe.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
-      <emItem  blockID="i109" id="{392e123b-b691-4a5e-b52f-c4c1027e749c}">
-                        <versionRange  minVersion="0" maxVersion="*">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i60" id="youtb3@youtb3.com">
-                        <versionRange  minVersion="0" maxVersion="*">
+      <emItem  blockID="i19" id="{46551EC9-40F0-4e47-8E18-8E5CF550CFB8}">
+                        <versionRange  minVersion="1.1b1" maxVersion="1.1b1">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i111" os="WINNT" id="{C3949AC2-4B17-43ee-B4F1-D26B9D42404D}">
                         <versionRange  minVersion="0" maxVersion="15.0.5" severity="1">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i38" id="{B7082FAA-CB62-4872-9106-E42DD88EDE45}">
                         <versionRange  minVersion="0.1" maxVersion="3.3.0.*">
@@ -230,207 +103,347 @@
                           </targetApplication>
                     </versionRange>
                                 <versionRange  minVersion="3.3.1" maxVersion="*">
                       <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="5.0a1" maxVersion="*" />
                           </targetApplication>
                     </versionRange>
                   </emItem>
+      <emItem  blockID="i98" id="youtubeeing@youtuberie.com">
+                        <versionRange  minVersion="0" maxVersion="*">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i39" id="{c2d64ff7-0ab8-4263-89c9-ea3b0f8f050c}">
+                        <versionRange  minVersion="0.1" maxVersion="4.3.1.00" severity="1">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i42" id="{D19CA586-DD6C-4a0a-96F8-14644F340D60}">
+                        <versionRange  minVersion="0.1" maxVersion="14.4.0" severity="1">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i93" id="{68b8676b-99a5-46d1-b390-22411d8bcd61}">
+                        <versionRange  minVersion="0" maxVersion="*">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i53" id="{a3a5c777-f583-4fef-9380-ab4add1bc2a8}">
+                        <versionRange  minVersion="2.0.3" maxVersion="2.0.3">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i63" id="youtube@youtuber.com">
+                        <versionRange  minVersion="0" maxVersion="*">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i18" id="msntoolbar@msn.com">
+                        <versionRange  minVersion=" " maxVersion="6.*">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i4" id="{4B3803EA-5230-4DC3-A7FC-33638F3D3542}">
+                        <versionRange  minVersion="1.2" maxVersion="1.2">
+                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+                              <versionRange  minVersion="3.0a1" maxVersion="*" />
+                          </targetApplication>
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i75" os="Darwin,Linux" id="firebug@software.joehewitt.com">
+                        <versionRange  minVersion="1.9.0" maxVersion="1.9.0" severity="1">
+                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+                              <versionRange  minVersion="9.0a1" maxVersion="9.*" />
+                          </targetApplication>
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i127" id="plugin@youtubeplayer.com">
+                        <versionRange  minVersion="0" maxVersion="*">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i77" id="{fa277cfc-1d75-4949-a1f9-4ac8e41b2dfd}">
+                        <versionRange  minVersion="0" maxVersion="*">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i59" id="ghostviewer@youtube2.com">
+                        <versionRange  minVersion="0" maxVersion="*">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i51" id="admin@youtubeplayer.com">
+                        <versionRange  minVersion="0" maxVersion="*">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i46" id="{841468a1-d7f4-4bd3-84e6-bb0f13a06c64}">
+                        <versionRange  minVersion="0.1" maxVersion="*">
+                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+                              <versionRange  minVersion="9.0a1" maxVersion="9.0" />
+                          </targetApplication>
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i22" id="ShopperReports@ShopperReports.com">
+                        <versionRange  minVersion="3.1.22.0" maxVersion="3.1.22.0">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i44" id="sigma@labs.mozilla">
+                        </emItem>
+      <emItem  blockID="i48" id="admin@youtubespeedup.com">
+                        </emItem>
+      <emItem  blockID="i109" id="{392e123b-b691-4a5e-b52f-c4c1027e749c}">
+                        <versionRange  minVersion="0" maxVersion="*">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i79" id="GifBlock@facebook.com">
+                        <versionRange  minVersion="0" maxVersion="*">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i69" id="{977f3b97-5461-4346-92c8-a14c749b77c9}">
+                        <versionRange  minVersion="0" maxVersion="*" severity="1">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i17" id="{3252b9ae-c69a-4eaf-9502-dc9c1f6c009e}">
+                        <versionRange  minVersion="2.2" maxVersion="2.2">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i115" id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+                        <versionRange  minVersion="0" maxVersion="*">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i7" id="{2224e955-00e9-4613-a844-ce69fccaae91}">
+                        </emItem>
+      <emItem  blockID="i52" id="ff-ext@youtube">
+                        <versionRange  minVersion="0" maxVersion="*">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i43" id="supportaccessplugin@gmail.com">
+                        </emItem>
+      <emItem  blockID="i54" id="applebeegifts@mozilla.doslash.org">
+                        <versionRange  minVersion="0" maxVersion="*">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i16" id="{27182e60-b5f3-411c-b545-b44205977502}">
+                        <versionRange  minVersion="1.0" maxVersion="1.0">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i92" id="play5@vide04flash.com">
+                        <versionRange  minVersion="0" maxVersion="*">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i10" id="{8CE11043-9A15-4207-A565-0C94C42D590D}">
+                        </emItem>
+      <emItem  blockID="i1" id="mozilla_cc@internetdownloadmanager.com">
+                        <versionRange  minVersion="2.1" maxVersion="3.3">
+                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+                              <versionRange  minVersion="3.0a1" maxVersion="*" />
+                          </targetApplication>
+                    </versionRange>
+                                <versionRange  minVersion=" " maxVersion="6.9.8">
+                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+                              <versionRange  minVersion="3.7a1pre" maxVersion="*" />
+                          </targetApplication>
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i13" id="{E8E88AB0-7182-11DF-904E-6045E0D72085}">
+                        </emItem>
+      <emItem  blockID="i83" id="flash@adobee.com">
+                        <versionRange  minVersion="0" maxVersion="*">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i104" id="yasd@youasdr3.com">
+                        <versionRange  minVersion="0" maxVersion="*">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i76" id="crossriderapp3924@crossrider.com">
+                        <versionRange  minVersion="0" maxVersion="*">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i91" id="crossriderapp4926@crossrider.com">
+                        <versionRange  minVersion="0" maxVersion="0.81.43" severity="1">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i67" id="youtube2@youtube2.com">
+                        <versionRange  minVersion="0" maxVersion="*">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i56" id="flash@adobe.com">
+                        <versionRange  minVersion="0" maxVersion="*">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i2" id="fdm_ffext@freedownloadmanager.org">
+                        <versionRange  minVersion="1.0" maxVersion="1.3.1">
+                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+                              <versionRange  minVersion="3.0a1" maxVersion="*" />
+                          </targetApplication>
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i6" id="{3f963a5b-e555-4543-90e2-c3908898db71}">
+                        <versionRange  minVersion=" " maxVersion="8.5">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i12" id="masterfiler@gmail.com">
+                        <versionRange  severity="3">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i20" id="{AB2CE124-6272-4b12-94A9-7303C7397BD1}">
+                        <versionRange  minVersion="0.1" maxVersion="5.2.0.7164" severity="1">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i47" id="youtube@youtube2.com">
+                        </emItem>
+      <emItem  blockID="i103" id="kdrgun@gmail.com">
+                        <versionRange  minVersion="0" maxVersion="*">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i3" id="langpack-vi-VN@firefox.mozilla.org">
+                        <versionRange  minVersion="2.0" maxVersion="2.0">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i106" os="WINNT" id="{97E22097-9A2F-45b1-8DAF-36AD648C7EF4}">
+                        <versionRange  minVersion="0" maxVersion="15.0.5" severity="1">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i15" id="personas@christopher.beard">
+                        <versionRange  minVersion="1.6" maxVersion="1.6">
+                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+                              <versionRange  minVersion="3.6" maxVersion="3.6.*" />
+                          </targetApplication>
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i86" id="{45147e67-4020-47e2-8f7a-55464fb535aa}">
+                        <versionRange  minVersion="0" maxVersion="*">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i108" id="{28bfb930-7620-11e1-b0c4-0800200c9a66}">
+                        <versionRange  minVersion="0" maxVersion="*">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i61" id="youtube@youtube3.com">
+                        <versionRange  minVersion="0" maxVersion="*">
+                    </versionRange>
+                                <versionRange  minVersion="0" maxVersion="*">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i84" id="pink@rosaplugin.info">
+                        <versionRange  minVersion="0" maxVersion="*">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i70" id="psid-vhvxQHMZBOzUZA@jetpack">
+                        <versionRange  minVersion="0" maxVersion="*" severity="1">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i60" id="youtb3@youtb3.com">
+                        <versionRange  minVersion="0" maxVersion="*">
+                    </versionRange>
+                  </emItem>
       <emItem  blockID="i23" id="firefox@bandoo.com">
                         <versionRange  minVersion="5.0" maxVersion="5.0" severity="1">
                       <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="3.7a1pre" maxVersion="*" />
                           </targetApplication>
                     </versionRange>
                   </emItem>
       <emItem  blockID="i55" id="youtube@youtube7.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
-      <emItem  blockID="i47" id="youtube@youtube2.com">
-                        </emItem>
-      <emItem  blockID="i22" id="ShopperReports@ShopperReports.com">
-                        <versionRange  minVersion="3.1.22.0" maxVersion="3.1.22.0">
+      <emItem  blockID="i90" id="videoplugin@player.com">
+                        <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
-      <emItem  blockID="i2" id="fdm_ffext@freedownloadmanager.org">
-                        <versionRange  minVersion="1.0" maxVersion="1.3.1">
+      <emItem  blockID="i68" id="flashupdate@adobe.com">
+                        <versionRange  minVersion="0" maxVersion="*">
+                    </versionRange>
+                  </emItem>
+      <emItem  blockID="i45" id="{22119944-ED35-4ab1-910B-E619EA06A115}">
+                        <versionRange  minVersion="0.1" maxVersion="7.6.1">
                       <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.0a1" maxVersion="*" />
+                              <versionRange  minVersion="8.0a1" maxVersion="*" />
                           </targetApplication>
                     </versionRange>
                   </emItem>
-      <emItem  blockID="i44" id="sigma@labs.mozilla">
-                        </emItem>
-      <emItem  blockID="i5" id="support@daemon-tools.cc">
-                        <versionRange  minVersion=" " maxVersion="1.0.0.5">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i69" id="{977f3b97-5461-4346-92c8-a14c749b77c9}">
-                        <versionRange  minVersion="0" maxVersion="*" severity="1">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i6" id="{3f963a5b-e555-4543-90e2-c3908898db71}">
-                        <versionRange  minVersion=" " maxVersion="8.5">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i12" id="masterfiler@gmail.com">
-                        <versionRange  severity="3">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i48" id="admin@youtubespeedup.com">
-                        </emItem>
-      <emItem  blockID="i20" id="{AB2CE124-6272-4b12-94A9-7303C7397BD1}">
-                        <versionRange  minVersion="0.1" maxVersion="5.2.0.7164" severity="1">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i104" id="yasd@youasdr3.com">
-                        <versionRange  minVersion="0" maxVersion="*">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i76" id="crossriderapp3924@crossrider.com">
+      <emItem  blockID="i82" id="{8f42fb8b-b6f6-45de-81c0-d6d39f54f971}">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
-      <emItem  blockID="i79" id="GifBlock@facebook.com">
-                        <versionRange  minVersion="0" maxVersion="*">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i62" id="jid0-EcdqvFOgWLKHNJPuqAnawlykCGZ@jetpack">
-                        <versionRange  minVersion="0" maxVersion="*">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i70" id="psid-vhvxQHMZBOzUZA@jetpack">
-                        <versionRange  minVersion="0" maxVersion="*" severity="1">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i115" id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                        <versionRange  minVersion="0" maxVersion="*">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i56" id="flash@adobe.com">
-                        <versionRange  minVersion="0" maxVersion="*">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i103" id="kdrgun@gmail.com">
-                        <versionRange  minVersion="0" maxVersion="*">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i99" id="pfzPXmnzQRXX6@2iABkVe.com">
-                        <versionRange  minVersion="0" maxVersion="*">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i19" id="{46551EC9-40F0-4e47-8E18-8E5CF550CFB8}">
-                        <versionRange  minVersion="1.1b1" maxVersion="1.1b1">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i3" id="langpack-vi-VN@firefox.mozilla.org">
-                        <versionRange  minVersion="2.0" maxVersion="2.0">
-                    </versionRange>
-                  </emItem>
       <emItem  blockID="i73" id="a1g0a9g219d@a1.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i96" id="youtubeee@youtuber3.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
-      <emItem  blockID="i77" id="{fa277cfc-1d75-4949-a1f9-4ac8e41b2dfd}">
-                        <versionRange  minVersion="0" maxVersion="*">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i106" os="WINNT" id="{97E22097-9A2F-45b1-8DAF-36AD648C7EF4}">
-                        <versionRange  minVersion="0" maxVersion="15.0.5" severity="1">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i11" id="yslow@yahoo-inc.com">
-                        <versionRange  minVersion="2.0.5" maxVersion="2.0.5">
+      <emItem  blockID="i24" id="{6E19037A-12E3-4295-8915-ED48BC341614}">
+                        <versionRange  minVersion="0.1" maxVersion="1.3.328.4" severity="1">
                       <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.5.7" maxVersion="*" />
-                          </targetApplication>
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i52" id="ff-ext@youtube">
-                        <versionRange  minVersion="0" maxVersion="*">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i45" id="{22119944-ED35-4ab1-910B-E619EA06A115}">
-                        <versionRange  minVersion="0.1" maxVersion="7.6.1">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="8.0a1" maxVersion="*" />
-                          </targetApplication>
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i15" id="personas@christopher.beard">
-                        <versionRange  minVersion="1.6" maxVersion="1.6">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.6" maxVersion="3.6.*" />
+                              <versionRange  minVersion="3.7a1pre" maxVersion="*" />
                           </targetApplication>
                     </versionRange>
                   </emItem>
       <emItem  blockID="i21" id="support@update-firefox.com">
                         </emItem>
     </emItems>
 
   <pluginItems>
+      <pluginItem  blockID="p32">
+                  <match name="filename" exp="npViewpoint.dll" />                      <versionRange >
+                      <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+              <versionRange  minVersion="3.0" maxVersion="*" />
+            </targetApplication>
+                  </versionRange>
+                  </pluginItem>
       <pluginItem  blockID="p26">
       <match name="name" exp="^Yahoo Application State Plugin$" />      <match name="description" exp="^Yahoo Application State Plugin$" />      <match name="filename" exp="npYState.dll" />                      <versionRange >
                       <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
               <versionRange  minVersion="3.0a1" maxVersion="3.*" />
             </targetApplication>
                   </versionRange>
                   </pluginItem>
       <pluginItem  blockID="p27">
       <match name="name" exp="QuickTime Plug-in 7[.]1[.]" />            <match name="filename" exp="npqtplugin.?[.]dll" />                      <versionRange >
                       <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
               <versionRange  minVersion="3.0a1" maxVersion="3.*" />
             </targetApplication>
                   </versionRange>
                   </pluginItem>
-      <pluginItem  blockID="p28">
-                  <match name="filename" exp="NPFFAddOn.dll" />                        </pluginItem>
-      <pluginItem  blockID="p31">
-                  <match name="filename" exp="NPMySrch.dll" />                        </pluginItem>
-      <pluginItem  blockID="p32">
-                  <match name="filename" exp="npViewpoint.dll" />                      <versionRange >
-                      <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-              <versionRange  minVersion="3.0" maxVersion="*" />
-            </targetApplication>
-                  </versionRange>
-                  </pluginItem>
-      <pluginItem  blockID="p33">
-      <match name="name" exp="[0-6]\.0\.[01]\d{2}\.\d+" />            <match name="filename" exp="npdeploytk.dll" />                      <versionRange  severity="1"></versionRange>
-                  </pluginItem>
       <pluginItem  blockID="p34">
                   <match name="filename" exp="[Nn][Pp][Jj][Pp][Ii]1[56]0_[0-9]+\.[Dd][Ll][Ll]" />                      <versionRange >
                       <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
               <versionRange  minVersion="3.6a1pre" maxVersion="*" />
             </targetApplication>
                   </versionRange>
                   </pluginItem>
+      <pluginItem  blockID="p28">
+                  <match name="filename" exp="NPFFAddOn.dll" />                        </pluginItem>
+      <pluginItem  blockID="p31">
+                  <match name="filename" exp="NPMySrch.dll" />                        </pluginItem>
+      <pluginItem  blockID="p33">
+      <match name="name" exp="[0-6]\.0\.[01]\d{2}\.\d+" />            <match name="filename" exp="npdeploytk.dll" />                      <versionRange  severity="1"></versionRange>
+                  </pluginItem>
       <pluginItem  blockID="p80">
       <match name="name" exp="\(TM\)" />      <match name="description" exp="[^\d\._]((0(\.\d+(\.\d+([_\.]\d+)?)?)?)|(1\.(([0-5](\.\d+([_\.]\d+)?)?)|(6(\.0([_\.](0?\d|1\d|2\d|30))?)?)|(7(\.0([_\.][0-2])?)?))))([^\d\._]|$)" />      <match name="filename" exp="(npjp2\.dll)|(libnpjp2\.so)" />                      <versionRange  severity="1"></versionRange>
                   </pluginItem>
+      <pluginItem  blockID="p119">
+      <match name="name" exp="Java\(TM\) Plug-in 1\.(6\.0_(\d|[0-2]\d?|3[0-2])|7\.0(_0?([1-4]))?)([^\d\._]|$)" />            <match name="filename" exp="libnpjp2\.so" />                      <versionRange  severity="1"></versionRange>
+                  </pluginItem>
+      <pluginItem  blockID="p125">
+      <match name="name" exp="Java\(TM\) Platform SE ((6( U(\d|([0-2]\d)|3[0-2]))?)|(7(\sU[0-4])?))(\s[^\d\._U]|$)" />            <match name="filename" exp="npjp2\.dll" />                      <versionRange  severity="1"></versionRange>
+                  </pluginItem>
       <pluginItem  blockID="p85">
                   <match name="filename" exp="JavaPlugin2_NPAPI\.plugin" />                      <versionRange  minVersion="0" maxVersion="13.6.0" severity="1"></versionRange>
                   </pluginItem>
       <pluginItem  os="Darwin" blockID="p89">
                   <match name="filename" exp="AdobePDFViewerNPAPI\.plugin" />                      <versionRange  minVersion="0" maxVersion="10.1.3" severity="1"></versionRange>
                   </pluginItem>
       <pluginItem  blockID="p94">
                   <match name="filename" exp="(NPSWF32\.dll)|(Flash\ Player\.plugin)" />                      <versionRange  minVersion="0" maxVersion="10.2.159.1" severity="0"></versionRange>
                   </pluginItem>
       <pluginItem  blockID="p102">
                   <match name="filename" exp="npmozax\.dll" />                      <versionRange  minVersion="0" maxVersion="*"></versionRange>
                   </pluginItem>
       <pluginItem  blockID="p113">
                   <match name="filename" exp="npuplaypc\.dll" />                      <versionRange  minVersion="0" maxVersion="1.0.0.0" severity="1"></versionRange>
                   </pluginItem>
+      <pluginItem  blockID="p123">
+                  <match name="filename" exp="JavaPlugin2_NPAPI\.plugin" />                      <versionRange  minVersion="0" maxVersion="14.2.0" severity="1"></versionRange>
+                  </pluginItem>
     </pluginItems>
 
   <gfxItems>
     <gfxBlacklistEntry  blockID="g35">      <os>WINNT 6.1</os>      <vendor>0x10de</vendor>              <devices>
                       <device>0x0a6c</device>
                   </devices>
             <feature>DIRECT2D</feature>      <featureStatus>BLOCKED_DRIVER_VERSION</featureStatus>      <driverVersion>8.17.12.5896</driverVersion>      <driverVersionComparator>LESS_THAN_OR_EQUAL</driverVersionComparator>    </gfxBlacklistEntry>
     <gfxBlacklistEntry  blockID="g36">      <os>WINNT 6.1</os>      <vendor>0x10de</vendor>              <devices>
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1123,16 +1123,22 @@ pref("browser.panorama.animate_zoom", tr
 // Defines the url to be used for new tabs.
 pref("browser.newtab.url", "about:newtab");
 // Activates preloading of the new tab url.
 pref("browser.newtab.preload", false);
 
 // Toggles the content of 'about:newtab'. Shows the grid when enabled.
 pref("browser.newtabpage.enabled", true);
 
+// number of rows of newtab grid
+pref("browser.newtabpage.rows", 3);
+
+// number of columns of newtab grid
+pref("browser.newtabpage.columns", 3);
+
 // Enable the DOM fullscreen API.
 pref("full-screen-api.enabled", true);
 
 // True if the fullscreen API requires approval upon a domain entering fullscreen.
 // Domains that have already had fullscreen permission granted won't re-request
 // approval.
 pref("full-screen-api.approval-required", true);
 
--- a/browser/base/content/aboutRobots.xhtml
+++ b/browser/base/content/aboutRobots.xhtml
@@ -37,16 +37,20 @@
           var newLabel = button.getAttribute("label2");
           button.textContent = newLabel;
           buttonClicked = true;
         }
       }
     ]]></script>
 
     <style type="text/css"><![CDATA[
+      #errorPageContainer {
+        background-image: none;
+      }
+
       #errorPageContainer:before {
         content: url('chrome://browser/content/aboutRobots-icon.png');
         position: absolute;
       }
 
       body[dir=rtl] #icon,
       body[dir=rtl] #errorPageContainer:before {
         transform: scaleX(-1);
--- a/browser/base/content/browser-social.js
+++ b/browser/base/content/browser-social.js
@@ -28,20 +28,28 @@ let SocialUI = {
   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":
-        this.updateToggleCommand();
-        SocialShareButton.updateButtonHiddenState();
-        SocialToolbar.updateButtonHiddenState();
-        SocialSidebar.updateSidebar();
+        // Exceptions here sometimes don't get reported properly, report them
+        // manually :(
+        try {
+          this.updateToggleCommand();
+          SocialShareButton.updateButtonHiddenState();
+          SocialToolbar.updateButtonHiddenState();
+          SocialSidebar.updateSidebar();
+          SocialChatBar.update();
+        } catch (e) {
+          Components.utils.reportError(e);
+          throw e;
+        }
         break;
       case "social:ambient-notification-changed":
         SocialToolbar.updateButton();
         break;
       case "social:profile-changed":
         SocialToolbar.updateProfile();
         SocialShareButton.updateProfileInfo();
         break;
@@ -145,16 +153,37 @@ let SocialUI = {
   },
 
   undoActivation: function SocialUI_undoActivation() {
     Social.active = false;
     this.notificationPanel.hidePopup();
   }
 }
 
+let SocialChatBar = {
+  get chatbar() {
+    return document.getElementById("pinnedchats");
+  },
+  // Whether the chats can be shown for this window.
+  get canShow() {
+    let docElem = document.documentElement;
+    let chromeless = docElem.getAttribute("disablechrome") ||
+                     docElem.getAttribute("chromehidden").indexOf("extrachrome") >= 0;
+    return Social.uiVisible && !chromeless;
+  },
+  newChat: function(aProvider, aURL, aCallback) {
+    if (this.canShow)
+      this.chatbar.newChat(aProvider, aURL, aCallback);
+  },
+  update: function() {
+    if (!this.canShow)
+      this.chatbar.removeAll();
+  }
+}
+
 let SocialShareButton = {
   // Called once, after window load, when the Social.provider object is initialized
   init: function SSB_init() {
     this.updateButtonHiddenState();
     this.updateProfileInfo();
   },
 
   updateProfileInfo: function SSB_updateProfileInfo() {
@@ -248,45 +277,50 @@ let SocialShareButton = {
   }
 };
 
 var SocialToolbar = {
   // Called once, after window load, when the Social.provider object is initialized
   init: function SocialToolbar_init() {
     document.getElementById("social-provider-image").setAttribute("image", Social.provider.iconURL);
 
-    let notifBrowser = document.getElementById("social-notification-browser");
-    notifBrowser.docShell.isAppTab = true;
-
     let removeItem = document.getElementById("social-remove-menuitem");
     let brandShortName = document.getElementById("bundle_brand").getString("brandShortName");
     let label = gNavigatorBundle.getFormattedString("social.remove.label",
                                                     [brandShortName]);
     let accesskey = gNavigatorBundle.getString("social.remove.accesskey");
     removeItem.setAttribute("label", label);
     removeItem.setAttribute("accesskey", accesskey);
 
     let statusAreaPopup = document.getElementById("social-statusarea-popup");
-    statusAreaPopup.addEventListener("popupshowing", function(e) {
+    statusAreaPopup.addEventListener("popupshown", function(e) {
       this.button.setAttribute("open", "true");
     }.bind(this));
     statusAreaPopup.addEventListener("popuphidden", function(e) {
       this.button.removeAttribute("open");
     }.bind(this));
 
     this.updateButton();
     this.updateProfile();
   },
 
   get button() {
     return document.getElementById("social-toolbar-button");
   },
 
   updateButtonHiddenState: function SocialToolbar_updateButtonHiddenState() {
     this.button.hidden = !Social.uiVisible;
+    if (!Social.provider || !Social.provider.profile || !Social.provider.profile.userName) {
+      ["social-notification-box",
+       "social-status-iconbox"].forEach(function removeChildren(parentId) {
+        let parent = document.getElementById(parentId);
+        while(parent.hasChildNodes())
+          parent.removeChild(parent.firstChild);
+      });
+    }
   },
 
   updateProfile: function SocialToolbar_updateProfile() {
     // Profile may not have been initialized yet, since it depends on a worker
     // response. In that case we'll be called again when it's available, via
     // social:profile-changed
     let profile = Social.provider.profile || {};
     let userPortrait = profile.portrait || "chrome://browser/skin/social/social.png";
@@ -301,84 +335,143 @@ var SocialToolbar = {
     } else {
       notLoggedInLabel.hidden = false;
       userNameBtn.hidden = true;
     }
   },
 
   updateButton: function SocialToolbar_updateButton() {
     this.updateButtonHiddenState();
-
     let provider = Social.provider;
-    // if there are no ambient icons, we collapse them in the following loop
     let iconNames = Object.keys(provider.ambientNotificationIcons);
     let iconBox = document.getElementById("social-status-iconbox");
-    for (var i = 0; i < iconBox.childNodes.length; i++) {
-      let iconContainer = iconBox.childNodes[i];
-      if (i > iconNames.length - 1) {
-        iconContainer.collapsed = true;
-        continue;
+    let notifBox = document.getElementById("social-notification-box");
+    let notifBrowsers = document.createDocumentFragment();
+    let iconContainers = document.createDocumentFragment();
+
+    for each(let name in iconNames) {
+      let icon = provider.ambientNotificationIcons[name];
+
+      let notifBrowserId = "social-status-" + icon.name;
+      let notifBrowser = document.getElementById(notifBrowserId);
+      if (!notifBrowser) {
+        notifBrowser = document.createElement("iframe");
+        notifBrowser.setAttribute("type", "content");
+        notifBrowser.setAttribute("id", notifBrowserId);
+        notifBrowsers.appendChild(notifBrowser);
       }
-
-      iconContainer.collapsed = false;
-      let icon = provider.ambientNotificationIcons[iconNames[i]];
-      let iconImage = iconContainer.firstChild;
-      let iconCounter = iconImage.nextSibling;
+      notifBrowser.setAttribute("origin", provider.origin);
+      if (notifBrowser.getAttribute("src") != icon.contentPanel)
+        notifBrowser.setAttribute("src", icon.contentPanel);
 
-      iconImage.setAttribute("contentPanel", icon.contentPanel);
-      iconImage.setAttribute("src", icon.iconURL);
+      let iconId = "social-notification-icon-" + icon.name;
+      let iconContainer = document.getElementById(iconId);
+      let iconImage, iconCounter;
+      if (iconContainer) {
+        iconImage = iconContainer.getElementsByClassName("social-notification-icon-image")[0];
+        iconCounter = iconContainer.getElementsByClassName("social-notification-icon-counter")[0];
+      } else {
+        iconContainer = document.createElement("box");
+        iconContainer.setAttribute("id", iconId);
+        iconContainer.classList.add("social-notification-icon-container");
+        iconContainer.addEventListener("click", function (e) { SocialToolbar.showAmbientPopup(iconContainer); }, false);
 
-      if (iconCounter.firstChild)
-        iconCounter.removeChild(iconCounter.firstChild);
+        iconImage = document.createElement("image");
+        iconImage.classList.add("social-notification-icon-image");
+        iconImage = iconContainer.appendChild(iconImage);
 
-      if (icon.counter) {
-        iconCounter.appendChild(document.createTextNode(icon.counter));
-        iconCounter.collapsed = false;
-      } else {
-        iconCounter.collapsed = true;
+        iconCounter = document.createElement("box");
+        iconCounter.classList.add("social-notification-icon-counter");
+        iconCounter.appendChild(document.createTextNode(""));
+        iconCounter = iconContainer.appendChild(iconCounter);
+
+        iconContainers.appendChild(iconContainer);
       }
+      if (iconImage.getAttribute("src") != icon.iconURL)
+        iconImage.setAttribute("src", icon.iconURL);
+      iconImage.setAttribute("notifBrowserId", notifBrowserId);
+
+      iconCounter.collapsed = !icon.counter;
+      iconCounter.firstChild.textContent = icon.counter || "";
+    }
+    notifBox.appendChild(notifBrowsers);
+    iconBox.appendChild(iconContainers);
+
+    let browserIter = notifBox.firstElementChild;
+    while (browserIter) {
+      browserIter.docShell.isAppTab = true;
+      browserIter = browserIter.nextElementSibling;
     }
   },
 
   showAmbientPopup: function SocialToolbar_showAmbientPopup(iconContainer) {
     let iconImage = iconContainer.firstChild;
     let panel = document.getElementById("social-notification-panel");
-    let notifBrowser = document.getElementById("social-notification-browser");
+    let notifBox = document.getElementById("social-notification-box");
+    let notifBrowser = document.getElementById(iconImage.getAttribute("notifBrowserId"));
 
     panel.hidden = false;
 
     function sizePanelToContent() {
       // FIXME: bug 764787: Maybe we can use nsIDOMWindowUtils.getRootBounds() here?
       // Need to handle dynamic sizing
       let doc = notifBrowser.contentDocument;
+      if (!doc) {
+        return;
+      }
       // "notif" is an implementation detail that we should get rid of
       // eventually
-      let body = doc.getElementById("notif") || (doc.body && doc.body.firstChild);
-      if (!body)
+      let body = doc.getElementById("notif") || doc.body;
+      if (!body || !body.firstChild) {
         return;
-      let h = body.scrollHeight > 0 ? body.scrollHeight : 300;
-      notifBrowser.style.width = body.scrollWidth + "px";
-      notifBrowser.style.height = h + "px";
+      }
+
+      // Clear dimensions on all browsers so the panel size will
+      // only use the selected browser.
+      let browserIter = notifBox.firstElementChild;
+      while (browserIter) {
+        browserIter.hidden = (browserIter != notifBrowser);
+        browserIter = browserIter.nextElementSibling;
+      }
+
+      let [height, width] = [body.firstChild.offsetHeight || 300, 330];
+      notifBrowser.style.width = width + "px";
+      notifBrowser.style.height = height + "px";
     }
 
-    notifBrowser.addEventListener("DOMContentLoaded", function onload() {
-      notifBrowser.removeEventListener("DOMContentLoaded", onload);
-      sizePanelToContent();
-    });
+    sizePanelToContent();
+
+    function dispatchPanelEvent(name) {
+      let evt = notifBrowser.contentDocument.createEvent("CustomEvent");
+      evt.initCustomEvent(name, true, true, {});
+      notifBrowser.contentDocument.documentElement.dispatchEvent(evt);
+    }
 
     panel.addEventListener("popuphiding", function onpopuphiding() {
       panel.removeEventListener("popuphiding", onpopuphiding);
-      // unload the panel
       SocialToolbar.button.removeAttribute("open");
-      notifBrowser.setAttribute("src", "about:blank");
+      dispatchPanelEvent("socialFrameHide");
     });
 
-    notifBrowser.setAttribute("origin", Social.provider.origin);
-    notifBrowser.setAttribute("src", iconImage.getAttribute("contentPanel"));
-    this.button.setAttribute("open", "true");
+    panel.addEventListener("popupshown", function onpopupshown() {
+      panel.removeEventListener("popupshown", onpopupshown);
+      SocialToolbar.button.setAttribute("open", "true");
+      if (notifBrowser.contentDocument.readyState == "complete") {
+        dispatchPanelEvent("socialFrameShow");
+      } else {
+        // first time load, wait for load and dispatch after load
+        notifBrowser.addEventListener("load", function panelBrowserOnload(e) {
+          notifBrowser.removeEventListener("load", panelBrowserOnload, true);
+          setTimeout(function() {
+            dispatchPanelEvent("socialFrameShow");
+          }, 0);
+        }, 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() {
     let sbrowser = document.getElementById("social-sidebar-browser");
@@ -421,33 +514,34 @@ var SocialSidebar = {
     // 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);
 
     let sbrowser = document.getElementById("social-sidebar-browser");
+    sbrowser.docShell.isActive = !hideSidebar;
     if (hideSidebar) {
-      this.dispatchEvent("sidebarhide");
+      this.dispatchEvent("socialFrameHide");
       // If we're disabled, unload the sidebar content
       if (!this.canShow) {
         sbrowser.removeAttribute("origin");
         sbrowser.setAttribute("src", "about:blank");
       }
     } else {
       // Make sure the right sidebar URL is loaded
       if (sbrowser.getAttribute("origin") != Social.provider.origin) {
         sbrowser.setAttribute("origin", Social.provider.origin);
         sbrowser.setAttribute("src", Social.provider.sidebarURL);
         sbrowser.addEventListener("load", function sidebarOnShow() {
           sbrowser.removeEventListener("load", sidebarOnShow);
           // let load finish, then fire our event
           setTimeout(function () {
-            SocialSidebar.dispatchEvent("sidebarshow");
+            SocialSidebar.dispatchEvent("socialFrameShow");
           }, 0);
         });
       } else {
-        this.dispatchEvent("sidebarshow");
+        this.dispatchEvent("socialFrameShow");
       }
     }
   }
 }
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -610,8 +610,17 @@ stack[anonid=browserStack][responsivemod
 
 stack[anonid=browserStack][responsivemode] {
   transition-property: min-width, max-width, min-height, max-height;
 }
 
 stack[anonid=browserStack][responsivemode][notransition] {
   transition: none;
 }
+
+chatbox {
+  -moz-binding: url("chrome://browser/content/socialchat.xml#chatbox");
+}
+
+chatbar {
+  -moz-binding: url("chrome://browser/content/socialchat.xml#chatbar");
+  height: 0;
+}
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -3156,16 +3156,62 @@ var DownloadsButtonDNDObserver = {
 const DOMLinkHandler = {
   handleEvent: function (event) {
     switch (event.type) {
       case "DOMLinkAdded":
         this.onLinkAdded(event);
         break;
     }
   },
+  getLinkIconURI: function(aLink) {
+    let targetDoc = aLink.ownerDocument;
+    var uri = makeURI(aLink.href, targetDoc.characterSet);
+
+    // Verify that the load of this icon is legal.
+    // Some error or special pages can load their favicon.
+    // To be on the safe side, only allow chrome:// favicons.
+    var isAllowedPage = [
+      /^about:neterror\?/,
+      /^about:blocked\?/,
+      /^about:certerror\?/,
+      /^about:home$/,
+    ].some(function (re) re.test(targetDoc.documentURI));
+
+    if (!isAllowedPage || !uri.schemeIs("chrome")) {
+      var ssm = Cc["@mozilla.org/scriptsecuritymanager;1"].
+                getService(Ci.nsIScriptSecurityManager);
+      try {
+        ssm.checkLoadURIWithPrincipal(targetDoc.nodePrincipal, uri,
+                                      Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT);
+      } catch(e) {
+        return null;
+      }
+    }
+
+    try {
+      var contentPolicy = Cc["@mozilla.org/layout/content-policy;1"].
+                          getService(Ci.nsIContentPolicy);
+    } catch(e) {
+      return null; // Refuse to load if we can't do a security check.
+    }
+
+    // Security says okay, now ask content policy
+    if (contentPolicy.shouldLoad(Ci.nsIContentPolicy.TYPE_IMAGE,
+                                 uri, targetDoc.documentURIObject,
+                                 aLink, aLink.type, null)
+                                 != Ci.nsIContentPolicy.ACCEPT)
+      return null;
+    
+    try {
+      uri.userPass = "";
+    } catch(e) {
+      // some URIs are immutable
+    }
+    return uri;
+  },
   onLinkAdded: function (event) {
     var link = event.originalTarget;
     var rel = link.rel && link.rel.toLowerCase();
     if (!link || !link.ownerDocument || !rel || !link.href)
       return;
 
     var feedAdded = false;
     var iconAdded = false;
@@ -3189,64 +3235,30 @@ const DOMLinkHandler = {
             }
           }
           break;
         case "icon":
           if (!iconAdded) {
             if (!gPrefService.getBoolPref("browser.chrome.site_icons"))
               break;
 
-            var targetDoc = link.ownerDocument;
-            var uri = makeURI(link.href, targetDoc.characterSet);
+            var uri = this.getLinkIconURI(link);
+            if (!uri)
+              break;
 
             if (gBrowser.isFailedIcon(uri))
               break;
 
-            // Verify that the load of this icon is legal.
-            // Some error or special pages can load their favicon.
-            // To be on the safe side, only allow chrome:// favicons.
-            var isAllowedPage = [
-              /^about:neterror\?/,
-              /^about:blocked\?/,
-              /^about:certerror\?/,
-              /^about:home$/,
-            ].some(function (re) re.test(targetDoc.documentURI));
-
-            if (!isAllowedPage || !uri.schemeIs("chrome")) {
-              var ssm = Cc["@mozilla.org/scriptsecuritymanager;1"].
-                        getService(Ci.nsIScriptSecurityManager);
-              try {
-                ssm.checkLoadURIWithPrincipal(targetDoc.nodePrincipal, uri,
-                                              Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT);
-              } catch(e) {
-                break;
-              }
-            }
-
-            try {
-              var contentPolicy = Cc["@mozilla.org/layout/content-policy;1"].
-                                  getService(Ci.nsIContentPolicy);
-            } catch(e) {
-              break; // Refuse to load if we can't do a security check.
-            }
-
-            // Security says okay, now ask content policy
-            if (contentPolicy.shouldLoad(Ci.nsIContentPolicy.TYPE_IMAGE,
-                                         uri, targetDoc.documentURIObject,
-                                         link, link.type, null)
-                                         != Ci.nsIContentPolicy.ACCEPT)
-              break;
-
-            var browserIndex = gBrowser.getBrowserIndexForDocument(targetDoc);
+            var browserIndex = gBrowser.getBrowserIndexForDocument(link.ownerDocument);
             // no browser? no favicon.
             if (browserIndex == -1)
               break;
 
             let tab = gBrowser.tabs[browserIndex];
-            gBrowser.setIcon(tab, link.href);
+            gBrowser.setIcon(tab, uri.spec);
             iconAdded = true;
           }
           break;
         case "search":
           if (!searchAdded) {
             var type = link.type && link.type.toLowerCase();
             type = type.replace(/^\s+|\s*(?:;.*)?$/g, "");
 
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -264,17 +264,17 @@
                 label="&social.sharePopup.undo.label;"
                 accesskey="&social.sharePopup.undo.accesskey;"
                 command="Social:UnsharePage"/>
 #endif
       </hbox>
     </panel>
 
     <panel id="social-notification-panel" type="arrow" hidden="true" noautofocus="true">
-      <browser id="social-notification-browser" type="content" flex="1"/>
+      <box id="social-notification-box" flex="1"></box>
     </panel>
 
     <menupopup id="inspector-node-popup">
       <menuitem id="inspectorHTMLCopyInner"
                 label="&inspectorHTMLCopyInner.label;"
                 accesskey="&inspectorHTMLCopyInner.accesskey;"
                 command="Inspector:CopyInner"/>
       <menuitem id="inspectorHTMLCopyOuter"
@@ -680,31 +680,16 @@
                         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>
-            <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>
-            <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>
           </hbox>
         </hbox>
       </toolbaritem>
 
       <toolbaritem id="bookmarks-menu-button-container"
                    class="chromeclass-toolbar-additional"
                    removable="true"
                    title="&bookmarksMenuButton.label;">
@@ -1061,16 +1046,17 @@
     <splitter id="sidebar-splitter" class="chromeclass-extrachrome sidebar-splitter" hidden="true"/>
     <vbox id="appcontent" flex="1">
       <tabbrowser id="content" disablehistory="true"
                   flex="1" contenttooltip="aHTMLTooltip"
                   tabcontainer="tabbrowser-tabs"
                   contentcontextmenu="contentAreaContextMenu"
                   autocompletepopup="PopupAutoComplete"
                   onclick="contentAreaClick(event, false);"/>
+      <chatbar id="pinnedchats" layer="true" mousethrough="always"/>
       <statuspanel id="statusbar-display" inactive="true"/>
     </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"/>
--- a/browser/base/content/newtab/grid.js
+++ b/browser/base/content/newtab/grid.js
@@ -17,41 +17,32 @@ let gGrid = {
   /**
    * The cached DOM fragment for sites.
    */
   _siteFragment: null,
 
   /**
    * All cells contained in the grid.
    */
-  get cells() {
-    let cells = [];
-    let children = this.node.querySelectorAll(".newtab-cell");
-    for (let i = 0; i < children.length; i++)
-      cells.push(new Cell(this, children[i]));
-
-    // Replace the getter with our cached value.
-    Object.defineProperty(this, "cells", {value: cells, enumerable: true});
-
-    return cells;
-  },
+  _cells: null,
+  get cells() this._cells,
 
   /**
    * All sites contained in the grid's cells. Sites may be empty.
    */
   get sites() [cell.site for each (cell in this.cells)],
 
   /**
    * Initializes the grid.
    * @param aSelector The query selector of the grid.
    */
   init: function Grid_init() {
     this._node = document.getElementById("newtab-grid");
     this._createSiteFragment();
-    this._draw();
+    this._render();
   },
 
   /**
    * Creates a new site in the grid.
    * @param aLink The new site's link.
    * @param aCell The cell that will contain the new site.
    * @return The newly created site.
    */
@@ -69,18 +60,18 @@ let gGrid = {
     this.cells.forEach(function (cell) {
       let node = cell.node;
       let child = node.firstElementChild;
 
       if (child)
         node.removeChild(child);
     }, this);
 
-    // Draw the grid again.
-    this._draw();
+    // Render the grid again.
+    this._render();
   },
 
   /**
    * Locks the grid to block all pointer events.
    */
   lock: function Grid_lock() {
     this.node.setAttribute("locked", "true");
   },
@@ -88,16 +79,42 @@ let gGrid = {
   /**
    * Unlocks the grid to allow all pointer events.
    */
   unlock: function Grid_unlock() {
     this.node.removeAttribute("locked");
   },
 
   /**
+   * Creates the newtab grid.
+   */
+  _renderGrid: function Grid_renderGrid() {
+    let row = document.createElementNS(HTML_NAMESPACE, "div");
+    let cell = document.createElementNS(HTML_NAMESPACE, "div");
+    row.classList.add("newtab-row");
+    cell.classList.add("newtab-cell");
+
+    // Clear the grid
+    this._node.innerHTML = "";
+
+    // Creates the structure of one row
+    for (let i = 0; i < gGridPrefs.gridColumns; i++) {
+      row.appendChild(cell.cloneNode(true));
+    }
+    // Creates the grid
+    for (let j = 0; j < gGridPrefs.gridRows; j++) {
+      this._node.appendChild(row.cloneNode(true));
+    }
+
+    // (Re-)initialize all cells.
+    let cellElements = this.node.querySelectorAll(".newtab-cell");
+    this._cells = [new Cell(this, cell) for (cell of cellElements)];
+  },
+
+  /**
    * Creates the DOM fragment that is re-used when creating sites.
    */
   _createSiteFragment: function Grid_createSiteFragment() {
     let site = document.createElementNS(HTML_NAMESPACE, "div");
     site.classList.add("newtab-site");
     site.setAttribute("draggable", "true");
 
     // Create the site's inner HTML code.
@@ -111,23 +128,41 @@ let gGrid = {
       '<input type="button" title="' + newTabString("block") + '"' +
       '       class="newtab-control newtab-control-block"/>';
 
     this._siteFragment = document.createDocumentFragment();
     this._siteFragment.appendChild(site);
   },
 
   /**
-   * Draws the grid, creates all sites and puts them into their cells.
+   * Renders the sites, creates all sites and puts them into their cells.
    */
-  _draw: function Grid_draw() {
+  _renderSites: function Grid_renderSites() {
     let cells = this.cells;
-
     // Put sites into the cells.
     let links = gLinks.getLinks();
     let length = Math.min(links.length, cells.length);
 
     for (let i = 0; i < length; i++) {
       if (links[i])
         this.createSite(links[i], cells[i]);
     }
+  },
+
+  /**
+   * Renders the grid.
+   */
+  _render: function Grid_render() {
+    if (this._shouldRenderGrid()) {
+      this._renderGrid();
+    }
+
+    this._renderSites();
+  },
+
+  _shouldRenderGrid : function Grid_shouldRenderGrid() {
+    let rowsLength = this._node.querySelectorAll(".newtab-row").length;
+    let cellsLength = this._node.querySelectorAll(".newtab-cell").length;
+
+    return (rowsLength != gGridPrefs.gridRows ||
+            cellsLength != (gGridPrefs.gridRows * gGridPrefs.gridColumns));
   }
 };
--- a/browser/base/content/newtab/newTab.js
+++ b/browser/base/content/newtab/newTab.js
@@ -15,17 +15,18 @@ Cu.import("resource:///modules/NewTabUti
 XPCOMUtils.defineLazyModuleGetter(this, "Rect",
   "resource://gre/modules/Geometry.jsm");
 
 let {
   links: gLinks,
   allPages: gAllPages,
   linkChecker: gLinkChecker,
   pinnedLinks: gPinnedLinks,
-  blockedLinks: gBlockedLinks
+  blockedLinks: gBlockedLinks,
+  gridPrefs: gGridPrefs
 } = NewTabUtils;
 
 XPCOMUtils.defineLazyGetter(this, "gStringBundle", function() {
   return Services.strings.
     createBundle("chrome://browser/locale/newTab.properties");
 });
 
 function newTabString(name) gStringBundle.GetStringFromName('newtab.' + name);
--- a/browser/base/content/newtab/newTab.xul
+++ b/browser/base/content/newtab/newTab.xul
@@ -21,31 +21,16 @@
 
     <div id="newtab-vertical-margin">
       <div id="newtab-margin-top"/>
 
       <div id="newtab-horizontal-margin">
         <div class="newtab-side-margin"/>
 
         <div id="newtab-grid">
-          <div class="newtab-row">
-            <div class="newtab-cell"/>
-            <div class="newtab-cell"/>
-            <div class="newtab-cell"/>
-          </div>
-          <div class="newtab-row">
-            <div class="newtab-cell"/>
-            <div class="newtab-cell"/>
-            <div class="newtab-cell"/>
-          </div>
-          <div class="newtab-row">
-            <div class="newtab-cell"/>
-            <div class="newtab-cell"/>
-            <div class="newtab-cell"/>
-          </div>
         </div>
 
         <div class="newtab-side-margin"/>
       </div>
 
       <div id="newtab-margin-bottom"/>
     </div>
     <input id="newtab-toggle" type="button"/>
new file mode 100644
--- /dev/null
+++ b/browser/base/content/socialchat.xml
@@ -0,0 +1,263 @@
+<?xml version="1.0"?>
+
+<bindings id="socialChatBindings"
+    xmlns="http://www.mozilla.org/xbl"
+    xmlns:xbl="http://www.mozilla.org/xbl"
+    xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+  <binding id="chatbox">
+    <content orient="vertical" mousethrough="never">
+      <xul:hbox class="chat-titlebar" xbl:inherits="minimized">
+        <xul:image class="chat-status-icon" xbl:inherits="src=image"/>
+        <xul:label class="chat-title" flex="1" xbl:inherits="value=label,crop"/>
+        <xul:toolbarbutton class="chat-toggle-button chat-toolbarbutton"
+                           xbl:inherits="minimized"
+                           oncommand="document.getBindingParent(this).toggle();"/>
+        <xul:toolbarbutton class="chat-close-button chat-toolbarbutton"
+                           oncommand="document.getBindingParent(this).close();"/>
+      </xul:hbox>
+      <xul:iframe anonid="iframe" class="chat-frame" flex="1"
+                  xbl:inherits="src,origin,collapsed=minimized" type="content"/>
+    </content>
+
+    <implementation implements="nsIDOMEventListener">
+      <field name="iframe" readonly="true">
+        document.getAnonymousElementByAttribute(this, "anonid", "iframe");
+      </field>
+
+      <method name="init">
+        <parameter name="aProvider"/>
+        <parameter name="aURL"/>
+        <parameter name="aCallback"/>
+        <body><![CDATA[
+          this._callback = aCallback;
+          this.setAttribute("origin", aProvider.origin);
+          this.setAttribute("src", aURL);
+        ]]></body>
+      </method>
+
+      <method name="close">
+        <body><![CDATA[
+          this.parentNode.remove(this);
+        ]]></body>
+      </method>
+
+      <method name="toggle">
+        <body><![CDATA[
+          let type;
+          if (this.getAttribute("minimized") == "true") {
+            this.removeAttribute("minimized");
+            type = "socialFrameShow";
+          } else {
+            this.setAttribute("minimized", "true");
+            type = "socialFrameHide";
+          }
+          // let the chat frame know if it is being shown or hidden
+          let evt = this.iframe.contentDocument.createEvent("CustomEvent");
+          evt.initCustomEvent(type, true, true, {});
+          this.iframe.contentDocument.documentElement.dispatchEvent(evt);
+        ]]></body>
+      </method>
+    </implementation>
+
+    <handlers>
+      <handler event="focus" phase="capturing">
+        this.parentNode.selectedChat = this;
+      </handler>
+      <handler event="DOMContentLoaded" action="if (this._callback) this._callback(this.iframe.contentWindow);"/>
+      <handler event="DOMTitleChanged" action="this.setAttribute('label', this.iframe.contentDocument.title);"/>
+      <handler event="DOMLinkAdded"><![CDATA[
+        // much of this logic is from DOMLinkHandler in browser.js
+        // this sets the presence icon for a chat user, we simply use favicon style updating
+        let link = event.originalTarget;
+        let rel = link.rel && link.rel.toLowerCase();
+        if (!link || !link.ownerDocument || !rel || !link.href)
+          return;
+        if (link.rel.indexOf("icon") < 0)
+          return;
+
+        let uri = DOMLinkHandler.getLinkIconURI(link);
+        if (!uri)
+          return;
+
+        // we made it this far, use it
+        this.setAttribute('image', uri.spec);
+      ]]></handler>
+    </handlers>
+  </binding>
+
+  <binding id="chatbar">
+    <content>
+      <xul:hbox align="end" pack="end" anonid="innerbox" class="chatbar-innerbox" mousethrough="always" flex="1">
+        <xul:toolbarbutton anonid="nub" class="chatbar-button" type="menu" collapsed="true" mousethrough="never">
+          <xul:menupopup anonid="nubMenu" oncommand="document.getBindingParent(this).swapChat(event)"/>
+        </xul:toolbarbutton>
+        <xul:spacer flex="1" anonid="spacer" class="chatbar-overflow-spacer"/>
+        <children/>
+      </xul:hbox>
+    </content>
+
+    <implementation implements="nsIDOMEventListener">
+
+      <field name="innerbox" readonly="true">
+        document.getAnonymousElementByAttribute(this, "anonid", "innerbox");
+      </field>
+
+      <field name="menupopup" readonly="true">
+        document.getAnonymousElementByAttribute(this, "anonid", "nubMenu");
+      </field>
+
+      <property name="emptyWidth">
+        <getter>
+          return document.getAnonymousElementByAttribute(this, "anonid", "spacer").boxObject.width;
+        </getter>
+      </property>
+
+      <field name="selectedChat"/>
+
+      <field name="menuitemMap">new WeakMap()</field>
+
+      <property name="firstCollapsedChild">
+        <getter><![CDATA[
+          let child = this.lastChild;
+          while (child && !child.collapsed) {
+            child = child.previousSibling;
+          }
+          return child;
+        ]]></getter>
+      </property>
+
+      <property name="firstVisibleChild">
+        <getter><![CDATA[
+          let child = this.firstChild;
+          while (child && child.collapsed) {
+            child = child.nextSibling;
+          }
+          return child;
+        ]]></getter>
+      </property>
+
+      <property name="firstRemovableChild">
+        <getter><![CDATA[
+          let child = this.firstChild;
+          // find the first visible non-focused chatbox, always keep one visible if we
+          // have enough width to do so.
+          while (child &&
+                (child.collapsed || child == this.selectedChat)) {
+            child = child.nextSibling;
+          }
+          if (!child && this.selectedChat) {
+            child = this.selectedChat;
+          }
+          return child;
+        ]]></getter>
+      </property>
+
+      <method name="resize">
+        <body><![CDATA[
+          let child = this.firstCollapsedChild;
+          if (child && this.emptyWidth > 200) {
+            this.showChat(child);
+          }
+          if (!this.firstCollapsedChild) {
+            window.removeEventListener("resize", this);
+            this.menupopup.parentNode.collapsed = true;
+          }
+        ]]></body>
+      </method>
+
+      <method name="handleEvent">
+        <parameter name="aEvent"/>
+        <body><![CDATA[
+          if (aEvent.type == "resize") {
+            this.resize();
+          }
+        ]]></body>
+      </method>
+
+      <method name="swapChat">
+        <parameter name="aEvent"/>
+        <body><![CDATA[
+          let menuitem = aEvent.target;
+          let newChat = menuitem.chat;
+          let oldChat = this.firstVisibleChild;
+          if (oldChat)
+            this.collapseChat(oldChat);
+          if (newChat) 
+            this.showChat(newChat);
+        ]]></body>
+      </method>
+
+      <method name="collapseChat">
+        <parameter name="aChatbox"/>
+        <body><![CDATA[
+          aChatbox.collapsed = true;
+          let menu = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "menuitem");
+          menu.setAttribute("label", aChatbox.iframe.contentDocument.title);
+          menu.chat = aChatbox;
+          this.menuitemMap.set(aChatbox, menu);
+          this.menupopup.appendChild(menu);
+          this.menupopup.parentNode.collapsed = false;
+        ]]></body>
+      </method>
+
+      <method name="showChat">
+        <parameter name="aChatbox"/>
+        <body><![CDATA[
+          let menuitem = this.menuitemMap.get(aChatbox);
+          this.menuitemMap.delete(aChatbox);
+          this.menupopup.removeChild(menuitem);
+          aChatbox.collapsed = false;
+        ]]></body>
+      </method>
+
+      <method name="remove">
+        <parameter name="aChatbox"/>
+        <body><![CDATA[
+          if (this.selectedChat == aChatbox) {
+            this.selectedChat = aChatbox.previousSibling ? aChatbox.previousSibling : aChatbox.nextSibling
+          }
+          this.removeChild(aChatbox);
+          this.resize();
+        ]]></body>
+      </method>
+
+      <method name="removeAll">
+        <body><![CDATA[
+          while (this.firstChild) {
+            this.removeChild(this.firstChild);
+          }
+        ]]></body>
+      </method>
+
+      <method name="newChat">
+        <parameter name="aProvider"/>
+        <parameter name="aURL"/>
+        <parameter name="aCallback"/>
+        <body><![CDATA[
+          let cb = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "chatbox");
+          this.selectedChat = cb;
+          this.appendChild(cb);
+          cb.init(aProvider, aURL, aCallback);
+        ]]></body>
+      </method>
+
+    </implementation>
+    <handlers>
+      <handler event="overflow"><![CDATA[
+        // make sure we're not getting an overflow from content
+        if (event.originalTarget != this.innerbox)
+          return;
+
+        let hasHidden = this.firstCollapsedChild;
+        let child = this.firstRemovableChild;
+        if (child)
+          this.collapseChat(child);
+        if (!hasHidden) {
+          window.addEventListener("resize", this);
+        }
+      ]]></handler>
+    </handlers>
+  </binding>
+
+</bindings>
--- a/browser/base/content/test/Makefile.in
+++ b/browser/base/content/test/Makefile.in
@@ -59,16 +59,19 @@ endif
 # 480169)
 
 # browser_drag.js is disabled, as it needs to be updated for the new behavior from bug 320638.
 
 # browser_bug321000.js is disabled because newline handling is shaky (bug 592528)
 
 # browser_pageInfo.js + feed_tab.html is disabled for leaking (bug 767896)
 
+# browser_social_shareButton.js is disabled for not properly
+#   tearing down the social providers (bug 780010).
+
 _BROWSER_FILES = \
                  head.js \
                  browser_typeAheadFind.js \
                  browser_keywordSearch.js \
                  browser_allTabsPanel.js \
                  browser_alltabslistener.js \
                  browser_bug304198.js \
                  title_test.svg \
@@ -84,16 +87,17 @@ endif
                  browser_bug417483.js \
                  browser_bug419612.js \
                  browser_identity_UI.js \
                  browser_bug422590.js \
                  browser_bug424101.js \
                  browser_bug427559.js \
                  browser_bug432599.js \
                  browser_bug435035.js \
+                 browser_bug435325.js \
                  browser_bug441778.js \
                  browser_popupNotification.js \
                  browser_bug455852.js \
                  browser_bug460146.js \
                  browser_bug462673.js \
                  browser_bug477014.js \
                  browser_bug479408.js \
                  browser_bug479408_sample.html \
@@ -151,17 +155,16 @@ endif
                  browser_bug710878.js \
                  browser_bug719271.js \
                  browser_bug724239.js \
                  browser_bug735471.js \
                  browser_bug743421.js \
                  browser_bug749738.js \
                  browser_bug763468.js \
                  browser_bug767836.js \
-                 browser_social_shareButton.js \
                  browser_canonizeURL.js \
                  browser_customize.js \
                  browser_findbarClose.js \
                  browser_homeDrop.js \
                  browser_keywordBookmarklets.js \
                  browser_contextSearchTabPosition.js \
                  browser_ctrlTab.js \
                  browser_customize_popupNotification.js \
@@ -256,18 +259,21 @@ endif
                  browser_middleMouse_inherit.js \
                  redirect_bug623155.sjs \
                  browser_tabDrop.js \
                  browser_lastAccessedTab.js \
                  browser_bug734076.js \
                  browser_social_toolbar.js \
                  browser_social_sidebar.js \
                  browser_social_mozSocial_API.js \
+                 browser_social_isVisible.js \
+                 browser_social_chatwindow.js \
                  social_panel.html \
                  social_sidebar.html \
+                 social_chat.html \
                  social_window.html \
                  social_worker.js \
                  $(NULL)
 
 ifneq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 _BROWSER_FILES += \
 		browser_bug462289.js \
 		$(NULL)
rename from docshell/test/browser/browser_bug435325.js
rename to browser/base/content/test/browser_bug435325.js
--- a/docshell/test/browser/browser_bug435325.js
+++ b/browser/base/content/test/browser_bug435325.js
@@ -1,13 +1,12 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /* Ensure that clicking the button in the Offline mode neterror page makes the browser go online. See bug 435325. */
-/* TEST_PATH=docshell/test/browser/browser_bug435325.js make -C $(OBJDIR) mochitest-browser-chrome */
 
 function test() {
   waitForExplicitFinish();
 
   gBrowser.selectedTab = gBrowser.addTab();
   window.addEventListener("DOMContentLoaded", checkPage, false);
 
   // Go offline and disable the cache, then try to load the test URL.
@@ -29,19 +28,18 @@ function checkPage() {
   is(gBrowser.contentDocument.documentURI.substring(0,27),
     "about:neterror?e=netOffline", "Loading the Offline mode neterror page.");
 
   // Now press the "Try Again" button
   ok(gBrowser.contentDocument.getElementById("errorTryAgain"),
     "The error page has got a #errorTryAgain element");
   gBrowser.contentDocument.getElementById("errorTryAgain").click();
 
-  ok(!Services.io.offline, "After clicking the Try Again button, we're back "
-   +" online. This depends on Components.interfaces.nsIDOMWindowUtils being "
-   +"available from untrusted content (bug 435325).");
+  ok(!Services.io.offline, "After clicking the Try Again button, we're back " +
+                           "online.");
 
   finish();
 }
 
 registerCleanupFunction(function() {
   Services.prefs.setBoolPref("browser.cache.disk.enable", true);
   Services.prefs.setBoolPref("browser.cache.memory.enable", true);
   Services.io.offline = false;
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_social_chatwindow.js
@@ -0,0 +1,94 @@
+/* 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() {
+  waitForExplicitFinish();
+
+  let manifest = { // normal provider
+    name: "provider 1",
+    origin: "https://example.com",
+    sidebarURL: "https://example.com/browser/browser/base/content/test/social_sidebar.html",
+    workerURL: "https://example.com/browser/browser/base/content/test/social_worker.js",
+    iconURL: "chrome://branding/content/icon48.png"
+  };
+  runSocialTestWithProvider(manifest, function (finishcb) {
+    runSocialTests(tests, undefined, undefined, function () {
+      let chats = document.getElementById("pinnedchats");
+      ok(chats.children.length == 0, "no chatty children left behind");
+      finishcb();
+    });
+  });
+}
+
+var tests = {
+  testOpenCloseChat: function(next) {
+    let chats = document.getElementById("pinnedchats");
+    let port = Social.provider.port;
+    ok(port, "provider has a port");
+    port.onmessage = function (e) {
+      let topic = e.data.topic;
+      switch (topic) {
+        case "got-sidebar-message":
+          port.postMessage({topic: "test-chatbox-open"});
+          break;
+        case "got-chatbox-visibility":
+          if (e.data.result == "hidden") {
+            ok(true, "chatbox got minimized");
+            chats.selectedChat.toggle();
+          } else if (e.data.result == "shown") {
+            ok(true, "chatbox got shown");
+            // close it now
+            let iframe = chats.selectedChat.iframe;
+            iframe.addEventListener("unload", function chatUnload() {
+              iframe.removeEventListener("unload", chatUnload, true);
+              ok(true, "got chatbox unload on close");
+              next();
+            }, true);
+            chats.selectedChat.close();
+          }
+          break;
+        case "got-chatbox-message":
+          ok(true, "got chatbox message");
+          ok(e.data.result == "ok", "got chatbox windowRef result: "+e.data.result);
+          chats.selectedChat.toggle();
+          break;
+      }
+    }
+    port.postMessage({topic: "test-init"});
+  },
+  testManyChats: function(next) {
+    // open enough chats to overflow the window, then check
+    // if the menupopup is visible
+    let port = Social.provider.port;
+    ok(port, "provider has a port");
+    let width = document.documentElement.boxObject.width;
+    let numToOpen = (width / 200) + 1;
+    port.onmessage = function (e) {
+      let topic = e.data.topic;
+      switch (topic) {
+        case "got-chatbox-message":
+          numToOpen--;
+          if (numToOpen >= 0) {
+            // we're waiting for all to open
+            ok(true, "got a chat window opened");
+            break;
+          }
+          // close our chats now
+          let chats = document.getElementById("pinnedchats");
+          ok(!chats.menupopup.parentNode.collapsed, "menu selection is visible");
+          while (chats.selectedChat) {
+            chats.selectedChat.close();
+          }
+          ok(!chats.selectedChat, "chats are all closed");
+          next();
+          break;
+      }
+    }
+    let num = numToOpen;
+    while (num-- > 0) {
+      port.postMessage({topic: "test-chatbox-open"});
+    }
+  }
+}
+
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_social_isVisible.js
@@ -0,0 +1,62 @@
+/* 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() {
+  waitForExplicitFinish();
+
+  let manifest = { // normal provider
+    name: "provider 1",
+    origin: "https://example.com",
+    sidebarURL: "https://example.com/browser/browser/base/content/test/social_sidebar.html",
+    workerURL: "https://example.com/browser/browser/base/content/test/social_worker.js",
+    iconURL: "chrome://branding/content/icon48.png"
+  };
+  runSocialTestWithProvider(manifest, function (finishcb) {
+    runSocialTests(tests, undefined, undefined, finishcb);
+  });
+}
+
+var tests = {
+  testSidebarMessage: function(next) {
+    let port = Social.provider.port;
+    ok(port, "provider has a port");
+    port.postMessage({topic: "test-init"});
+    Social.provider.port.onmessage = function (e) {
+      let topic = e.data.topic;
+      switch (topic) {
+        case "got-sidebar-message":
+          // The sidebar message will always come first, since it loads by default
+          ok(true, "got sidebar message");
+          next();
+          break;
+      }
+    };
+  },
+  testIsVisible: function(next) {
+    let port = Social.provider.port;
+    port.onmessage = function (e) {
+      let topic = e.data.topic;
+      switch (topic) {
+        case "got-isVisible-response":
+          is(e.data.result, true, "Sidebar should be visible by default");
+          Social.toggleSidebar();
+          next();
+      }
+    };
+    port.postMessage({topic: "test-isVisible"});
+  },
+  testIsNotVisible: function(next) {
+    let port = Social.provider.port;
+    port.onmessage = function (e) {
+      let topic = e.data.topic;
+      switch (topic) {
+        case "got-isVisible-response":
+          is(e.data.result, false, "Sidebar should be hidden");
+          Services.prefs.clearUserPref("social.sidebar.open");
+          next();
+      }
+    };
+    port.postMessage({topic: "test-isVisible"});
+  }
+}
--- a/browser/base/content/test/browser_social_mozSocial_API.js
+++ b/browser/base/content/test/browser_social_mozSocial_API.js
@@ -2,19 +2,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/. */
 
 function test() {
   waitForExplicitFinish();
 
   let manifest = { // normal provider
     name: "provider 1",
-    origin: "http://example.com",
-    sidebarURL: "http://example.com/browser/browser/base/content/test/social_sidebar.html",
-    workerURL: "http://example.com/browser/browser/base/content/test/social_worker.js",
+    origin: "https://example.com",
+    sidebarURL: "https://example.com/browser/browser/base/content/test/social_sidebar.html",
+    workerURL: "https://example.com/browser/browser/base/content/test/social_worker.js",
     iconURL: "chrome://branding/content/icon48.png"
   };
   runSocialTestWithProvider(manifest, function (finishcb) {
     runSocialTests(tests, undefined, undefined, finishcb);
   });
 }
 
 var tests = {
@@ -24,46 +24,48 @@ var tests = {
 
     function checkNext() {
       if (iconsReady && gotSidebarMessage)
         triggerIconPanel();
     }
 
     function triggerIconPanel() {
       let statusIcons = document.getElementById("social-status-iconbox");
-      ok(!statusIcons.firstChild.collapsed, "status icon is visible");
+      ok(!statusIcons.firstChild.hidden, "status icon is visible");
       // Click the button to trigger its contentPanel
       let panel = document.getElementById("social-notification-panel");
       EventUtils.synthesizeMouseAtCenter(statusIcons.firstChild, {});
     }
 
     let port = Social.provider.port;
     ok(port, "provider has a port");
-    port.postMessage({topic: "test-init"});
-    Social.provider.port.onmessage = function (e) {
+    port.onmessage = function (e) {
       let topic = e.data.topic;
       switch (topic) {
         case "got-panel-message":
           ok(true, "got panel message");
-          // Wait for the panel to close before ending the test
-          let panel = document.getElementById("social-notification-panel");
-          panel.addEventListener("popuphidden", function hiddenListener() {
-            panel.removeEventListener("popuphidden", hiddenListener);
+          break;
+        case "got-social-panel-visibility":
+          if (e.data.result == "shown") {
+            ok(true, "panel shown");
+            let panel = document.getElementById("social-notification-panel");
+            panel.hidePopup();
+          } else if (e.data.result == "hidden") {
+            ok(true, "panel hidden");
             next();
-          });
-          panel.hidePopup();
-          break;
+          }
         case "got-sidebar-message":
           // The sidebar message will always come first, since it loads by default
           ok(true, "got sidebar message");
           gotSidebarMessage = true;
           checkNext();
           break;
       }
     }
+    port.postMessage({topic: "test-init"});
 
     // Our worker sets up ambient notification at the same time as it responds to
     // the workerAPI initialization. If it's already initialized, we can
     // immediately check the icons, otherwise wait for initialization by
     // observing the topic sent out by the social service.
     if (Social.provider.workerAPI.initialized) {
       iconsReady = true;
       checkNext();
--- a/browser/base/content/test/browser_social_sidebar.js
+++ b/browser/base/content/test/browser_social_sidebar.js
@@ -33,23 +33,23 @@ function doTest(finishcb) {
     if (shouldBeShown)
       is(browser.getAttribute('src'), Social.provider.sidebarURL, "sidebar url should be set");
   }
 
   // First check the the sidebar is initially visible, and loaded
   ok(!command.hidden, "toggle command should be visible");
   checkShown(true);
 
-  browser.addEventListener("sidebarhide", function sidebarhide() {
-    browser.removeEventListener("sidebarhide", sidebarhide);
+  browser.addEventListener("socialFrameHide", function sidebarhide() {
+    browser.removeEventListener("socialFrameHide", sidebarhide);
 
     checkShown(false);
 
-    browser.addEventListener("sidebarshow", function sidebarshow() {
-      browser.removeEventListener("sidebarshow", sidebarshow);
+    browser.addEventListener("socialFrameShow", function sidebarshow() {
+      browser.removeEventListener("socialFrameShow", sidebarshow);
 
       checkShown(true);
 
       // Finish the test
       finishcb();
     });
 
     // Toggle it back on
--- a/browser/base/content/test/browser_social_toolbar.js
+++ b/browser/base/content/test/browser_social_toolbar.js
@@ -57,16 +57,16 @@ var tests = {
     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");
+      ok(ambience.collapsed, "ambient icon (" + ambience.id + ") is collapsed");
       ambience = ambience.nextSibling;
     }
     
     next();
   }
 }
 
--- a/browser/base/content/test/newtab/Makefile.in
+++ b/browser/base/content/test/newtab/Makefile.in
@@ -23,14 +23,15 @@ include $(topsrcdir)/config/rules.mk
 	browser_newtab_unpin.js \
 	browser_newtab_bug721442.js \
 	browser_newtab_bug722273.js \
 	browser_newtab_bug723102.js \
 	browser_newtab_bug723121.js \
 	browser_newtab_bug725996.js \
 	browser_newtab_bug734043.js \
 	browser_newtab_bug735987.js \
+	browser_newtab_bug752841.js \
 	browser_newtab_bug765628.js \
 	head.js \
 	$(NULL)
 
 libs::	$(_BROWSER_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/newtab/browser_newtab_bug752841.js
@@ -0,0 +1,53 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const PREF_NEWTAB_ROWS = "browser.newtabpage.rows";
+const PREF_NEWTAB_COLUMNS = "browser.newtabpage.columns";
+
+function runTests() {
+  let testValues = [
+    {row: 0, column: 0},
+    {row: -1, column: -1},
+    {row: -1, column: 0},
+    {row: 0, column: -1},
+    {row: 2, column: 4},
+    {row: 2, column: 5},
+  ];
+
+  // Expected length of grid
+  let expectedValues = [1, 1, 1, 1, 8, 10];
+
+   // Values before setting new pref values (9 is the default value -> 3 x 3)
+  let previousValues = [9, 1, 1, 1, 1, 8];
+
+  let existingTab, existingTabGridLength, newTab, newTabGridLength;
+  yield addNewTabPageTab();
+  existingTab = gBrowser.selectedTab;
+
+  for (let i = 0; i < expectedValues.length; i++) {
+    gBrowser.selectedTab = existingTab;
+    existingTabGridLength = getGrid().cells.length;
+    is(existingTabGridLength, previousValues[i],
+      "Grid length of existing page before update is correctly.");
+
+    Services.prefs.setIntPref(PREF_NEWTAB_ROWS, testValues[i].row);
+    Services.prefs.setIntPref(PREF_NEWTAB_COLUMNS, testValues[i].column);
+
+    existingTabGridLength = getGrid().cells.length;
+    is(existingTabGridLength, expectedValues[i],
+      "Existing page grid is updated correctly.");
+
+    yield addNewTabPageTab();
+    newTab = gBrowser.selectedTab;
+    newTabGridLength = getGrid().cells.length;
+    is(newTabGridLength, expectedValues[i],
+      "New page grid is updated correctly.");
+
+    gBrowser.removeTab(newTab);
+  }
+
+  gBrowser.removeTab(existingTab);
+
+  Services.prefs.clearUserPref(PREF_NEWTAB_ROWS);
+  Services.prefs.clearUserPref(PREF_NEWTAB_COLUMNS);
+}
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/social_chat.html
@@ -0,0 +1,22 @@
+<html>
+  <head>
+    <meta charset="utf-8">
+    <script>
+      function pingWorker() {
+        var port = navigator.mozSocial.getWorker().port;
+        port.postMessage({topic: "chatbox-message", result: "ok"});
+      }
+      window.addEventListener("socialFrameShow", function(e) {
+        var port = navigator.mozSocial.getWorker().port;
+        port.postMessage({topic: "chatbox-visibility", result: "shown"});
+      }, false);
+      window.addEventListener("socialFrameHide", function(e) {
+        var port = navigator.mozSocial.getWorker().port;
+        port.postMessage({topic: "chatbox-visibility", result: "hidden"});
+      }, false);
+    </script>
+  </head>
+  <body onload="pingWorker();">
+    <p>This is a test social chat window.</p>
+  </body>
+</html>
--- a/browser/base/content/test/social_panel.html
+++ b/browser/base/content/test/social_panel.html
@@ -1,14 +1,22 @@
 <html>
   <head>
     <meta charset="utf-8">
     <script>
       function pingWorker() {
         var port = navigator.mozSocial.getWorker().port;
         port.postMessage({topic: "panel-message", result: "ok"});
       }
+      window.addEventListener("socialFrameShow", function(e) {
+        var port = navigator.mozSocial.getWorker().port;
+        port.postMessage({topic: "status-panel-visibility", result: "shown"});
+      }, false);
+      window.addEventListener("socialFrameHide", function(e) {
+        var port = navigator.mozSocial.getWorker().port;
+        port.postMessage({topic: "status-panel-visibility", result: "hidden"});
+      }, false);
     </script>
   </head>
   <body onload="pingWorker();">
     <p>This is a test social panel.</p>
   </body>
 </html>
--- a/browser/base/content/test/social_sidebar.html
+++ b/browser/base/content/test/social_sidebar.html
@@ -3,16 +3,21 @@
     <meta charset="utf-8">
     <script>
       var win;
       function pingWorker() {
         var port = navigator.mozSocial.getWorker().port;
         port.onmessage = function(e) {
           var topic = e.data.topic;
           switch (topic) {
+            case "test-chatbox-open":
+              navigator.mozSocial.openChatWindow("social_chat.html", function(chatwin) {
+                port.postMessage({topic: "chatbox-opened", result: chatwin ? "ok" : "failed"});
+              });
+              break;
             case "test-service-window":
               win = navigator.mozSocial.openServiceWindow("social_window.html", "test-service-window", "width=300,height=300");
               break;
             case "test-service-window-twice":
               win = navigator.mozSocial.openServiceWindow("social_window.html", "test-service-window", "width=300,height=300");
               var win2 = navigator.mozSocial.openServiceWindow("social_window.html", "test-service-window", "");
               var result;
               if (win == win2)
@@ -23,16 +28,19 @@
               break;
             case "test-close-service-window":
               win.addEventListener("unload", function watchClose() {
                 win.removeEventListener("unload", watchClose);
                 port.postMessage({topic: "service-window-closed-message", result: "ok"});
               }, false)
               win.close();
               break;
+            case "test-isVisible":
+              port.postMessage({topic: "test-isVisible-response", result: navigator.mozSocial.isVisible});
+              break;
           }
         }
         port.postMessage({topic: "sidebar-message", result: "ok"});
       }
     </script>
   </head>
   <body onload="pingWorker();">
     <p>This is a test social sidebar.</p>
--- a/browser/base/content/test/social_worker.js
+++ b/browser/base/content/test/social_worker.js
@@ -34,26 +34,44 @@ onconnect = function(e) {
         break;
       case "test-close-service-window":
         sidebarPort.postMessage({topic:"test-close-service-window"});
         break;
       case "panel-message":
         if (testPort && event.data.result == "ok")
           testPort.postMessage({topic:"got-panel-message"});
         break;
+      case "status-panel-visibility":
+        testPort.postMessage({topic:"got-social-panel-visibility", result: event.data.result });
+        break;
+      case "test-chatbox-open":
+        sidebarPort.postMessage({topic:"test-chatbox-open"});
+        break;
+      case "chatbox-message":
+        testPort.postMessage({topic:"got-chatbox-message", result: event.data.result});
+        break;
+      case "chatbox-visibility":
+        testPort.postMessage({topic:"got-chatbox-visibility", result: event.data.result});
+        break;
       case "social.initialize":
         // This is the workerAPI port, respond and set up a notification icon.
         port.postMessage({topic: "social.initialize-response"});
         let profile = {
           userName: "foo"
         };
         port.postMessage({topic: "social.user-profile", data: profile});
         let icon = {
           name: "testIcon",
           iconURL: "chrome://branding/content/icon48.png",
-          contentPanel: "http://example.com/browser/browser/base/content/test/social_panel.html",
+          contentPanel: "https://example.com/browser/browser/base/content/test/social_panel.html",
           counter: 1
         };
         port.postMessage({topic: "social.ambient-notification", data: icon});
         break;
+      case "test-isVisible":
+        sidebarPort.postMessage({topic: "test-isVisible"});
+        break;
+      case "test-isVisible-response":
+        testPort.postMessage({topic: "got-isVisible-response", result: event.data.result});
+        break;
     }
   }
 }
--- a/browser/base/jar.mn
+++ b/browser/base/jar.mn
@@ -97,11 +97,12 @@ browser.jar:
 *       content/browser/jsConsoleOverlay.xul          (content/jsConsoleOverlay.xul)
 *       content/browser/softwareUpdateOverlay.xul  (content/softwareUpdateOverlay.xul)
 #endif
 *       content/browser/viewSourceOverlay.xul         (content/viewSourceOverlay.xul)
 #ifdef XP_WIN
         content/browser/win6BrowserOverlay.xul        (content/win6BrowserOverlay.xul)
 #endif
         content/browser/social-icon.png               (content/social-icon.png)
+        content/browser/socialchat.xml                (content/socialchat.xml)
 # the following files are browser-specific overrides
 *       content/browser/license.html                  (/toolkit/content/license.html)
 % override chrome://global/content/license.html chrome://browser/content/license.html
--- a/browser/components/feeds/src/FeedConverter.js
+++ b/browser/components/feeds/src/FeedConverter.js
@@ -280,17 +280,17 @@ FeedConverter.prototype = {
     // Check for a header that tells us there was no sniffing
     // The value doesn't matter.
     try {
       var httpChannel = channel.QueryInterface(Ci.nsIHttpChannel);
       // Make sure to check requestSucceeded before the potentially-throwing
       // getResponseHeader.
       if (!httpChannel.requestSucceeded) {
         // Just give up, but don't forget to cancel the channel first!
-        request.cancel(0x804b0002); // NS_BINDING_ABORTED
+        request.cancel(Cr.NS_BINDING_ABORTED);
         return;
       }
       var noSniff = httpChannel.getResponseHeader("X-Moz-Is-Feed");
     }
     catch (ex) {
       this._sniffed = true;
     }
 
--- a/browser/components/sessionstore/test/Makefile.in
+++ b/browser/components/sessionstore/test/Makefile.in
@@ -55,21 +55,16 @@ MOCHITEST_BROWSER_FILES = \
 	browser_461743.js \
 	browser_461743_sample.html \
 	browser_463205.js \
 	browser_463205_helper.html \
 	browser_463205_sample.html \
 	browser_463206.js \
 	browser_463206_sample.html \
 	browser_464199.js \
-	browser_464620_a.js \
-	browser_464620_a.html \
-	browser_464620_b.js \
-	browser_464620_b.html \
-	browser_464620_xd.html \
 	browser_465215.js \
 	browser_465223.js \
 	browser_466937.js \
 	browser_466937_sample.html \
 	browser_467409-backslashplosion.js \
 	browser_477657.js \
 	browser_480148.js \
 	browser_480893.js \
@@ -131,16 +126,30 @@ MOCHITEST_BROWSER_FILES = \
 	browser_701377.js \
 	browser_705597.js \
 	browser_707862.js \
 	browser_739531.js \
 	browser_739531_sample.html \
 	browser_739805.js \
 	$(NULL)
 
+# Disabled on Windows for frequent intermittent failures
+ifneq ($(OS_ARCH), WINNT)
+MOCHITEST_FILES += \
+	browser_464620_a.js \
+	browser_464620_a.html \
+	browser_464620_b.js \
+	browser_464620_b.html \
+	browser_464620_xd.html \
+	$(NULL)
+else
+$(warning browser_464620_a.js is disabled on Windows for intermittent failures. Bug 552424)
+$(warning browser_464620_b.js is disabled on Windows for intermittent failures. Bug 552424)
+endif
+
 ifneq ($(OS_ARCH),Darwin)
 MOCHITEST_BROWSER_FILES += \
 	browser_597071.js \
 	browser_625016.js \
 	$(NULL)
 endif
 
 include $(topsrcdir)/config/rules.mk
--- a/browser/devtools/debugger/debugger.xul
+++ b/browser/devtools/debugger/debugger.xul
@@ -1,14 +1,13 @@
 <?xml version="1.0" encoding="utf-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/. -->
 <?xml-stylesheet href="chrome://browser/skin/" type="text/css"?>
-<?xml-stylesheet href="chrome://browser/content/orion.css" type="text/css"?>
 <?xml-stylesheet href="chrome://browser/content/debugger.css" type="text/css"?>
 <?xml-stylesheet href="chrome://browser/skin/devtools/common.css" type="text/css"?>
 <?xml-stylesheet href="chrome://browser/skin/devtools/debugger.css" type="text/css"?>
 <!DOCTYPE window [
 <!ENTITY % debuggerDTD SYSTEM "chrome://browser/locale/devtools/debugger.dtd" >
  %debuggerDTD;
 ]>
 <?xul-overlay href="chrome://global/content/editMenuOverlay.xul"?>
--- a/browser/devtools/webconsole/WebConsoleUtils.jsm
+++ b/browser/devtools/webconsole/WebConsoleUtils.jsm
@@ -904,58 +904,73 @@ function JSPropertyProvider(aScope, aInp
 
   let completionPart = aInputValue.substring(beginning.startPos);
 
   // Don't complete on just an empty string.
   if (completionPart.trim() == "") {
     return null;
   }
 
-  let properties = completionPart.split(".");
-  let matchProp;
-  if (properties.length > 1) {
-    matchProp = properties.pop().trimLeft();
-    for (let i = 0; i < properties.length; i++) {
-      let prop = properties[i].trim();
-      if (!prop) {
-        return null;
-      }
+  let matches = null;
+  let matchProp = "";
+
+  let lastDot = completionPart.lastIndexOf(".");
+  if (lastDot > 0 &&
+      (completionPart[0] == "'" || completionPart[0] == '"') &&
+      completionPart[lastDot - 1] == completionPart[0]) {
+    // We are completing a string literal.
+    obj = obj.String.prototype;
+    matchProp = completionPart.slice(lastDot + 1);
+
+  }
+  else {
+    // We are completing a variable / a property lookup.
 
-      // If obj is undefined or null (which is what "== null" does),
-      // then there is no chance to run completion on it. Exit here.
-      if (obj == null) {
-        return null;
-      }
+    let properties = completionPart.split(".");
+    if (properties.length > 1) {
+      matchProp = properties.pop().trimLeft();
+      for (let i = 0; i < properties.length; i++) {
+        let prop = properties[i].trim();
+        if (!prop) {
+          return null;
+        }
 
-      // Check if prop is a getter function on obj. Functions can change other
-      // stuff so we can't execute them to get the next object. Stop here.
-      if (WCU.isNonNativeGetter(obj, prop)) {
-        return null;
-      }
-      try {
-        obj = obj[prop];
-      }
-      catch (ex) {
-        return null;
+        // If obj is undefined or null (which is what "== null" does),
+        // then there is no chance to run completion on it. Exit here.
+        if (obj == null) {
+          return null;
+        }
+
+        // Check if prop is a getter function on obj. Functions can change other
+        // stuff so we can't execute them to get the next object. Stop here.
+        if (WCU.isNonNativeGetter(obj, prop)) {
+          return null;
+        }
+        try {
+          obj = obj[prop];
+        }
+        catch (ex) {
+          return null;
+        }
       }
     }
-  }
-  else {
-    matchProp = properties[0].trimLeft();
-  }
+    else {
+      matchProp = properties[0].trimLeft();
+    }
 
-  // If obj is undefined or null (which is what "== null" does),
-  // then there is no chance to run completion on it. Exit here.
-  if (obj == null) {
-    return null;
-  }
+    // If obj is undefined or null (which is what "== null" does),
+    // then there is no chance to run completion on it. Exit here.
+    if (obj == null) {
+      return null;
+    }
 
-  // Skip Iterators and Generators.
-  if (WCU.isIteratorOrGenerator(obj)) {
-    return null;
+    // Skip Iterators and Generators.
+    if (WCU.isIteratorOrGenerator(obj)) {
+      return null;
+    }
   }
 
   let matches = Object.keys(getMatchedProps(obj, {matchProp:matchProp}));
 
   return {
     matchProp: matchProp,
     matches: matches.sort(),
   };
--- a/browser/devtools/webconsole/test/browser_webconsole_completion.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_completion.js
@@ -100,13 +100,20 @@ function testCompletion(hud) {
 
   // Test non-object autocompletion.
   input.value = "Object.name.sl";
   jsterm.complete(jsterm.COMPLETE_HINT_ONLY, testNext);
   yield;
 
   is(jsterm.completeNode.value, "              ice", "non-object completion");
 
+  // Test string literal autocompletion.
+  input.value = "'Asimov'.sl";
+  jsterm.complete(jsterm.COMPLETE_HINT_ONLY, testNext);
+  yield;
+
+  is(jsterm.completeNode.value, "           ice", "string literal completion");
+
   testDriver = jsterm = input = null;
   executeSoon(finishTest);
   yield;
 }
 
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -701,11 +701,12 @@ bin/components/@DLL_PREFIX@nkgnomevfs@DL
 @BINPATH@/webapprt/chrome/@AB_CD@@JAREXT@
 @BINPATH@/webapprt/chrome/@AB_CD@.manifest
 @BINPATH@/webapprt/components/CommandLineHandler.js
 @BINPATH@/webapprt/components/ContentPermission.js
 @BINPATH@/webapprt/components/ContentPolicy.js
 @BINPATH@/webapprt/components/DirectoryProvider.js
 @BINPATH@/webapprt/components/components.manifest
 @BINPATH@/webapprt/defaults/preferences/prefs.js
+@BINPATH@/webapprt/modules/Startup.jsm
 @BINPATH@/webapprt/modules/WebappRT.jsm
 @BINPATH@/webapprt/modules/WebappsHandler.jsm
 #endif
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -353,16 +353,19 @@ telemetryNoButtonLabel = No
 telemetryNoButtonAccessKey = N
 
 # Webapps notification popup
 webapps.install = Install
 webapps.install.accesskey = I
 #LOCALIZATION NOTE (webapps.requestInstall) %1$S is the web app name, %2$S is the site from which the web app is installed
 webapps.requestInstall = Do you want to install "%1$S" from this site (%2$S)?
 webapps.install.success = Application Installed
+# LOCALIZATION NOTE (webapps.uninstall.notification): %S will be replaced with the name of the uninstalled web app
+webapps.uninstall.notification = %S has been uninstalled from your computer.
+webapps.uninstall.label = Uninstall App
 
 # Telemetry opt-out prompt for Aurora and Nightly
 # LOCALIZATION NOTE (telemetryOptOutPrompt): %1$S and %3$S will be replaced by
 # brandFullName, and %2$S by the value of the toolkit.telemetry.server_owner preference.
 telemetryOptOutPrompt = %1$S sends information about performance, hardware, usage and customizations back to %2$S to help improve %3$S.
 
 # LOCALIZATION NOTE (fullscreen.entered): displayed when we enter HTML5 fullscreen mode, %S is the domain name of the focused website (e.g. mozilla.com).
 fullscreen.entered=%S is now fullscreen.
--- a/browser/modules/NewTabUtils.jsm
+++ b/browser/modules/NewTabUtils.jsm
@@ -19,16 +19,22 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 XPCOMUtils.defineLazyGetter(this, "gPrincipal", function () {
   let uri = Services.io.newURI("about:newtab", null, null);
   return Services.scriptSecurityManager.getNoAppCodebasePrincipal(uri);
 });
 
 // The preference that tells whether this feature is enabled.
 const PREF_NEWTAB_ENABLED = "browser.newtabpage.enabled";
 
+// The preference that tells the number of rows of the newtab grid.
+const PREF_NEWTAB_ROWS = "browser.newtabpage.rows";
+
+// The preference that tells the number of columns of the newtab grid.
+const PREF_NEWTAB_COLUMNS = "browser.newtabpage.columns";
+
 // The maximum number of results we want to retrieve from history.
 const HISTORY_RESULTS_LIMIT = 100;
 
 // The gather telemetry topic.
 const TOPIC_GATHER_TELEMETRY = "gather-telemetry";
 
 /**
  * Singleton that provides storage functionality.
@@ -179,16 +185,70 @@ let AllPages = {
     this._addObserver = function () {};
   },
 
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
                                          Ci.nsISupportsWeakReference])
 };
 
 /**
+ * Singleton that keeps Grid preferences
+ */
+let GridPrefs = {
+  /**
+   * Cached value that tells the number of rows of newtab grid.
+   */
+  _gridRows: null,
+  get gridRows() {
+    if (!this._gridRows) {
+      this._gridRows = Math.max(1, Services.prefs.getIntPref(PREF_NEWTAB_ROWS));
+    }
+
+    return this._gridRows;
+  },
+
+  /**
+   * Cached value that tells the number of columns of newtab grid.
+   */
+  _gridColumns: null,
+  get gridColumns() {
+    if (!this._gridColumns) {
+      this._gridColumns = Math.max(1, Services.prefs.getIntPref(PREF_NEWTAB_COLUMNS));
+    }
+
+    return this._gridColumns;
+  },
+
+
+  /**
+   * Initializes object. Adds a preference observer
+   */
+  init: function GridPrefs_init() {
+    Services.prefs.addObserver(PREF_NEWTAB_ROWS, this, false);
+    Services.prefs.addObserver(PREF_NEWTAB_COLUMNS, this, false);
+  },
+
+  /**
+   * Implements the nsIObserver interface to get notified when the preference
+   * value changes.
+   */
+  observe: function GridPrefs_observe(aSubject, aTopic, aData) {
+    if (aData == PREF_NEWTAB_ROWS) {
+      this._gridRows = null;
+    } else {
+      this._gridColumns = null;
+    }
+
+    AllPages.update();
+  }
+};
+
+GridPrefs.init();
+
+/**
  * Singleton that keeps track of all pinned links and their positions in the
  * grid.
  */
 let PinnedLinks = {
   /**
    * The cached list of pinned links.
    */
   _links: null,
@@ -601,10 +661,11 @@ let NewTabUtils = {
       AllPages.update();
     }, true);
   },
 
   links: Links,
   allPages: AllPages,
   linkChecker: LinkChecker,
   pinnedLinks: PinnedLinks,
-  blockedLinks: BlockedLinks
+  blockedLinks: BlockedLinks,
+  gridPrefs: GridPrefs
 };
--- a/browser/themes/gnomestripe/browser.css
+++ b/browser/themes/gnomestripe/browser.css
@@ -2743,8 +2743,131 @@ stack[anonid=browserStack][responsivemod
 
 #social-notification-panel {
   min-height: 100px;
   min-width: 100px;
   max-height: 600px;
   max-width: 400px;
 }
 
+
+.chat-status-icon {
+  max-height: 16px;
+  max-width: 16px;
+  padding: 0;
+}
+
+.chat-toolbarbutton {
+  -moz-appearance: none;
+  border: none;
+  padding: 0;
+  margin: 0;
+  background: none;
+}
+
+.chat-toolbarbutton > .toolbarbutton-text {
+  display: none;
+}
+
+.chat-close-button {
+  list-style-image: url("chrome://global/skin/icons/close.png");
+  -moz-image-region: rect(0, 16px, 16px, 0);
+}
+
+.chat-close-button:hover {
+  -moz-image-region: rect(0, 32px, 16px, 16px);
+}
+
+.chat-close-button:hover:active {
+  -moz-image-region: rect(0, 48px, 16px, 32px);
+}
+
+
+.chat-toggle-button {
+  /* XXX get a real image for this */
+  list-style-image: url("chrome://global/skin/icons/checkbox.png");
+  -moz-image-region: rect(0, 32px, 16px, 16px);
+}
+
+.chat-toggle-button:hover {
+  -moz-image-region: rect(0, 16px, 16px, 0);
+}
+
+.chat-toggle-button[minimized="true"] {
+  -moz-image-region: rect(0, 16px, 16px, 0);
+}
+
+.chat-toggle-button[minimized="true"]:hover {
+  -moz-image-region: rect(0, 32px, 16px, 16px);
+}
+
+.chat-title {
+  font-weight: bold;
+  color: -moz-dialogtext;
+}
+
+.chat-titlebar {
+  background-image: linear-gradient(white, #ddd);
+  height: 20px;
+  min-height: 20px;
+  width: 100%;
+  margin: 0;
+  padding: 2px;
+  border: none;
+  border-bottom: 1px solid gray;
+}
+
+.chat-titlebar[minimized="true"] {
+  border-bottom: none;
+}
+
+.chat-frame {
+  padding: 0;
+  margin: 0;
+  overflow: hidden;
+}
+
+.chatbar-button {
+  /* XXX get a real image for this */
+  list-style-image: url("chrome://browser/skin/social/social.png");
+  border: none;
+  margin: 0;
+  padding: 2px;
+  height: 21px;
+  width: 21px;
+  border-top: 1px solid gray;
+  -moz-border-end: 1px solid gray;
+}
+
+.chatbar-button[open="true"],
+.chatbar-button:active:hover {
+  box-shadow: inset 0 2px 5px rgba(0,0,0,0.6), 0 1px rgba(255,255,255,0.2);
+}
+
+/* toolbarbutton-icon */
+.chatbar-button > .toolbarbutton-text,
+.chatbar-button > .toolbarbutton-menu-dropmarker {
+  display: none;
+}
+
+.chatbar-innerbox {
+  background: transparent;
+  margin: -200px -1px 0 -1px;
+  overflow: hidden;
+}
+
+chatbar > chatbox {
+  height: 200px;
+  width: 200px;
+  background-color: white;
+  border: 1px solid gray;
+  border-bottom: none;
+}
+
+chatbar > chatbox[minimized="true"] {
+  width: 100px;
+  height: 20px;
+  border-bottom: none;
+}
+
+chatbar > chatbox + chatbox {
+  -moz-margin-start: -1px;
+}
--- a/browser/themes/pinstripe/browser.css
+++ b/browser/themes/pinstripe/browser.css
@@ -3514,8 +3514,134 @@ stack[anonid=browserStack][responsivemod
 }
 
 #social-notification-panel .panel-arrow[side="right"] {
   list-style-image: url("chrome://browser/skin/social/panelarrow-horiz.png");
   margin-left: -1px;
 }
 
 /* === end of social toolbar panels === */
+
+
+.chat-status-icon {
+  max-height: 16px;
+  max-width: 16px;
+  padding: 0;
+}
+
+.chat-toolbarbutton {
+  -moz-appearance: none;
+  border: none;
+  padding: 0;
+  margin: 0;
+  background: none;
+}
+
+.chat-toolbarbutton > .toolbarbutton-text {
+  display: none;
+}
+
+.chat-close-button {
+  list-style-image: url("chrome://global/skin/icons/close.png");
+  -moz-image-region: rect(0, 16px, 16px, 0);
+}
+
+.chat-close-button:hover {
+  -moz-image-region: rect(0, 32px, 16px, 16px);
+}
+
+.chat-close-button:hover:active {
+  -moz-image-region: rect(0, 48px, 16px, 32px);
+}
+
+
+.chat-toggle-button {
+  /* XXX get a real image for this */
+  list-style-image: url("chrome://global/skin/icons/checkbox.png");
+  -moz-image-region: rect(0, 32px, 16px, 16px);
+}
+
+.chat-toggle-button:hover {
+  -moz-image-region: rect(0, 16px, 16px, 0);
+}
+
+.chat-toggle-button[minimized="true"] {
+  -moz-image-region: rect(0, 16px, 16px, 0);
+}
+
+.chat-toggle-button[minimized="true"]:hover {
+  -moz-image-region: rect(0, 32px, 16px, 16px);
+}
+
+.chat-title {
+  font-weight: bold;
+  color: -moz-dialogtext;
+}
+
+.chat-titlebar {
+  background-image: linear-gradient(white, #ddd);
+  height: 20px;
+  min-height: 20px;
+  width: 100%;
+  margin: 0;
+  padding: 2px;
+  border: none;
+  border-bottom: 1px solid #404040;
+}
+
+.chat-titlebar[minimized="true"] {
+  border-bottom: none;
+}
+
+.chat-frame {
+  padding: 0;
+  margin: 0;
+  overflow: hidden;
+}
+
+.chatbar-button {
+  /* XXX get a real image for this */
+  background-image: linear-gradient(white, #ddd);
+  list-style-image: url("chrome://browser/skin/social/social.png");
+  border: none;
+  margin: 0;
+  padding: 2px;
+  height: 21px;
+  width: 21px;
+  border-top: 1px solid #404040;
+  -moz-border-end: 1px solid #404040;
+}
+
+.chatbar-button[open="true"],
+.chatbar-button:active:hover {
+  box-shadow: inset 0 2px 5px rgba(0,0,0,0.6), 0 1px rgba(255,255,255,0.2);
+}
+
+/* toolbarbutton-icon */
+.chatbar-button > .toolbarbutton-text,
+.chatbar-button > .toolbarbutton-menu-dropmarker {
+  display: none;
+}
+
+.chatbar-innerbox {
+  background: transparent;
+  margin: -200px -1px 0 -1px;
+  overflow: hidden;
+}
+
+chatbar > chatbox {
+  height: 200px;
+  width: 200px;
+  background-color: white;
+  border: 1px solid #404040;
+  border-bottom: none;
+}
+
+chatbar > chatbox[minimized="true"] {
+  width: 100px;
+  height: 20px;
+  border-bottom: none;
+}
+
+chatbar > chatbox + chatbox {
+  -moz-margin-start: -1px;
+}
+
--- a/browser/themes/winstripe/browser-aero.css
+++ b/browser/themes/winstripe/browser-aero.css
@@ -105,16 +105,22 @@
     -moz-margin-start: 0;
     -moz-margin-end: -3px;
   }
 
   .menu-accel,
   .menu-iconic-accel {
     color: graytext;
   }
+
+  .chatbar-button,
+  chatbar > chatbox {
+    border-color: #A9B7C9;
+  }
+  
 }
 
 @media (-moz-windows-compositor) {
   /* These should be hidden w/ glass enabled. Windows draws its own buttons. */
   .titlebar-button {
     display: none;
   }
 
--- a/browser/themes/winstripe/browser.css
+++ b/browser/themes/winstripe/browser.css
@@ -3445,8 +3445,141 @@ stack[anonid=browserStack][responsivemod
 }
 
 #social-notification-panel {
   min-height: 100px;
   min-width: 100px;
   max-height: 600px;
   max-width: 400px;
 }
+
+
+.chat-status-icon {
+  max-height: 16px;
+  max-width: 16px;
+  padding: 0;
+}
+
+.chat-toolbarbutton {
+  -moz-appearance: none;
+  border: none;
+  padding: 0;
+  margin: 0;
+  background: none;
+}
+
+.chat-toolbarbutton > .toolbarbutton-text {
+  display: none;
+}
+
+.chat-close-button {
+  list-style-image: url("chrome://global/skin/icons/Close.gif");
+  padding: 2px 4px;
+}
+
+.chat-close-button:hover {
+  box-shadow: inset 0 2px 5px rgba(0,0,0,0.6), 0 1px rgba(255,255,255,0.2);
+}
+
+.chat-close-button:hover:active {
+  box-shadow: inset 0 2px 5px rgba(0,0,0,0.6), 0 1px rgba(255,255,255,0.2);
+}
+
+
+.chat-toggle-button {
+  /* XXX get a real image for this */
+  list-style-image: url("chrome://global/skin/icons/expand.png");
+}
+
+.chat-toggle-button:hover {
+  box-shadow: inset 0 2px 5px rgba(0,0,0,0.6), 0 1px rgba(255,255,255,0.2);
+}
+
+.chat-toggle-button[minimized="true"] {
+  list-style-image: url("chrome://global/skin/icons/collapse.png");
+}
+
+.chat-toggle-button[minimized="true"]:hover {
+  box-shadow: inset 0 2px 5px rgba(0,0,0,0.6), 0 1px rgba(255,255,255,0.2);
+}
+
+.chat-title {
+  font-weight: bold;
+  color: -moz-dialogtext;
+}
+
+.chat-titlebar {
+  background-image: linear-gradient(white, #ddd);
+  height: 20px;
+  min-height: 20px;
+  width: 100%;
+  margin: 0;
+  padding: 2px;
+  border: none;
+  border-bottom: 1px solid gray;
+}
+
+.chat-titlebar[minimized="true"] {
+  border-bottom: none;
+}
+
+.chat-frame {
+  padding: 0;
+  margin: 0;
+  overflow: hidden;
+}
+
+.chatbar-button {
+  /* XXX get a real image for this */
+  -moz-appearance: none;
+  list-style-image: url("chrome://browser/skin/social/social.png");
+  background-image: linear-gradient(white, #ddd);
+  border: none;
+  margin: 0;
+  padding: 2px;
+  height: 21px;
+  width: 21px;
+  border-top: 1px solid gray;
+  -moz-border-end: 1px solid gray;
+}
+
+.chatbar-button > .button-box > .box-inherit > .button-icon {
+  max-height: 16px;
+  max-width: 16px;
+  padding: 2px;
+}
+
+.chatbar-button[open="true"],
+.chatbar-button:hover,
+.chatbar-button:active:hover {
+  box-shadow: inset 0 2px 5px rgba(0,0,0,0.6), 0 1px rgba(255,255,255,0.2);
+}
+
+/* toolbarbutton-icon */
+.chatbar-button > .toolbarbutton-text,
+.chatbar-button > .toolbarbutton-menu-dropmarker {
+  display: none;
+}
+
+.chatbar-innerbox {
+  background: transparent;
+  margin: -200px -1px 0 -1px;
+  overflow: hidden;
+}
+
+chatbar > chatbox {
+  height: 200px;
+  width: 200px;
+  background-color: white;
+  border: 1px solid gray;
+  border-bottom: none;
+}
+
+chatbar > chatbox[minimized="true"] {
+  width: 100px;
+  height: 20px;
+  border-bottom: none;
+}
+
+chatbar > chatbox + chatbox {
+  -moz-margin-start: -1px;
+}
+
--- a/build/autoconf/compiler-opts.m4
+++ b/build/autoconf/compiler-opts.m4
@@ -80,17 +80,21 @@ dnl A high level macro for selecting com
 AC_DEFUN([MOZ_COMPILER_OPTS],
 [
   MOZ_RTTI
 if test "$CLANG_CXX"; then
     ## We disable return-type-c-linkage because jsval is defined as a C++ type but is
     ## returned by C functions. This is possible because we use knowledge about the ABI
     ## to typedef it to a C type with the same layout when the headers are included
     ## from C.
-    _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wno-unknown-warning-option -Wno-return-type-c-linkage"
+    ##
+    ## mismatched-tags is disabled (bug 780474) mostly because it's useless.
+    ## Worse, it's not supported by gcc, so it will cause tryserver bustage
+    ## without any easy way for non-Clang users to check for it.
+    _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wno-unknown-warning-option -Wno-return-type-c-linkage -Wno-mismatched-tags"
 fi
 
 if test "$GNU_CC"; then
     CFLAGS="$CFLAGS -ffunction-sections -fdata-sections"
     CXXFLAGS="$CXXFLAGS -ffunction-sections -fdata-sections -fno-exceptions"
 fi
 
 dnl ========================================================
--- a/build/autoconf/config.status.m4
+++ b/build/autoconf/config.status.m4
@@ -69,28 +69,30 @@ test "x$exec_prefix" = xNONE && exec_pre
 trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
 
 : ${CONFIG_STATUS=./config.status}
 
 dnl We're going to need [ ] for python syntax.
 changequote(<<<, >>>)dnl
 echo creating $CONFIG_STATUS
 
+extra_python_path=${COMM_BUILD:+"'mozilla', "}
+
 cat > $CONFIG_STATUS <<EOF
 #!${PYTHON}
 # coding=$encoding
 
 import os, sys
 dnl topsrcdir is the top source directory in native form, as opposed to a
 dnl form suitable for make.
 topsrcdir = '''${WIN_TOP_SRC:-$srcdir}'''
 if not os.path.isabs(topsrcdir):
     topsrcdir = os.path.normpath(os.path.join(os.path.dirname(<<<__file__>>>), topsrcdir))
 dnl Don't rely on virtualenv here. Standalone js doesn't use it.
-sys.path.append(os.path.join(topsrcdir, ${COMM_BUILD:+'mozilla',} 'build'))
+sys.path.append(os.path.join(topsrcdir, ${extra_python_path}'build'))
 from ConfigStatus import config_status
 
 args = {
     'topsrcdir': topsrcdir,
     'topobjdir': os.path.dirname(<<<__file__>>>),
 
 dnl All defines and substs are stored with an additional space at the beginning
 dnl and at the end of the string, to avoid any problem with values starting or
--- a/build/mobile/sutagent/android/CmdWorkerThread.java
+++ b/build/mobile/sutagent/android/CmdWorkerThread.java
@@ -93,17 +93,17 @@ public class CmdWorkerThread extends Thr
         try {
             OutputStream cmdOut = socket.getOutputStream();
             InputStream cmdIn = socket.getInputStream();
             PrintWriter out = new PrintWriter(cmdOut, true);
             BufferedInputStream in = new BufferedInputStream(cmdIn);
             String inputLine, outputLine;
             DoCommand dc = new DoCommand(theParent.svc);
 
-            SUTAgentAndroid.logToFile(dc.GetTestRoot(), dc.GetSystemTime(), "CmdWorkerThread starts: "+getId());
+            SUTAgentAndroid.logToFile(dc, "CmdWorkerThread starts: "+getId());
 
             int nAvail = cmdIn.available();
             cmdIn.skip(nAvail);
 
             out.print(prompt);
             out.flush();
 
             while (bListening)
@@ -131,17 +131,17 @@ public class CmdWorkerThread extends Thr
                     }
                 else
                     inputLine = "";
 
                 if ((inputLine += readLine(in)) != null)
                     {
                     String message = String.format("%s : %s",
                                      socket.getInetAddress().getHostAddress(), inputLine);
-                    SUTAgentAndroid.logToFile(dc.GetTestRoot(), dc.GetSystemTime(), message);
+                    SUTAgentAndroid.logToFile(dc, message);
 
                     outputLine = dc.processCommand(inputLine, out, in, cmdOut);
                     if (outputLine.length() > 0)
                         {
                         out.print(outputLine + "\n" + prompt);
                         }
                     else
                         out.print(prompt);
@@ -161,17 +161,17 @@ public class CmdWorkerThread extends Thr
                 else
                     break;
                 }
             out.close();
             out = null;
             in.close();
             in = null;
             socket.close();
-            SUTAgentAndroid.logToFile(dc.GetTestRoot(), dc.GetSystemTime(), "CmdWorkerThread ends: "+getId());
+            SUTAgentAndroid.logToFile(dc, "CmdWorkerThread ends: "+getId());
         }
     catch (IOException e)
         {
         // TODO Auto-generated catch block
         e.printStackTrace();
         }
     }
 }
--- a/build/mobile/sutagent/android/SUTAgentAndroid.java
+++ b/build/mobile/sutagent/android/SUTAgentAndroid.java
@@ -70,16 +70,17 @@ public class SUTAgentAndroid extends Act
     public PrintWriter dataOut = null;
 
     private static boolean bNetworkingStarted = false;
     private static String RegSvrIPAddr = "";
     private static String RegSvrIPPort = "";
     private static String HardwareID = "";
     private static String Pool = "";
     private static String sRegString = "";
+    private static boolean LogCommands = false;
 
     private WifiLock wl = null;
 
     private BroadcastReceiver battReceiver = null;
 
     private TextView  tv = null;
 
     public boolean onCreateOptionsMenu(Menu menu)
@@ -147,27 +148,30 @@ public class SUTAgentAndroid extends Act
         super.onCreate(savedInstanceState);
 
         setContentView(R.layout.main);
 
         fixScreenOrientation();
 
         DoCommand dc = new DoCommand(getApplication());
 
-        logToFile(dc.GetTestRoot(), dc.GetSystemTime(), "onCreate");
-
         // Get configuration settings from "ini" file
         File dir = getFilesDir();
         File iniFile = new File(dir, "SUTAgent.ini");
         String sIniFile = iniFile.getAbsolutePath();
 
+        String lc = dc.GetIniData("General", "LogCommands", sIniFile);
+        if (lc != "" && Integer.parseInt(lc) == 1) {
+            SUTAgentAndroid.LogCommands = true;
+        }
         SUTAgentAndroid.RegSvrIPAddr = dc.GetIniData("Registration Server", "IPAddr", sIniFile);
         SUTAgentAndroid.RegSvrIPPort = dc.GetIniData("Registration Server", "PORT", sIniFile);
         SUTAgentAndroid.HardwareID = dc.GetIniData("Registration Server", "HARDWARE", sIniFile);
         SUTAgentAndroid.Pool = dc.GetIniData("Registration Server", "POOL", sIniFile);
+        logToFile(dc, "onCreate");
 
         tv = (TextView) this.findViewById(R.id.Textview01);
 
         if (getLocalIpAddress() == null)
             setUpNetwork(sIniFile);
 
         String macAddress = "Unknown";
         if (android.os.Build.VERSION.SDK_INT > 8) {
@@ -349,61 +353,61 @@ public class SUTAgentAndroid extends Act
             {
                Toast.makeText(getApplication().getApplicationContext(), "SUTAgent startprg finished ...", Toast.LENGTH_LONG).show();
             }
         }
 
     @Override
     public void onDestroy()
         {
+        DoCommand dc = new DoCommand(getApplication());
         super.onDestroy();
-        DoCommand dc = new DoCommand(getApplication());
         if (isFinishing())
             {
-            logToFile(dc.GetTestRoot(), dc.GetSystemTime(), "onDestroy - finishing");
+            logToFile(dc, "onDestroy - finishing");
             Intent listenerSvc = new Intent(this, ASMozStub.class);
             listenerSvc.setAction("com.mozilla.SUTAgentAndroid.service.LISTENER_SERVICE");
             stopService(listenerSvc);
             bNetworkingStarted = false;
 
             unregisterReceiver(battReceiver);
 
             if (wl != null)
                 wl.release();
 
             System.exit(0);
             }
         else
             {
-            logToFile(dc.GetTestRoot(), dc.GetSystemTime(), "onDestroy - not finishing");
+            logToFile(dc, "onDestroy - not finishing");
             }
         }
 
     @Override
     public void onLowMemory()
         {
         System.gc();
         DoCommand dc = new DoCommand(getApplication());
         if (dc != null)
             {
-            logToFile(dc.GetTestRoot(), dc.GetSystemTime(), "onLowMemory");
-            logToFile(dc.GetTestRoot(), dc.GetSystemTime(), dc.GetMemoryInfo());
+            logToFile(dc, "onLowMemory");
+            logToFile(dc, dc.GetMemoryInfo());
             String procInfo = dc.GetProcessInfo();
             if (procInfo != null)
                 {
                 String lines[] = procInfo.split("\n");
                 for (String line : lines) 
                     {
                     if (line.contains("mozilla"))
                         {
-                        logToFile(dc.GetTestRoot(), dc.GetSystemTime(), line);
+                        logToFile(dc, line);
                         String words[] = line.split("\t");
                         if ((words != null) && (words.length > 1))
                             {
-                            logToFile(dc.GetTestRoot(), dc.GetSystemTime(), dc.StatProcess(words[1]));
+                            logToFile(dc, dc.StatProcess(words[1]));
                             }
                         }
                     }
                 }
             }
         else
             {
             Log.e("SUTAgentAndroid", "onLowMemory: unable to log to file!");
@@ -753,27 +757,39 @@ public class SUTAgentAndroid extends Act
             }
         catch (SocketException ex)
             {
             Toast.makeText(getApplication().getApplicationContext(), ex.toString(), Toast.LENGTH_LONG).show();
             }
         return null;
         }
 
-    public static void logToFile(String testRoot, String datestamp, String message)
+    public static void logToFile(DoCommand dc, String message)
         {
-        if (testRoot == null ||
-            datestamp == null ||
-            message == null)
+        if (SUTAgentAndroid.LogCommands == false)
+            {
+            return;
+            }
+
+        if (message == null)
             {
             Log.e("SUTAgentAndroid", "bad arguments in logToFile()!");
             return;
             }
         Log.i("SUTAgentAndroid", message);
         String fileDateStr = "00";
+        String testRoot = dc.GetTestRoot();
+        String datestamp = dc.GetSystemTime();
+        if (testRoot == null || datestamp == null)
+            {
+            Log.e("SUTAgentAndroid", "Unable to get testRoot or datestamp in logToFile!");
+            return;
+            }
+
+
         try 
             {
             SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS");
             Date dateStr = sdf.parse(datestamp);
             SimpleDateFormat sdf_file = new SimpleDateFormat("yyyy-MM-dd");
             fileDateStr = sdf_file.format(dateStr);
             } 
         catch (ParseException pe) {}
--- 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(6df7d16d-5b26-42a1-b1f7-069d46c37aa8)]
+[scriptable, uuid(825ffce8-962d-11e1-aef3-8f2b6188709b)]
 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;
@@ -168,33 +168,43 @@ interface nsIPrincipal : nsISerializable
      */
     boolean subsumesIgnoringDomain(in nsIPrincipal other);
 
     /**
      * Checks whether this principal is allowed to load the network resource
      * located at the given URI under the same-origin policy. This means that
      * codebase principals are only allowed to load resources from the same
      * domain, the system principal is allowed to load anything, and null
-     * principals are not allowed to load anything.
+     * principals are not allowed to load anything. This is changed slightly
+     * by the optional flag allowIfInheritsPrincipal (which defaults to false)
+     * which allows the load of a data: URI (which inherits the principal of
+     * its loader) or a URI with the same principal as its loader (eg. a 
+     * Blob URI).
+     * In these cases, with allowIfInheritsPrincipal set to true, the URI can
+     * be loaded by a null principal.
      *
      * If the load is allowed this function does nothing. If the load is not
      * allowed the function throws NS_ERROR_DOM_BAD_URI.
      *
      * NOTE: Other policies might override this, such as the Access-Control
      *       specification.
      * NOTE: The 'domain' attribute has no effect on the behaviour of this
      *       function.
      *
      *
      * @param uri    The URI about to be loaded.
      * @param report If true, will report a warning to the console service
      *               if the load is not allowed.
+     * @param allowIfInheritsPrincipal   If true, the load is allowed if the
+     *                                   loadee inherits the principal of the
+     *                                   loader.
      * @throws NS_ERROR_DOM_BAD_URI if the load is not allowed.
      */
-    void checkMayLoad(in nsIURI uri, in boolean report);
+    void checkMayLoad(in nsIURI uri, in boolean report,
+                      in boolean allowIfInheritsPrincipal);
 
     /**
      * The subject name for the certificate.  This actually identifies the
      * subject of the certificate.  This may well not be a string that would
      * mean much to a typical user on its own (e.g. it may have a number of
      * different names all concatenated together with some information on what
      * they mean in between).
      *
--- a/caps/include/nsNullPrincipal.h
+++ b/caps/include/nsNullPrincipal.h
@@ -10,16 +10,17 @@
  */
 
 #ifndef nsNullPrincipal_h__
 #define nsNullPrincipal_h__
 
 #include "nsIPrincipal.h"
 #include "nsJSPrincipals.h"
 #include "nsCOMPtr.h"
+#include "nsPrincipal.h"
 
 class nsIURI;
 
 #define NS_NULLPRINCIPAL_CLASSNAME "nullprincipal"
 #define NS_NULLPRINCIPAL_CID \
 { 0xdd156d62, 0xd26f, 0x4441, \
  { 0x9c, 0xdb, 0xe8, 0xf0, 0x91, 0x07, 0xc2, 0x73 } }
 #define NS_NULLPRINCIPAL_CONTRACTID "@mozilla.org/nullprincipal;1"
--- a/caps/include/nsPrincipal.h
+++ b/caps/include/nsPrincipal.h
@@ -8,16 +8,19 @@
 
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsVoidArray.h"
 #include "nsHashtable.h"
 #include "nsJSPrincipals.h"
 #include "nsTArray.h"
 #include "nsAutoPtr.h"
+#include "nsIProtocolHandler.h"
+#include "nsNetUtil.h"
+#include "nsScriptSecurityManager.h"
 
 class nsIObjectInputStream;
 class nsIObjectOutputStream;
 class DomainPolicy; 
 
 class nsBasePrincipal : public nsJSPrincipals
 {
 public:
@@ -118,17 +121,17 @@ public:
   NS_IMETHOD EqualsIgnoringDomain(nsIPrincipal* other, bool* _retval);
   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_IMETHOD SubsumesIgnoringDomain(nsIPrincipal* other, bool* _retval);
-  NS_IMETHOD CheckMayLoad(nsIURI* uri, bool report);
+  NS_IMETHOD CheckMayLoad(nsIURI* uri, bool report, bool allowIfInheritsPrincipal);
   NS_IMETHOD GetExtendedOrigin(nsACString& aExtendedOrigin);
   NS_IMETHOD GetAppStatus(PRUint16* aAppStatus);
   NS_IMETHOD GetAppId(PRUint32* aAppStatus);
   NS_IMETHOD GetIsInBrowserElement(bool* aIsInBrowserElement);
 #ifdef DEBUG
   virtual void dumpImpl();
 #endif
 
@@ -153,16 +156,33 @@ public:
                               bool aIsCert,
                               bool aTrusted,
                               PRUint32 aAppId,
                               bool aInMozBrowser);
 
   virtual void GetScriptLocation(nsACString& aStr) MOZ_OVERRIDE;
   void SetURI(nsIURI* aURI);
 
+  static bool IsPrincipalInherited(nsIURI* aURI) {
+    // return true if the loadee URI has
+    // the URI_INHERITS_SECURITY_CONTEXT flag set.
+    bool doesInheritSecurityContext;
+    nsresult rv =
+    NS_URIChainHasFlags(aURI,
+                        nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
+                        &doesInheritSecurityContext);
+
+    if (NS_SUCCEEDED(rv) && doesInheritSecurityContext) {
+      return true;
+    }
+
+    return false;
+  }
+
+
   /**
    * Computes the puny-encoded origin of aURI.
    */
   static nsresult GetOriginForURI(nsIURI* aURI, char **aOrigin);
 
   nsCOMPtr<nsIURI> mDomain;
   nsCOMPtr<nsIURI> mCodebase;
   PRUint32 mAppId;
@@ -197,17 +217,17 @@ public:
   NS_IMETHOD EqualsIgnoringDomain(nsIPrincipal* other, bool* _retval);
   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_IMETHOD SubsumesIgnoringDomain(nsIPrincipal* other, bool* _retval);
-  NS_IMETHOD CheckMayLoad(nsIURI* uri, bool report);
+  NS_IMETHOD CheckMayLoad(nsIURI* uri, bool report, bool allowIfInheritsPrincipal);
   NS_IMETHOD GetExtendedOrigin(nsACString& aExtendedOrigin);
   NS_IMETHOD GetAppStatus(PRUint16* aAppStatus);
   NS_IMETHOD GetAppId(PRUint32* aAppStatus);
   NS_IMETHOD GetIsInBrowserElement(bool* aIsInBrowserElement);
 #ifdef DEBUG
   virtual void dumpImpl();
 #endif
   
--- a/caps/src/nsNullPrincipal.cpp
+++ b/caps/src/nsNullPrincipal.cpp
@@ -287,18 +287,36 @@ nsNullPrincipal::Subsumes(nsIPrincipal *
 
 NS_IMETHODIMP
 nsNullPrincipal::SubsumesIgnoringDomain(nsIPrincipal *aOther, bool *aResult)
 {
   return Subsumes(aOther, aResult);
 }
 
 NS_IMETHODIMP
-nsNullPrincipal::CheckMayLoad(nsIURI* aURI, bool aReport)
-{
+nsNullPrincipal::CheckMayLoad(nsIURI* aURI, bool aReport, bool aAllowIfInheritsPrincipal)
+ {
+  if (aAllowIfInheritsPrincipal) {
+    if (nsPrincipal::IsPrincipalInherited(aURI)) {
+      return NS_OK;
+    }
+
+    // Also allow the load if the principal of the URI being checked is exactly
+    // us ie this.
+    nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(aURI);
+    if (uriPrinc) {
+      nsCOMPtr<nsIPrincipal> principal;
+      uriPrinc->GetPrincipal(getter_AddRefs(principal));
+
+      if (principal && principal == this) {
+        return NS_OK;
+      }
+    }
+  }
+
   if (aReport) {
     nsScriptSecurityManager::ReportError(
       nullptr, NS_LITERAL_STRING("CheckSameOriginError"), mURI, aURI);
   }
 
   return NS_ERROR_DOM_BAD_URI;
 }
 
--- a/caps/src/nsPrincipal.cpp
+++ b/caps/src/nsPrincipal.cpp
@@ -841,18 +841,26 @@ URIIsLocalFile(nsIURI *aURI)
 
   return util && NS_SUCCEEDED(util->ProtocolHasFlags(aURI,
                                 nsIProtocolHandler::URI_IS_LOCAL_FILE,
                                 &isFile)) &&
          isFile;
 }
 
 NS_IMETHODIMP
-nsPrincipal::CheckMayLoad(nsIURI* aURI, bool aReport)
+nsPrincipal::CheckMayLoad(nsIURI* aURI, bool aReport, bool aAllowIfInheritsPrincipal)
 {
+   if (aAllowIfInheritsPrincipal) {
+    // If the caller specified to allow loads of URIs that inherit
+    // our principal, allow the load if this URI inherits its principal
+    if (nsPrincipal::IsPrincipalInherited(aURI)) {
+      return NS_OK;
+    }
+  }
+
   if (!nsScriptSecurityManager::SecurityCompareURIs(mCodebase, aURI)) {
     if (nsScriptSecurityManager::GetStrictFileOriginPolicy() &&
         URIIsLocalFile(aURI)) {
       nsCOMPtr<nsIFileURL> fileURL(do_QueryInterface(aURI));
 
       if (!URIIsLocalFile(mCodebase)) {
         // If the codebase is not also a file: uri then forget it
         // (don't want resource: principals in a file: doc)
@@ -1427,21 +1435,21 @@ nsExpandedPrincipal::Subsumes(nsIPrincip
 
 NS_IMETHODIMP
 nsExpandedPrincipal::SubsumesIgnoringDomain(nsIPrincipal* aOther, bool* aResult)
 {
   return ::Subsumes(this, &nsIPrincipal::SubsumesIgnoringDomain, aOther, aResult);
 }
 
 NS_IMETHODIMP
-nsExpandedPrincipal::CheckMayLoad(nsIURI* uri, bool aReport)
+nsExpandedPrincipal::CheckMayLoad(nsIURI* uri, bool aReport, bool aAllowIfInheritsPrincipal)
 {
   nsresult rv;
   for (uint32_t i = 0; i < mPrincipals.Length(); ++i){
-    rv = mPrincipals[i]->CheckMayLoad(uri, aReport);
+    rv = mPrincipals[i]->CheckMayLoad(uri, aReport, aAllowIfInheritsPrincipal);
     if (NS_SUCCEEDED(rv))
       return rv;
   }
 
   return NS_ERROR_DOM_BAD_URI;
 }
 
 NS_IMETHODIMP
--- a/caps/src/nsScriptSecurityManager.cpp
+++ b/caps/src/nsScriptSecurityManager.cpp
@@ -841,20 +841,19 @@ nsScriptSecurityManager::CheckPropertyAc
         objectPrincipal = nullptr;
 
         NS_ConvertUTF8toUTF16 className(classInfoData.GetName());
         nsCAutoString subjectOrigin;
         nsCAutoString subjectDomain;
         if (!nsAutoInPrincipalDomainOriginSetter::sInPrincipalDomainOrigin) {
             nsCOMPtr<nsIURI> uri, domain;
             subjectPrincipal->GetURI(getter_AddRefs(uri));
-            // Subject can't be system if we failed the security
-            // check, so |uri| is non-null.
-            NS_ASSERTION(uri, "How did that happen?");
-            GetOriginFromURI(uri, subjectOrigin);
+            if (uri) { // Object principal might be expanded
+                GetOriginFromURI(uri, subjectOrigin);
+            }
             subjectPrincipal->GetDomain(getter_AddRefs(domain));
             if (domain) {
                 GetOriginFromURI(domain, subjectDomain);
             }
         } else {
             subjectOrigin.AssignLiteral("the security manager");
         }
         NS_ConvertUTF8toUTF16 subjectOriginUnicode(subjectOrigin);
@@ -1064,66 +1063,74 @@ nsScriptSecurityManager::LookupPolicy(ns
     }
 
     if (!dpolicy && mOriginToPolicyMap)
     {
         //-- Look up the relevant domain policy, if any
 #ifdef DEBUG_CAPS_LookupPolicy
         printf("DomainLookup ");
 #endif
-
-        nsCAutoString origin;
-        rv = GetPrincipalDomainOrigin(aPrincipal, origin);
-        NS_ENSURE_SUCCESS(rv, rv);
+        if (nsCOMPtr<nsIExpandedPrincipal> exp = do_QueryInterface(aPrincipal)) 
+        {
+            // For expanded principals domain origin is not defined so let's just
+            // use the default policy
+            dpolicy = mDefaultPolicy;
+        }
+        else
+        {
+            nsCAutoString origin;
+            rv = GetPrincipalDomainOrigin(aPrincipal, origin);
+            NS_ENSURE_SUCCESS(rv, rv);
  
-        char *start = origin.BeginWriting();
-        const char *nextToLastDot = nullptr;
-        const char *lastDot = nullptr;
-        const char *colon = nullptr;
-        char *p = start;
-
-        //-- search domain (stop at the end of the string or at the 3rd slash)
-        for (PRUint32 slashes=0; *p; p++)
-        {
-            if (*p == '/' && ++slashes == 3) 
-            {
-                *p = '\0'; // truncate at 3rd slash
-                break;
-            }
-            if (*p == '.')
+            char *start = origin.BeginWriting();
+            const char *nextToLastDot = nullptr;
+            const char *lastDot = nullptr;
+            const char *colon = nullptr;
+            char *p = start;
+
+            //-- search domain (stop at the end of the string or at the 3rd slash)
+            for (PRUint32 slashes=0; *p; p++)
             {
-                nextToLastDot = lastDot;
-                lastDot = p;
-            } 
-            else if (!colon && *p == ':')
-                colon = p;
+                if (*p == '/' && ++slashes == 3) 
+                {
+                    *p = '\0'; // truncate at 3rd slash
+                    break;
+                }
+                if (*p == '.')
+                {
+                    nextToLastDot = lastDot;
+                    lastDot = p;
+                } 
+                else if (!colon && *p == ':')
+                    colon = p;
+            }
+
+            nsCStringKey key(nextToLastDot ? nextToLastDot+1 : start);
+            DomainEntry *de = (DomainEntry*) mOriginToPolicyMap->Get(&key);
+            if (!de)
+            {
+                nsCAutoString scheme(start, colon-start+1);
+                nsCStringKey schemeKey(scheme);
+                de = (DomainEntry*) mOriginToPolicyMap->Get(&schemeKey);
+            }
+
+            while (de)
+            {
+                if (de->Matches(start))
+                {
+                    dpolicy = de->mDomainPolicy;
+                    break;
+                }
+                de = de->mNext;
+            }
+
+            if (!dpolicy)
+                dpolicy = mDefaultPolicy;
         }
 
-        nsCStringKey key(nextToLastDot ? nextToLastDot+1 : start);
-        DomainEntry *de = (DomainEntry*) mOriginToPolicyMap->Get(&key);
-        if (!de)
-        {
-            nsCAutoString scheme(start, colon-start+1);
-            nsCStringKey schemeKey(scheme);
-            de = (DomainEntry*) mOriginToPolicyMap->Get(&schemeKey);
-        }
-
-        while (de)
-        {
-            if (de->Matches(start))
-            {
-                dpolicy = de->mDomainPolicy;
-                break;
-            }
-            de = de->mNext;
-        }
-
-        if (!dpolicy)
-            dpolicy = mDefaultPolicy;
-
         aPrincipal->SetSecurityPolicy((void*)dpolicy);
     }
 
     ClassPolicy* cpolicy = nullptr;
 
     if ((dpolicy == mDefaultPolicy) && aCachedClassPolicy)
     {
         // No per-domain policy for this principal (the more common case)
@@ -1382,17 +1389,17 @@ nsScriptSecurityManager::CheckLoadURIWit
     // Check for uris that are only loadable by principals that subsume them
     bool hasFlags;
     rv = NS_URIChainHasFlags(targetBaseURI,
                              nsIProtocolHandler::URI_LOADABLE_BY_SUBSUMERS,
                              &hasFlags);
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (hasFlags) {
-        return aPrincipal->CheckMayLoad(targetBaseURI, true);
+        return aPrincipal->CheckMayLoad(targetBaseURI, true, false);
     }
 
     //-- get the source scheme
     nsCAutoString sourceScheme;
     rv = sourceBaseURI->GetScheme(sourceScheme);
     if (NS_FAILED(rv)) return rv;
 
     if (sourceScheme.LowerCaseEqualsLiteral(NS_NULLPRINCIPAL_SCHEME)) {
--- a/caps/src/nsSystemPrincipal.cpp
+++ b/caps/src/nsSystemPrincipal.cpp
@@ -110,17 +110,17 @@ nsSystemPrincipal::Subsumes(nsIPrincipal
 NS_IMETHODIMP
 nsSystemPrincipal::SubsumesIgnoringDomain(nsIPrincipal *other, bool *result)
 {
     *result = true;
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSystemPrincipal::CheckMayLoad(nsIURI* uri, bool aReport)
+nsSystemPrincipal::CheckMayLoad(nsIURI* uri, bool aReport, bool aAllowIfInheritsPrincipal)
 {
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSystemPrincipal::GetHashValue(PRUint32 *result)
 {
     *result = NS_PTR_TO_INT32(this);
--- a/caps/tests/mochitest/test_bug292789.html.in
+++ b/caps/tests/mochitest/test_bug292789.html.in
@@ -8,17 +8,18 @@ https://bugzilla.mozilla.org/show_bug.cg
   <script type="text/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=292789">Mozilla Bug 292789</a>
 <p id="display"></p>
 <div id="content" style="display: none">
   <script src="chrome://global/content/strres.js"></script>
-  <script src="chrome://mozapps/content/xpinstall/xpinstallConfirm.js"></script>
+  <script type="application/javascript;version=1.8" src="chrome://mozapps/content/xpinstall/xpinstallConfirm.js"></script>
+  <script id="resjs" type="application/javascript;version=1.8"></script>
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 /** Test for Bug 292789
  **
  ** Selectively allow access to whitelisted chrome packages
  ** even for ALLOW_CHROME mechanisms (<script>, <img> etc)
@@ -31,23 +32,23 @@ function testScriptSrc(aCallback) {
     is(typeof srGetStrBundle, "function",
        "content can still load <script> from chrome://global");
     is(typeof XPInstallConfirm, "undefined",
        "content should not be able to load <script> from chrome://mozapps");
     
     /** make sure the last one didn't pass because someone
      ** moved the resource
      **/
-    var resjs = document.createElement("script");
+    var resjs = document.getElementById("resjs");
+    resjs.onload = scriptOnload;
 #ifdef MOZ_CHROME_FILE_FORMAT_JAR
     resjs.src = "jar:resource://gre/chrome/toolkit.jar!/content/mozapps/xpinstall/xpinstallConfirm.js";
 #else
     resjs.src = "resource://gre/chrome/toolkit/content/mozapps/xpinstall/xpinstallConfirm.js";
 #endif
-    resjs.onload = scriptOnload;
     document.getElementById("content").appendChild(resjs);
 
     function scriptOnload() {
       is(typeof XPInstallConfirm, "object",
          "xpinstallConfirm.js has not moved unexpectedly");
   
       // trigger the callback
       if (aCallback)
--- a/chrome/test/unit/data/test_bug519468.manifest
+++ b/chrome/test/unit/data/test_bug519468.manifest
@@ -1,3 +1,4 @@
 locale testmatchos en-US jar:en-US.jar!/locale/en-US/global/
 locale testmatchos fr-FR jar:en-US.jar!/locale/en-US/global/
 locale testmatchos de-DE jar:en-US.jar!/locale/en-US/global/
+locale testmatchos xx-AA jar:en-US.jar!/locale/en-US/global/
--- a/chrome/test/unit/test_bug519468.js
+++ b/chrome/test/unit/test_bug519468.js
@@ -2,61 +2,114 @@
  * 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/.
  */
 
 var MANIFESTS = [
   do_get_file("data/test_bug519468.manifest")
 ];
 
+// Stub in the locale service so we can control what gets returned as the OS locale setting
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+let stubOSLocale = null;
+
+stubID = Components.ID("9d09d686-d913-414c-a1e6-4be8652d7d93");
+localeContractID = "@mozilla.org/intl/nslocaleservice;1";
+
+StubLocaleService = {
+  classDescription: "Stub version of Locale service for testing",
+  classID:          stubID,
+  contractID:       localeContractID,
+  QueryInterface:   XPCOMUtils.generateQI([Ci.nsILocaleService, Ci.nsISupports, Ci.nsIFactory]),
+
+  createInstance: function (outer, iid) {
+    if (outer)
+      throw Components.results.NS_ERROR_NO_AGGREGATION;
+    return this.QueryInterface(iid);
+  },
+  lockFactory: function (lock) {
+    throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
+  },
+
+  getLocaleComponentForUserAgent: function SLS_getLocaleComponentForUserAgent()
+  {
+    return stubOSLocale;
+  }
+}
+
+let registrar = Components.manager.nsIComponentRegistrar;
+// Save original factory.
+let localeCID = registrar.contractIDToCID(localeContractID)
+let originalFactory =
+      Components.manager.getClassObject(Components.classes[localeContractID],
+                                        Components.interfaces.nsIFactory);
+
+registrar.registerFactory(stubID, "Unit test Locale Service", localeContractID, StubLocaleService);
+
+// Now fire up the test
 do_test_pending()
 registerManifests(MANIFESTS);
 
 var chromeReg = Cc["@mozilla.org/chrome/chrome-registry;1"]
                 .getService(Ci.nsIXULChromeRegistry)
                 .QueryInterface(Ci.nsIToolkitChromeRegistry);
 chromeReg.checkForNewChrome();
 
-var localeService = Cc["@mozilla.org/intl/nslocaleservice;1"]
-                    .getService(Ci.nsILocaleService);
-
 var prefService = Cc["@mozilla.org/preferences-service;1"]
                   .getService(Ci.nsIPrefService)
                   .QueryInterface(Ci.nsIPrefBranch);
 var os = Cc["@mozilla.org/observer-service;1"]
          .getService(Ci.nsIObserverService);
 
-var systemLocale = localeService.getLocaleComponentForUserAgent();
-var count = 0;
 var testsLocale = [
-  {matchOS: false, selected: null, locale: "en-US"},
-  {matchOS: true, selected: null, locale: systemLocale},
-  {matchOS: true, selected: "fr-FR", locale: systemLocale},
-  {matchOS: false, selected: "fr-FR", locale: "fr-FR"},
-  {matchOS: false, selected: "de-DE", locale: "de-DE"},
-  {matchOS: true, selected: null, locale: systemLocale}
+  // These tests cover when the OS local is included in our manifest
+  {matchOS: false, selected: "en-US", osLocale: "xx-AA", locale: "en-US"},
+  {matchOS: true, selected: "en-US", osLocale: "xx-AA", locale: "xx-AA"},
+  {matchOS: false, selected: "fr-FR", osLocale: "xx-AA", locale: "fr-FR"},
+  {matchOS: true, selected: "fr-FR", osLocale: "xx-AA", locale: "xx-AA"},
+  {matchOS: false, selected: "de-DE", osLocale: "xx-AA", locale: "de-DE"},
+  {matchOS: true, selected: "de-DE", osLocale: "xx-AA", locale: "xx-AA"},
+  // these tests cover the case where the OS locale is not available in our manifest, but the
+  // base language is (ie, substitute xx-AA which we have for xx-BB which we don't)
+  {matchOS: false, selected: "en-US", osLocale: "xx-BB", locale: "en-US"},
+  {matchOS: true, selected: "en-US", osLocale: "xx-BB", locale: "xx-AA"},
+  {matchOS: false, selected: "fr-FR", osLocale: "xx-BB", locale: "fr-FR"},
+  {matchOS: true, selected: "fr-FR", osLocale: "xx-BB", locale: "xx-AA"},
+  // These tests cover where the language is not available
+  {matchOS: false, selected: "en-US", osLocale: "xy-BB", locale: "en-US"},
+  {matchOS: true, selected: "en-US", osLocale: "xy-BB", locale: "en-US"},
+  {matchOS: false, selected: "fr-FR", osLocale: "xy-BB", locale: "fr-FR"},
+  {matchOS: true, selected: "fr-FR", osLocale: "xy-BB", locale: "en-US"},
 ];
 
+var observedLocale = null;
+
 function test_locale(aTest) {
+  observedLocale = null;
+
+  stubOSLocale = aTest.osLocale;
   prefService.setBoolPref("intl.locale.matchOS", aTest.matchOS);
-  prefService.setCharPref("general.useragent.locale", aTest.selected || "en-US");
+  prefService.setCharPref("general.useragent.locale", aTest.selected);
 
   chromeReg.reloadChrome();
+
+  do_check_eq(observedLocale, aTest.locale);
 }
 
+// Callback function for observing locale change. May be called more than once
+// per test iteration.
 function checkValidity() {
-  var selectedLocale = chromeReg.getSelectedLocale("testmatchos");
-  do_check_eq(selectedLocale, testsLocale[count].locale);
-
-  count++;
-  if (count >= testsLocale.length) {
-    os.removeObserver(checkValidity, "selected-locale-has-changed");
-    do_test_finished();
-  }
-  else {
-    test_locale(testsLocale[count]);
-  }
+  observedLocale = chromeReg.getSelectedLocale("testmatchos");
+  dump("checkValidity called back with locale = " + observedLocale + "\n");
 }
 
 function run_test() {
   os.addObserver(checkValidity, "selected-locale-has-changed", false);
-  test_locale(testsLocale[count]);
+
+  for (let count = 0 ; count < testsLocale.length ; count++) {
+    dump("count = " + count + " " + testsLocale[count].toSource() + "\n");
+    test_locale(testsLocale[count]);
+  }
+
+  os.removeObserver(checkValidity, "selected-locale-has-changed");
+  do_test_finished();
 }
--- a/configure.in
+++ b/configure.in
@@ -4330,17 +4330,17 @@ dnl ====================================
 
 if test -z "$gonkdir" ; then
     # Minimum Android SDK API Level we require.
     case "$MOZ_BUILD_APP" in
     mobile/xul)
         android_min_api_level=13
         ;;
     mobile/android)
-        android_min_api_level=14
+        android_min_api_level=16
         ;;
     esac
 
     MOZ_ANDROID_SDK($android_min_api_level)
 fi
 
 dnl ========================================================
 dnl =
@@ -5268,18 +5268,23 @@ MOZ_ARG_DISABLE_BOOL(webm,
     MOZ_WEBM=1)
 
 if test -n "$MOZ_WEBM"; then
     AC_DEFINE(MOZ_WEBM)
     MOZ_VP8=1
 fi;
 
 dnl ========================================================
-dnl = Disable media plugin support
-dnl ========================================================
+dnl = Enable media plugin support
+dnl ========================================================
+if test "$OS_TARGET" = Android -a x"$MOZ_WIDGET_TOOLKIT" != x"gonk"; then
+  dnl Enable support on android by default
+  MOZ_MEDIA_PLUGINS=1
+fi
+
 MOZ_ARG_ENABLE_BOOL(media-plugins,
 [  --enable-media-plugins  Enable support for media plugins],
     MOZ_MEDIA_PLUGINS=1,
     MOZ_MEDIA_PLUGINS=)
 
 if test -n "$MOZ_MEDIA_PLUGINS"; then
   AC_DEFINE(MOZ_MEDIA_PLUGINS)
 fi
@@ -5294,16 +5299,21 @@ MOZ_ARG_ENABLE_BOOL(media-navigator,
 
 if test -n "$MOZ_MEDIA_NAVIGATOR"; then
   AC_DEFINE(MOZ_MEDIA_NAVIGATOR)
 fi
 
 dnl ========================================================
 dnl = Enable building OMX media plugin (B2G or Android)
 dnl ========================================================
+if test "$OS_TARGET" = Android -a x"$MOZ_WIDGET_TOOLKIT" != x"gonk"; then
+  dnl Enable support on android by default
+  MOZ_OMX_PLUGIN=1
+fi
+
 MOZ_ARG_ENABLE_BOOL(omx-plugin,
 [  --enable-omx-plugin      Enable building OMX plugin (B2G)],
     MOZ_OMX_PLUGIN=1,
     MOZ_OMX_PLUGIN=)
 
 if test -n "$MOZ_OMX_PLUGIN"; then
     if test "$OS_TARGET" = "Android"; then
         dnl Only allow building OMX plugin on Gonk (B2G) or Android
@@ -5791,26 +5801,26 @@ esac
 MOZ_ARG_DISABLE_BOOL(crashreporter,
 [  --disable-crashreporter Disable breakpad crash reporting],
     MOZ_CRASHREPORTER=,
     MOZ_CRASHREPORTER=1)
 
 if test -n "$MOZ_CRASHREPORTER"; then
    AC_DEFINE(MOZ_CRASHREPORTER)
 
-  if (test "$OS_TARGET" = "Linux" -o "$OS_ARCH" = "SunOS") && \
+  if test "$OS_TARGET" = "Linux" -o "$OS_ARCH" = "SunOS" && \
     test -z "$SKIP_LIBRARY_CHECKS"; then
     PKG_CHECK_MODULES(MOZ_GTHREAD, gthread-2.0)
     AC_SUBST(MOZ_GTHREAD_CFLAGS)
     AC_SUBST(MOZ_GTHREAD_LIBS)
 
     MOZ_CHECK_HEADERS([curl/curl.h], [], [AC_MSG_ERROR([Couldn't find curl/curl.h which is required for the crash reporter.  Use --disable-crashreporter to disable the crash reporter.])])
   fi
 
-  if (test "$OS_ARCH" != "$HOST_OS_ARCH"); then
+  if test "$OS_ARCH" != "$HOST_OS_ARCH"; then
     AC_MSG_ERROR([Breakpad tools do not support compiling on $HOST_OS_ARCH while targeting $OS_ARCH.  Use --disable-crashreporter.])
   fi
 
   if test "$OS_ARCH" = "WINNT" -a -z "$HAVE_64BIT_OS"; then
     MOZ_CRASHREPORTER_INJECTOR=1
     AC_DEFINE(MOZ_CRASHREPORTER_INJECTOR)
   fi
 fi
@@ -7676,17 +7686,17 @@ MOZ_ARG_DISABLE_BOOL(md,
      _cpp_md_flag=1
    fi
   dnl Default is to use -xM if using Sun Studio on Solaris
    if test "$SOLARIS_SUNPRO_CC"; then
      _cpp_md_flag=1
    fi])
 if test "$_cpp_md_flag"; then
   COMPILER_DEPEND=1
-  _DEPEND_CFLAGS='$(filter-out %/.pp,-MD -MF $(MDDEPDIR)/$(@F).pp)'
+  _DEPEND_CFLAGS='$(filter-out %/.pp,-MMD -MF $(MDDEPDIR)/$(@F).pp)'
   dnl Sun Studio on Solaris use -xM instead of -MD, see config/rules.mk
   if test "$SOLARIS_SUNPRO_CC"; then
     _DEPEND_CFLAGS=
   fi
 else
   COMPILER_DEPEND=
   dnl Don't override this for MSVC
   if test -z "$_WIN32_MSVC"; then
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -812,16 +812,26 @@ public:
   /**
    * Get the localized string named |aKey| in properties file |aFile|.
    */
   static nsresult GetLocalizedString(PropertiesFile aFile,
                                      const char* aKey,
                                      nsXPIDLString& aResult);
 
   /**
+   * A helper function that parses a sandbox attribute (of an <iframe> or
+   * a CSP directive) and converts it to the set of flags used internally.
+   *
+   * @param aAttribute 	the value of the sandbox attribute
+   * @return 			the set of flags
+   */
+  static PRUint32 ParseSandboxAttributeToFlags(const nsAString& aSandboxAttr);
+
+
+  /**
    * Fill (with the parameters given) the localized string named |aKey| in
    * properties file |aFile|.
    */
 private:
   static nsresult FormatLocalizedString(PropertiesFile aFile,
                                         const char* aKey,
                                         const PRUnichar** aParams,
                                         PRUint32 aParamsLength,
@@ -1689,17 +1699,17 @@ public:
    *
    * @param aScriptContext the script context to get the document for; can be null
    *
    * @return the document associated with the script context
    */
   static already_AddRefed<nsIDocument>
   GetDocumentFromScriptContext(nsIScriptContext *aScriptContext);
 
-  static bool CheckMayLoad(nsIPrincipal* aPrincipal, nsIChannel* aChannel);
+  static bool CheckMayLoad(nsIPrincipal* aPrincipal, nsIChannel* aChannel, bool aAllowIfInheritsPrincipal);
 
   /**
    * The method checks whether the caller can access native anonymous content.
    * If there is no JS in the stack or privileged JS is running, this
    * method returns true, otherwise false.
    */
   static bool CanAccessNativeAnon();
 
@@ -1945,42 +1955,44 @@ public:
    * from the document it comes from.
    */
   static nsresult URIInheritsSecurityContext(nsIURI *aURI, bool *aResult);
 
   /**
    * Set the given principal as the owner of the given channel, if
    * needed.  aURI must be the URI of aChannel.  aPrincipal may be
    * null.  If aSetUpForAboutBlank is true, then about:blank will get
-   * the principal set up on it.
-   *
+   * the principal set up on it. If aForceOwner is true, the owner
+   * will be set on the channel, even if the principal can be determined
+   * from the channel.
    * The return value is whether the principal was set up as the owner
    * of the channel.
    */
   static bool SetUpChannelOwner(nsIPrincipal* aLoadingPrincipal,
                                 nsIChannel* aChannel,
                                 nsIURI* aURI,
-                                bool aSetUpForAboutBlank);
+                                bool aSetUpForAboutBlank,
+                                bool aForceOwner = false);
 
   static nsresult Btoa(const nsAString& aBinaryData,
                        nsAString& aAsciiBase64String);
 
   static nsresult Atob(const nsAString& aAsciiString,
                        nsAString& aBinaryData);
 
   /** If aJSArray is a Javascript array, this method iterates over its
    *  elements and appends values to aRetVal as nsIAtoms.
    *  @throw NS_ERROR_ILLEGAL_VALUE if aJSArray isn't a JS array.
    */ 
   static nsresult JSArrayToAtomArray(JSContext* aCx, const JS::Value& aJSArray,
                                      nsCOMArray<nsIAtom>& aRetVal);
 
   /**
    * Returns whether the input element passed in parameter has the autocomplete
-   * functionnality enabled. It is taking into account the form owner.
+   * functionality enabled. It is taking into account the form owner.
    * NOTE: the caller has to make sure autocomplete makes sense for the
    * element's type.
    *
    * @param aInput the input element to check. NOTE: aInput can't be null.
    * @return whether the input element has autocomplete enabled.
    */
   static bool IsAutocompleteEnabled(nsIDOMHTMLInputElement* aInput);
 
--- a/content/base/public/nsDeprecatedOperationList.h
+++ b/content/base/public/nsDeprecatedOperationList.h
@@ -40,11 +40,10 @@ DEPRECATED_OPERATION(IsEqualNode)
 DEPRECATED_OPERATION(TextContent)
 DEPRECATED_OPERATION(EnablePrivilege)
 DEPRECATED_OPERATION(Position)
 DEPRECATED_OPERATION(TotalSize)
 DEPRECATED_OPERATION(InputEncoding)
 DEPRECATED_OPERATION(MozBeforePaint)
 DEPRECATED_OPERATION(MozBlobBuilder)
 DEPRECATED_OPERATION(DOMExceptionCode)
-DEPRECATED_OPERATION(NoExposedProps)
 DEPRECATED_OPERATION(MutationEvent)
 DEPRECATED_OPERATION(MozSlice)
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -74,18 +74,18 @@ class ImageLoader;
 
 namespace dom {
 class Link;
 class Element;
 } // namespace dom
 } // namespace mozilla
 
 #define NS_IDOCUMENT_IID \
-{ 0xdb888523, 0x541f, 0x49e3, \
-  { 0xa9, 0x71, 0xb5, 0xea, 0xd1, 0xf0, 0xc3, 0xcf } }
+{ 0x57fe44ae, 0x6656, 0x44b8, \
+  { 0x8d, 0xc0, 0xfc, 0xa7, 0x43, 0x28, 0xbe, 0x86 } }
 
 // Flag for AddStyleSheet().
 #define NS_STYLESHEET_FROM_CATALOG                (1 << 0)
 
 // Enum for requesting a particular type of document when creating a doc
 enum DocumentFlavor {
   DocumentFlavorLegacyGuess, // compat with old code until made HTML5-compliant
   DocumentFlavorHTML, // HTMLDocument with HTMLness bit set to true
@@ -395,16 +395,35 @@ public:
    * change to actually change anything immediately.
    * @see nsBidiUtils.h
    */
   void SetBidiOptions(PRUint32 aBidiOptions)
   {
     mBidiOptions = aBidiOptions;
   }
 
+
+  /**
+   * Get the sandbox flags for this document.
+   * @see nsSandboxFlags.h for the possible flags
+   */
+  PRUint32 GetSandboxFlags() const
+  {
+    return mSandboxFlags;
+  }
+
+  /**
+   * Set the sandbox flags for this document.
+   * @see nsSandboxFlags.h for the possible flags
+   */
+  void SetSandboxFlags(PRUint32 sandboxFlags)
+  {
+    mSandboxFlags = sandboxFlags;
+  }
+
   inline mozilla::directionality::Directionality GetDocumentDirectionality() {
     return mDirectionality;
   }
   
   /**
    * Access HTTP header data (this may also get set from other
    * sources, like HTML META tags).
    */
@@ -451,16 +470,21 @@ public:
 
   /**
    * Set the parent document of this document.
    */
   void SetParentDocument(nsIDocument* aParent)
   {
     mParentDocument = aParent;
   }
+  
+  /**
+   * Are plugins allowed in this document ?
+   */
+  virtual nsresult GetAllowPlugins (bool* aAllowPlugins) = 0;
 
   /**
    * Set the sub document for aContent to aSubDoc.
    */
   virtual nsresult SetSubDocumentFor(Element* aContent,
                                      nsIDocument* aSubDoc) = 0;
 
   /**
@@ -1862,16 +1886,21 @@ protected:
   // If mIsStaticDocument is true, mOriginalDocument points to the original
   // document.
   nsCOMPtr<nsIDocument> mOriginalDocument;
 
   // The bidi options for this document.  What this bitfield means is
   // defined in nsBidiUtils.h
   PRUint32 mBidiOptions;
 
+  // The sandbox flags on the document. These reflect the value of the sandbox attribute of the
+  // associated IFRAME or CSP-protectable content, if existent. These are set at load time and
+  // are immutable - see nsSandboxFlags.h for the possible flags.
+  PRUint32 mSandboxFlags;
+
   // The root directionality of this document.
   mozilla::directionality::Directionality mDirectionality;
 
   nsCString mContentLanguage;
 private:
   nsCString mContentType;
 protected:
 
--- a/content/base/public/nsLineBreaker.h
+++ b/content/base/public/nsLineBreaker.h
@@ -142,24 +142,24 @@ public:
   nsresult AppendInvisibleWhitespace(PRUint32 aFlags);
 
   /**
    * Feed Unicode text into the linebreaker for analysis. aLength must be
    * nonzero.
    * @param aSink can be null if the breaks are not actually needed (we may
    * still be setting up state for later breaks)
    */
-  nsresult AppendText(nsIAtom* aLangGroup, const PRUnichar* aText, PRUint32 aLength,
+  nsresult AppendText(nsIAtom* aHyphenationLanguage, const PRUnichar* aText, PRUint32 aLength,
                       PRUint32 aFlags, nsILineBreakSink* aSink);
   /**
    * Feed 8-bit text into the linebreaker for analysis. aLength must be nonzero.
    * @param aSink can be null if the breaks are not actually needed (we may
    * still be setting up state for later breaks)
    */
-  nsresult AppendText(nsIAtom* aLangGroup, const PRUint8* aText, PRUint32 aLength,
+  nsresult AppendText(nsIAtom* aHyphenationLanguage, const PRUint8* aText, PRUint32 aLength,
                       PRUint32 aFlags, nsILineBreakSink* aSink);
   /**
    * Reset all state. This means the current run has ended; any outstanding
    * calls through nsILineBreakSink are made, and all outstanding references to
    * nsILineBreakSink objects are dropped.
    * After this call, this linebreaker can be reused.
    * This must be called at least once between any call to AppendText() and
    * destroying the object.
@@ -193,27 +193,27 @@ private:
   // State for the nonwhitespace "word" that started in previous text and hasn't
   // finished yet.
 
   // When the current word ends, this computes the linebreak opportunities
   // *inside* the word (excluding either end) and sets them through the
   // appropriate sink(s). Then we clear the current word state.
   nsresult FlushCurrentWord();
 
-  void UpdateCurrentWordLangGroup(nsIAtom *aLangGroup);
+  void UpdateCurrentWordLanguage(nsIAtom *aHyphenationLanguage);
 
   void FindHyphenationPoints(nsHyphenator *aHyphenator,
                              const PRUnichar *aTextStart,
                              const PRUnichar *aTextLimit,
                              PRUint8 *aBreakState);
 
   nsAutoTArray<PRUnichar,100> mCurrentWord;
   // All the items that contribute to mCurrentWord
   nsAutoTArray<TextItem,2>    mTextItems;
-  nsIAtom*                    mCurrentWordLangGroup;
+  nsIAtom*                    mCurrentWordLanguage;
   bool                        mCurrentWordContainsMixedLang;
   bool                        mCurrentWordContainsComplexChar;
 
   // True if the previous character was breakable whitespace
   bool                        mAfterBreakableSpace;
   // True if a break must be allowed at the current position because
   // a run of breakable whitespace ends here
   bool                        mBreakHere;
--- a/content/base/src/CSPUtils.jsm
+++ b/content/base/src/CSPUtils.jsm
@@ -8,16 +8,17 @@
  * Overview
  * This contains a set of classes and utilities for CSP.  It is in this
  * separate file for testing purposes.
  */
 
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "Services",
                                   "resource://gre/modules/Services.jsm");
 
 // Module stuff
 var EXPORTED_SYMBOLS = ["CSPRep", "CSPSourceList", "CSPSource", "CSPHost",
                         "CSPWarning", "CSPError", "CSPdebug",
                         "CSPViolationReportListener", "CSPLocalizer"];
@@ -26,16 +27,51 @@ var STRINGS_URI = "chrome://global/local
 
 // these are not exported
 var gIoService = Components.classes["@mozilla.org/network/io-service;1"]
                  .getService(Components.interfaces.nsIIOService);
 
 var gETLDService = Components.classes["@mozilla.org/network/effective-tld-service;1"]
                    .getService(Components.interfaces.nsIEffectiveTLDService);
 
+// These regexps represent the concrete syntax on the w3 spec as of 7-5-2012
+// scheme          = <scheme production from RFC 3986>
+const R_SCHEME     = new RegExp ("([a-zA-Z0-9\\-]+)", 'i');
+const R_GETSCHEME  = new RegExp ("^" + R_SCHEME.source + "(?=\\:)", 'i');
+
+// scheme-source   = scheme ":"
+const R_SCHEMESRC  = new RegExp ("^" + R_SCHEME.source + "\\:$", 'i');
+
+// host-char       = ALPHA / DIGIT / "-"
+const R_HOSTCHAR   = new RegExp ("[a-zA-Z0-9\\-]", 'i');
+
+// host            = "*" / [ "*." ] 1*host-char *( "." 1*host-char )
+const R_HOST       = new RegExp ("\\*|(((\\*\\.)?" + R_HOSTCHAR.source +
+                                      "+)(\\." + R_HOSTCHAR.source +"+)+)",'i');
+// port            = ":" ( 1*DIGIT / "*" )
+const R_PORT       = new RegExp ("(\\:([0-9]+|\\*))", 'i');
+
+// host-source     = [ scheme "://" ] host [ port ]
+const R_HOSTSRC    = new RegExp ("^((" + R_SCHEME.source + "\\:\\/\\/)?("
+                                       +   R_HOST.source + ")"
+                                       +   R_PORT.source + "?)$", 'i');
+
+// ext-host-source = host-source "/" *( <VCHAR except ";" and ","> )
+//                 ; ext-host-source is reserved for future use.
+const R_EXTHOSTSRC = new RegExp ("^" + R_HOSTSRC.source + "\\/[:print:]+$", 'i');
+
+// keyword-source  = "'self'" / "'unsafe-inline'" / "'unsafe-eval'"
+const R_KEYWORDSRC = new RegExp ("^('self'|'unsafe-inline'|'unsafe-eval')$", 'i');
+
+// source-exp      = scheme-source / host-source / keyword-source
+const R_SOURCEEXP  = new RegExp (R_SCHEMESRC.source + "|" +
+                                   R_HOSTSRC.source + "|" +
+                                R_KEYWORDSRC.source,  'i');
+
+
 var gPrefObserver = {
   get debugEnabled () {
     if (!this._branch)
       this._initialize();
     return this._debugEnabled;
   },
 
   _initialize: function() {
@@ -474,18 +510,20 @@ CSPRep.prototype = {
    *        a new CSPRep instance of the intersection
    */
   intersectWith:
   function cspsd_intersectWith(aCSPRep) {
     var newRep = new CSPRep();
 
     for (var dir in CSPRep.SRC_DIRECTIVES) {
       var dirv = CSPRep.SRC_DIRECTIVES[dir];
-      newRep._directives[dirv] = this._directives[dirv]
-               .intersectWith(aCSPRep._directives[dirv]);
+      if (this._directives.hasOwnProperty(dirv))
+        newRep._directives[dirv] = this._directives[dirv].intersectWith(aCSPRep._directives[dirv]);
+      else
+        newRep._directives[dirv] = aCSPRep._directives[dirv];
     }
 
     // REPORT_URI
     var reportURIDir = CSPRep.URI_DIRECTIVES.REPORT_URI;
     if (this._directives[reportURIDir] && aCSPRep._directives[reportURIDir]) {
       newRep._directives[reportURIDir] =
         this._directives[reportURIDir].concat(aCSPRep._directives[reportURIDir]);
     }
@@ -493,22 +531,16 @@ CSPRep.prototype = {
       // blank concat makes a copy of the string.
       newRep._directives[reportURIDir] = this._directives[reportURIDir].concat();
     }
     else if (aCSPRep._directives[reportURIDir]) {
       // blank concat makes a copy of the string.
       newRep._directives[reportURIDir] = aCSPRep._directives[reportURIDir].concat();
     }
 
-    for (var dir in CSPRep.SRC_DIRECTIVES) {
-      var dirv = CSPRep.SRC_DIRECTIVES[dir];
-      newRep._directives[dirv] = this._directives[dirv]
-               .intersectWith(aCSPRep._directives[dirv]);
-    }
-
     newRep._allowEval =          this.allowsEvalInScripts
                            && aCSPRep.allowsEvalInScripts;
 
     newRep._allowInlineScripts = this.allowsInlineScripts 
                            && aCSPRep.allowsInlineScripts;
 
     return newRep;
   },
@@ -583,46 +615,53 @@ function CSPSourceList() {
  *        URI or CSPSource representing the "self" source
  * @param enforceSelfChecks (optional)
  *        if present, and "true", will check to be sure "self" has the
  *        appropriate values to inherit when they are omitted from the source.
  * @returns
  *        an instance of CSPSourceList 
  */
 CSPSourceList.fromString = function(aStr, self, enforceSelfChecks) {
-  // Source list is:
-  //    <host-dir-value> ::= <source-list>
-  //                       | "'none'"
-  //    <source-list>    ::= <source>
-  //                       | <source-list>" "<source>
+  // source-list = *WSP [ source-expression *( 1*WSP source-expression ) *WSP ]
+  //             / *WSP "'none'" *WSP
 
   /* If self parameter is passed, convert to CSPSource,
      unless it is already a CSPSource. */
   if(self && !(self instanceof CSPSource)) {
      self = CSPSource.create(self);
   }
 
   var slObj = new CSPSourceList();
-  if (aStr === "'none'")
-    return slObj;
-
-  if (aStr === "*") {
-    slObj._permitAllSources = true;
+  aStr = aStr.trim();
+  // w3 specifies case insensitive equality
+  if (aStr.toUpperCase() === "'NONE'"){
+    slObj._permitAllSources = false;
     return slObj;
   }
 
   var tokens = aStr.split(/\s+/);
   for (var i in tokens) {
-    if (tokens[i] === "") continue;
+    if (!R_SOURCEEXP.test(tokens[i])){
+      CSPWarning(CSPLocalizer.getFormatStr("failedToParseUnrecognizedSource",
+                                           [tokens[i]]));
+      continue;
+    }
     var src = CSPSource.create(tokens[i], self, enforceSelfChecks);
     if (!src) {
-      CSPWarning(CSPLocalizer.getFormatStr("failedToParseUnrecognizedSource", [tokens[i]]));
+      CSPWarning(CSPLocalizer.getFormatStr("failedToParseUnrecognizedSource",
+                                           [tokens[i]]));
       continue;
     }
-    slObj._sources.push(src);
+    // if a source is a *, then we can permit all sources
+    if (src.permitAll){
+      slObj._permitAllSources = true;
+      return slObj;
+    } else {
+      slObj._sources.push(src);
+    }
   }
 
   return slObj;
 };
 
 CSPSourceList.prototype = {
   /**
    * Compares one CSPSourceList to another.
@@ -731,16 +770,18 @@ CSPSourceList.prototype = {
    * @returns
    *        a new instance of a CSPSourceList representing the intersection
    */
   intersectWith:
   function cspsd_intersectWith(that) {
 
     var newCSPSrcList = null;
 
+    if (!that) return this.clone();
+
     if (this.isNone() || that.isNone())
       newCSPSrcList = CSPSourceList.fromString("'none'");
 
     if (this.isAll()) newCSPSrcList = that.clone();
     if (that.isAll()) newCSPSrcList = this.clone();
 
     if (!newCSPSrcList) {
       // the shortcuts didn't apply, must do intersection the hard way.
@@ -782,16 +823,19 @@ CSPSourceList.prototype = {
 /**
  * Class to model a source (scheme, host, port)
  */
 function CSPSource() {
   this._scheme = undefined;
   this._port = undefined;
   this._host = undefined;
 
+  //when set to true, this allows all source
+  this._permitAll = false;
+
   // when set to true, this source represents 'self'
   this._isSelf = false;
 }
 
 /**
  * General factory method to create a new source from one of the following
  * types:
  *  - nsURI
@@ -919,157 +963,93 @@ CSPSource.fromString = function(aStr, se
   if (!aStr)
     return null;
 
   if (!(typeof aStr === 'string')) {
     CSPError(CSPLocalizer.getStr("argumentIsNotString"));
     return null;
   }
 
+  var sObj = new CSPSource();
+  sObj._self = self;
+
+  // if equal, return does match
+  if (aStr === "*"){
+    sObj._permitAll = true;
+    return sObj;
+  }
+
   if (!self && enforceSelfChecks) {
     CSPError(CSPLocalizer.getStr("selfDataNotProvided"));
     return null;
   }
 
   if (self && !(self instanceof CSPSource)) {
     self = CSPSource.create(self, undefined, false);
   }
 
-  var sObj = new CSPSource();
-  sObj._self = self;
+  // check for scheme-source match
+  if (R_SCHEMESRC.test(aStr)){
+    var schemeSrcMatch = R_GETSCHEME.exec(aStr);
+    sObj._scheme = schemeSrcMatch[0];
+    if (!sObj._host) sObj._host = CSPHost.fromString("*");
+    if (!sObj._port) sObj._port = "*";
+    return sObj;
+  }
+
+  // check for host-source or ext-host-source match
+  if (R_HOSTSRC.test(aStr) || R_EXTHOSTSRC.test(aStr)){
+    var schemeMatch = R_GETSCHEME.exec(aStr);
+    if (!schemeMatch)
+      sObj._scheme = self.scheme;
+    else {
+      sObj._scheme = schemeMatch[0];
+    }
 
-  // take care of 'self' keyword
-  if (aStr === "'self'") {
-    if (!self) {
+    var hostMatch = R_HOST.exec(aStr);
+    if (!hostMatch) {
+      CSPError(CSPLocalizer.getFormatStr("couldntParseInvalidSource", [aStr]));
+      return null;
+    }
+    sObj._host = CSPHost.fromString(hostMatch[0]);
+    var portMatch = R_PORT.exec(aStr);
+    if (!portMatch) {
+      // gets the default port for the given scheme
+      defPort = Services.io.getProtocolHandler(sObj._scheme).defaultPort;
+      if (!defPort) {
+        CSPError(CSPLocalizer.getFormatStr("couldntParseInvalidSource", [aStr]));
+        return null;
+      }
+      sObj._port = defPort;
+    }
+    else {
+      // strip the ':' from the port
+      sObj._port = portMatch[0].substr(1);
+    }
+    return sObj;
+  }
+
+  // check for 'self' (case insensitive)
+  if (aStr.toUpperCase() === "'SELF'"){
+    if (!self){
       CSPError(CSPLocalizer.getStr("selfKeywordNoSelfData"));
       return null;
     }
     sObj._self = self.clone();
     sObj._isSelf = true;
     return sObj;
   }
-
-  // We could just create a URI and then send this off to fromURI, but
-  // there's no way to leave out the scheme or wildcard the port in an nsURI.
-  // That has to be supported here.
-
-  // split it up
-  var chunks = aStr.split(":");
-
-  // If there is only one chunk, it's gotta be a host.
-  if (chunks.length == 1) {
-    sObj._host = CSPHost.fromString(chunks[0]);
-    if (!sObj._host) {
-      CSPError(CSPLocalizer.getFormatStr("couldntParseInvalidSource",[aStr]));
-      return null;
-    }
-
-    // enforce 'self' inheritance
-    if (enforceSelfChecks) {
-      // note: the non _scheme accessor checks sObj._self
-      if (!sObj.scheme || !sObj.port) {
-        CSPError(CSPLocalizer.getFormatStr("hostSourceWithoutData",[aStr]));
-        return null;
-      }
-    }
-    return sObj;
-  }
-
-  // If there are two chunks, it's either scheme://host or host:port
-  //   ... but scheme://host can have an empty host.
-  //   ... and host:port can have an empty host
-  if (chunks.length == 2) {
-
-    // is the last bit a port?
-    if (chunks[1] === "*" || chunks[1].match(/^\d+$/)) {
-      sObj._port = chunks[1];
-      // then the previous chunk *must* be a host or empty.
-      if (chunks[0] !== "") {
-        sObj._host = CSPHost.fromString(chunks[0]);
-        if (!sObj._host) {
-          CSPError(CSPLocalizer.getFormatStr("couldntParseInvalidSource",[aStr]));
-          return null;
-        }
-      }
-      // enforce 'self' inheritance 
-      // (scheme:host requires port, host:port does too.  Wildcard support is
-      // only available if the scheme and host are wildcarded)
-      if (enforceSelfChecks) {
-        // note: the non _scheme accessor checks sObj._self
-        if (!sObj.scheme || !sObj.host || !sObj.port) {
-          CSPError(CSPLocalizer.getFormatStr("sourceWithoutData",[aStr]));
-          return null;
-        }
-      }
-    }
-    // is the first bit a scheme?
-    else if (CSPSource.validSchemeName(chunks[0])) {
-      sObj._scheme = chunks[0];
-      // then the second bit *must* be a host or empty
-      if (chunks[1] === "") {
-        // Allow scheme-only sources!  These default to wildcard host/port,
-        // especially since host and port don't always matter.
-        // Example: "javascript:" and "data:" 
-        if (!sObj._host) sObj._host = CSPHost.fromString("*");
-        if (!sObj._port) sObj._port = "*";
-      } else {
-        // some host was defined.
-        // ... remove <= 3 leading slashes (from the scheme) and parse
-        var cleanHost = chunks[1].replace(/^\/{0,3}/,"");
-        // ... and parse
-        sObj._host = CSPHost.fromString(cleanHost);
-        if (!sObj._host) {
-          CSPError(CSPLocalizer.getFormatStr("couldntParseInvalidHost",[cleanHost]));
-          return null;
-        }
-      }
-
-      // enforce 'self' inheritance (scheme-only should be scheme:*:* now, and
-      // if there was a host provided it should be scheme:host:selfport
-      if (enforceSelfChecks) {
-        // note: the non _scheme accessor checks sObj._self
-        if (!sObj.scheme || !sObj.host || !sObj.port) {
-          CSPError(CSPLocalizer.getFormatStr("sourceWithoutData",[aStr]));
-          return null;
-        }
-      }
-    }
-    else  {
-      // AAAH!  Don't know what to do!  No valid scheme or port!
-      CSPError(CSPLocalizer.getFormatStr("couldntParseInvalidSource",[aStr]));
-      return null;
-    }
-
-    return sObj;
-  }
-
-  // If there are three chunks, we got 'em all!
-  if (!CSPSource.validSchemeName(chunks[0])) {
-    CSPError(CSPLocalizer.getFormatStr("couldntParseScheme",[aStr]));
-    return null;
-  }
-  sObj._scheme = chunks[0];
-  if (!(chunks[2] === "*" || chunks[2].match(/^\d+$/))) {
-    CSPError(CSPLocalizer.getFormatStr("couldntParsePort",[aStr]));
-    return null;
-  }
-
-  sObj._port = chunks[2];
-
-  // ... remove <= 3 leading slashes (from the scheme) and parse
-  var cleanHost = chunks[1].replace(/^\/{0,3}/,"");
-  sObj._host = CSPHost.fromString(cleanHost);
-
-  return sObj._host ? sObj : null;
+  CSPError(CSPLocalizer.getFormatStr("couldntParseInvalidSource",[aStr]));
+  return null;
 };
 
 CSPSource.validSchemeName = function(aStr) {
   // <scheme-name>       ::= <alpha><scheme-suffix>
-  // <scheme-suffix>     ::= <scheme-chr> 
-  //                      | <scheme-suffix><scheme-chr> 
+  // <scheme-suffix>     ::= <scheme-chr>
+  //                      | <scheme-suffix><scheme-chr>
   // <scheme-chr>        ::= <letter> | <digit> | "+" | "." | "-"
   
   return aStr.match(/^[a-zA-Z][a-zA-Z0-9+.-]*$/);
 };
 
 CSPSource.prototype = {
 
   get scheme () {
@@ -1083,17 +1063,23 @@ CSPSource.prototype = {
   get host () {
     if (this._isSelf && this._self)
       return this._self.host;
     if (!this._host && this._self)
       return this._self.host;
     return this._host;
   },
 
-  /** 
+  get permitAll () {
+    if (this._isSelf && this._self)
+      return this._self.permitAll;
+    return this._permitAll;
+  },
+
+  /**
    * If this doesn't have a nonstandard port (hard-defined), use the default
    * port for this source's scheme. Should never inherit port from 'self'.
    */
   get port () {
     if (this._isSelf && this._self)
       return this._self.port;
     if (this._port) return this._port;
     // if no port, get the default port for the scheme
@@ -1194,64 +1180,64 @@ CSPSource.prototype = {
     // 'self' is not part of the intersection.  Intersect the raw values from
     // the source, self must be set by someone creating this source.
     // When intersecting, we take the more specific of the two: if one scheme,
     // host or port is undefined, the other is taken.  (This is contrary to
     // when "permits" is called -- there, the value of 'self' is looked at 
     // when a scheme, host or port is undefined.)
 
     // port
-    if (!this._port)
-      newSource._port = that._port;
-    else if (!that._port)
-      newSource._port = this._port;
-    else if (this._port === "*") 
-      newSource._port = that._port;
-    else if (that._port === "*")
-      newSource._port = this._port;
-    else if (that._port === this._port)
-      newSource._port = this._port;
+    if (!this.port)
+      newSource._port = that.port;
+    else if (!that.port)
+      newSource._port = this.port;
+    else if (this.port === "*")
+      newSource._port = that.port;
+    else if (that.port === "*")
+      newSource._port = this.port;
+    else if (that.port === this.port)
+      newSource._port = this.port;
     else {
       CSPError(CSPLocalizer.getFormatStr("notIntersectPort", [this.toString(), that.toString()]));
       return null;
     }
 
     // scheme
-    if (!this._scheme)
-      newSource._scheme = that._scheme;
-    else if (!that._scheme)
-      newSource._scheme = this._scheme;
-    if (this._scheme === "*")
-      newSource._scheme = that._scheme;
-    else if (that._scheme === "*")
-      newSource._scheme = this._scheme;
-    else if (that._scheme === this._scheme)
-      newSource._scheme = this._scheme;
+    if (!this.scheme)
+      newSource._scheme = that.scheme;
+    else if (!that.scheme)
+      newSource._scheme = this.scheme;
+    if (this.scheme === "*")
+      newSource._scheme = that.scheme;
+    else if (that.scheme === "*")
+      newSource._scheme = this.scheme;
+    else if (that.scheme === this.scheme)
+      newSource._scheme = this.scheme;
     else {
       CSPError(CSPLocalizer.getFormatStr("notIntersectScheme", [this.toString(), that.toString()]));
       return null;
     }
 
     // NOTE: Both sources must have a host, if they don't, something funny is
     // going on.  The fromString() factory method should have set the host to
     // * if there's no host specified in the input. Regardless, if a host is
     // not present either the scheme is hostless or any host should be allowed.
     // This means we can use the other source's host as the more restrictive
     // host expression, or if neither are present, we can use "*", but the
     // error should still be reported.
 
     // host
-    if (this._host && that._host) {
-      newSource._host = this._host.intersectWith(that._host);
-    } else if (this._host) {
+    if (this.host && that.host) {
+      newSource._host = this.host.intersectWith(that.host);
+    } else if (this.host) {
       CSPError(CSPLocalizer.getFormatStr("intersectingSourceWithUndefinedHost", [that.toString()]));
-      newSource._host = this._host.clone();
-    } else if (that._host) {
+      newSource._host = this.host.clone();
+    } else if (that.host) {
       CSPError(CSPLocalizer.getFormatStr("intersectingSourceWithUndefinedHost", [this.toString()]));
-      newSource._host = that._host.clone();
+      newSource._host = that.host.clone();
     } else {
       CSPError(CSPLocalizer.getFormatStr("intersectingSourcesWithUndefinedHosts", [this.toString(), that.toString()]));
       newSource._host = CSPHost.fromString("*");
     }
 
     return newSource;
   },
 
--- a/content/base/src/Makefile.in
+++ b/content/base/src/Makefile.in
@@ -35,16 +35,17 @@ EXPORTS		= \
 		nsFrameMessageManager.h \
 		nsAttrAndChildArray.h \
 		nsAttrValue.h \
 		nsCrossSiteListenerProxy.h \
 		nsDOMAttributeMap.h \
 		nsGenericElement.h \
 		nsMappedAttributeElement.h \
 		nsStyledElement.h \
+    nsSandboxFlags.h \
 		$(NULL)
 
 EXPORTS_NAMESPACES = mozilla/dom
 
 EXPORTS_mozilla/dom = \
   Link.h \
   $(NULL)
 
--- a/content/base/src/nsContentSink.cpp
+++ b/content/base/src/nsContentSink.cpp
@@ -1059,17 +1059,17 @@ nsContentSink::ProcessOfflineManifest(co
     nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(manifestURI),
                                               aManifestSpec, mDocument,
                                               mDocumentURI);
     if (!manifestURI) {
       return;
     }
 
     // Documents must list a manifest from the same origin
-    rv = mDocument->NodePrincipal()->CheckMayLoad(manifestURI, true);
+    rv = mDocument->NodePrincipal()->CheckMayLoad(manifestURI, true, false);
     if (NS_FAILED(rv)) {
       action = CACHE_SELECTION_RESELECT_WITHOUT_MANIFEST;
     }
     else {
       // Only continue if the document has permission to use offline APIs.
       if (!nsContentUtils::OfflineAppAllowed(mDocument->NodePrincipal())) {
         return;
       }
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -7,16 +7,17 @@
 /* A namespace class for static layout utilities. */
 
 #include "mozilla/Util.h"
 
 #include "jsapi.h"
 #include "jsdbgapi.h"
 #include "jsfriendapi.h"
 
+#include "Layers.h"
 #include "nsJSUtils.h"
 #include "nsCOMPtr.h"
 #include "nsAString.h"
 #include "nsPrintfCString.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIScriptContext.h"
 #include "nsDOMCID.h"
 #include "nsContentUtils.h"
@@ -154,16 +155,17 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_
 #include "nsICharsetDetector.h"
 #include "nsICharsetDetectionObserver.h"
 #include "nsIPlatformCharset.h"
 #include "nsIEditor.h"
 #include "nsIEditorDocShell.h"
 #include "mozilla/Attributes.h"
 #include "nsIParserService.h"
 #include "nsIDOMScriptObjectFactory.h"
+#include "nsSandboxFlags.h"
 
 #include "nsWrapperCacheInlines.h"
 
 extern "C" int MOZ_XMLTranslateEntity(const char* ptr, const char* end,
                                       const char** next, PRUnichar* result);
 extern "C" int MOZ_XMLCheckQName(const char* ptr, const char* end,
                                  int ns_aware, const char** colon);
 
@@ -917,16 +919,63 @@ nsContentUtils::GetParserService()
     if (NS_FAILED(rv)) {
       sParserService = nullptr;
     }
   }
 
   return sParserService;
 }
 
+/**
+ * A helper function that parses a sandbox attribute (of an <iframe> or
+ * a CSP directive) and converts it to the set of flags used internally.
+ *
+ * @param aAttribute    the value of the sandbox attribute
+ * @return              the set of flags
+ */
+PRUint32
+nsContentUtils::ParseSandboxAttributeToFlags(const nsAString& aSandboxAttrValue)
+{
+  // If there's a sandbox attribute at all (and there is if this is being
+  // called), start off by setting all the restriction flags.
+  PRUint32 out = SANDBOXED_NAVIGATION |
+                 SANDBOXED_TOPLEVEL_NAVIGATION |
+                 SANDBOXED_PLUGINS |
+                 SANDBOXED_ORIGIN |
+                 SANDBOXED_FORMS |
+                 SANDBOXED_SCRIPTS |
+                 SANDBOXED_AUTOMATIC_FEATURES;
+
+  if (!aSandboxAttrValue.IsEmpty()) {
+    // The separator optional flag is used because the HTML5 spec says any
+    // whitespace is ok as a separator, which is what this does.
+    HTMLSplitOnSpacesTokenizer tokenizer(aSandboxAttrValue, ' ',
+      nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace>::SEPARATOR_OPTIONAL);
+
+    while (tokenizer.hasMoreTokens()) {
+      nsDependentSubstring token = tokenizer.nextToken();
+
+      if (token.LowerCaseEqualsLiteral("allow-same-origin")) {
+        out &= ~SANDBOXED_ORIGIN;
+      } else if (token.LowerCaseEqualsLiteral("allow-forms")) {
+        out &= ~SANDBOXED_FORMS;
+      } else if (token.LowerCaseEqualsLiteral("allow-scripts")) {
+        // allow-scripts removes both SANDBOXED_SCRIPTS and
+        // SANDBOXED_AUTOMATIC_FEATURES.
+        out &= ~SANDBOXED_SCRIPTS;
+        out &= ~SANDBOXED_AUTOMATIC_FEATURES;
+      } else if (token.LowerCaseEqualsLiteral("allow-top-navigation")) {
+        out &= ~SANDBOXED_TOPLEVEL_NAVIGATION;
+      }
+    }
+  }
+
+  return out;
+}
+
 #ifdef MOZ_XTF
 nsIXTFService*
 nsContentUtils::GetXTFService()
 {
   if (!sXTFService) {
     nsresult rv = CallGetService(kXTFServiceCID, &sXTFService);
     if (NS_FAILED(rv)) {
       sXTFService = nullptr;
@@ -4552,17 +4601,17 @@ nsContentUtils::CheckSecurityBeforeLoad(
 
   // Same Origin
   if ((aAllowData && SchemeIs(aURIToLoad, "data")) ||
       ((aCheckLoadFlags & nsIScriptSecurityManager::ALLOW_CHROME) &&
        SchemeIs(aURIToLoad, "chrome"))) {
     return NS_OK;
   }
 
-  return aLoadingPrincipal->CheckMayLoad(aURIToLoad, true);
+  return aLoadingPrincipal->CheckMayLoad(aURIToLoad, true, false);
 }
 
 bool
 nsContentUtils::IsSystemPrincipal(nsIPrincipal* aPrincipal)
 {
   bool isSystem;
   nsresult rv = sSecurityManager->IsSystemPrincipal(aPrincipal, &isSystem);
   return NS_SUCCEEDED(rv) && isSystem;
@@ -5702,19 +5751,19 @@ nsContentUtils::CheckSameOrigin(nsIChann
 
   nsCOMPtr<nsIURI> newURI;
   aNewChannel->GetURI(getter_AddRefs(newURI));
   nsCOMPtr<nsIURI> newOriginalURI;
   aNewChannel->GetOriginalURI(getter_AddRefs(newOriginalURI));
 
   NS_ENSURE_STATE(oldPrincipal && newURI && newOriginalURI);
 
-  nsresult rv = oldPrincipal->CheckMayLoad(newURI, false);
+  nsresult rv = oldPrincipal->CheckMayLoad(newURI, false, false);
   if (NS_SUCCEEDED(rv) && newOriginalURI != newURI) {
-    rv = oldPrincipal->CheckMayLoad(newOriginalURI, false);
+    rv = oldPrincipal->CheckMayLoad(newOriginalURI, false, false);
   }
 
   return rv;
 }
 
 NS_IMPL_ISUPPORTS2(SameOriginChecker,
                    nsIChannelEventSink,
                    nsIInterfaceRequestor)
@@ -5875,23 +5924,23 @@ nsContentUtils::GetDocumentFromScriptCon
       CallQueryInterface(domdoc, &doc);
     }
   }
   return doc;
 }
 
 /* static */
 bool
-nsContentUtils::CheckMayLoad(nsIPrincipal* aPrincipal, nsIChannel* aChannel)
+nsContentUtils::CheckMayLoad(nsIPrincipal* aPrincipal, nsIChannel* aChannel, bool aAllowIfInheritsPrincipal)
 {
   nsCOMPtr<nsIURI> channelURI;
   nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(channelURI));
   NS_ENSURE_SUCCESS(rv, false);
 
-  return NS_SUCCEEDED(aPrincipal->CheckMayLoad(channelURI, false));
+  return NS_SUCCEEDED(aPrincipal->CheckMayLoad(channelURI, false, aAllowIfInheritsPrincipal));
 }
 
 nsContentTypeParser::nsContentTypeParser(const nsAString& aString)
   : mString(aString), mService(nullptr)
 {
   CallGetService("@mozilla.org/network/mime-hdrparam;1", &mService);
 }
 
@@ -6550,16 +6599,28 @@ nsContentUtils::FindInternalContentViewe
         if (docFactory && aLoaderType) {
           *aLoaderType = TYPE_CONTENT;
         }
         return docFactory.forget();
       }
     }
   }
 #endif
+
+#ifdef MOZ_MEDIA_PLUGINS
+  if (nsHTMLMediaElement::IsMediaPluginsEnabled() &&
+      nsHTMLMediaElement::IsMediaPluginsType(nsDependentCString(aType))) {
+    docFactory = do_GetService("@mozilla.org/content/document-loader-factory;1");
+    if (docFactory && aLoaderType) {
+      *aLoaderType = TYPE_CONTENT;
+    }
+    return docFactory.forget();
+  }
+#endif // MOZ_MEDIA_PLUGINS
+
 #endif // MOZ_MEDIA
 
   return NULL;
 }
 
 // static
 bool
 nsContentUtils::IsPatternMatching(nsAString& aValue, nsAString& aPattern,
@@ -6605,17 +6666,18 @@ nsContentUtils::URIInheritsSecurityConte
                              aResult);
 }
 
 // static
 bool
 nsContentUtils::SetUpChannelOwner(nsIPrincipal* aLoadingPrincipal,
                                   nsIChannel* aChannel,
                                   nsIURI* aURI,
-                                  bool aSetUpForAboutBlank)
+                                  bool aSetUpForAboutBlank,
+                                  bool aForceOwner)
 {
   //
   // Set the owner of the channel, but only for channels that can't
   // provide their own security context.
   //
   // XXX: It seems wrong that the owner is ignored - even if one is
   //      supplied) unless the URI is javascript or data or about:blank.
   // XXX: If this is ever changed, check all callers for what owners
@@ -6623,37 +6685,49 @@ nsContentUtils::SetUpChannelOwner(nsIPri
   //      comments in nsDocShell::LoadURI where we fall back on
   //      inheriting the owner if called from chrome.  That would be
   //      very wrong if this code changed anything but channels that
   //      can't provide their own security context!
   //
   //      (Currently chrome URIs set the owner when they are created!
   //      So setting a NULL owner would be bad!)
   //
+  // If aForceOwner is true, the owner will be set, even for a channel that
+  // can provide its own security context. This is used for the HTML5 IFRAME
+  // sandbox attribute, so we can force the channel (and its document) to
+  // explicitly have a null principal.
   bool inherit;
   // We expect URIInheritsSecurityContext to return success for an
   // about:blank URI, so don't call NS_IsAboutBlank() if this call fails.
   // This condition needs to match the one in nsDocShell::InternalLoad where
   // we're checking for things that will use the owner.
-  if (NS_SUCCEEDED(URIInheritsSecurityContext(aURI, &inherit)) &&
-      (inherit || (aSetUpForAboutBlank && NS_IsAboutBlank(aURI)))) {
+  if (aForceOwner || ((NS_SUCCEEDED(URIInheritsSecurityContext(aURI, &inherit)) &&
+      (inherit || (aSetUpForAboutBlank && NS_IsAboutBlank(aURI)))))) {
+#ifdef DEBUG
+    // Assert that aForceOwner is only set for null principals
+    if (aForceOwner) {
+      nsCOMPtr<nsIURI> ownerURI;
+      nsresult rv = aLoadingPrincipal->GetURI(getter_AddRefs(ownerURI));
+      MOZ_ASSERT(NS_SUCCEEDED(rv) && SchemeIs(ownerURI, NS_NULLPRINCIPAL_SCHEME));
+    }
+#endif
     aChannel->SetOwner(aLoadingPrincipal);
     return true;
   }
 
   //
   // file: uri special-casing
   //
   // If this is a file: load opened from another file: then it may need
   // to inherit the owner from the referrer so they can script each other.
   // If we don't set the owner explicitly then each file: gets an owner
   // based on its own codebase later.
   //
   if (URIIsLocalFile(aURI) && aLoadingPrincipal &&
-      NS_SUCCEEDED(aLoadingPrincipal->CheckMayLoad(aURI, false)) &&
+      NS_SUCCEEDED(aLoadingPrincipal->CheckMayLoad(aURI, false, false)) &&
       // One more check here.  CheckMayLoad will always return true for the
       // system principal, but we do NOT want to inherit in that case.
       !IsSystemPrincipal(aLoadingPrincipal)) {
     aChannel->SetOwner(aLoadingPrincipal);
     return true;
   }
 
   return false;
--- a/content/base/src/nsCrossSiteListenerProxy.cpp
+++ b/content/base/src/nsCrossSiteListenerProxy.cpp
@@ -738,20 +738,20 @@ nsCORSListenerProxy::UpdateChannel(nsICh
   if (originalURI != uri) {
     rv = nsContentUtils::GetSecurityManager()->
       CheckLoadURIWithPrincipal(mRequestingPrincipal, originalURI,
                                 nsIScriptSecurityManager::STANDARD);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   if (!mHasBeenCrossSite &&
-      NS_SUCCEEDED(mRequestingPrincipal->CheckMayLoad(uri, false)) &&
+      NS_SUCCEEDED(mRequestingPrincipal->CheckMayLoad(uri, false, false)) &&
       (originalURI == uri ||
        NS_SUCCEEDED(mRequestingPrincipal->CheckMayLoad(originalURI,
-                                                       false)))) {
+                                                       false, false)))) {
     return NS_OK;
   }
 
   // It's a cross site load
   mHasBeenCrossSite = true;
 
   nsCString userpass;
   uri->GetUserPass(userpass);
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -163,16 +163,17 @@
 #include "mozilla/dom/Link.h"
 #include "nsXULAppAPI.h"
 #include "nsDOMTouchEvent.h"
 
 #include "mozilla/Preferences.h"
 
 #include "imgILoader.h"
 #include "nsWrapperCacheInlines.h"
+#include "nsSandboxFlags.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::directionality;
 
 typedef nsTArray<Link*> LinkArray;
 
 // Reference to the document which requested DOM full-screen mode.
@@ -1059,28 +1060,22 @@ nsExternalResourceMap::PendingLoad::Star
 
   nsIPrincipal* requestingPrincipal = aRequestingNode->NodePrincipal();
 
   nsresult rv = nsContentUtils::GetSecurityManager()->
     CheckLoadURIWithPrincipal(requestingPrincipal, aURI,
                               nsIScriptSecurityManager::STANDARD);
   NS_ENSURE_SUCCESS(rv, rv);
   
-  // Allow data URIs (let them skip the CheckMayLoad call), since we want
+  // Allow data URIs and other URI's that inherit their principal by passing
+  // true as the 3rd argument of CheckMayLoad, since we want
   // to allow external resources from data URIs regardless of the difference
   // in URI scheme.
-  bool doesInheritSecurityContext;
-  rv =
-    NS_URIChainHasFlags(aURI,
-                        nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
-                        &doesInheritSecurityContext);
-  if (NS_FAILED(rv) || !doesInheritSecurityContext) {
-    rv = requestingPrincipal->CheckMayLoad(aURI, true);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
+  rv = requestingPrincipal->CheckMayLoad(aURI, true, true);
+  NS_ENSURE_SUCCESS(rv, rv);
 
   PRInt16 shouldLoad = nsIContentPolicy::ACCEPT;
   rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_OTHER,
                                  aURI,
                                  requestingPrincipal,
                                  aRequestingNode,
                                  EmptyCString(), //mime guess
                                  nullptr,         //extra
@@ -2407,16 +2402,25 @@ nsDocument::StartDocumentLoad(const char
     FindCharInReadable(';', semicolon, end);
     SetContentTypeInternal(Substring(start, semicolon));
   }
 
   RetrieveRelevantHeaders(aChannel);
 
   mChannel = aChannel;
 
+  // If this document is being loaded by a docshell, copy its sandbox flags
+  // to the document. These are immutable after being set here.
+  nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(aContainer);
+
+  if (docShell) {
+    nsresult rv = docShell->GetSandboxFlags(&mSandboxFlags);
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
   nsresult rv = InitCSP();
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
 nsresult
 nsDocument::InitCSP()
@@ -2715,16 +2719,34 @@ nsDocument::SetContentType(const nsAStri
 {
   NS_ASSERTION(GetContentTypeInternal().IsEmpty() ||
                GetContentTypeInternal().Equals(NS_ConvertUTF16toUTF8(aContentType)),
                "Do you really want to change the content-type?");
 
   SetContentTypeInternal(NS_ConvertUTF16toUTF8(aContentType));
 }
 
+nsresult
+nsDocument::GetAllowPlugins(bool * aAllowPlugins)
+{
+  // First, we ask our docshell if it allows plugins.
+  nsCOMPtr<nsIDocShell> docShell = do_QueryReferent(mDocumentContainer);
+
+  if (docShell) {
+    docShell->GetAllowPlugins(aAllowPlugins);
+      
+    // If the docshell allows plugins, we check whether
+    // we are sandboxed and plugins should not be allowed.
+    if (*aAllowPlugins)
+      *aAllowPlugins = !(mSandboxFlags & SANDBOXED_PLUGINS);
+  }
+
+  return NS_OK;
+}
+
 /* Return true if the document is in the focused top-level window, and is an
  * ancestor of the focused DOMWindow. */
 NS_IMETHODIMP
 nsDocument::HasFocus(bool* aResult)
 {
   *aResult = false;
 
   nsIFocusManager* fm = nsFocusManager::GetFocusManager();
@@ -6410,16 +6432,22 @@ nsDocument::GetXMLDeclaration(nsAString&
       aStandalone.AssignLiteral("no");
     }
   }
 }
 
 bool
 nsDocument::IsScriptEnabled()
 {
+  // If this document is sandboxed without 'allow-scripts'
+  // script is not enabled
+  if (mSandboxFlags & SANDBOXED_SCRIPTS) {
+    return false;
+  }
+
   nsCOMPtr<nsIScriptSecurityManager> sm(do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID));
   NS_ENSURE_TRUE(sm, false);
 
   nsIScriptGlobalObject* globalObject = GetScriptGlobalObject();
   NS_ENSURE_TRUE(globalObject, false);
 
   nsIScriptContext *scriptContext = globalObject->GetContext();
   NS_ENSURE_TRUE(scriptContext, false);
@@ -8487,20 +8515,23 @@ DispatchFullScreenChange(nsIDocument* aT
                         true,
                         false);
   e->PostDOMEvent();
 }
 
 NS_IMETHODIMP
 nsDocument::MozCancelFullScreen()
 {
-  if (!nsContentUtils::IsRequestFullScreenAllowed()) {
-    return NS_OK;
-  }
-  RestorePreviousFullScreenState();
+  // Only perform fullscreen changes if we're running in a webapp
+  // same-origin to the web app, or if we're in a user generated event
+  // handler.
+  if (NodePrincipal()->GetAppStatus() >= nsIPrincipal::APP_STATUS_INSTALLED ||
+      nsContentUtils::IsRequestFullScreenAllowed()) {
+    RestorePreviousFullScreenState();
+  }
   return NS_OK;
 }
 
 // Runnable to set window full-screen mode. Used as a script runner
 // to ensure we only call nsGlobalWindow::SetFullScreen() when it's safe to
 // run script. nsGlobalWindow::SetFullScreen() dispatches a synchronous event
 // (handled in chome code) which is unsafe to run if this is called in