Merge mozilla-central into holly
authorMike Conley <mconley@mozilla.com>
Thu, 05 Dec 2013 13:48:49 -0500
changeset 174466 2bcfb7046e72eb3b620ead5e8405726790e63bf3
parent 174386 aca9247177d80a651ae05cb065a17698793e8f8e (current diff)
parent 174465 725c36b5de1a4667ce33a0ced6143b1d8162edff (diff)
child 174520 8a631d00cf5dd3abacf5368f3e6d27e72643bfb2
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone28.0a1
Merge mozilla-central into holly
layout/inspector/public/inICSSValueSearch.idl
layout/inspector/public/inIDOMUtils.idl
layout/inspector/public/inIDOMView.idl
layout/inspector/public/inIDeepTreeWalker.idl
layout/inspector/public/inIFlasher.idl
layout/inspector/public/inISearchObserver.idl
layout/inspector/public/inISearchProcess.idl
layout/inspector/public/moz.build
layout/inspector/public/nsIDOMFontFace.idl
layout/inspector/public/nsIDOMFontFaceList.idl
layout/inspector/src/inCSSValueSearch.cpp
layout/inspector/src/inCSSValueSearch.h
layout/inspector/src/inDOMUtils.cpp
layout/inspector/src/inDOMUtils.h
layout/inspector/src/inDOMView.cpp
layout/inspector/src/inDOMView.h
layout/inspector/src/inDeepTreeWalker.cpp
layout/inspector/src/inDeepTreeWalker.h
layout/inspector/src/inFlasher.cpp
layout/inspector/src/inFlasher.h
layout/inspector/src/inLayoutUtils.cpp
layout/inspector/src/inLayoutUtils.h
layout/inspector/src/inSearchLoop.cpp
layout/inspector/src/inSearchLoop.h
layout/inspector/src/moz.build
layout/inspector/src/nsFontFace.cpp
layout/inspector/src/nsFontFace.h
layout/inspector/src/nsFontFaceList.cpp
layout/inspector/src/nsFontFaceList.h
layout/xul/base/public/moz.build
layout/xul/base/public/nsIBoxObject.idl
layout/xul/base/public/nsIBrowserBoxObject.idl
layout/xul/base/public/nsIContainerBoxObject.idl
layout/xul/base/public/nsIEditorBoxObject.idl
layout/xul/base/public/nsIIFrameBoxObject.idl
layout/xul/base/public/nsIListBoxObject.idl
layout/xul/base/public/nsIMenuBoxObject.idl
layout/xul/base/public/nsIPopupBoxObject.idl
layout/xul/base/public/nsIScrollBoxObject.idl
layout/xul/base/public/nsIScrollbarMediator.h
layout/xul/base/public/nsISliderListener.idl
layout/xul/base/public/nsPIBoxObject.h
layout/xul/base/public/nsXULPopupManager.h
layout/xul/base/reftest/image-scaling-min-height-1-ref.xul
layout/xul/base/reftest/image-scaling-min-height-1.xul
layout/xul/base/reftest/image-size-ref.xul
layout/xul/base/reftest/image-size.xul
layout/xul/base/reftest/image4x3.png
layout/xul/base/reftest/popup-explicit-size-ref.xul
layout/xul/base/reftest/popup-explicit-size.xul
layout/xul/base/reftest/reftest.list
layout/xul/base/reftest/textbox-multiline-noresize.xul
layout/xul/base/reftest/textbox-multiline-ref.xul
layout/xul/base/reftest/textbox-multiline-resize.xul
layout/xul/base/src/crashtests/131008-1.xul
layout/xul/base/src/crashtests/137216-1.xul
layout/xul/base/src/crashtests/140218-1.xml
layout/xul/base/src/crashtests/151826-1.xul
layout/xul/base/src/crashtests/168724-1.xul
layout/xul/base/src/crashtests/189814-1.xul
layout/xul/base/src/crashtests/237787-1.xul
layout/xul/base/src/crashtests/265161-1.xul
layout/xul/base/src/crashtests/289410-1.xul
layout/xul/base/src/crashtests/291702-1.xul
layout/xul/base/src/crashtests/291702-2.xul
layout/xul/base/src/crashtests/291702-3.xul
layout/xul/base/src/crashtests/294371-1.xul
layout/xul/base/src/crashtests/311457-1.html
layout/xul/base/src/crashtests/321056-1.xhtml
layout/xul/base/src/crashtests/322786-1.xul
layout/xul/base/src/crashtests/325377.xul
layout/xul/base/src/crashtests/326834-1-inner.xul
layout/xul/base/src/crashtests/326834-1.html
layout/xul/base/src/crashtests/326879-1.xul
layout/xul/base/src/crashtests/327776-1.xul
layout/xul/base/src/crashtests/328135-1.xul
layout/xul/base/src/crashtests/329327-1.xul
layout/xul/base/src/crashtests/329407-1.xml
layout/xul/base/src/crashtests/329477-1.xhtml
layout/xul/base/src/crashtests/336962-1.xul
layout/xul/base/src/crashtests/344228-1.xul
layout/xul/base/src/crashtests/346083-1.xul
layout/xul/base/src/crashtests/346281-1.xul
layout/xul/base/src/crashtests/350460.xul
layout/xul/base/src/crashtests/360642-1.xul
layout/xul/base/src/crashtests/365151.xul
layout/xul/base/src/crashtests/366112-1.xul
layout/xul/base/src/crashtests/369942-1.xhtml
layout/xul/base/src/crashtests/374102-1.xul
layout/xul/base/src/crashtests/376137-1.html
layout/xul/base/src/crashtests/376137-2.html
layout/xul/base/src/crashtests/377592-1.svg
layout/xul/base/src/crashtests/381862.html
layout/xul/base/src/crashtests/382746-1.xul
layout/xul/base/src/crashtests/382899-1.xul
layout/xul/base/src/crashtests/383236-1.xul
layout/xul/base/src/crashtests/384037-1.xhtml
layout/xul/base/src/crashtests/384105-1-inner.xul
layout/xul/base/src/crashtests/384105-1.html
layout/xul/base/src/crashtests/384491-1.xhtml
layout/xul/base/src/crashtests/384871-1-inner.xul
layout/xul/base/src/crashtests/384871-1.html
layout/xul/base/src/crashtests/387033-1.xhtml
layout/xul/base/src/crashtests/387080-1.xul
layout/xul/base/src/crashtests/391974-1-inner.xul
layout/xul/base/src/crashtests/391974-1.html
layout/xul/base/src/crashtests/394120-1.xhtml
layout/xul/base/src/crashtests/397293.xhtml
layout/xul/base/src/crashtests/397304-1.html
layout/xul/base/src/crashtests/398326-1.xhtml
layout/xul/base/src/crashtests/399013.xul
layout/xul/base/src/crashtests/400779-1.xhtml
layout/xul/base/src/crashtests/402912-1.xhtml
layout/xul/base/src/crashtests/408904-1.xul
layout/xul/base/src/crashtests/412479-1.xhtml
layout/xul/base/src/crashtests/415394-1.xhtml
layout/xul/base/src/crashtests/420424-1.xul
layout/xul/base/src/crashtests/430356-1.xhtml
layout/xul/base/src/crashtests/431738.xhtml
layout/xul/base/src/crashtests/432058-1.xul
layout/xul/base/src/crashtests/432068-1.xul
layout/xul/base/src/crashtests/432068-2.xul
layout/xul/base/src/crashtests/433296-1.xul
layout/xul/base/src/crashtests/433429.xul
layout/xul/base/src/crashtests/434458-1.xul
layout/xul/base/src/crashtests/452185.html
layout/xul/base/src/crashtests/452185.xml
layout/xul/base/src/crashtests/460900-1.xul
layout/xul/base/src/crashtests/464149-1.xul
layout/xul/base/src/crashtests/464407-1.xhtml
layout/xul/base/src/crashtests/467080.xul
layout/xul/base/src/crashtests/467481-1.xul
layout/xul/base/src/crashtests/470063-1.html
layout/xul/base/src/crashtests/470272.html
layout/xul/base/src/crashtests/472189.xul
layout/xul/base/src/crashtests/475133.html
layout/xul/base/src/crashtests/488210-1.xhtml
layout/xul/base/src/crashtests/495728-1.xul
layout/xul/base/src/crashtests/508927-1.xul
layout/xul/base/src/crashtests/508927-2.xul
layout/xul/base/src/crashtests/514300-1.xul
layout/xul/base/src/crashtests/536931-1.xhtml
layout/xul/base/src/crashtests/538308-1.xul
layout/xul/base/src/crashtests/557174-1.xml
layout/xul/base/src/crashtests/564705-1.xul
layout/xul/base/src/crashtests/583957-1.html
layout/xul/base/src/crashtests/crashtests.list
layout/xul/base/src/crashtests/menulist-focused.xhtml
layout/xul/base/src/moz.build
layout/xul/base/src/nsBox.cpp
layout/xul/base/src/nsBox.h
layout/xul/base/src/nsBoxFrame.cpp
layout/xul/base/src/nsBoxFrame.h
layout/xul/base/src/nsBoxLayout.cpp
layout/xul/base/src/nsBoxLayout.h
layout/xul/base/src/nsBoxLayoutState.cpp
layout/xul/base/src/nsBoxLayoutState.h
layout/xul/base/src/nsBoxObject.cpp
layout/xul/base/src/nsBoxObject.h
layout/xul/base/src/nsButtonBoxFrame.cpp
layout/xul/base/src/nsButtonBoxFrame.h
layout/xul/base/src/nsContainerBoxObject.cpp
layout/xul/base/src/nsDeckFrame.cpp
layout/xul/base/src/nsDeckFrame.h
layout/xul/base/src/nsDocElementBoxFrame.cpp
layout/xul/base/src/nsGroupBoxFrame.cpp
layout/xul/base/src/nsIRootBox.h
layout/xul/base/src/nsImageBoxFrame.cpp
layout/xul/base/src/nsImageBoxFrame.h
layout/xul/base/src/nsLeafBoxFrame.cpp
layout/xul/base/src/nsLeafBoxFrame.h
layout/xul/base/src/nsListBoxBodyFrame.cpp
layout/xul/base/src/nsListBoxBodyFrame.h
layout/xul/base/src/nsListBoxLayout.cpp
layout/xul/base/src/nsListBoxLayout.h
layout/xul/base/src/nsListBoxObject.cpp
layout/xul/base/src/nsListItemFrame.cpp
layout/xul/base/src/nsListItemFrame.h
layout/xul/base/src/nsMenuBarFrame.cpp
layout/xul/base/src/nsMenuBarFrame.h
layout/xul/base/src/nsMenuBarListener.cpp
layout/xul/base/src/nsMenuBarListener.h
layout/xul/base/src/nsMenuBoxObject.cpp
layout/xul/base/src/nsMenuFrame.cpp
layout/xul/base/src/nsMenuFrame.h
layout/xul/base/src/nsMenuParent.h
layout/xul/base/src/nsMenuPopupFrame.cpp
layout/xul/base/src/nsMenuPopupFrame.h
layout/xul/base/src/nsPIListBoxObject.h
layout/xul/base/src/nsPopupBoxObject.cpp
layout/xul/base/src/nsPopupSetFrame.cpp
layout/xul/base/src/nsPopupSetFrame.h
layout/xul/base/src/nsProgressMeterFrame.cpp
layout/xul/base/src/nsProgressMeterFrame.h
layout/xul/base/src/nsRepeatService.cpp
layout/xul/base/src/nsRepeatService.h
layout/xul/base/src/nsResizerFrame.cpp
layout/xul/base/src/nsResizerFrame.h
layout/xul/base/src/nsRootBoxFrame.cpp
layout/xul/base/src/nsScrollBoxFrame.cpp
layout/xul/base/src/nsScrollBoxObject.cpp
layout/xul/base/src/nsScrollbarButtonFrame.cpp
layout/xul/base/src/nsScrollbarButtonFrame.h
layout/xul/base/src/nsScrollbarFrame.cpp
layout/xul/base/src/nsScrollbarFrame.h
layout/xul/base/src/nsSliderFrame.cpp
layout/xul/base/src/nsSliderFrame.h
layout/xul/base/src/nsSplitterFrame.cpp
layout/xul/base/src/nsSplitterFrame.h
layout/xul/base/src/nsSprocketLayout.cpp
layout/xul/base/src/nsSprocketLayout.h
layout/xul/base/src/nsStackFrame.cpp
layout/xul/base/src/nsStackFrame.h
layout/xul/base/src/nsStackLayout.cpp
layout/xul/base/src/nsStackLayout.h
layout/xul/base/src/nsTextBoxFrame.cpp
layout/xul/base/src/nsTextBoxFrame.h
layout/xul/base/src/nsTitleBarFrame.cpp
layout/xul/base/src/nsTitleBarFrame.h
layout/xul/base/src/nsXULLabelFrame.cpp
layout/xul/base/src/nsXULLabelFrame.h
layout/xul/base/src/nsXULPopupManager.cpp
layout/xul/base/src/nsXULTooltipListener.cpp
layout/xul/base/src/nsXULTooltipListener.h
layout/xul/base/test/chrome.ini
layout/xul/base/test/mochitest.ini
layout/xul/base/test/moz.build
layout/xul/base/test/test_bug381167.xhtml
layout/xul/base/test/test_bug393970.xul
layout/xul/base/test/test_bug477754.xul
layout/xul/base/test/test_bug511075.html
layout/xul/base/test/test_popupSizeTo.xul
layout/xul/base/test/test_resizer.xul
layout/xul/base/test/test_resizer_incontent.xul
layout/xul/base/test/test_splitter.xul
layout/xul/base/test/test_stack.xul
layout/xul/base/test/test_windowminmaxsize.xul
layout/xul/base/test/window_resizer.xul
layout/xul/base/test/window_resizer_element.xul
modules/libpref/src/init/all.js
--- a/accessible/src/base/moz.build
+++ b/accessible/src/base/moz.build
@@ -59,17 +59,17 @@ if a11y_log:
     ]
 
 LOCAL_INCLUDES += [
     '../../../content/xbl/src',
     '../../../ipc/chromium/src',
     '../../../layout/generic',
     '../../../layout/style',
     '../../../layout/svg',
-    '../../../layout/xul/base/src',
+    '../../../layout/xul',
     '../../../layout/xul/tree/',
     '../generic',
     '../html',
     '../xpcom',
     '../xul',
 ]
 
 if CONFIG['MOZ_ENABLE_GTK']:
--- a/accessible/src/generic/moz.build
+++ b/accessible/src/generic/moz.build
@@ -22,17 +22,17 @@ UNIFIED_SOURCES += [
     'OuterDocAccessible.cpp',
     'RootAccessible.cpp',
     'TableCellAccessible.cpp',
     'TextLeafAccessible.cpp',
 ]
 
 LOCAL_INCLUDES += [
     '../../../layout/generic',
-    '../../../layout/xul/base/src',
+    '../../../layout/xul',
     '../base',
     '../html',
     '../xpcom',
     '../xul',
 ]
 
 if CONFIG['MOZ_ENABLE_GTK']:
     LOCAL_INCLUDES += [
--- a/accessible/src/html/moz.build
+++ b/accessible/src/html/moz.build
@@ -13,17 +13,17 @@ UNIFIED_SOURCES += [
     'HTMLListAccessible.cpp',
     'HTMLSelectAccessible.cpp',
     'HTMLTableAccessible.cpp',
 ]
 
 LOCAL_INCLUDES += [
     '../../../layout/generic',
     '../../../layout/tables',
-    '../../../layout/xul/base/src',
+    '../../../layout/xul',
     '../base',
     '../generic',
     '../xpcom',
 ]
 
 if CONFIG['MOZ_ENABLE_GTK']:
     LOCAL_INCLUDES += [
         '../atk',
--- a/accessible/src/mac/moz.build
+++ b/accessible/src/mac/moz.build
@@ -27,14 +27,14 @@ UNIFIED_SOURCES += [
 ]
 
 LOCAL_INCLUDES += [
     '../base',
     '../generic',
     '../html',
     '../xul',
     '/layout/generic',
-    '/layout/xul/base/src',
+    '/layout/xul',
     '/widget/cocoa',
     '/widget/xpwidgets',
 ]
 
 FINAL_LIBRARY = 'xul'
--- a/accessible/src/xul/moz.build
+++ b/accessible/src/xul/moz.build
@@ -16,18 +16,18 @@ UNIFIED_SOURCES += [
     'XULSliderAccessible.cpp',
     'XULTabAccessible.cpp',
     'XULTreeAccessible.cpp',
     'XULTreeGridAccessible.cpp',
 ]
 
 LOCAL_INCLUDES += [
     '../../../layout/generic',
-    '../../../layout/xul/base/src',
-    '../../../layout/xul/tree//',
+    '../../../layout/xul',
+    '../../../layout/xul/tree',
     '../base',
     '../generic',
     '../html',
     '../xpcom',
 ]
 
 if CONFIG['MOZ_ENABLE_GTK']:
     LOCAL_INCLUDES += [
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,4 +1,4 @@
 {
-    "revision": "428cccdc7a3b4c40f40dda80b6031d26ac9d2d68", 
+    "revision": "adb7896ababd1ccb828e11b05909c0e9ca22594e", 
     "repo_path": "/integration/gaia-central"
 }
--- a/browser/devtools/debugger/test/browser_dbg_variables-view-popup-01.js
+++ b/browser/devtools/debugger/test/browser_dbg_variables-view-popup-01.js
@@ -7,34 +7,19 @@
  */
 
 const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
 
 function test() {
   Task.spawn(function() {
     let [tab, debuggee, panel] = yield initDebugger(TAB_URL);
     let win = panel.panelWin;
-    let events = win.EVENTS;
-    let editor = win.DebuggerView.editor;
     let bubble = win.DebuggerView.VariableBubble;
     let tooltip = bubble._tooltip.panel;
 
-    function openPopup(coords) {
-      let popupshown = once(tooltip, "popupshown");
-      let { left, top } = editor.getCoordsFromPosition(coords);
-      bubble._findIdentifier(left, top);
-      return popupshown;
-    }
-
-    function hidePopup() {
-      let popuphiding = once(tooltip, "popuphiding");
-      bubble.hideContents();
-      return popuphiding.then(waitForTick);
-    }
-
     function verifyContents(textContent, className) {
       is(tooltip.querySelectorAll(".variables-view-container").length, 0,
         "There should be no variables view containers added to the tooltip.");
       is(tooltip.querySelectorAll(".devtools-tooltip-simple-text").length, 1,
         "There should be a simple text node added to the tooltip instead.");
 
       is(tooltip.querySelector(".devtools-tooltip-simple-text").textContent, textContent,
         "The inspected property's value is correct.");
@@ -42,32 +27,32 @@ function test() {
         "The inspected property's value is colorized correctly.");
     }
 
     // Allow this generator function to yield first.
     executeSoon(() => debuggee.start());
     yield waitForSourceAndCaretAndScopes(panel, ".html", 24);
 
     // Inspect variables.
-    yield openPopup({ line: 15, ch: 12 });
+    yield openVarPopup(panel, { line: 15, ch: 12 });
     verifyContents("1", "token-number");
 
-    yield hidePopup().then(() => openPopup({ line: 16, ch: 21 }));
+    yield reopenVarPopup(panel, { line: 16, ch: 21 });
     verifyContents("1", "token-number");
 
-    yield hidePopup().then(() => openPopup({ line: 17, ch: 21 }));
+    yield reopenVarPopup(panel, { line: 17, ch: 21 });
     verifyContents("1", "token-number");
 
-    yield hidePopup().then(() => openPopup({ line: 17, ch: 27 }));
+    yield reopenVarPopup(panel, { line: 17, ch: 27 });
     verifyContents("\"beta\"", "token-string");
 
-    yield hidePopup().then(() => openPopup({ line: 17, ch: 44 }));
+    yield reopenVarPopup(panel, { line: 17, ch: 44 });
     verifyContents("false", "token-boolean");
 
-    yield hidePopup().then(() => openPopup({ line: 17, ch: 54 }));
+    yield reopenVarPopup(panel, { line: 17, ch: 54 });
     verifyContents("null", "token-null");
 
-    yield hidePopup().then(() => openPopup({ line: 17, ch: 63 }));
+    yield reopenVarPopup(panel, { line: 17, ch: 63 });
     verifyContents("undefined", "token-undefined");
 
     yield resumeDebuggerThenCloseAndFinish(panel);
   });
 }
--- a/browser/devtools/debugger/test/browser_dbg_variables-view-popup-02.js
+++ b/browser/devtools/debugger/test/browser_dbg_variables-view-popup-02.js
@@ -7,34 +7,19 @@
  */
 
 const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
 
 function test() {
   Task.spawn(function() {
     let [tab, debuggee, panel] = yield initDebugger(TAB_URL);
     let win = panel.panelWin;
-    let events = win.EVENTS;
-    let editor = win.DebuggerView.editor;
     let bubble = win.DebuggerView.VariableBubble;
     let tooltip = bubble._tooltip.panel;
 
-    function openPopup(coords) {
-      let popupshown = once(tooltip, "popupshown");
-      let { left, top } = editor.getCoordsFromPosition(coords);
-      bubble._findIdentifier(left, top);
-      return popupshown;
-    }
-
-    function hidePopup() {
-      let popuphiding = once(tooltip, "popuphiding");
-      bubble.hideContents();
-      return popuphiding.then(waitForTick);
-    }
-
     function verifyContents(textContent, className) {
       is(tooltip.querySelectorAll(".variables-view-container").length, 0,
         "There should be no variables view containers added to the tooltip.");
       is(tooltip.querySelectorAll(".devtools-tooltip-simple-text").length, 1,
         "There should be a simple text node added to the tooltip instead.");
 
       is(tooltip.querySelector(".devtools-tooltip-simple-text").textContent, textContent,
         "The inspected property's value is correct.");
@@ -42,20 +27,20 @@ function test() {
         "The inspected property's value is colorized correctly.");
     }
 
     // Allow this generator function to yield first.
     executeSoon(() => debuggee.start());
     yield waitForSourceAndCaretAndScopes(panel, ".html", 24);
 
     // Inspect properties.
-    yield openPopup({ line: 19, ch: 10 });
+    yield openVarPopup(panel, { line: 19, ch: 10 });
     verifyContents("42", "token-number");
 
-    yield hidePopup().then(() => openPopup({ line: 20, ch: 14 }));
+    yield reopenVarPopup(panel, { line: 20, ch: 14 });
     verifyContents("42", "token-number");
 
-    yield hidePopup().then(() => openPopup({ line: 21, ch: 14 }));
+    yield reopenVarPopup(panel, { line: 21, ch: 14 });
     verifyContents("42", "token-number");
 
     yield resumeDebuggerThenCloseAndFinish(panel);
   });
 }
--- a/browser/devtools/debugger/test/browser_dbg_variables-view-popup-03.js
+++ b/browser/devtools/debugger/test/browser_dbg_variables-view-popup-03.js
@@ -6,49 +6,33 @@
  */
 
 const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
 
 function test() {
   Task.spawn(function() {
     let [tab, debuggee, panel] = yield initDebugger(TAB_URL);
     let win = panel.panelWin;
-    let events = win.EVENTS;
-    let editor = win.DebuggerView.editor;
     let bubble = win.DebuggerView.VariableBubble;
-    let tooltip = bubble._tooltip.panel;
-
-    function openPopup(coords) {
-      let popupshown = once(tooltip, "popupshown");
-      let { left, top } = editor.getCoordsFromPosition(coords);
-      bubble._findIdentifier(left, top);
-      return popupshown;
-    }
-
-    function hidePopup() {
-      let popuphiding = once(tooltip, "popuphiding");
-      bubble.hideContents();
-      return popuphiding.then(waitForTick);
-    }
 
     // Allow this generator function to yield first.
     executeSoon(() => debuggee.start());
     yield waitForSourceAndCaretAndScopes(panel, ".html", 24);
 
     // Inspect variable.
-    yield openPopup({ line: 15, ch: 12 });
+    yield openVarPopup(panel, { line: 15, ch: 12 });
 
     ok(!bubble._tooltip.isEmpty(),
       "The variable inspection popup isn't empty.");
     ok(bubble._markedText,
       "There's some marked text in the editor.");
     ok(bubble._markedText.clear,
       "The marked text in the editor can be cleared.");
 
-    yield hidePopup();
+    yield hideVarPopup(panel);
 
     ok(bubble._tooltip.isEmpty(),
       "The variable inspection popup is now empty.");
     ok(!bubble._markedText,
       "The marked text in the editor was removed.");
 
     yield resumeDebuggerThenCloseAndFinish(panel);
   });
--- a/browser/devtools/debugger/test/browser_dbg_variables-view-popup-04.js
+++ b/browser/devtools/debugger/test/browser_dbg_variables-view-popup-04.js
@@ -6,41 +6,25 @@
  */
 
 const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
 
 function test() {
   Task.spawn(function() {
     let [tab, debuggee, panel] = yield initDebugger(TAB_URL);
     let win = panel.panelWin;
-    let events = win.EVENTS;
-    let editor = win.DebuggerView.editor;
     let bubble = win.DebuggerView.VariableBubble;
-    let tooltip = bubble._tooltip.panel;
-
-    function openPopup(coords) {
-      let popupshown = once(tooltip, "popupshown");
-      let { left, top } = editor.getCoordsFromPosition(coords);
-      bubble._findIdentifier(left, top);
-      return popupshown;
-    }
-
-    function scrollEditor() {
-      let popuphiding = once(tooltip, "popuphiding");
-      editor.setFirstVisibleLine(0);
-      return popuphiding.then(waitForTick);
-    }
 
     // Allow this generator function to yield first.
     executeSoon(() => debuggee.start());
     yield waitForSourceAndCaretAndScopes(panel, ".html", 24);
 
     // Inspect variable.
-    yield openPopup({ line: 15, ch: 12 });
-    yield scrollEditor();
+    yield openVarPopup(panel, { line: 15, ch: 12 });
+    yield hideVarPopupByScrollingEditor(panel);
     ok(true, "The variable inspection popup was hidden.");
 
     ok(bubble._tooltip.isEmpty(),
       "The variable inspection popup is now empty.");
     ok(!bubble._markedText,
       "The marked text in the editor was removed.");
 
     yield resumeDebuggerThenCloseAndFinish(panel);
--- a/browser/devtools/debugger/test/browser_dbg_variables-view-popup-05.js
+++ b/browser/devtools/debugger/test/browser_dbg_variables-view-popup-05.js
@@ -7,29 +7,19 @@
  */
 
 const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
 
 function test() {
   Task.spawn(function() {
     let [tab, debuggee, panel] = yield initDebugger(TAB_URL);
     let win = panel.panelWin;
-    let events = win.EVENTS;
-    let editor = win.DebuggerView.editor;
     let bubble = win.DebuggerView.VariableBubble;
     let tooltip = bubble._tooltip.panel;
 
-    function openPopup(coords) {
-      let popupshown = once(tooltip, "popupshown");
-      let fetched = waitForDebuggerEvents(panel, events.FETCHED_BUBBLE_PROPERTIES);
-      let { left, top } = editor.getCoordsFromPosition(coords);
-      bubble._findIdentifier(left, top);
-      return promise.all([popupshown, fetched]);
-    }
-
     function verifyContents() {
       is(tooltip.querySelectorAll(".variables-view-container").length, 1,
         "There should be one variables view container added to the tooltip.");
 
       is(tooltip.querySelectorAll(".variables-view-scope[non-header]").length, 1,
         "There should be one scope with no header displayed.");
       is(tooltip.querySelectorAll(".variables-view-variable[non-header]").length, 1,
         "There should be one variable with no header displayed.");
@@ -48,14 +38,14 @@ function test() {
         "The second property's value is correct.");
     }
 
     // Allow this generator function to yield first.
     executeSoon(() => debuggee.start());
     yield waitForSourceAndCaretAndScopes(panel, ".html", 24);
 
     // Inspect variable.
-    yield openPopup({ line: 16, ch: 12 });
+    yield openVarPopup(panel, { line: 16, ch: 12 }, true);
     verifyContents();
 
     yield resumeDebuggerThenCloseAndFinish(panel);
   });
 }
--- a/browser/devtools/debugger/test/browser_dbg_variables-view-popup-06.js
+++ b/browser/devtools/debugger/test/browser_dbg_variables-view-popup-06.js
@@ -7,29 +7,19 @@
  */
 
 const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
 
 function test() {
   Task.spawn(function() {
     let [tab, debuggee, panel] = yield initDebugger(TAB_URL);
     let win = panel.panelWin;
-    let events = win.EVENTS;
-    let editor = win.DebuggerView.editor;
     let bubble = win.DebuggerView.VariableBubble;
     let tooltip = bubble._tooltip.panel;
 
-    function openPopup(coords) {
-      let popupshown = once(tooltip, "popupshown");
-      let fetched = waitForDebuggerEvents(panel, events.FETCHED_BUBBLE_PROPERTIES);
-      let { left, top } = editor.getCoordsFromPosition(coords);
-      bubble._findIdentifier(left, top);
-      return promise.all([popupshown, fetched]);
-    }
-
     function verifyContents() {
       is(tooltip.querySelectorAll(".variables-view-container").length, 1,
         "There should be one variables view container added to the tooltip.");
 
       is(tooltip.querySelectorAll(".variables-view-scope[non-header]").length, 1,
         "There should be one scope with no header displayed.");
       is(tooltip.querySelectorAll(".variables-view-variable[non-header]").length, 1,
         "There should be one variable with no header displayed.");
@@ -73,14 +63,14 @@ function test() {
         "The seventh property's value is correct.");
     }
 
     // Allow this generator function to yield first.
     executeSoon(() => debuggee.start());
     yield waitForSourceAndCaretAndScopes(panel, ".html", 24);
 
     // Inspect variable.
-    yield openPopup({ line: 17, ch: 12 });
+    yield openVarPopup(panel, { line: 17, ch: 12 }, true);
     verifyContents();
 
     yield resumeDebuggerThenCloseAndFinish(panel);
   });
 }
--- a/browser/devtools/debugger/test/browser_dbg_variables-view-popup-07.js
+++ b/browser/devtools/debugger/test/browser_dbg_variables-view-popup-07.js
@@ -7,42 +7,19 @@
  */
 
 const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
 
 function test() {
   Task.spawn(function() {
     let [tab, debuggee, panel] = yield initDebugger(TAB_URL);
     let win = panel.panelWin;
-    let events = win.EVENTS;
-    let editor = win.DebuggerView.editor;
     let bubble = win.DebuggerView.VariableBubble;
     let tooltip = bubble._tooltip.panel;
 
-    function openSimplePopup(coords) {
-      let popupshown = once(tooltip, "popupshown");
-      let { left, top } = editor.getCoordsFromPosition(coords);
-      bubble._findIdentifier(left, top);
-      return popupshown;
-    }
-
-    function openComplexPopup(coords) {
-      let popupshown = once(tooltip, "popupshown");
-      let fetched = waitForDebuggerEvents(panel, events.FETCHED_BUBBLE_PROPERTIES);
-      let { left, top } = editor.getCoordsFromPosition(coords);
-      bubble._findIdentifier(left, top);
-      return promise.all([popupshown, fetched]);
-    }
-
-    function hidePopup() {
-      let popuphiding = once(tooltip, "popuphiding");
-      bubble.hideContents();
-      return popuphiding.then(waitForTick);
-    }
-
     function verifySimpleContents(textContent, className) {
       is(tooltip.querySelectorAll(".variables-view-container").length, 0,
         "There should be no variables view container added to the tooltip.");
       is(tooltip.querySelectorAll(".devtools-tooltip-simple-text").length, 1,
         "There should be one simple text node added to the tooltip.");
 
       is(tooltip.querySelector(".devtools-tooltip-simple-text").textContent, textContent,
         "The inspected property's value is correct.");
@@ -65,23 +42,23 @@ function test() {
         "There should be some properties displayed.");
     }
 
     // Allow this generator function to yield first.
     executeSoon(() => debuggee.start());
     yield waitForSourceAndCaretAndScopes(panel, ".html", 24);
 
     // Inspect variables.
-    yield openSimplePopup({ line: 15, ch: 12 });
+    yield openVarPopup(panel, { line: 15, ch: 12 });
     verifySimpleContents("1", "token-number");
 
-    yield hidePopup().then(() => openComplexPopup({ line: 16, ch: 12 }));
+    yield reopenVarPopup(panel, { line: 16, ch: 12 }, true);
     verifyComplexContents(2);
 
-    yield hidePopup().then(() => openSimplePopup({ line: 19, ch: 10 }));
+    yield reopenVarPopup(panel, { line: 19, ch: 10 });
     verifySimpleContents("42", "token-number");
 
-    yield hidePopup().then(() => openComplexPopup({ line: 31, ch: 10 }));
+    yield reopenVarPopup(panel, { line: 31, ch: 10 }, true);
     verifyComplexContents(100);
 
     yield resumeDebuggerThenCloseAndFinish(panel);
   });
 }
--- a/browser/devtools/debugger/test/browser_dbg_variables-view-popup-08.js
+++ b/browser/devtools/debugger/test/browser_dbg_variables-view-popup-08.js
@@ -12,29 +12,16 @@ function test() {
     let [tab, debuggee, panel] = yield initDebugger(TAB_URL);
     let win = panel.panelWin;
     let events = win.EVENTS;
     let editor = win.DebuggerView.editor;
     let frames = win.DebuggerView.StackFrames;
     let bubble = win.DebuggerView.VariableBubble;
     let tooltip = bubble._tooltip.panel;
 
-    function openPopup(coords) {
-      let popupshown = once(tooltip, "popupshown");
-      let { left, top } = editor.getCoordsFromPosition(coords);
-      bubble._findIdentifier(left, top);
-      return popupshown;
-    }
-
-    function hidePopup() {
-      let popuphiding = once(tooltip, "popuphiding");
-      bubble.hideContents();
-      return popuphiding.then(waitForTick);
-    }
-
     function verifyContents(textContent, className) {
       is(tooltip.querySelectorAll(".variables-view-container").length, 0,
         "There should be no variables view containers added to the tooltip.");
       is(tooltip.querySelectorAll(".devtools-tooltip-simple-text").length, 1,
         "There should be a simple text node added to the tooltip instead.");
 
       is(tooltip.querySelector(".devtools-tooltip-simple-text").textContent, textContent,
         "The inspected property's value is correct.");
@@ -54,26 +41,26 @@ function test() {
     }
 
     // Allow this generator function to yield first.
     executeSoon(() => debuggee.test());
     yield waitForSourceAndCaretAndScopes(panel, ".html", 20);
     checkView(0, 20);
 
     // Inspect variable in topmost frame.
-    yield openPopup({ line: 18, ch: 12 });
+    yield openVarPopup(panel, { line: 18, ch: 12 });
     verifyContents("\"second scope\"", "token-string");
     checkView(0, 20);
 
     // Change frame.
     let updatedFrame = waitForDebuggerEvents(panel, events.FETCHED_SCOPES);
-    yield hidePopup().then(() => frames.selectedDepth = 1);
+    frames.selectedDepth = 1;
     yield updatedFrame;
     checkView(1, 15);
 
     // Inspect variable in oldest frame.
-    yield openPopup({ line: 13, ch: 12 });
+    yield reopenVarPopup(panel, { line: 13, ch: 12 });
     verifyContents("\"first scope\"", "token-string");
     checkView(1, 15);
 
     yield resumeDebuggerThenCloseAndFinish(panel);
   });
 }
--- a/browser/devtools/debugger/test/head.js
+++ b/browser/devtools/debugger/test/head.js
@@ -523,16 +523,18 @@ function closeDebuggerAndFinish(aPanel, 
 
 function resumeDebuggerThenCloseAndFinish(aPanel, aFlags = {}) {
   let deferred = promise.defer();
   let thread = aPanel.panelWin.gThreadClient;
   thread.resume(() => closeDebuggerAndFinish(aPanel, aFlags).then(deferred.resolve));
   return deferred.promise;
 }
 
+// Blackboxing helpers
+
 function getBlackBoxButton(aPanel) {
   return aPanel.panelWin.document.getElementById("black-box");
 }
 
 function toggleBlackBoxing(aPanel, aSource = null) {
   function clickBlackBoxButton() {
     getBlackBoxButton(aPanel).click();
   }
@@ -540,16 +542,61 @@ function toggleBlackBoxing(aPanel, aSour
   const blackBoxChanged = waitForThreadEvents(aPanel, "blackboxchange");
 
   if (aSource) {
     aPanel.panelWin.DebuggerView.Sources.selectedValue = aSource;
     ensureSourceIs(aPanel, aSource, true).then(clickBlackBoxButton);
   } else {
     clickBlackBoxButton();
   }
+
   return blackBoxChanged;
 }
 
 function selectSourceAndGetBlackBoxButton(aPanel, aSource) {
+  function returnBlackboxButton() {
+    return getBlackBoxButton(aPanel);
+  }
+
   aPanel.panelWin.DebuggerView.Sources.selectedValue = aSource;
-  return ensureSourceIs(aPanel, aSource, true)
-    .then(getBlackBoxButton.bind(null, aPanel));
+  return ensureSourceIs(aPanel, aSource, true).then(returnBlackboxButton);
+}
+
+// Variables view inspection popup helpers
+
+function openVarPopup(aPanel, aCoords, aWaitForFetchedProperties) {
+  let events = aPanel.panelWin.EVENTS;
+  let editor = aPanel.panelWin.DebuggerView.editor;
+  let bubble = aPanel.panelWin.DebuggerView.VariableBubble;
+  let tooltip = bubble._tooltip.panel;
+
+  let popupShown = once(tooltip, "popupshown");
+  let fetchedProperties = aWaitForFetchedProperties
+    ? waitForDebuggerEvents(aPanel, events.FETCHED_BUBBLE_PROPERTIES)
+    : promise.resolve(null);
+
+  let { left, top } = editor.getCoordsFromPosition(aCoords);
+  bubble._findIdentifier(left, top);
+  return promise.all([popupShown, fetchedProperties]).then(waitForTick);
 }
+
+function hideVarPopup(aPanel) {
+  let bubble = aPanel.panelWin.DebuggerView.VariableBubble;
+  let tooltip = bubble._tooltip.panel;
+
+  let popupHiding = once(tooltip, "popuphiding");
+  bubble.hideContents();
+  return popupHiding.then(waitForTick);
+}
+
+function hideVarPopupByScrollingEditor(aPanel) {
+  let editor = aPanel.panelWin.DebuggerView.editor;
+  let bubble = aPanel.panelWin.DebuggerView.VariableBubble;
+  let tooltip = bubble._tooltip.panel;
+
+  let popupHiding = once(tooltip, "popuphiding");
+  editor.setFirstVisibleLine(0);
+  return popupHiding.then(waitForTick);
+}
+
+function reopenVarPopup(...aArgs) {
+  return hideVarPopup.apply(this, aArgs).then(() => openVarPopup.apply(this, aArgs));
+}
--- a/browser/metro/base/content/browser-scripts.js
+++ b/browser/metro/base/content/browser-scripts.js
@@ -111,16 +111,17 @@ let ScriptContexts = {};
   ["TopSites", "chrome://browser/content/TopSites.js"],
   ["Sanitizer", "chrome://browser/content/sanitize.js"],
   ["SanitizeUI", "chrome://browser/content/sanitizeUI.js"],
   ["SSLExceptions", "chrome://browser/content/exceptions.js"],
   ["ItemPinHelper", "chrome://browser/content/helperui/ItemPinHelper.js"],
   ["NavButtonSlider", "chrome://browser/content/NavButtonSlider.js"],
   ["ContextUI", "chrome://browser/content/ContextUI.js"],
   ["FlyoutPanelsUI", "chrome://browser/content/flyoutpanels/FlyoutPanelsUI.js"],
+  ["SettingsCharm", "chrome://browser/content/flyoutpanels/SettingsCharm.js"],
   ["APZCObserver", "chrome://browser/content/apzc.js"],
 ].forEach(function (aScript) {
   let [name, script] = aScript;
   XPCOMUtils.defineLazyGetter(window, name, function() {
     let sandbox;
     if (script in ScriptContexts) {
       sandbox = ScriptContexts[script];
     } else {
--- a/browser/metro/base/content/browser-ui.js
+++ b/browser/metro/base/content/browser-ui.js
@@ -1271,75 +1271,8 @@ var DialogUI = {
       if (targetNode instanceof Element && targetNode.hasAttribute("for"))
         targetNode = document.getElementById(targetNode.getAttribute("for"));
       else
         targetNode = targetNode.parentNode;
     }
     return targetNode ? true : false;
   }
 };
-
-/**
- * Manage the contents of the Windows 8 "Settings" charm.
- */
-var SettingsCharm = {
-  _entries: new Map(),
-  _nextId: 0,
-
-  /**
-   * Add a new item to the "Settings" menu in the Windows 8 charms.
-   * @param aEntry Object with a "label" property (string that will appear in the UI)
-   *    and an "onselected" property (function to be called when the user chooses this entry)
-   */
-  addEntry: function addEntry(aEntry) {
-    try {
-      let id = Services.metro.addSettingsPanelEntry(aEntry.label);
-      this._entries.set(id, aEntry);
-    } catch (e) {
-      // addSettingsPanelEntry does not work on non-Metro platforms
-      Cu.reportError(e);
-    }
-  },
-
-  init: function SettingsCharm_init() {
-    Services.obs.addObserver(this, "metro-settings-entry-selected", false);
-
-    // Options
-    this.addEntry({
-        label: Strings.browser.GetStringFromName("optionsCharm"),
-        onselected: function() FlyoutPanelsUI.show('PrefsFlyoutPanel')
-    });
-/*
- * Temporarily disabled until we can have sync prefs together with the
- * Desktop browser's sync prefs.
-    // Sync
-    this.addEntry({
-        label: Strings.brand.GetStringFromName("syncBrandShortName"),
-        onselected: function() FlyoutPanelsUI.show('SyncFlyoutPanel')
-    });
-*/
-    // About
-    this.addEntry({
-        label: Strings.browser.GetStringFromName("aboutCharm1"),
-        onselected: function() FlyoutPanelsUI.show('AboutFlyoutPanel')
-    });
-    // Help
-    this.addEntry({
-        label: Strings.browser.GetStringFromName("helpOnlineCharm"),
-        onselected: function() {
-          let url = Services.urlFormatter.formatURLPref("app.support.baseURL");
-          BrowserUI.addAndShowTab(url, Browser.selectedTab);
-        }
-    });
-  },
-
-  observe: function SettingsCharm_observe(aSubject, aTopic, aData) {
-    if (aTopic == "metro-settings-entry-selected") {
-      let entry = this._entries.get(parseInt(aData, 10));
-      if (entry)
-        entry.onselected();
-    }
-  },
-
-  uninit: function SettingsCharm_uninit() {
-    Services.obs.removeObserver(this, "metro-settings-entry-selected");
-  }
-};
--- a/browser/metro/base/content/browser.xul
+++ b/browser/metro/base/content/browser.xul
@@ -16,16 +16,18 @@
 <!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd">
 %browserDTD;
 <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
 %brandDTD;
 <!ENTITY % prefsDTD SYSTEM "chrome://browser/locale/preferences.dtd">
 %prefsDTD;
 <!ENTITY % aboutPanelDTD SYSTEM "chrome://browser/locale/aboutPanel.dtd">
 %aboutPanelDTD;
+<!ENTITY % searchPanelDTD SYSTEM "chrome://browser/locale/searchPanel.dtd">
+%searchPanelDTD;
 #ifdef MOZ_SERVICES_SYNC
 <!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd">
 %syncBrandDTD;
 <!ENTITY % syncDTD SYSTEM "chrome://browser/locale/sync.dtd">
 %syncDTD;
 #endif
 ]>
 
@@ -681,16 +683,20 @@ Desktop browser's sync prefs.
                    label="&doNotTrack.options.doTrack;" value="0"/>
             <radio id="prefs-dnt-nopref" class="flyoutpanel-hack"
                    label="&doNotTrack.options.default;" value="-1"/>
           </radiogroup>
         </setting>
         <label class="text-link" href="https://www.mozilla.org/dnt">&doNotTrack.learnMoreLink;</label>
       </settings>
     </flyoutpanel>
+    <flyoutpanel id="search-flyoutpanel" class="flyout-narrow" headertext="&searchFlyoutHeader.title;">
+      <settings id="search-options" label="&searchSetting.title;">
+      </settings>
+    </flyoutpanel>
 
     <!-- Chrome touch selection overlay -->
     <box class="selection-overlay-hidden" id="chrome-selection-overlay"/>
 
     <box onclick="event.stopPropagation();" id="context-container" class="menu-container" hidden="true">
       <vbox id="context-popup" class="menu-popup">
         <richlistbox id="context-commands" bindingType="contextmenu" flex="1">
           <!-- priority="low" items are hidden by default when a context is being displayed
--- a/browser/metro/base/content/flyoutpanels/FlyoutPanelsUI.js
+++ b/browser/metro/base/content/flyoutpanels/FlyoutPanelsUI.js
@@ -17,16 +17,17 @@ let FlyoutPanelsUI = {
     Cu.import("resource://gre/modules/Services.jsm");
 
     this._isInitialized = true;
     let scriptContexts = {};
     let scripts =
           [
             ['AboutFlyoutPanel', 'chrome://browser/content/flyoutpanels/AboutFlyoutPanel.js'],
             ['PrefsFlyoutPanel', 'chrome://browser/content/flyoutpanels/PrefsFlyoutPanel.js'],
+            ['SearchFlyoutPanel', 'chrome://browser/content/flyoutpanels/SearchFlyoutPanel.js'],
 #ifdef MOZ_SERVICES_SYNC
             ['SyncFlyoutPanel', 'chrome://browser/content/flyoutpanels/SyncFlyoutPanel.js'],
 #endif
           ];
 
     scripts.forEach(function (aScript) {
       let [name, script] = aScript;
       XPCOMUtils.defineLazyGetter(FlyoutPanelsUI, name, function() {
new file mode 100644
--- /dev/null
+++ b/browser/metro/base/content/flyoutpanels/SearchFlyoutPanel.js
@@ -0,0 +1,60 @@
+// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
+/* 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";
+
+Components.utils.import("resource://gre/modules/Services.jsm");
+
+const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+
+let SearchFlyoutPanel = {
+  _isInitialized: false,
+  _hasShown: false,
+  init: function pv_init() {
+    if (this._isInitialized) {
+      Cu.reportError("Attempting to re-initialize PreferencesPanelView");
+      return;
+    }
+    this._topmostElement = document.getElementById("search-flyoutpanel");
+    this._isInitialized = true;
+  },
+
+  checked: function checked(aId) {
+    aId = aId.replace("search-", "");
+    Services.search.defaultEngine = this._engines[parseInt(aId)];
+    this.updateSearchEngines();
+  },
+
+  updateSearchEngines: function () {
+    // Clear the list
+    let setting = document.getElementById("search-options");
+    while(setting.hasChildNodes()) {
+      setting.removeChild(setting.firstChild);
+    }
+
+    // Build up the list and check the default
+    this._engines = Services.search.getVisibleEngines();
+    let defaultEngine = Services.search.defaultEngine;
+
+    this._engines.forEach(function (aEngine, aIndex) {
+      let radio = document.createElementNS(XUL_NS, "radio");
+      radio.setAttribute("id", "search-" + aIndex);
+      radio.setAttribute("label", aEngine.name);
+      radio.setAttribute("oncommand", "FlyoutPanelsUI.SearchFlyoutPanel.checked(this.id)");
+      if (defaultEngine == aEngine) {
+        radio.setAttribute("selected", true);
+      }
+      setting.appendChild(radio);
+    }.bind(this));
+  },
+
+  _show: function() {
+    if (!this._hasShown) {
+      this._hasShown = true;
+      this.updateSearchEngines();
+    }
+    this._topmostElement.show();
+  }
+};
new file mode 100644
--- /dev/null
+++ b/browser/metro/base/content/flyoutpanels/SettingsCharm.js
@@ -0,0 +1,76 @@
+
+/**
+ * Manage the contents of the Windows 8 "Settings" charm.
+ */
+var SettingsCharm = {
+  _entries: new Map(),
+  _nextId: 0,
+
+  /**
+   * Add a new item to the "Settings" menu in the Windows 8 charms.
+   * @param aEntry Object with a "label" property (string that will appear in the UI)
+   *    and an "onselected" property (function to be called when the user chooses this entry)
+   */
+  addEntry: function addEntry(aEntry) {
+    try {
+      let id = Services.metro.addSettingsPanelEntry(aEntry.label);
+      this._entries.set(id, aEntry);
+    } catch (e) {
+      // addSettingsPanelEntry does not work on non-Metro platforms
+      Cu.reportError(e);
+    }
+  },
+
+  init: function SettingsCharm_init() {
+    Services.obs.addObserver(this, "metro-settings-entry-selected", false);
+
+    // Options
+    this.addEntry({
+        label: Strings.browser.GetStringFromName("optionsCharm"),
+        onselected: function() FlyoutPanelsUI.show('PrefsFlyoutPanel')
+    });
+
+    // Search providers
+    this.addEntry({
+        label: Strings.browser.GetStringFromName("searchCharm"),
+        onselected: function() FlyoutPanelsUI.show('SearchFlyoutPanel')
+    });
+
+/*
+ * Temporarily disabled until we can have sync prefs together with the
+ * Desktop browser's sync prefs.
+    // Sync
+    this.addEntry({
+        label: Strings.brand.GetStringFromName("syncBrandShortName"),
+        onselected: function() FlyoutPanelsUI.show('SyncFlyoutPanel')
+    });
+*/
+
+    // About
+    this.addEntry({
+        label: Strings.browser.GetStringFromName("aboutCharm1"),
+        onselected: function() FlyoutPanelsUI.show('AboutFlyoutPanel')
+    });
+
+    // Help
+    this.addEntry({
+        label: Strings.browser.GetStringFromName("helpOnlineCharm"),
+        onselected: function() {
+          let url = Services.urlFormatter.formatURLPref("app.support.baseURL");
+          BrowserUI.addAndShowTab(url, Browser.selectedTab);
+        }
+    });
+  },
+
+  observe: function SettingsCharm_observe(aSubject, aTopic, aData) {
+    if (aTopic == "metro-settings-entry-selected") {
+      let entry = this._entries.get(parseInt(aData, 10));
+      if (entry)
+        entry.onselected();
+    }
+  },
+
+  uninit: function SettingsCharm_uninit() {
+    Services.obs.removeObserver(this, "metro-settings-entry-selected");
+  }
+};
--- a/browser/metro/base/jar.mn
+++ b/browser/metro/base/jar.mn
@@ -25,19 +25,24 @@ chrome.jar:
   content/bindings/flyoutpanel.xml             (content/bindings/flyoutpanel.xml)
   content/bindings/selectionoverlay.xml        (content/bindings/selectionoverlay.xml)
   content/bindings/cssthrobber.xml             (content/bindings/cssthrobber.xml)
   content/bindings/popup.xml                   (content/bindings/popup.xml)
   content/bindings/circularprogress.xml        (content/bindings/circularprogress.xml)
   content/bindings/notification.xml            (content/bindings/notification.xml)
   content/bindings/tabprompts.xml              (content/bindings/tabprompts.xml)
 
+  content/flyoutpanels/SettingsCharm.js        (content/flyoutpanels/SettingsCharm.js)
 * content/flyoutpanels/FlyoutPanelsUI.js       (content/flyoutpanels/FlyoutPanelsUI.js)
 * content/flyoutpanels/AboutFlyoutPanel.js     (content/flyoutpanels/AboutFlyoutPanel.js)
   content/flyoutpanels/PrefsFlyoutPanel.js     (content/flyoutpanels/PrefsFlyoutPanel.js)
+  content/flyoutpanels/SearchFlyoutPanel.js    (content/flyoutpanels/SearchFlyoutPanel.js)
+#ifdef MOZ_SERVICES_SYNC
+  content/flyoutpanels/SyncFlyoutPanel.js      (content/flyoutpanels/SyncFlyoutPanel.js)
+#endif
 
   content/helperui/AlertsHelper.js             (content/helperui/AlertsHelper.js)
   content/helperui/IndexedDB.js                (content/helperui/IndexedDB.js)
   content/helperui/MenuUI.js                   (content/helperui/MenuUI.js)
   content/helperui/OfflineApps.js              (content/helperui/OfflineApps.js)
   content/helperui/SelectHelperUI.js           (content/helperui/SelectHelperUI.js)
   content/helperui/SelectionHelperUI.js        (content/helperui/SelectionHelperUI.js)
   content/helperui/ChromeSelectionHandler.js   (content/helperui/ChromeSelectionHandler.js)
@@ -76,19 +81,16 @@ chrome.jar:
   content/Util.js                              (content/Util.js)
   content/bookmarks.js                         (content/bookmarks.js)
   content/exceptions.js                        (content/exceptions.js)
   content/downloads.js                         (content/downloads.js)
   content/Site.js                              (content/Site.js)
   content/TopSites.js                          (content/TopSites.js)
   content/console.js                           (content/console.js)
   content/dbg-metro-actors.js                  (content/dbg-metro-actors.js)
-#ifdef MOZ_SERVICES_SYNC
-  content/flyoutpanels/SyncFlyoutPanel.js      (content/flyoutpanels/SyncFlyoutPanel.js)
-#endif
   content/NavButtonSlider.js                   (content/NavButtonSlider.js)
   content/ContextUI.js                         (content/ContextUI.js)
   content/apzc.js                              (content/apzc.js)
 
 * content/Start.xul                            (content/startui/Start.xul)
 * content/startui-scripts.js                   (content/startui/startui-scripts.js)
   content/StartUI.js                           (content/startui/StartUI.js)
   content/BookmarksView.js                     (content/startui/BookmarksView.js)
--- a/browser/metro/locales/en-US/chrome/browser.properties
+++ b/browser/metro/locales/en-US/chrome/browser.properties
@@ -39,16 +39,17 @@ contextAppbar2.clear=Clear selection
 # Clear private data
 clearPrivateData.clearButton=Clear
 clearPrivateData.title=Clear Private Data
 clearPrivateData.message=Clear your private data?
 
 # Settings Charms
 aboutCharm1=About
 optionsCharm=Options
+searchCharm=Search
 helpOnlineCharm=Help (online)
 
 # General
 # LOCALIZATION NOTE (browserForSaveLocation): Title for the "Save..." file picker dialog
 browserForSaveLocation=Save Location
 # LOCALIZATION NOTE (browserForSaveLocation): Title for the "Open..." file picker dialog
 browserForOpenLocation=Open Location
 
new file mode 100644
--- /dev/null
+++ b/browser/metro/locales/en-US/chrome/searchPanel.dtd
@@ -0,0 +1,7 @@
+<!-- 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/. -->
+
+
+<!ENTITY searchFlyoutHeader.title  "Search">
+<!ENTITY searchSetting.title  "Default Search Provider">
--- a/browser/metro/locales/jar.mn
+++ b/browser/metro/locales/jar.mn
@@ -11,16 +11,17 @@
 % locale browser @AB_CD@ %locale/browser/
   locale/browser/aboutCertError.dtd       (%chrome/aboutCertError.dtd)
   locale/browser/browser.dtd              (%chrome/browser.dtd)
   locale/browser/browser.properties       (%chrome/browser.properties)
   locale/browser/region.properties        (%chrome/region.properties)
   locale/browser/config.dtd               (%chrome/config.dtd)
   locale/browser/preferences.dtd          (%chrome/preferences.dtd)
   locale/browser/aboutPanel.dtd           (%chrome/aboutPanel.dtd)
+  locale/browser/searchPanel.dtd          (%chrome/searchPanel.dtd)
   locale/browser/checkbox.dtd             (%chrome/checkbox.dtd)
   locale/browser/sync.dtd                 (%chrome/sync.dtd)
   locale/browser/sync.properties          (%chrome/sync.properties)
   locale/browser/passwordmgr.properties   (%chrome/passwordmgr.properties)
   locale/browser/phishing.dtd             (%chrome/phishing.dtd)
   locale/browser/crashprompt.properties   (%chrome/crashprompt.properties)
   locale/browser/aboutAddons.dtd          (%chrome/aboutAddons.dtd)
 
--- a/content/base/public/nsViewportInfo.h
+++ b/content/base/public/nsViewportInfo.h
@@ -20,20 +20,21 @@ static const int32_t  kViewportDefaultSc
 
 /**
  * Information retrieved from the <meta name="viewport"> tag. See
  * nsContentUtils::GetViewportInfo for more information on this functionality.
  */
 class MOZ_STACK_CLASS nsViewportInfo
 {
   public:
-    nsViewportInfo(const mozilla::ScreenIntSize& aDisplaySize) :
+    nsViewportInfo(const mozilla::ScreenIntSize& aDisplaySize,
+                   bool aAllowZoom = true) :
       mDefaultZoom(1.0),
       mAutoSize(true),
-      mAllowZoom(true)
+      mAllowZoom(aAllowZoom)
     {
         mSize = mozilla::gfx::RoundedToInt(mozilla::ScreenSize(aDisplaySize) / mDefaultZoom);
         mozilla::CSSToLayoutDeviceScale pixelRatio(1.0f);
         mMinZoom = pixelRatio * kViewportMinScale;
         mMaxZoom = pixelRatio * kViewportMaxScale;
         ConstrainViewportValues();
     }
 
--- a/content/base/src/moz.build
+++ b/content/base/src/moz.build
@@ -210,11 +210,11 @@ LOCAL_INCLUDES += [
     '/image/src',
     '/js/ipc',
     '/js/xpconnect/src',
     '/js/xpconnect/wrappers',
     '/layout/base',
     '/layout/generic',
     '/layout/style',
     '/layout/svg',
-    '/layout/xul/base/src',
+    '/layout/xul',
     '/netwerk/base/src',
 ]
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -6826,16 +6826,18 @@ nsIDocument::AdoptNode(nsINode& aAdopted
 }
 
 nsViewportInfo
 nsDocument::GetViewportInfo(const ScreenIntSize& aDisplaySize)
 {
   switch (mViewportType) {
   case DisplayWidthHeight:
     return nsViewportInfo(aDisplaySize);
+  case DisplayWidthHeightNoZoom:
+    return nsViewportInfo(aDisplaySize, /* allowZoom */ false);
   case Unknown:
   {
     nsAutoString viewport;
     GetHeaderData(nsGkAtoms::viewport, viewport);
     if (viewport.IsEmpty()) {
       // If the docType specifies that we are on a site optimized for mobile,
       // then we want to return specially crafted defaults for the viewport info.
       nsCOMPtr<nsIDOMDocumentType> docType;
@@ -6856,16 +6858,31 @@ nsDocument::GetViewportInfo(const Screen
       }
 
       nsAutoString handheldFriendly;
       GetHeaderData(nsGkAtoms::handheldFriendly, handheldFriendly);
       if (handheldFriendly.EqualsLiteral("true")) {
         mViewportType = DisplayWidthHeight;
         return nsViewportInfo(aDisplaySize);
       }
+
+      // Bug 940036. This is bad. When FirefoxOS was built, apps installed
+      // where not using the AsyncPanZoom code. As a result a lot of apps
+      // in the marketplace does not use it yet and instead are built to
+      // render correctly in FirefoxOS only. For a smooth transition the above
+      // code force installed apps to render as if they have a viewport with
+      // content="width=device-width, height=device-height, user-scalable=no".
+      // This could be safely remove once it is known that most apps in the
+      // marketplace use it and that users does not use an old version of the
+      // app that does not use it.
+      nsCOMPtr<nsIDocShell> docShell(mDocumentContainer);
+      if (docShell && docShell->GetIsApp()) {
+        mViewportType = DisplayWidthHeightNoZoom;
+        return nsViewportInfo(aDisplaySize, /* allowZoom */ false);
+      }
     }
 
     nsAutoString minScaleStr;
     GetHeaderData(nsGkAtoms::viewport_minimum_scale, minScaleStr);
 
     nsresult errorCode;
     mScaleMinFloat = LayoutDeviceToScreenScale(minScaleStr.ToFloat(&errorCode));
 
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -1385,16 +1385,17 @@ private:
 
   // Tracking for plugins in the document.
   nsTHashtable< nsPtrHashKey<nsIObjectLoadingContent> > mPlugins;
 
   nsRefPtr<mozilla::dom::UndoManager> mUndoManager;
 
   enum ViewportType {
     DisplayWidthHeight,
+    DisplayWidthHeightNoZoom,
     Specified,
     Unknown
   };
 
   ViewportType mViewportType;
 
   // These member variables cache information about the viewport so we don't have to
   // recalculate it each time.
--- a/content/canvas/src/moz.build
+++ b/content/canvas/src/moz.build
@@ -90,11 +90,11 @@ LOCAL_INCLUDES += [
     '/content/base/src',
     '/content/html/content/src',
     '/content/xul/content/src',
     '/dom/base',
     '/image/src',
     '/js/xpconnect/src',
     '/layout/generic',
     '/layout/style',
-    '/layout/xul/base/src',
+    '/layout/xul',
 ]
 
--- a/content/events/src/moz.build
+++ b/content/events/src/moz.build
@@ -82,17 +82,17 @@ LOCAL_INCLUDES += [
     '/content/base/src',
     '/content/html/content/src',
     '/content/xml/content/src',
     '/content/xul/content/src',
     '/dom/base',
     '/dom/settings',
     '/dom/src/storage',
     '/layout/generic',
-    '/layout/xul/base/src',
+    '/layout/xul',
     '/layout/xul/tree/',
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
     LOCAL_INCLUDES += [
         '/dom/wifi',
     ]
 
--- a/content/html/content/src/HTMLOptionElement.cpp
+++ b/content/html/content/src/HTMLOptionElement.cpp
@@ -189,53 +189,60 @@ HTMLOptionElement::BeforeSetAttr(int32_t
                                                     aValue, aNotify);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (aNamespaceID != kNameSpaceID_None || aName != nsGkAtoms::selected ||
       mSelectedChanged) {
     return NS_OK;
   }
 
+  bool defaultSelected = aValue;
+  // First make sure we actually set our mIsSelected state to reflect our new
+  // defaultSelected state.  If that turns out to be wrong,
+  // SetOptionsSelectedByIndex will fix it up.  But otherwise we can end up in a
+  // situation where mIsSelected is still false, but mSelectedChanged becomes
+  // true (later in this method, when we compare mIsSelected to
+  // defaultSelected), and then we start returning false for Selected() even
+  // though we're actually selected.
+  mIsSelected = defaultSelected;
+
   // We just changed out selected state (since we look at the "selected"
   // attribute when mSelectedChanged is false).  Let's tell our select about
   // it.
   HTMLSelectElement* selectInt = GetSelect();
   if (!selectInt) {
     return NS_OK;
   }
 
-  // Note that at this point mSelectedChanged is false and as long as that's
-  // true it doesn't matter what value mIsSelected has.
   NS_ASSERTION(!mSelectedChanged, "Shouldn't be here");
 
   bool inSetDefaultSelected = mIsInSetDefaultSelected;
   mIsInSetDefaultSelected = true;
 
   int32_t index = Index();
   uint32_t mask = HTMLSelectElement::SET_DISABLED;
-  bool defaultSelected = aValue;
   if (defaultSelected) {
     mask |= HTMLSelectElement::IS_SELECTED;
   }
 
   if (aNotify) {
     mask |= HTMLSelectElement::NOTIFY;
   }
 
-  // This should end up calling SetSelectedInternal, which we will allow to
-  // take effect so that parts of SetOptionsSelectedByIndex that might depend
-  // on it working don't get confused.
+  // This can end up calling SetSelectedInternal if our selected state needs to
+  // change, which we will allow to take effect so that parts of
+  // SetOptionsSelectedByIndex that might depend on it working don't get
+  // confused.
   selectInt->SetOptionsSelectedByIndex(index, index, mask);
 
   // Now reset our members; when we finish the attr set we'll end up with the
   // rigt selected state.
   mIsInSetDefaultSelected = inSetDefaultSelected;
-  // mIsSelected has already been set by SetOptionsSelectedByIndex.
-  // Possibly more than once; make sure our mSelectedChanged state is
-  // set correctly.
+  // mIsSelected might have been changed by SetOptionsSelectedByIndex.  Possibly
+  // more than once; make sure our mSelectedChanged state is set correctly.
   mSelectedChanged = mIsSelected != defaultSelected;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HTMLOptionElement::GetText(nsAString& aText)
 {
--- a/content/html/content/src/moz.build
+++ b/content/html/content/src/moz.build
@@ -174,13 +174,13 @@ LOCAL_INCLUDES += [
     '/dom/base',
     '/editor/libeditor/base',
     '/editor/libeditor/text',
     '/editor/txmgr/src',
     '/layout/forms',
     '/layout/generic',
     '/layout/style',
     '/layout/tables',
-    '/layout/xul/base/src',
+    '/layout/xul',
     '/netwerk/base/src',
     '/xpcom/ds',
 ]
 
--- a/content/html/content/test/mochitest.ini
+++ b/content/html/content/test/mochitest.ini
@@ -399,16 +399,17 @@ support-files =
 [test_mod_attributes_reflection.html]
 [test_mozaudiochannel.html]
 [test_named_options.html]
 [test_nested_invalid_fieldsets.html]
 [test_object_attributes_reflection.html]
 [test_object_plugin_nav.html]
 [test_ol_attributes_reflection.html]
 [test_option_defaultSelected.html]
+[test_option_selected_state.html]
 [test_param_attributes_reflection.html]
 [test_q_attributes_reflection.html]
 [test_restore_from_parser_fragment.html]
 [test_rowscollection.html]
 [test_srcdoc-2.html]
 [test_srcdoc.html]
 [test_style_attributes_reflection.html]
 [test_track.html]
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/test_option_selected_state.html
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=942648
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 942648</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=942648">Mozilla Bug 942648</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+  <select>
+    <option value="1">1</option>
+    <option id="e1" value="2">2</option>
+  </select>
+  <select>
+    <option value="1">1</option>
+    <option id="e2" selected value="2">2</option>
+  </select>
+  <select>
+    <option value="1">1</option>
+    <option id="e3" selected="" value="2">2</option>
+  </select>
+  <select>
+    <option value="1">1</option>
+    <option id="e4" selected="selected" value="2">2</option>
+  </select>
+</pre>
+  <script type="application/javascript">
+
+  /** Test for Bug 942648 **/
+SimpleTest.waitForExplicitFinish();
+  window.onload = function() {
+    var e1 = document.getElementById('e1');
+    var e2 = document.getElementById('e2');
+    var e3 = document.getElementById('e3');
+    var e4 = document.getElementById('e4');
+    ok(!e1.selected, "e1 should not be selected");
+    ok(e2.selected, "e2 should be selected");
+    ok(e3.selected, "e3 should be selected");
+    ok(e4.selected, "e4 should be selected");
+    e1.setAttribute('selected', 'selected');
+    e2.setAttribute('selected', 'selected');
+    e3.setAttribute('selected', 'selected');
+    e4.setAttribute('selected', 'selected');
+    ok(e1.selected, "e1 should now be selected");
+    ok(e2.selected, "e2 should still be selected");
+    ok(e3.selected, "e3 should still be selected");
+    ok(e4.selected, "e4 should still be selected");
+    SimpleTest.finish();
+  };
+  </script>
+</body>
+</html>
--- a/content/media/moz.build
+++ b/content/media/moz.build
@@ -159,17 +159,17 @@ if CONFIG['CPU_ARCH'] == 'arm' and CONFI
 MSVC_ENABLE_PGO = True
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'gklayout'
 LOCAL_INCLUDES += [
     '/content/base/src',
     '/layout/generic',
-    '/layout/xul/base/src',
+    '/layout/xul',
 ]
 
 if CONFIG['MOZ_DIRECTSHOW']:
     LOCAL_INCLUDES += [
         '/media/webrtc/trunk/webrtc/modules/video_capture/windows',
     ]
 
 DEFINES['MOZILLA_INTERNAL_API'] = True
--- a/content/svg/content/src/moz.build
+++ b/content/svg/content/src/moz.build
@@ -254,11 +254,11 @@ LOCAL_INCLUDES += [
     '/content/html/content/src',
     '/content/smil',
     '/content/xbl/src',
     '/content/xml/content/src',
     '/dom',
     '/layout/generic',
     '/layout/style',
     '/layout/svg',
-    '/layout/xul/base/src',
+    '/layout/xul',
 ]
 
--- a/content/xul/content/src/moz.build
+++ b/content/xul/content/src/moz.build
@@ -21,13 +21,13 @@ LOCAL_INCLUDES += [
     '/content/base/src',
     '/content/events/src',
     '/content/html/content/src',
     '/content/xbl/src',
     '/content/xml/content/src',
     '/content/xml/document/src',
     '/layout/generic',
     '/layout/style',
-    '/layout/xul/base/src',
+    '/layout/xul',
     '/xpcom/ds',
 ]
 
 FINAL_LIBRARY = 'gklayout'
--- a/content/xul/document/src/moz.build
+++ b/content/xul/document/src/moz.build
@@ -28,13 +28,13 @@ LOCAL_INCLUDES += [
     '/content/xml/document/src',
     '/content/xul/content/src',
     '/content/xul/templates/src',
     '/docshell/base',
     '/dom/base',
     '/layout/base',
     '/layout/generic',
     '/layout/style',
-    '/layout/xul/base/src',
+    '/layout/xul',
     '/xpcom/ds',
 ]
 
 FINAL_LIBRARY = 'gklayout'
--- a/content/xul/templates/src/nsXULContentUtils.cpp
+++ b/content/xul/templates/src/nsXULContentUtils.cpp
@@ -56,18 +56,16 @@
 #include "nsCollationCID.h"
 #include "nsILocale.h"
 #include "nsILocaleService.h"
 #include "nsIConsoleService.h"
 #include "nsEscape.h"
 
 using namespace mozilla;
 
-static NS_DEFINE_CID(kRDFServiceCID,        NS_RDFSERVICE_CID);
-
 //------------------------------------------------------------------------
 
 nsIRDFService* nsXULContentUtils::gRDF;
 nsIDateTimeFormat* nsXULContentUtils::gFormat;
 nsICollation *nsXULContentUtils::gCollation;
 
 #ifdef PR_LOGGING
 extern PRLogModuleInfo* gXULTemplateLog;
@@ -81,16 +79,17 @@ extern PRLogModuleInfo* gXULTemplateLog;
 
 //------------------------------------------------------------------------
 // Constructors n' stuff
 //
 
 nsresult
 nsXULContentUtils::Init()
 {
+    static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
     nsresult rv = CallGetService(kRDFServiceCID, &gRDF);
     if (NS_FAILED(rv)) {
         return rv;
     }
 
 #define XUL_RESOURCE(ident, uri)                              \
   PR_BEGIN_MACRO                                              \
    rv = gRDF->GetResource(NS_LITERAL_CSTRING(uri), &(ident)); \
--- a/content/xul/templates/src/nsXULTemplateResultStorage.cpp
+++ b/content/xul/templates/src/nsXULTemplateResultStorage.cpp
@@ -4,22 +4,21 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIServiceManager.h"
 #include "nsRDFCID.h"
 #include "nsIRDFService.h"
 #include "nsString.h"
 #include "nsXULTemplateResultStorage.h"
 
-static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
-
 NS_IMPL_ISUPPORTS1(nsXULTemplateResultStorage, nsIXULTemplateResult)
 
 nsXULTemplateResultStorage::nsXULTemplateResultStorage(nsXULTemplateResultSetStorage* aResultSet)
 {
+    static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
     nsCOMPtr<nsIRDFService> rdfService = do_GetService(kRDFServiceCID);
     rdfService->GetAnonymousResource(getter_AddRefs(mNode));
     mResultSet = aResultSet;
     if (aResultSet) {
         mResultSet->FillColumnValues(mValues);
     }
 }
 
--- a/docshell/base/moz.build
+++ b/docshell/base/moz.build
@@ -74,15 +74,15 @@ include('/ipc/chromium/chromium-config.m
 
 FINAL_LIBRARY = 'xul'
 LOCAL_INCLUDES += [
     '../shistory/src',
     '/content/base/src',
     '/dom/base',
     '/layout/base',
     '/layout/generic',
-    '/layout/xul/base/src',
+    '/layout/xul',
     '/netwerk/protocol/viewsource',
     '/xpcom/ds',
 ]
 
 if CONFIG['MOZ_TOOLKIT_SEARCH']:
     DEFINES['MOZ_TOOLKIT_SEARCH'] = True
--- a/dom/base/moz.build
+++ b/dom/base/moz.build
@@ -140,17 +140,17 @@ LOCAL_INCLUDES += [
     '../time',
     '/content/base/src',
     '/content/events/src',
     '/content/html/document/src',
     '/content/xbl/src',
     '/content/xul/document/src',
     '/layout/generic',
     '/layout/style',
-    '/layout/xul/base/src',
+    '/layout/xul',
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
     LOCAL_INCLUDES += [
         '../fmradio',
         '../system/gonk',
     ]
 
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -4492,19 +4492,17 @@ nsStorage2SH::NewEnumerate(nsIXPConnectW
   }
 
   nsTArray<nsString> *keys =
     (nsTArray<nsString> *)JSVAL_TO_PRIVATE(*statep);
 
   if (enum_op == JSENUMERATE_NEXT && keys->Length() != 0) {
     nsString& key = keys->ElementAt(0);
     JSString *str =
-      JS_NewUCStringCopyN(cx, reinterpret_cast<const jschar *>
-                                              (key.get()),
-                          key.Length());
+      JS_NewUCStringCopyN(cx, key.get(), key.Length());
     NS_ENSURE_TRUE(str, NS_ERROR_OUT_OF_MEMORY);
 
     JS_ValueToId(cx, STRING_TO_JSVAL(str), idp);
 
     keys->RemoveElementAt(0);
 
     return NS_OK;
   }
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -851,16 +851,55 @@ nsDOMWindowUtils::SendTouchEvent(const n
                                  uint32_t *aRys,
                                  float *aRotationAngles,
                                  float *aForces,
                                  uint32_t aCount,
                                  int32_t aModifiers,
                                  bool aIgnoreRootScrollFrame,
                                  bool *aPreventDefault)
 {
+  return SendTouchEventCommon(aType, aIdentifiers, aXs, aYs, aRxs, aRys,
+                              aRotationAngles, aForces, aCount, aModifiers,
+                              aIgnoreRootScrollFrame, false, aPreventDefault);
+}
+
+NS_IMETHODIMP
+nsDOMWindowUtils::SendTouchEventToWindow(const nsAString& aType,
+                                         uint32_t* aIdentifiers,
+                                         int32_t* aXs,
+                                         int32_t* aYs,
+                                         uint32_t* aRxs,
+                                         uint32_t* aRys,
+                                         float* aRotationAngles,
+                                         float* aForces,
+                                         uint32_t aCount,
+                                         int32_t aModifiers,
+                                         bool aIgnoreRootScrollFrame,
+                                         bool* aPreventDefault)
+{
+  return SendTouchEventCommon(aType, aIdentifiers, aXs, aYs, aRxs, aRys,
+                              aRotationAngles, aForces, aCount, aModifiers,
+                              aIgnoreRootScrollFrame, true, aPreventDefault);
+}
+
+NS_IMETHODIMP
+nsDOMWindowUtils::SendTouchEventCommon(const nsAString& aType,
+                                       uint32_t* aIdentifiers,
+                                       int32_t* aXs,
+                                       int32_t* aYs,
+                                       uint32_t* aRxs,
+                                       uint32_t* aRys,
+                                       float* aRotationAngles,
+                                       float* aForces,
+                                       uint32_t aCount,
+                                       int32_t aModifiers,
+                                       bool aIgnoreRootScrollFrame,
+                                       bool aToWindow,
+                                       bool* aPreventDefault)
+{
   if (!nsContentUtils::IsCallerChrome()) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   // get the widget to send the event to
   nsPoint offset;
   nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
   if (!widget) {
@@ -895,16 +934,37 @@ nsDOMWindowUtils::SendTouchEvent(const n
                                   LayoutDeviceIntPoint::ToUntyped(pt),
                                   nsIntPoint(aRxs[i], aRys[i]),
                                   aRotationAngles[i],
                                   aForces[i]);
     event.touches.AppendElement(t);
   }
 
   nsEventStatus status;
+  if (aToWindow) {
+    nsCOMPtr<nsIPresShell> presShell = presContext->PresShell();
+    if (!presShell) {
+      return NS_ERROR_FAILURE;
+    }
+
+    nsViewManager* viewManager = presShell->GetViewManager();
+    if (!viewManager) {
+      return NS_ERROR_FAILURE;
+    }
+
+    nsView* view = viewManager->GetRootView();
+    if (!view) {
+      return NS_ERROR_FAILURE;
+    }
+
+    status = nsEventStatus_eIgnore;
+    *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault);
+    return presShell->HandleEvent(view->GetFrame(), &event, false, &status);
+  }
+
   nsresult rv = widget->DispatchEvent(&event, status);
   *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault);
   return rv;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::SendKeyEvent(const nsAString& aType,
                                int32_t aKeyCode,
--- a/dom/base/nsDOMWindowUtils.h
+++ b/dom/base/nsDOMWindowUtils.h
@@ -43,12 +43,27 @@ protected:
                                   int32_t aClickCount,
                                   int32_t aModifiers,
                                   bool aIgnoreRootScrollFrame,
                                   float aPressure,
                                   unsigned short aInputSourceArg,
                                   bool aToWindow,
                                   bool *aPreventDefault);
 
+  NS_IMETHOD SendTouchEventCommon(const nsAString& aType,
+                                  uint32_t* aIdentifiers,
+                                  int32_t* aXs,
+                                  int32_t* aYs,
+                                  uint32_t* aRxs,
+                                  uint32_t* aRys,
+                                  float* aRotationAngles,
+                                  float* aForces,
+                                  uint32_t aCount,
+                                  int32_t aModifiers,
+                                  bool aIgnoreRootScrollFrame,
+                                  bool aToWindow,
+                                  bool* aPreventDefault);
+
+
   static mozilla::Modifiers GetWidgetModifiers(int32_t aModifiers);
 };
 
 #endif
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -1325,19 +1325,17 @@ nsJSContext::AddSupportsPrimitiveTojsval
 
       nsAutoString data;
 
       p->GetData(data);
 
       // cast is probably safe since wchar_t and jschar are expected
       // to be equivalent; both unsigned 16-bit entities
       JSString *str =
-        ::JS_NewUCStringCopyN(cx,
-                              reinterpret_cast<const jschar *>(data.get()),
-                              data.Length());
+        ::JS_NewUCStringCopyN(cx, data.get(), data.Length());
       NS_ENSURE_TRUE(str, NS_ERROR_OUT_OF_MEMORY);
 
       *aArgv = STRING_TO_JSVAL(str);
       break;
     }
     case nsISupportsPrimitive::TYPE_PRBOOL : {
       nsCOMPtr<nsISupportsPRBool> p(do_QueryInterface(argPrimitive));
       NS_ENSURE_TRUE(p, NS_ERROR_UNEXPECTED);
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -21,16 +21,19 @@ FINALIZE_HOOK_NAME = '_finalize'
 CONSTRUCT_HOOK_NAME = '_constructor'
 LEGACYCALLER_HOOK_NAME = '_legacycaller'
 HASINSTANCE_HOOK_NAME = '_hasInstance'
 NEWRESOLVE_HOOK_NAME = '_newResolve'
 ENUMERATE_HOOK_NAME= '_enumerate'
 ENUM_ENTRY_VARIABLE_NAME = 'strings'
 INSTANCE_RESERVED_SLOTS = 3
 
+def memberReservedSlot(member):
+    return "(DOM_INSTANCE_RESERVED_SLOTS + %d)" % member.slotIndex
+
 def replaceFileIfChanged(filename, newContents):
     """
     Read a copy of the old file, so that we don't touch it if it hasn't changed.
     Returns True if the file was updated, false otherwise.
     """
     oldFileContents = ""
     try:
         oldFile = open(filename, 'rb')
@@ -2422,46 +2425,96 @@ class CGWrapGlobalMethod(CGAbstractMetho
 
   // XXXkhuey can't do this yet until workers can lazy resolve.
   // JS_FireOnNewGlobalObject(aCx, obj);
 
   return obj;""" % (AssertInheritanceChain(self.descriptor),
                     self.descriptor.nativeType,
                     InitUnforgeableProperties(self.descriptor, self.properties))
 
-class CGUpdateMemberSlotsMethod(CGAbstractMethod):
+class CGUpdateMemberSlotsMethod(CGAbstractStaticMethod):
     def __init__(self, descriptor):
         args = [Argument('JSContext*', 'aCx'),
                 Argument('JS::Handle<JSObject*>', 'aWrapper'),
                 Argument(descriptor.nativeType + '*' , 'aObject')]
-        CGAbstractMethod.__init__(self, descriptor, 'UpdateMemberSlots', 'bool', args)
+        CGAbstractStaticMethod.__init__(self, descriptor, 'UpdateMemberSlots', 'bool', args)
 
     def definition_body(self):
         slotMembers = (m for m in self.descriptor.interface.members if
                        m.isAttr() and m.getExtendedAttribute("StoreInSlot"))
-        def slotIndex(member):
-            return member.slotIndex + INSTANCE_RESERVED_SLOTS
         storeSlots = (
             CGGeneric(
-                'static_assert(%d < js::shadow::Object::MAX_FIXED_SLOTS,\n'
+                'static_assert(%s < js::shadow::Object::MAX_FIXED_SLOTS,\n'
                 '              "Not enough fixed slots to fit \'%s.%s\'");\n'
                 "if (!get_%s(aCx, aWrapper, aObject, args)) {\n"
                 "  return false;\n"
                 "}\n"
-                "js::SetReservedSlot(aWrapper, %d, args.rval());" %
-                (slotIndex(m), self.descriptor.interface.identifier.name,
-                 m.identifier.name, m.identifier.name, slotIndex(m)))
+                "// Getter handled setting our reserved slots" %
+                (memberReservedSlot(m),
+                 self.descriptor.interface.identifier.name,
+                 m.identifier.name, m.identifier.name))
             for m in slotMembers)
         body = CGList(storeSlots, "\n\n")
         body.prepend(CGGeneric("JS::Rooted<JS::Value> temp(aCx);\n"
                                "JSJitGetterCallArgs args(&temp);"))
         body.append(CGGeneric("return true;"))
 
         return CGIndenter(body).define()
 
+class CGClearCachedValueMethod(CGAbstractMethod):
+    def __init__(self, descriptor, member):
+        self.member = member
+        # If we're StoreInSlot, we'll need to call the getter
+        if member.getExtendedAttribute("StoreInSlot"):
+            args = [Argument('JSContext*', 'aCx')]
+            returnType = 'bool'
+        else:
+            args = []
+            returnType = 'void'
+        args.append(Argument(descriptor.nativeType + '*', 'aObject'))
+        name = ("ClearCached%sValue" % MakeNativeName(member.identifier.name))
+        CGAbstractMethod.__init__(self, descriptor, name, returnType, args)
+
+    def definition_body(self):
+        slotIndex = memberReservedSlot(self.member)
+        if self.member.getExtendedAttribute("StoreInSlot"):
+            # We have to root things and save the old value in case
+            # regetting fails, so we can restore it.
+            declObj = "JS::Rooted<JSObject*> obj(aCx);"
+            noopRetval = " true"
+            saveMember = (
+                "JS::Rooted<JS::Value> oldValue(aCx, js::GetReservedSlot(obj, %s));\n" %
+                slotIndex)
+            regetMember = ("\n"
+                           "JS::Rooted<JS::Value> temp(aCx);\n"
+                           "JSJitGetterCallArgs args(&temp);\n"
+                           "if (!get_%s(aCx, obj, aObject, args)) {\n"
+                           "  js::SetReservedSlot(obj, %s, oldValue);\n"
+                           "  nsJSUtils::ReportPendingException(aCx);\n"
+                           "  return false;\n"
+                           "}\n"
+                           "return true;" % (self.member.identifier.name, slotIndex))
+        else:
+            declObj = "JSObject* obj;"
+            noopRetval = ""
+            saveMember = ""
+            regetMember = ""
+
+        return CGIndenter(CGGeneric(
+                "%s\n"
+                "obj = aObject->GetWrapper();\n"
+                "if (!obj) {\n"
+                "  return%s;\n"
+                "}\n"
+                "%s"
+                "js::SetReservedSlot(obj, %s, JS::UndefinedValue());"
+                "%s"
+                % (declObj, noopRetval, saveMember, slotIndex, regetMember)
+                )).define()
+
 builtinNames = {
     IDLType.Tags.bool: 'bool',
     IDLType.Tags.int8: 'int8_t',
     IDLType.Tags.int16: 'int16_t',
     IDLType.Tags.int32: 'int32_t',
     IDLType.Tags.int64: 'int64_t',
     IDLType.Tags.uint8: 'uint8_t',
     IDLType.Tags.uint16: 'uint16_t',
@@ -4067,16 +4120,36 @@ class CGArgumentConverter(CGThing):
                         }
                     )), 4).define()
 
         variadicConversion += ("\n"
                                "  }\n"
                                "}")
         return variadicConversion
 
+def getMaybeWrapValueFuncForType(type):
+    # Callbacks might actually be DOM objects; nothing prevents a page from
+    # doing that.
+    if type.isCallback() or type.isCallbackInterface() or type.isObject():
+        if type.nullable():
+            return "MaybeWrapObjectOrNullValue"
+        return "MaybeWrapObjectValue"
+    # Spidermonkey interfaces are never DOM objects
+    if type.isSpiderMonkeyInterface():
+        if type.nullable():
+            return "MaybeWrapNonDOMObjectOrNullValue"
+        return "MaybeWrapNonDOMObjectValue"
+    if type.isAny():
+        return "MaybeWrapValue"
+
+    # For other types, just go ahead an fall back on MaybeWrapValue for now:
+    # it's always safe to do, and shouldn't be particularly slow for any of
+    # them
+    return "MaybeWrapValue"
+
 sequenceWrapLevel = 0
 
 def getWrapTemplateForType(type, descriptorProvider, result, successCode,
                            returnsNewObject, exceptionCode, typedArraysAreStructs):
     """
     Reflect a C++ value stored in "result", of IDL type "type" into JS.  The
     "successCode" is the code to run once we have successfully done the
     conversion and must guarantee that execution of the conversion template
@@ -4103,40 +4176,29 @@ def getWrapTemplateForType(type, descrip
     """
     if successCode is None:
         successCode = "return true;"
 
     # We often want exceptionCode to be indented, since it often appears in an
     # if body.
     exceptionCodeIndented = CGIndenter(CGGeneric(exceptionCode))
 
-    def setValue(value, callWrapValue=None):
+    def setValue(value, wrapAsType=None):
         """
         Returns the code to set the jsval to value.
 
-        "callWrapValue" can be set to the following values:
-          * None: no wrapping will be done.
-          * "object": will wrap using MaybeWrapObjectValue.
-          * "objectOrNull": will wrap using MaybeWrapObjectOrNullValue.
-          * "nonDOMObject": will wrap using MaybeWrapNonDOMObjectValue.
-          * "nonDOMObjectOrNull": will wrap using MaybeWrapNonDOMObjectOrNullValue
-          * "value": will wrap using MaybeWrapValue.
+        If wrapAsType is not None, then will wrap the resulting value using the
+        function that getMaybeWrapValueFuncForType(wrapAsType) returns.
+        Otherwise, no wrapping will be done.
         """
-        if not callWrapValue:
+        if wrapAsType is None:
             tail = successCode
         else:
-            methodMap = {
-                "object": "MaybeWrapObjectValue",
-                "objectOrNull": "MaybeWrapObjectOrNullValue",
-                "nonDOMObject": "MaybeWrapNonDOMObjectValue",
-                "nonDOMObjectOrNull": "MaybeWrapNonDOMObjectOrNullValue",
-                "value": "MaybeWrapValue"
-                }
             tail = (("if (!%s(cx, ${jsvalHandle})) {\n"
-                     "%s\n" % (methodMap[callWrapValue],
+                     "%s\n" % (getMaybeWrapValueFuncForType(wrapAsType),
                                exceptionCodeIndented.define())) +
                     "}\n" +
                     successCode)
         return ("${jsvalRef}.set(%s);\n" +
                 tail) % (value)
 
     def wrapAndSetPtr(wrapCall, failureCode=None):
         """
@@ -4289,58 +4351,50 @@ if (!returnArray) {
         "strings" : type.unroll().inner.identifier.name + "Values::" + ENUM_ENTRY_VARIABLE_NAME,
         "exceptionCode" : CGIndenter(exceptionCodeIndented).define() } +
         CGIndenter(CGGeneric(setValue("JS::StringValue(resultStr)"))).define() +
                       "\n}")
 
         if type.nullable():
             conversion = CGIfElseWrapper(
                 "%s.IsNull()" % result,
-                CGGeneric(setValue("JS::NullValue()", False)),
+                CGGeneric(setValue("JS::NullValue()")),
                 CGGeneric(conversion)).define()
         return conversion, False
 
     if type.isCallback() or type.isCallbackInterface():
         wrapCode = setValue(
             "JS::ObjectValue(*GetCallbackFromCallbackObject(%(result)s))",
-            "object")
+            wrapAsType=type)
         if type.nullable():
             wrapCode = (
                 "if (%(result)s) {\n" +
                 CGIndenter(CGGeneric(wrapCode)).define() + "\n"
                 "} else {\n" +
                 CGIndenter(CGGeneric(setValue("JS::NullValue()"))).define() + "\n"
                 "}")
         wrapCode = wrapCode % { "result": result }
         return wrapCode, False
 
     if type.isAny():
         # See comments in WrapNewBindingObject explaining why we need
         # to wrap here.
-        # NB: setValue(..., True) calls JS_WrapValue(), so is fallible
-        return (setValue(result, "value"), False)
+        # NB: setValue(..., type-that-is-any) calls JS_WrapValue(), so is fallible
+        return (setValue(result, wrapAsType=type), False)
 
     if (type.isObject() or (type.isSpiderMonkeyInterface() and
                             not typedArraysAreStructs)):
         # See comments in WrapNewBindingObject explaining why we need
         # to wrap here.
         if type.nullable():
             toValue = "JS::ObjectOrNullValue(%s)"
-            if type.isSpiderMonkeyInterface():
-                wrapType = "nonDOMObjectOrNull"
-            else:
-                wrapType = "objectOrNull"
         else:
             toValue = "JS::ObjectValue(*%s)"
-            if type.isSpiderMonkeyInterface():
-                wrapType = "nonDOMObject"
-            else:
-                wrapType = "object"
-        # NB: setValue(..., True) calls JS_WrapValue(), so is fallible
-        return (setValue(toValue % result, wrapType), False)
+        # NB: setValue(..., some-object-type) calls JS_WrapValue(), so is fallible
+        return (setValue(toValue % result, wrapAsType=type), False)
 
     if not (type.isUnion() or type.isPrimitive() or type.isDictionary() or
             type.isDate() or
             (type.isSpiderMonkeyInterface() and typedArraysAreStructs)):
         raise TypeError("Need to learn to wrap %s" % type)
 
     if type.nullable():
         (recTemplate, recInfal) = getWrapTemplateForType(type.inner, descriptorProvider,
@@ -4350,19 +4404,19 @@ if (!returnArray) {
         return ("if (%s.IsNull()) {\n" % result +
                 CGIndenter(CGGeneric(setValue("JSVAL_NULL"))).define() + "\n" +
                 "}\n" + recTemplate, recInfal)
 
     if type.isSpiderMonkeyInterface():
         assert typedArraysAreStructs
         # See comments in WrapNewBindingObject explaining why we need
         # to wrap here.
-        # NB: setValue(..., True) calls JS_WrapValue(), so is fallible
+        # NB: setValue(..., some-object-type) calls JS_WrapValue(), so is fallible
         return (setValue("JS::ObjectValue(*%s.Obj())" % result,
-                         "nonDOMObject"), False)
+                         wrapAsType=type), False)
 
     if type.isUnion():
         return (wrapAndSetPtr("%s.ToJSVal(cx, ${obj}, ${jsvalHandle})" % result),
                 False)
 
     if type.isDictionary():
         return (wrapAndSetPtr("%s.ToObject(cx, ${obj}, ${jsvalHandle})" % result),
                 False)
@@ -5017,19 +5071,55 @@ if (!${obj}) {
         returnsNewObject = memberReturnsNewObject(self.idlNode)
         if returnsNewObject:
             # We better be returning addrefed things!
             assert(isResultAlreadyAddRefed(self.extendedAttributes) or
                    # NewObject can return raw pointers to owned objects
                    (self.returnType.isGeckoInterface() and
                     self.descriptor.getDescriptor(self.returnType.unroll().inner.identifier.name).nativeOwnership == 'owned'))
 
+        if self.idlNode.isAttr() and self.idlNode.slotIndex is not None:
+            # For the case of Cached attributes, go ahead and preserve our
+            # wrapper if needed.  We need to do this because otherwise the
+            # wrapper could get garbage-collected and the cached value would
+            # suddenly disappear, but the whole premise of cached values is that
+            # they never change without explicit action on someone's part.  We
+            # don't do this for StoreInSlot, since those get dealt with during
+            # wrapper setup, and failure would involve us trying to clear an
+            # already-preserved wrapper.
+            if (self.idlNode.getExtendedAttribute("Cached") and
+                self.descriptor.wrapperCache):
+                preserveWrapper = "  PreserveWrapper(self);\n"
+            else:
+                preserveWrapper = ""
+            successCode = (
+                "// Be careful here: Have to wrap the value into the\n"
+                "// compartment of reflector before storing, since we might\n"
+                "// be coming in via Xrays and the value is already in the\n"
+                "// caller compartment.\n"
+                "{ // Scope for tempVal\n"
+                "  JS::Rooted<JS::Value> tempVal(cx, args.rval());\n"
+                "  JSAutoCompartment ac(cx, reflector);\n"
+                "  if (!%s(cx, &tempVal)) {\n"
+                "    return false;\n"
+                "  }\n"
+                "  js::SetReservedSlot(reflector, %s, tempVal);\n"
+                "%s"
+                "}\n"
+                "return true;" %
+                (getMaybeWrapValueFuncForType(self.idlNode.type),
+                 memberReservedSlot(self.idlNode), preserveWrapper))
+        else:
+            successCode = None
+
         resultTemplateValues = { 'jsvalRef': 'args.rval()',
                                  'jsvalHandle': 'args.rval()',
-                                 'returnsNewObject': returnsNewObject}
+                                 'returnsNewObject': returnsNewObject,
+                                 'successCode': successCode,
+                                 }
         try:
             return wrapForType(self.returnType, self.descriptor,
                                resultTemplateValues)
         except MethodNotNewObjectError, err:
             assert not returnsNewObject
             raise TypeError("%s being returned from non-NewObject method or property %s.%s" %
                             (err.typename,
                              self.descriptor.interface.identifier.name,
@@ -5855,18 +5945,46 @@ class CGSpecializedGetter(CGAbstractStat
                  Argument('JS::Handle<JSObject*>', 'obj'),
                  Argument('%s*' % descriptor.nativeType, 'self'),
                  Argument('JSJitGetterCallArgs', 'args') ]
         CGAbstractStaticMethod.__init__(self, descriptor, name, "bool", args)
 
     def definition_body(self):
         nativeName = CGSpecializedGetter.makeNativeName(self.descriptor,
                                                         self.attr)
-        return CGIndenter(CGGetterCall(self.attr.type, nativeName,
-                                       self.descriptor, self.attr)).define()
+        if self.attr.slotIndex is not None:
+            if self.descriptor.hasXPConnectImpls:
+                raise TypeError("Interface '%s' has XPConnect impls, so we "
+                                "can't use our slot for property '%s'!" %
+                                (self.descriptor.interface.identifier.name,
+                                 self.attr.identifier.name))
+            prefix = (
+                "  // Have to either root across the getter call or reget after.\n"
+                "  JS::Rooted<JSObject*> reflector(cx);\n"
+                "  // Safe to do an unchecked unwrap, since we've gotten this far.\n"
+                "  // Also make sure to unwrap outer windows, since we want the\n"
+                "  // real DOM object.\n"
+                "  reflector = IsDOMObject(obj) ? obj : js::UncheckedUnwrap(obj, /* stopAtOuter = */ false);\n"
+                "  {\n"
+                "    // Scope for cachedVal\n"
+                "    JS::Value cachedVal = js::GetReservedSlot(reflector, %s);\n"
+                "    if (!cachedVal.isUndefined()) {\n"
+                "      args.rval().set(cachedVal);\n"
+                "      // The cached value is in the compartment of reflector,\n"
+                "      // so wrap into the caller compartment as needed.\n"
+                "      return %s(cx, args.rval());\n"
+                "    }\n"
+                "  }\n\n" % (memberReservedSlot(self.attr),
+                             getMaybeWrapValueFuncForType(self.attr.type)))
+        else:
+            prefix = ""
+
+        return (prefix +
+                CGIndenter(CGGetterCall(self.attr.type, nativeName,
+                                        self.descriptor, self.attr)).define())
 
     @staticmethod
     def makeNativeName(descriptor, attr):
         name = attr.identifier.name
         nativeName = MakeNativeName(descriptor.binaryNames.get(name, name))
         # resultOutParam does not depend on whether resultAlreadyAddRefed is set
         (_, resultOutParam, _, _) = getRetvalDeclarationForType(attr.type,
                                                                 descriptor,
@@ -6063,17 +6181,17 @@ class CGMemberJITInfo(CGThing):
                 "  { %s },\n"
                 "  %s,\n"
                 "  %s,\n"
                 "  JSJitInfo::%s,\n"
                 "  %s,  /* isInfallible. False in setters. */\n"
                 "  %s,  /* isMovable.  Not relevant for setters. */\n"
                 "  JSJitInfo::%s,  /* aliasSet.  Not relevant for setters. */\n"
                 "  %s,  /* hasSlot.  Only relevant for getters. */\n"
-                "  %d,  /* Reserved slot index, if we're stored in a slot, else 0. */\n"
+                "  %s,  /* Reserved slot index, if we're stored in a slot, else 0. */\n"
                 "  %s,  /* returnType.  Not relevant for setters. */\n"
                 "  %s,  /* argTypes.  Only relevant for methods */\n"
                 "  nullptr /* parallelNative */\n"
                 "};\n" % (argTypesDecl, infoName, opName, protoID, depth,
                           opType, failstr, movablestr, aliasSet, slotStr,
                           slotIndex, returnType, argTypes))
 
     def define(self):
@@ -6092,38 +6210,37 @@ class CGMemberJITInfo(CGThing):
                 aliasSet = "AliasDOMSets"
             else:
                 aliasSet = "AliasEverything"
             movable = getterpure and getterinfal
 
             getterinfal = getterinfal and infallibleForMember(self.member, self.member.type, self.descriptor)
             isInSlot = self.member.getExtendedAttribute("StoreInSlot")
             if isInSlot:
-                slotIndex = INSTANCE_RESERVED_SLOTS + self.member.slotIndex;
-                if slotIndex >= 16 : # JS engine currently allows 16 fixed slots
-                    raise TypeError("Make sure we can actually have this many "
-                                    "fixed slots, please!")
+                slotIndex = memberReservedSlot(self.member);
+                # We'll statically assert that this is not too big in
+                # CGUpdateMemberSlotsMethod
             else:
-                slotIndex = 0
+                slotIndex = "0"
 
             result = self.defineJitInfo(getterinfo, getter, "Getter",
                                         getterinfal, movable, aliasSet,
                                         isInSlot, slotIndex,
                                         [self.member.type], None)
             if (not self.member.readonly or
                 self.member.getExtendedAttribute("PutForwards") is not None or
                 self.member.getExtendedAttribute("Replaceable") is not None):
                 setterinfo = ("%s_setterinfo" % self.member.identifier.name)
                 # Actually a JSJitSetterOp, but JSJitGetterOp is first in the
                 # union.
                 setter = ("(JSJitGetterOp)set_%s" % self.member.identifier.name)
                 # Setters are always fallible, since they have to do a typed unwrap.
                 result += self.defineJitInfo(setterinfo, setter, "Setter",
                                              False, False, "AliasEverything",
-                                             False, 0,
+                                             False, "0",
                                              [BuiltinTypes[IDLBuiltinType.Types.void]],
                                              None)
             return result
         if self.member.isMethod():
             methodinfo = ("%s_methodinfo" % self.member.identifier.name)
             name = CppKeywords.checkMethodName(self.member.identifier.name)
             # Actually a JSJitMethodOp, but JSJitGetterOp is first in the union.
             method = ("(JSJitGetterOp)%s" % name)
@@ -6154,17 +6271,17 @@ class CGMemberJITInfo(CGThing):
                 else:
                     args = None
 
             if args:
                 aliasSet = "AliasDOMSets"
             else:
                 aliasSet = "AliasEverything"
             result = self.defineJitInfo(methodinfo, method, "Method",
-                                        methodInfal, False, aliasSet, False, 0,
+                                        methodInfal, False, aliasSet, False, "0",
                                         [s[0] for s in sigs], args)
             return result
         raise TypeError("Illegal member type to CGPropertyJITInfo")
 
     @staticmethod
     def getJSReturnTypeTag(t):
         if t.nullable():
             # Sometimes it might return null, sometimes not
@@ -8473,16 +8590,23 @@ class CGDescriptor(CGThing):
                 cgThings.append(CGWrapGlobalMethod(descriptor, properties))
             elif descriptor.wrapperCache:
                 cgThings.append(CGWrapWithCacheMethod(descriptor, properties))
                 cgThings.append(CGWrapMethod(descriptor))
             else:
                 cgThings.append(CGWrapNonWrapperCacheMethod(descriptor,
                                                             properties))
 
+        # If we're not wrappercached, we don't know how to clear our
+        # cached values, since we can't get at the JSObject.
+        if descriptor.wrapperCache:
+            cgThings.extend(CGClearCachedValueMethod(descriptor, m) for
+                            m in descriptor.interface.members if
+                            m.isAttr() and m.slotIndex is not None)
+
         # CGCreateInterfaceObjectsMethod needs to come after our
         # CGDOMJSClass, if any.
         cgThings.append(CGCreateInterfaceObjectsMethod(descriptor, properties))
 
         # CGGetProtoObjectMethod and CGGetConstructorObjectMethod need
         # to come after CGCreateInterfaceObjectsMethod.
         if descriptor.interface.hasInterfacePrototypeObject():
             cgThings.append(CGGetProtoObjectMethod(descriptor))
@@ -8791,17 +8915,17 @@ if (""",
 
         if self.needToInitIds:
             methods.append(self.initIdsMethod())
 
         methods.append(self.initMethod())
         methods.append(self.initFromJSONMethod())
         try:
             methods.append(self.toObjectMethod())
-        except MethodNotCreatorError:
+        except MethodNotNewObjectError:
             # If we can't have a ToObject() because one of our members can only
             # be returned from [NewObject] methods, then just skip generating
             # ToObject().
             pass
         methods.append(self.traceDictionaryMethod())
 
         if CGDictionary.isDictionaryCopyConstructible(d):
             disallowCopyConstruction = False
@@ -9325,16 +9449,23 @@ class CGBindingRoot(CGThing):
                 return False
             try:
                 typeDesc = provider.getDescriptor(type.inner.identifier.name)
             except NoSuchDescriptorError:
                 return False
             return typeDesc.hasXPConnectImpls
         addHeaderBasedOnTypes("nsDOMQS.h", checkForXPConnectImpls)
 
+        def descriptorClearsPropsInSlots(descriptor):
+            if not descriptor.wrapperCache:
+                return False
+            return any(m.isAttr() and m.getExtendedAttribute("StoreInSlot")
+                       for m in descriptor.interface.members)
+        bindingHeaders["nsJSUtils.h"] = any(descriptorClearsPropsInSlots(d) for d in descriptors)
+
         # Do codegen for all the enums
         enums = config.getEnums(webIDLFile)
         cgthings = [ CGEnum(e) for e in enums ]
 
         hasCode = (descriptors or callbackDescriptors or dictionaries or
                    mainCallbacks or workerCallbacks)
         bindingHeaders["mozilla/dom/BindingUtils.h"] = hasCode
         bindingHeaders["mozilla/dom/OwningNonNull.h"] = hasCode
--- a/dom/bindings/JSSlots.h
+++ b/dom/bindings/JSSlots.h
@@ -20,16 +20,20 @@
 #define DOM_XRAY_EXPANDO_SLOT 1
 
 // We use slot 2 for holding either a JS::ObjectValue which points to the cached
 // SOW or JS::UndefinedValue if this class doesn't need SOWs. This is not safe
 // for globals until bug 760095 is fixed, so that bug blocks converting Window
 // to new bindings.
 #define DOM_OBJECT_SLOT_SOW 2
 
+// The total number of slots non-proxy DOM objects use by default.
+// Specific objects may have more for storing cached values.
+#define DOM_INSTANCE_RESERVED_SLOTS 3
+
 // NOTE: This is baked into the Ion JIT as 0 in codegen for LGetDOMProperty and
 // LSetDOMProperty. Those constants need to be changed accordingly if this value
 // changes.
 #define DOM_PROTO_INSTANCE_CLASS_SLOT 0
 
 // Interface objects store a number of reserved slots equal to
 // DOM_INTERFACE_SLOTS_BASE + number of named constructors.
 #define DOM_INTERFACE_SLOTS_BASE (DOM_XRAY_EXPANDO_SLOT + 1)
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -656,20 +656,23 @@ class IDLInterface(IDLObjectWithScope):
         for member in self.members:
             if (member.isAttr() and member.isUnforgeable() and
                 not hasattr(member, "originatingInterface")):
                 member.originatingInterface = self
 
         # Compute slot indices for our members before we pull in
         # unforgeable members from our parent.
         for member in self.members:
-            if member.isAttr() and member.getExtendedAttribute("StoreInSlot"):
+            if (member.isAttr() and
+                (member.getExtendedAttribute("StoreInSlot") or
+                 member.getExtendedAttribute("Cached"))):
                 member.slotIndex = self.totalMembersInSlots
                 self.totalMembersInSlots += 1
-                self._ownMembersInSlots += 1
+                if member.getExtendedAttribute("StoreInSlot"):
+                    self._ownMembersInSlots += 1
 
         if self.parent:
             # Make sure we don't shadow any of the [Unforgeable] attributes on
             # our ancestor interfaces.  We don't have to worry about
             # consequential interfaces here, because those have already been
             # imported into the relevant .members lists.  And we don't have to
             # worry about anything other than our parent, because it has already
             # imported its ancestors unforgeable attributes into its member
@@ -2616,17 +2619,17 @@ class IDLAttribute(IDLInterfaceMember):
         self.readonly = readonly
         self.inherit = inherit
         self.static = static
         self.lenientThis = False
         self._unforgeable = False
         self.stringifier = stringifier
         self.enforceRange = False
         self.clamp = False
-        self.slotIndex = 0
+        self.slotIndex = None
 
         if static and identifier.name == "prototype":
             raise WebIDLError("The identifier of a static attribute must not be 'prototype'",
                               [location])
 
         if readonly and inherit:
             raise WebIDLError("An attribute cannot be both 'readonly' and 'inherit'",
                               [self.location])
@@ -2644,19 +2647,19 @@ class IDLAttribute(IDLInterfaceMember):
             assert not isinstance(t, IDLUnresolvedType)
             assert not isinstance(t, IDLTypedefType)
             assert not isinstance(t.name, IDLUnresolvedIdentifier)
             self.type = t
 
         if self.type.isDictionary():
             raise WebIDLError("An attribute cannot be of a dictionary type",
                               [self.location])
-        if self.type.isSequence():
-            raise WebIDLError("An attribute cannot be of a sequence type",
-                              [self.location])
+        if self.type.isSequence() and not self.getExtendedAttribute("Cached"):
+            raise WebIDLError("A non-cached attribute cannot be of a sequence "
+                              "type", [self.location])
         if self.type.isUnion():
             for f in self.type.unroll().flatMemberTypes:
                 if f.isDictionary():
                     raise WebIDLError("An attribute cannot be of a union "
                                       "type if one of its member types (or "
                                       "one of its member types's member "
                                       "types, and so on) is a dictionary "
                                       "type", [self.location, f.location])
@@ -2670,16 +2673,24 @@ class IDLAttribute(IDLInterfaceMember):
             raise WebIDLError("An attribute with [PutForwards] must have an "
                               "interface type as its type", [self.location])
 
         if not self.type.isInterface() and self.getExtendedAttribute("SameObject"):
             raise WebIDLError("An attribute with [SameObject] must have an "
                               "interface type as its type", [self.location])
 
     def validate(self):
+        if ((self.getExtendedAttribute("Cached") or
+             self.getExtendedAttribute("StoreInSlot")) and
+            not self.getExtendedAttribute("Constant") and
+            not self.getExtendedAttribute("Pure")):
+            raise WebIDLError("Cached attributes and attributes stored in "
+                              "slots must be constant or pure, since the "
+                              "getter won't always be called.",
+                              [self.location])
         pass
 
     def handleExtendedAttribute(self, attr):
         identifier = attr.identifier()
         if identifier == "TreatNonCallableAsNull":
             raise WebIDLError("TreatNonCallableAsNull cannot be specified on attributes",
                               [attr.location, self.location])
         elif identifier == "SetterThrows" and self.readonly:
@@ -2748,26 +2759,35 @@ class IDLAttribute(IDLInterfaceMember):
                 raise WebIDLError("[EnforceRange] used on a readonly attribute",
                                   [attr.location, self.location])
             self.enforceRange = True
         elif identifier == "Clamp":
             if self.readonly:
                 raise WebIDLError("[Clamp] used on a readonly attribute",
                                   [attr.location, self.location])
             self.clamp = True
+        elif identifier == "StoreInSlot":
+            if self.getExtendedAttribute("Cached"):
+                raise WebIDLError("[StoreInSlot] and [Cached] must not be "
+                                  "specified on the same attribute",
+                                  [attr.location, self.location])
+        elif identifier == "Cached":
+            if self.getExtendedAttribute("StoreInSlot"):
+                raise WebIDLError("[Cached] and [StoreInSlot] must not be "
+                                  "specified on the same attribute",
+                                  [attr.location, self.location])
         elif (identifier == "Pref" or
               identifier == "SetterThrows" or
               identifier == "Pure" or
               identifier == "Throws" or
               identifier == "GetterThrows" or
               identifier == "ChromeOnly" or
               identifier == "SameObject" or
               identifier == "Constant" or
               identifier == "Func" or
-              identifier == "StoreInSlot" or
               identifier == "NewObject"):
             # Known attributes that we don't need to do anything with here
             pass
         else:
             raise WebIDLError("Unknown extended attribute %s on attribute" % identifier,
                               [attr.location])
         IDLInterfaceMember.handleExtendedAttribute(self, attr)
 
--- a/dom/bindings/test/TestBindingHeader.h
+++ b/dom/bindings/test/TestBindingHeader.h
@@ -163,16 +163,17 @@ public:
   int8_t ReceiveByte();
   void PassOptionalByte(const Optional<int8_t>&);
   void PassOptionalByteBeforeRequired(const Optional<int8_t>&, int8_t);
   void PassOptionalByteWithDefault(int8_t);
   void PassOptionalByteWithDefaultBeforeRequired(int8_t, int8_t);
   void PassNullableByte(const Nullable<int8_t>&);
   void PassOptionalNullableByte(const Optional< Nullable<int8_t> >&);
   void PassVariadicByte(const Sequence<int8_t>&);
+  int8_t CachedByte();
 
   int16_t ReadonlyShort();
   int16_t WritableShort();
   void SetWritableShort(int16_t);
   void PassShort(int16_t);
   int16_t ReceiveShort();
   void PassOptionalShort(const Optional<int16_t>&);
   void PassOptionalShortWithDefault(int16_t);
@@ -334,16 +335,17 @@ public:
   void PassOptionalCallbackInterface(const Optional<nsRefPtr<TestCallbackInterface> >&);
   void PassOptionalNonNullCallbackInterface(const Optional<OwningNonNull<TestCallbackInterface> >&);
   void PassOptionalCallbackInterfaceWithDefault(TestCallbackInterface*);
 
   already_AddRefed<IndirectlyImplementedInterface> ReceiveConsequentialInterface();
   void PassConsequentialInterface(IndirectlyImplementedInterface&);
 
   // Sequence types
+  void GetReadonlySequence(nsTArray<int32_t>&);
   void ReceiveSequence(nsTArray<int32_t>&);
   void ReceiveNullableSequence(Nullable< nsTArray<int32_t> >&);
   void ReceiveSequenceOfNullableInts(nsTArray< Nullable<int32_t> >&);
   void ReceiveNullableSequenceOfNullableInts(Nullable< nsTArray< Nullable<int32_t> > >&);
   void PassSequence(const Sequence<int32_t> &);
   void PassNullableSequence(const Nullable< Sequence<int32_t> >&);
   void PassSequenceOfNullableInts(const Sequence<Nullable<int32_t> >&);
   void PassOptionalSequenceOfNullableInts(const Optional<Sequence<Nullable<int32_t> > > &);
--- a/dom/bindings/test/TestCodeGen.webidl
+++ b/dom/bindings/test/TestCodeGen.webidl
@@ -119,16 +119,18 @@ interface TestInterface {
   byte receiveByte();
   void passOptionalByte(optional byte arg);
   void passOptionalByteBeforeRequired(optional byte arg1, byte arg2);
   void passOptionalByteWithDefault(optional byte arg = 0);
   void passOptionalByteWithDefaultBeforeRequired(optional byte arg1 = 0, byte arg2);
   void passNullableByte(byte? arg);
   void passOptionalNullableByte(optional byte? arg);
   void passVariadicByte(byte... arg);
+  [StoreInSlot, Pure]
+  readonly attribute byte cachedByte;
 
   readonly attribute short readonlyShort;
   attribute short writableShort;
   void passShort(short arg);
   short receiveShort();
   void passOptionalShort(optional short arg);
   void passOptionalShortWithDefault(optional short arg = 5);
 
@@ -288,16 +290,18 @@ interface TestInterface {
   void passOptionalNonNullCallbackInterface(optional TestCallbackInterface arg);
   void passOptionalCallbackInterfaceWithDefault(optional TestCallbackInterface? arg = null);
 
   // Miscellaneous interface tests
   IndirectlyImplementedInterface receiveConsequentialInterface();
   void passConsequentialInterface(IndirectlyImplementedInterface arg);
 
   // Sequence types
+  [Cached, Pure]
+  readonly attribute sequence<long> readonlySequence;
   sequence<long> receiveSequence();
   sequence<long>? receiveNullableSequence();
   sequence<long?> receiveSequenceOfNullableInts();
   sequence<long?>? receiveNullableSequenceOfNullableInts();
   void passSequence(sequence<long> arg);
   void passNullableSequence(sequence<long>? arg);
   void passSequenceOfNullableInts(sequence<long?> arg);
   void passOptionalSequenceOfNullableInts(optional sequence<long?> arg);
--- a/dom/bindings/test/TestExampleGen.webidl
+++ b/dom/bindings/test/TestExampleGen.webidl
@@ -24,16 +24,18 @@ interface TestExampleInterface {
   byte receiveByte();
   void passOptionalByte(optional byte arg);
   void passOptionalByteBeforeRequired(optional byte arg1, byte arg2);
   void passOptionalByteWithDefault(optional byte arg = 0);
   void passOptionalByteWithDefaultBeforeRequired(optional byte arg1 = 0, byte arg2);
   void passNullableByte(byte? arg);
   void passOptionalNullableByte(optional byte? arg);
   void passVariadicByte(byte... arg);
+  [Cached, Pure]
+  readonly attribute byte cachedByte;
 
   readonly attribute short readonlyShort;
   attribute short writableShort;
   void passShort(short arg);
   short receiveShort();
   void passOptionalShort(optional short arg);
   void passOptionalShortWithDefault(optional short arg = 5);
 
@@ -184,16 +186,18 @@ interface TestExampleInterface {
   void passOptionalNonNullCallbackInterface(optional TestCallbackInterface arg);
   void passOptionalCallbackInterfaceWithDefault(optional TestCallbackInterface? arg = null);
 
   // Miscellaneous interface tests
   IndirectlyImplementedInterface receiveConsequentialInterface();
   void passConsequentialInterface(IndirectlyImplementedInterface arg);
 
   // Sequence types
+  [Cached, Pure]
+  readonly attribute sequence<long> readonlySequence;
   sequence<long> receiveSequence();
   sequence<long>? receiveNullableSequence();
   sequence<long?> receiveSequenceOfNullableInts();
   sequence<long?>? receiveNullableSequenceOfNullableInts();
   void passSequence(sequence<long> arg);
   void passNullableSequence(sequence<long>? arg);
   void passSequenceOfNullableInts(sequence<long?> arg);
   void passOptionalSequenceOfNullableInts(optional sequence<long?> arg);
--- a/dom/bindings/test/TestJSImplGen.webidl
+++ b/dom/bindings/test/TestJSImplGen.webidl
@@ -36,16 +36,18 @@ interface TestJSImplInterface {
   byte receiveByte();
   void passOptionalByte(optional byte arg);
   void passOptionalByteBeforeRequired(optional byte arg1, byte arg2);
   void passOptionalByteWithDefault(optional byte arg = 0);
   void passOptionalByteWithDefaultBeforeRequired(optional byte arg1 = 0, byte arg2);
   void passNullableByte(byte? arg);
   void passOptionalNullableByte(optional byte? arg);
   void passVariadicByte(byte... arg);
+  [Cached, Pure]
+  readonly attribute byte cachedByte;
 
   readonly attribute short readonlyShort;
   attribute short writableShort;
   void passShort(short arg);
   short receiveShort();
   void passOptionalShort(optional short arg);
   void passOptionalShortWithDefault(optional short arg = 5);
 
@@ -205,16 +207,18 @@ interface TestJSImplInterface {
   void passOptionalNonNullCallbackInterface(optional TestCallbackInterface arg);
   void passOptionalCallbackInterfaceWithDefault(optional TestCallbackInterface? arg = null);
 
   // Miscellaneous interface tests
   IndirectlyImplementedInterface receiveConsequentialInterface();
   void passConsequentialInterface(IndirectlyImplementedInterface arg);
 
   // Sequence types
+  [Cached, Pure]
+  readonly attribute sequence<long> readonlySequence;
   sequence<long> receiveSequence();
   sequence<long>? receiveNullableSequence();
   sequence<long?> receiveSequenceOfNullableInts();
   sequence<long?>? receiveNullableSequenceOfNullableInts();
   void passSequence(sequence<long> arg);
   void passNullableSequence(sequence<long>? arg);
   void passSequenceOfNullableInts(sequence<long?> arg);
   void passOptionalSequenceOfNullableInts(optional sequence<long?> arg);
--- a/dom/bluetooth/BluetoothCommon.h
+++ b/dom/bluetooth/BluetoothCommon.h
@@ -14,49 +14,52 @@
 
 extern bool gBluetoothDebugFlag;
 
 #define SWITCH_BT_DEBUG(V) (gBluetoothDebugFlag = V)
 
 #undef BT_LOG
 #if defined(MOZ_WIDGET_GONK)
 #include <android/log.h>
+
 /**
  * Prints 'D'EBUG build logs, which show in DEBUG build only when
  * developer setting 'Bluetooth output in adb' is enabled.
  */
-#define BT_LOGD(args...)                                             \
+#define BT_LOGD(msg, ...)                                            \
   do {                                                               \
     if (gBluetoothDebugFlag) {                                       \
-      __android_log_print(ANDROID_LOG_INFO, "GeckoBluetooth", args); \
+      __android_log_print(ANDROID_LOG_INFO, "GeckoBluetooth",        \
+                          "%s: " msg, __FUNCTION__, ##__VA_ARGS__);  \
     }                                                                \
   } while(0)
 
 /**
  * Prints 'R'ELEASE build logs, which show in both RELEASE and DEBUG builds.
  */
-#define BT_LOGR(args...)                                             \
-  __android_log_print(ANDROID_LOG_INFO, "GeckoBluetooth", args)      \
+#define BT_LOGR(msg, ...)                                            \
+  __android_log_print(ANDROID_LOG_INFO, "GeckoBluetooth",            \
+                      "%s: " msg, __FUNCTION__, ##__VA_ARGS__)       \
 
 /**
  * Prints DEBUG build warnings, which show in DEBUG build only.
  */
 #define BT_WARNING(args...)                                          \
   NS_WARNING(nsPrintfCString(args).get())                            \
 
 #else
-#define BT_LOGD(args, ...)                                           \
+#define BT_LOGD(msg, ...)                                            \
   do {                                                               \
     if (gBluetoothDebugFlag) {                                       \
-      printf(args, ##__VA_ARGS__);                                   \
+      printf("%s: " msg, __FUNCTION__, ##__VA_ARGS__);               \
     }                                                                \
   } while(0)
 
-#define BT_LOGR(args, ...) printf(args, ##__VA_ARGS__)
-#define BT_WARNING(args, ...) printf(args, ##__VA_ARGS__)
+#define BT_LOGR(msg, ...) printf("%s: " msg, __FUNCTION__, ##__VA_ARGS__))
+#define BT_WARNING(msg, ...) printf("%s: " msg, __FUNCTION__, ##__VA_ARGS__))
 #endif
 
 #define BEGIN_BLUETOOTH_NAMESPACE \
   namespace mozilla { namespace dom { namespace bluetooth {
 #define END_BLUETOOTH_NAMESPACE \
   } /* namespace bluetooth */ } /* namespace dom */ } /* namespace mozilla */
 #define USING_BLUETOOTH_NAMESPACE \
   using namespace mozilla::dom::bluetooth;
--- a/dom/bluetooth/BluetoothProfileController.cpp
+++ b/dom/bluetooth/BluetoothProfileController.cpp
@@ -11,22 +11,21 @@
 #include "BluetoothHfpManager.h"
 #include "BluetoothHidManager.h"
 
 #include "BluetoothUtils.h"
 #include "mozilla/dom/bluetooth/BluetoothTypes.h"
 
 USING_BLUETOOTH_NAMESPACE
 
-#define BT_LOGR_PROFILE(mgr, args...)                 \
-  do {                                                \
-    nsCString name;                                   \
-    mgr->GetName(name);                               \
-    BT_LOGR("%s: [%s] %s", __FUNCTION__, name.get(),  \
-      nsPrintfCString(args).get());                   \
+#define BT_LOGR_PROFILE(mgr, msg, ...)               \
+  do {                                               \
+    nsCString name;                                  \
+    mgr->GetName(name);                              \
+    BT_LOGR("[%s] " msg, name.get(), ##__VA_ARGS__); \
   } while(0)
 
 BluetoothProfileController::BluetoothProfileController(
                                    bool aConnect,
                                    const nsAString& aDeviceAddress,
                                    BluetoothReplyRunnable* aRunnable,
                                    BluetoothProfileControllerCallback aCallback,
                                    uint16_t aServiceUuid,
--- a/dom/bluetooth/BluetoothRilListener.cpp
+++ b/dom/bluetooth/BluetoothRilListener.cpp
@@ -374,18 +374,17 @@ BluetoothRilListener::ServiceChanged(uin
     mClientId = aClientId;
   } else {
     SelectClient();
   }
 
   // Restart listening
   ListenMobileConnAndIccInfo(true);
 
-  BT_LOGR("%s: %d client %d. new mClientId %d",
-          __FUNCTION__, aRegistered, aClientId,
+  BT_LOGR("%d client %d. new mClientId %d", aRegistered, aClientId,
           (mClientId < mMobileConnListeners.Length()) ? mClientId : -1);
 }
 
 void
 BluetoothRilListener::EnumerateCalls()
 {
   nsCOMPtr<nsITelephonyProvider> provider =
     do_GetService(TELEPHONY_PROVIDER_CONTRACTID);
--- a/dom/bluetooth/bluedroid/BluetoothHfpManager.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothHfpManager.cpp
@@ -66,16 +66,17 @@ namespace {
   // Dialer stops playing.
   static int sBusyToneInterval = 3700; //unit: ms
 } // anonymous namespace
 
 // Main thread task commands
 enum MainThreadTaskCmd {
   NOTIFY_CONN_STATE_CHANGED,
   NOTIFY_DIALER,
+  NOTIFY_SCO_VOLUME_CHANGED,
   POST_TASK_RESPOND_TO_BLDN,
   POST_TASK_CLOSE_SCO
 };
 
 static void
 ConnectionStateCallback(bthf_connection_state_t state, bt_bdaddr_t* bd_addr)
 {
   BT_HF_PROCESS_CB(ProcessConnectionState, state, bd_addr);
@@ -271,16 +272,26 @@ public:
 
     switch (mCommand) {
       case MainThreadTaskCmd::NOTIFY_CONN_STATE_CHANGED:
         sBluetoothHfpManager->NotifyConnectionStateChanged(mParameter);
         break;
       case MainThreadTaskCmd::NOTIFY_DIALER:
         sBluetoothHfpManager->NotifyDialer(mParameter);
         break;
+      case MainThreadTaskCmd::NOTIFY_SCO_VOLUME_CHANGED:
+        {
+          nsCOMPtr<nsIObserverService> os =
+            mozilla::services::GetObserverService();
+          NS_ENSURE_TRUE(os, NS_OK);
+
+          os->NotifyObservers(nullptr, "bluetooth-volume-change",
+                              mParameter.get());
+        }
+        break;
       case MainThreadTaskCmd::POST_TASK_RESPOND_TO_BLDN:
         MessageLoop::current()->
           PostDelayedTask(FROM_HERE, new RespondToBLDNTask(),
                           sWaitingForDialingInterval);
         break;
       case MainThreadTaskCmd::POST_TASK_CLOSE_SCO:
         MessageLoop::current()->
           PostDelayedTask(FROM_HERE, new CloseScoTask(),
@@ -502,17 +513,17 @@ BluetoothHfpManager::Notify(const hal::B
   mBattChg = (int) ceil(aBatteryInfo.level() * 5.0);
   UpdateDeviceCIND();
 }
 
 void
 BluetoothHfpManager::ProcessConnectionState(bthf_connection_state_t aState,
                                             bt_bdaddr_t* aBdAddress)
 {
-  BT_LOGR("%s: state %d", __FUNCTION__, aState);
+  BT_LOGR("state %d", aState);
 
   mConnectionState = aState;
 
   if (aState == BTHF_CONNECTION_STATE_CONNECTED) {
     BdAddressTypeToString(aBdAddress, mDeviceAddress);
     BT_HF_DISPATCH_MAIN(MainThreadTaskCmd::NOTIFY_CONN_STATE_CHANGED,
                         NS_LITERAL_STRING(BLUETOOTH_HFP_STATUS_CHANGED_ID));
   } else if (aState == BTHF_CONNECTION_STATE_DISCONNECTED) {
@@ -521,17 +532,17 @@ BluetoothHfpManager::ProcessConnectionSt
                         NS_LITERAL_STRING(BLUETOOTH_HFP_STATUS_CHANGED_ID));
   }
 }
 
 void
 BluetoothHfpManager::ProcessAudioState(bthf_audio_state_t aState,
                                        bt_bdaddr_t* aBdAddress)
 {
-  BT_LOGR("%s: state %d", __FUNCTION__, aState);
+  BT_LOGR("state %d", aState);
 
   mAudioState = aState;
 
   if (aState == BTHF_AUDIO_STATE_CONNECTED ||
       aState == BTHF_AUDIO_STATE_DISCONNECTED) {
     BT_HF_DISPATCH_MAIN(MainThreadTaskCmd::NOTIFY_CONN_STATE_CHANGED,
                         NS_LITERAL_STRING(BLUETOOTH_SCO_STATUS_CHANGED_ID));
   }
@@ -547,31 +558,31 @@ BluetoothHfpManager::ProcessAnswerCall()
 void
 BluetoothHfpManager::ProcessHangupCall()
 {
   BT_HF_DISPATCH_MAIN(MainThreadTaskCmd::NOTIFY_DIALER,
                       NS_LITERAL_STRING("CHUP"));
 }
 
 void
-BluetoothHfpManager::ProcessVolumeControl(bthf_volume_type_t aType, int aVolume)
+BluetoothHfpManager::ProcessVolumeControl(bthf_volume_type_t aType,
+                                          int aVolume)
 {
   NS_ENSURE_TRUE_VOID(aVolume >= 0 && aVolume <= 15);
 
   if (aType == BTHF_VOLUME_TYPE_MIC) {
     mCurrentVgm = aVolume;
   } else if (aType == BTHF_VOLUME_TYPE_SPK) {
     // Adjust volume by headset
     mReceiveVgsFlag = true;
     NS_ENSURE_TRUE_VOID(aVolume != mCurrentVgs);
 
     nsString data;
-    nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
     data.AppendInt(aVolume);
-    os->NotifyObservers(nullptr, "bluetooth-volume-change", data.get());
+    BT_HF_DISPATCH_MAIN(MainThreadTaskCmd::NOTIFY_SCO_VOLUME_CHANGED, data);
   }
 }
 
 void
 BluetoothHfpManager::ProcessDtmfCmd(char aDtmf)
 {
   NS_ENSURE_TRUE_VOID(IsValidDtmf(aDtmf));
 
@@ -686,17 +697,17 @@ BluetoothHfpManager::ProcessAtClcc()
 
     SendCLCC(mCdmaSecondCall, 2);
   }
 }
 
 void
 BluetoothHfpManager::ProcessUnknownAt(char *aAtString)
 {
-  BT_LOGR("%s: [%s]", __FUNCTION__, aAtString);
+  BT_LOGR("[%s]", aAtString);
 
   NS_ENSURE_TRUE_VOID(sBluetoothHfpInterface);
   NS_ENSURE_TRUE_VOID(BT_STATUS_SUCCESS ==
     sBluetoothHfpInterface->at_response(BTHF_AT_RESPONSE_ERROR, 0));
 }
 
 void
 BluetoothHfpManager::NotifyConnectionStateChanged(const nsAString& aType)
@@ -951,18 +962,18 @@ BluetoothHfpManager::UpdatePhoneCIND(uin
   NS_ENSURE_TRUE_VOID(sBluetoothHfpInterface);
 
   int numActive = GetNumberOfCalls(nsITelephonyProvider::CALL_STATE_CONNECTED);
   int numHeld = GetNumberOfCalls(nsITelephonyProvider::CALL_STATE_HELD);
   bthf_call_state_t bthfCallState = ConvertToBthfCallState(mCallSetupState);
   nsAutoCString number = NS_ConvertUTF16toUTF8(mCurrentCallArray[aCallIndex].mNumber);
   bthf_call_addrtype_t type = mCurrentCallArray[aCallIndex].mType;
 
-  BT_LOGR("%s: [%d] state %d => BTHF: active[%d] held[%d] state[%d]",
-    __FUNCTION__, aCallIndex, callState, numActive, numHeld, bthfCallState);
+  BT_LOGR("[%d] state %d => BTHF: active[%d] held[%d] state[%d]",
+          aCallIndex, callState, numActive, numHeld, bthfCallState);
 
   NS_ENSURE_TRUE_VOID(BT_STATUS_SUCCESS ==
     sBluetoothHfpInterface->phone_state_change(
       numActive, numHeld, bthfCallState, number.get(), type));
 }
 
 void
 BluetoothHfpManager::UpdateDeviceCIND()
@@ -1063,33 +1074,31 @@ BluetoothHfpManager::HandleCallStateChan
   switch (aCallState) {
     case nsITelephonyProvider::CALL_STATE_DIALING:
       // We've send Dialer a dialing request and this is the response.
       if (!mDialingRequestProcessed) {
         SendResponse(BTHF_AT_RESPONSE_OK);
         mDialingRequestProcessed = true;
       }
       break;
-
     case nsITelephonyProvider::CALL_STATE_DISCONNECTED:
       // -1 is necessary because call 0 is an invalid (padding) call object.
       if (mCurrentCallArray.Length() - 1 ==
           GetNumberOfCalls(nsITelephonyProvider::CALL_STATE_DISCONNECTED)) {
         // In order to let user hear busy tone via connected Bluetooth headset,
         // we postpone the timing of dropping SCO.
         if (aError.Equals(NS_LITERAL_STRING("BusyError"))) {
           // FIXME: UpdatePhoneCIND later since it causes SCO close but
           // Dialer is still playing busy tone via HF.
           BT_HF_DISPATCH_MAIN(MainThreadTaskCmd::POST_TASK_CLOSE_SCO);
         }
 
         ResetCallArray();
       }
       break;
-
     default:
       break;
   }
 }
 
 PhoneType
 BluetoothHfpManager::GetPhoneType(const nsAString& aType)
 {
--- a/dom/bluetooth/bluedroid/BluetoothOppManager.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothOppManager.cpp
@@ -378,34 +378,34 @@ BluetoothOppManager::DiscardBlobsToSend(
 
   MOZ_ASSERT(!mBatches.IsEmpty());
   MOZ_ASSERT(!mIsServer);
 
   int length = (int) mBatches[0].mBlobs.Length();
   while (length > mCurrentBlobIndex + 1) {
     mBlob = mBatches[0].mBlobs[++mCurrentBlobIndex];
 
-    BT_LOGR("%s: idx %d", __FUNCTION__, mCurrentBlobIndex);
+    BT_LOGR("idx %d", mCurrentBlobIndex);
     ExtractBlobHeaders();
     StartFileTransfer();
     FileTransferComplete();
   }
 }
 
 bool
 BluetoothOppManager::ProcessNextBatch()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   // Remove the processed batch.
   // A batch is processed if we've incremented mCurrentBlobIndex for it.
   if (mCurrentBlobIndex >= 0) {
     ClearQueue();
     mBatches.RemoveElementAt(0);
-    BT_LOGR("%s: REMOVE. %d remaining", __FUNCTION__, mBatches.Length());
+    BT_LOGR("REMOVE. %d remaining", mBatches.Length());
   }
 
   // Process the next batch
   if (!mBatches.IsEmpty()) {
     ConnectInternal(mBatches[0].mDeviceAddress);
     return true;
   }
 
@@ -753,17 +753,17 @@ BluetoothOppManager::ComposePacket(uint8
     mPutFinalFlag = (aOpCode == ObexRequestCode::PutFinal);
   }
 
   int dataLength = aMessage->mSize - frameHeaderLength;
 
   // Check length before memcpy to prevent from memory pollution
   if (dataLength < 0 ||
       mPacketReceivedLength + dataLength > mPacketLength) {
-    BT_LOGR("%s: Received packet size is unreasonable", __FUNCTION__);
+    BT_LOGR("Received packet size is unreasonable");
 
     ReplyToPut(mPutFinalFlag, false);
     DeleteReceivedFile();
     FileTransferComplete();
 
     return false;
   }
 
@@ -1371,17 +1371,17 @@ BluetoothOppManager::NotifyAboutFileChan
   NS_ENSURE_TRUE_VOID(obs);
 
   obs->NotifyObservers(mDsFile, "file-watcher-notify", data.get());
 }
 
 void
 BluetoothOppManager::OnSocketConnectSuccess(BluetoothSocket* aSocket)
 {
-  BT_LOGR("%s: [%s]", __FUNCTION__, (mIsServer)? "server" : "client");
+  BT_LOGR("[%s]", (mIsServer)? "server" : "client");
   MOZ_ASSERT(aSocket);
 
   /**
    * If the created connection is an inbound connection, close server socket
    * because currently only one file-transfer session is allowed. After that,
    * we need to make sure that server socket would be nulled out.
    * As for outbound connections, we just notify the controller that it's done.
    */
@@ -1398,17 +1398,17 @@ BluetoothOppManager::OnSocketConnectSucc
   if (!mIsServer) {
     StartSendingNextFile();
   }
 }
 
 void
 BluetoothOppManager::OnSocketConnectError(BluetoothSocket* aSocket)
 {
-  BT_LOGR("%s: [%s]", __FUNCTION__, (mIsServer)? "server" : "client");
+  BT_LOGR("[%s]", (mIsServer)? "server" : "client");
 
   mServerSocket = nullptr;
   mSocket = nullptr;
 
   if (!mIsServer) {
     // Inform gaia of remaining blobs' sending failure
     DiscardBlobsToSend();
   }
@@ -1422,17 +1422,17 @@ BluetoothOppManager::OnSocketConnectErro
 void
 BluetoothOppManager::OnSocketDisconnect(BluetoothSocket* aSocket)
 {
   MOZ_ASSERT(aSocket);
   if (aSocket != mSocket) {
     // Do nothing when a listening server socket is closed.
     return;
   }
-  BT_LOGR("%s: [%s]", __FUNCTION__, (mIsServer) ? "client" : "server");
+  BT_LOGR("[%s]", (mIsServer) ? "client" : "server");
 
   /**
    * It is valid for a bluetooth device which is transfering file via OPP
    * closing socket without sending OBEX disconnect request first. So we
    * delete the broken file when we failed to receive a file from the remote,
    * and notify the transfer has been completed (but failed). We also call
    * AfterOppDisconnected here to ensure all variables will be cleaned.
    */
--- a/dom/bluetooth/bluedroid/BluetoothSocket.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothSocket.cpp
@@ -664,25 +664,25 @@ BluetoothSocket::ReceiveSocketInfo(nsAut
   }
   mReceivedSocketInfoLength += aMessage->mSize;
 
   size_t offset = 0;
   if (mReceivedSocketInfoLength == FIRST_SOCKET_INFO_MSG_LENGTH) {
     // 1st message: [channel:4]
     int32_t channel = ReadInt32(aMessage->mData, &offset);
 
-    BT_LOGR("%s: channel %d", __FUNCTION__, channel);
+    BT_LOGR("channel %d", channel);
   } else if (mReceivedSocketInfoLength == TOTAL_SOCKET_INFO_LENGTH) {
     // 2nd message: [size:2][bd address:6][channel:4][connection status:4]
     int16_t size = ReadInt16(aMessage->mData, &offset);
     ReadBdAddress(aMessage->mData, &offset, mDeviceAddress);
     int32_t channel = ReadInt32(aMessage->mData, &offset);
     int32_t connectionStatus = ReadInt32(aMessage->mData, &offset);
 
-    BT_LOGR("%s: size %d channel %d remote addr %s status %d", __FUNCTION__,
+    BT_LOGR("size %d channel %d remote addr %s status %d",
       size, channel, NS_ConvertUTF16toUTF8(mDeviceAddress).get(), connectionStatus);
 
     if (connectionStatus != 0) {
       OnConnectError();
       return true;
     }
 
     if (mIsServer) {
--- a/dom/bluetooth/bluedroid/gonk/BluetoothServiceBluedroid.cpp
+++ b/dom/bluetooth/bluedroid/gonk/BluetoothServiceBluedroid.cpp
@@ -100,31 +100,31 @@ public:
     prop.type = BT_PROPERTY_ADAPTER_SCAN_MODE;
     prop.val = (void*)&mode;
     prop.len = sizeof(mode);
 
     NS_ENSURE_TRUE(sBtInterface, NS_ERROR_FAILURE);
 
     int ret = sBtInterface->set_adapter_property(&prop);
     if (ret != BT_STATUS_SUCCESS) {
-      BT_LOGR("%s: Fail to set: BT_SCAN_MODE_CONNECTABLE", __FUNCTION__);
+      BT_LOGR("Fail to set: BT_SCAN_MODE_CONNECTABLE");
     }
 
     // Try to fire event 'AdapterAdded' to fit the original behaviour when
     // we used BlueZ as backend.
     BluetoothService* bs = BluetoothService::Get();
     NS_ENSURE_TRUE(bs, NS_ERROR_FAILURE);
 
     bs->AdapterAddedReceived();
     bs->TryFiringAdapterAdded();
 
     // Trigger BluetoothOppManager to listen
     BluetoothOppManager* opp = BluetoothOppManager::Get();
     if (!opp || !opp->Listen()) {
-      BT_LOGR("%s: Fail to start BluetoothOppManager listening", __FUNCTION__);
+      BT_LOGR("Fail to start BluetoothOppManager listening");
     }
 
     return NS_OK;
   }
 };
 
 /**
  *  Static callback functions
@@ -267,17 +267,17 @@ BdAddressTypeToString(bt_bdaddr_t* aBdAd
   aRetBdAddress = NS_ConvertUTF8toUTF16((char*)bdstr);
 }
 
 static void
 AdapterStateChangeCallback(bt_state_t aStatus)
 {
   MOZ_ASSERT(!NS_IsMainThread());
 
-  BT_LOGR("%s, BT_STATE:%d", __FUNCTION__, aStatus);
+  BT_LOGR("BT_STATE %d", aStatus);
 
   sIsBtEnabled = (aStatus == BT_STATE_ON);
 
   {
     MonitorAutoLock lock(*sToggleBtMonitor);
     lock.Notify();
   }
 
@@ -668,26 +668,26 @@ bt_callbacks_t sBluetoothCallbacks =
  */
 static bool
 EnsureBluetoothHalLoad()
 {
   hw_module_t* module;
   hw_device_t* device;
   int err = hw_get_module(BT_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
   if (err != 0) {
-    BT_LOGR("Error: %s ", strerror(err));
+    BT_LOGR("Error: %s", strerror(err));
     return false;
   }
   module->methods->open(module, BT_HARDWARE_MODULE_ID, &device);
   sBtDevice = (bluetooth_device_t *)device;
   sBtInterface = sBtDevice->get_bluetooth_interface();
 
   int ret = sBtInterface->init(&sBluetoothCallbacks);
   if (ret != BT_STATUS_SUCCESS) {
-    BT_LOGR("Error while setting the callbacks %s", __FUNCTION__);
+    BT_LOGR("Error while setting the callbacks");
     sBtInterface = nullptr;
   }
 
   return true;
 }
 
 static nsresult
 StartStopGonkBluetooth(bool aShouldEnable)
@@ -707,17 +707,17 @@ StartStopGonkBluetooth(bool aShouldEnabl
 }
 
 static void
 ReplyStatusError(BluetoothReplyRunnable* aBluetoothReplyRunnable,
                  int aStatusCode, const nsAString& aCustomMsg)
 {
   MOZ_ASSERT(aBluetoothReplyRunnable, "Reply runnable is nullptr");
 
-  BT_LOGR("%s: error code(%d)", __FUNCTION__, aStatusCode);
+  BT_LOGR("error code(%d)", aStatusCode);
 
   nsAutoString replyError;
   replyError.Assign(aCustomMsg);
 
   if (aStatusCode == BT_STATUS_BUSY) {
     replyError.AppendLiteral(":BT_STATUS_BUSY");
   } else if (aStatusCode == BT_STATUS_NOT_READY) {
     replyError.AppendLiteral(":BT_STATUS_NOT_READY");
@@ -738,17 +738,17 @@ ReplyStatusError(BluetoothReplyRunnable*
 /**
  *  Member functions
  */
 BluetoothServiceBluedroid::BluetoothServiceBluedroid()
 {
   sToggleBtMonitor = new Monitor("BluetoothService.sToggleBtMonitor");
 
   if (!EnsureBluetoothHalLoad()) {
-    BT_LOGR("Error! Failed to load bluedroid library.\n");
+    BT_LOGR("Error! Failed to load bluedroid library.");
     return;
   }
 
   // Register all the bluedroid callbacks before enable() get called
   // It is required to register a2dp callbacks before a2dp media task starts up.
   BluetoothHfpManager::Get();
   BluetoothA2dpManager::Get();
 }
@@ -760,30 +760,30 @@ BluetoothServiceBluedroid::~BluetoothSer
 
 nsresult
 BluetoothServiceBluedroid::StartInternal()
 {
   MOZ_ASSERT(!NS_IsMainThread());
 
   nsresult ret = StartStopGonkBluetooth(true);
   if (NS_FAILED(ret)) {
-    BT_LOGR("Error: %s", __FUNCTION__);
+    BT_LOGR("Error");
   }
 
   return ret;
 }
 
 nsresult
 BluetoothServiceBluedroid::StopInternal()
 {
   MOZ_ASSERT(!NS_IsMainThread());
 
   nsresult ret = StartStopGonkBluetooth(false);
   if (NS_FAILED(ret)) {
-    BT_LOGR("Error: %s", __FUNCTION__);
+    BT_LOGR("Error");
   }
 
   return ret;
 }
 
 bool
 BluetoothServiceBluedroid::IsEnabledInternal()
 {
@@ -1356,29 +1356,56 @@ BluetoothServiceBluedroid::ConfirmReceiv
   }
 
   DispatchBluetoothReply(aRunnable, BluetoothValue(true), errorStr);
 }
 
 void
 BluetoothServiceBluedroid::ConnectSco(BluetoothReplyRunnable* aRunnable)
 {
+  MOZ_ASSERT(NS_IsMainThread());
 
+  BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
+  if (!hfp || !hfp->ConnectSco()) {
+    NS_NAMED_LITERAL_STRING(replyError, "Calling ConnectSco() failed");
+    DispatchBluetoothReply(aRunnable, BluetoothValue(), replyError);
+    return;
+  }
+
+  DispatchBluetoothReply(aRunnable, BluetoothValue(true), EmptyString());
 }
 
 void
 BluetoothServiceBluedroid::DisconnectSco(BluetoothReplyRunnable* aRunnable)
 {
+  MOZ_ASSERT(NS_IsMainThread());
 
+  BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
+  if (!hfp || !hfp->DisconnectSco()) {
+    NS_NAMED_LITERAL_STRING(replyError, "Calling DisconnectSco() failed");
+    DispatchBluetoothReply(aRunnable, BluetoothValue(), replyError);
+    return;
+  }
+
+  DispatchBluetoothReply(aRunnable, BluetoothValue(true), EmptyString());
 }
 
 void
 BluetoothServiceBluedroid::IsScoConnected(BluetoothReplyRunnable* aRunnable)
 {
+  MOZ_ASSERT(NS_IsMainThread());
 
+  BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
+  if (!hfp) {
+    NS_NAMED_LITERAL_STRING(replyError, "Fail to get BluetoothHfpManager");
+    DispatchBluetoothReply(aRunnable, BluetoothValue(), replyError);
+    return;
+  }
+
+  DispatchBluetoothReply(aRunnable, hfp->IsScoConnected(), EmptyString());
 }
 
 void
 BluetoothServiceBluedroid::SendMetaData(const nsAString& aTitle,
                                         const nsAString& aArtist,
                                         const nsAString& aAlbum,
                                         int64_t aMediaNumber,
                                         int64_t aTotalMediaCount,
--- a/dom/bluetooth/bluez/BluetoothHfpManager.cpp
+++ b/dom/bluetooth/bluez/BluetoothHfpManager.cpp
@@ -815,17 +815,21 @@ BluetoothHfpManager::ReceiveSocketData(B
 
     nsresult rv;
     int vgm = atCommandValues[0].ToInteger(&rv);
     if (NS_FAILED(rv)) {
       BT_WARNING("Failed to extract microphone volume from bluetooth headset!");
       goto respond_with_ok;
     }
 
-    NS_ASSERTION(vgm >= 0 && vgm <= 15, "Received invalid VGM value");
+    if (vgm < 0 || vgm > 15) {
+      BT_WARNING("Received invalid VGM value");
+      goto respond_with_ok;
+    }
+
     mCurrentVgm = vgm;
 #ifdef MOZ_B2G_RIL
   } else if (msg.Find("AT+CHLD=?") != -1) {
     SendLine("+CHLD: (0,1,2)");
   } else if (msg.Find("AT+CHLD=") != -1) {
     ParseAtCommand(msg, 8, atCommandValues);
 
     if (atCommandValues.IsEmpty()) {
@@ -890,20 +894,28 @@ BluetoothHfpManager::ReceiveSocketData(B
       BT_WARNING("Failed to extract volume value from bluetooth headset!");
       goto respond_with_ok;
     }
 
     if (newVgs == mCurrentVgs) {
       goto respond_with_ok;
     }
 
-    NS_ASSERTION(newVgs >= 0 && newVgs <= 15, "Received invalid VGS value");
+    if (newVgs < 0 || newVgs > 15) {
+      BT_WARNING("Received invalid VGS value");
+      goto respond_with_ok;
+    }
+
+    nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
+    if (!os) {
+      BT_WARNING("Failed to get observer service!");
+      goto respond_with_ok;
+    }
 
     nsString data;
-    nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
     data.AppendInt(newVgs);
     os->NotifyObservers(nullptr, "bluetooth-volume-change", data.get());
 #ifdef MOZ_B2G_RIL
   } else if ((msg.Find("AT+BLDN") != -1) || (msg.Find("ATD>") != -1)) {
     // Dialer app of FFOS v1 does not have plan to support Memory Dailing.
     // However, in order to pass Bluetooth HFP certification, we still have to
     // make a call when we receive AT command 'ATD>n'.
     mDialingRequestProcessed = false;
--- a/dom/bluetooth/bluez/BluetoothOppManager.cpp
+++ b/dom/bluetooth/bluez/BluetoothOppManager.cpp
@@ -394,34 +394,34 @@ BluetoothOppManager::DiscardBlobsToSend(
 
   MOZ_ASSERT(!mBatches.IsEmpty());
   MOZ_ASSERT(!mIsServer);
 
   int length = (int) mBatches[0].mBlobs.Length();
   while (length > mCurrentBlobIndex + 1) {
     mBlob = mBatches[0].mBlobs[++mCurrentBlobIndex];
 
-    BT_LOGR("%s: idx %d", __FUNCTION__, mCurrentBlobIndex);
+    BT_LOGR("idx %d", mCurrentBlobIndex);
     ExtractBlobHeaders();
     StartFileTransfer();
     FileTransferComplete();
   }
 }
 
 bool
 BluetoothOppManager::ProcessNextBatch()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   // Remove the processed batch.
   // A batch is processed if we've incremented mCurrentBlobIndex for it.
   if (mCurrentBlobIndex >= 0) {
     ClearQueue();
     mBatches.RemoveElementAt(0);
-    BT_LOGR("%s: REMOVE. %d remaining", __FUNCTION__, mBatches.Length());
+    BT_LOGR("REMOVE. %d remaining", mBatches.Length());
   }
 
   // Process the next batch
   if (!mBatches.IsEmpty()) {
     ConnectInternal(mBatches[0].mDeviceAddress);
     return true;
   }
 
@@ -769,17 +769,17 @@ BluetoothOppManager::ComposePacket(uint8
     mPutFinalFlag = (aOpCode == ObexRequestCode::PutFinal);
   }
 
   int dataLength = aMessage->mSize - frameHeaderLength;
 
   // Check length before memcpy to prevent from memory pollution
   if (dataLength < 0 ||
       mPacketReceivedLength + dataLength > mPacketLength) {
-    BT_LOGR("%s: Received packet size is unreasonable", __FUNCTION__);
+    BT_LOGR("Received packet size is unreasonable");
 
     ReplyToPut(mPutFinalFlag, false);
     DeleteReceivedFile();
     FileTransferComplete();
 
     return false;
   }
 
@@ -1387,17 +1387,17 @@ BluetoothOppManager::NotifyAboutFileChan
   NS_ENSURE_TRUE_VOID(obs);
 
   obs->NotifyObservers(mDsFile, "file-watcher-notify", data.get());
 }
 
 void
 BluetoothOppManager::OnSocketConnectSuccess(BluetoothSocket* aSocket)
 {
-  BT_LOGR("%s: [%s]", __FUNCTION__, (mIsServer)? "server" : "client");
+  BT_LOGR("[%s]", (mIsServer)? "server" : "client");
   MOZ_ASSERT(aSocket);
 
   /**
    * If the created connection is an inbound connection, close another server
    * socket because currently only one file-transfer session is allowed. After
    * that, we need to make sure that both server socket would be nulled out.
    * As for outbound connections, we just notify the controller that it's done.
    */
@@ -1423,17 +1423,17 @@ BluetoothOppManager::OnSocketConnectSucc
   if (!mIsServer) {
     StartSendingNextFile();
   }
 }
 
 void
 BluetoothOppManager::OnSocketConnectError(BluetoothSocket* aSocket)
 {
-  BT_LOGR("%s: [%s]", __FUNCTION__, (mIsServer)? "server" : "client");
+  BT_LOGR("[%s]", (mIsServer)? "server" : "client");
 
   mRfcommSocket = nullptr;
   mL2capSocket = nullptr;
   mSocket = nullptr;
 
   if (!mIsServer) {
     // Inform gaia of remaining blobs' sending failure
     DiscardBlobsToSend();
@@ -1443,17 +1443,17 @@ BluetoothOppManager::OnSocketConnectErro
   if (!ProcessNextBatch()) {
     Listen();
   }
 }
 
 void
 BluetoothOppManager::OnSocketDisconnect(BluetoothSocket* aSocket)
 {
-  BT_LOGR("%s: [%s]", __FUNCTION__, (mIsServer)? "server" : "client");
+  BT_LOGR("[%s]", (mIsServer)? "server" : "client");
   MOZ_ASSERT(aSocket);
 
   if (aSocket != mSocket) {
     // Do nothing when a listening server socket is closed.
     return;
   }
 
   /**
--- a/dom/bluetooth/bluez/linux/BluetoothDBusService.cpp
+++ b/dom/bluetooth/bluez/linux/BluetoothDBusService.cpp
@@ -41,16 +41,17 @@
 #include "mozilla/ipc/UnixSocket.h"
 #include "mozilla/ipc/DBusThread.h"
 #include "mozilla/ipc/DBusUtils.h"
 #include "mozilla/ipc/RawDBusConnection.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/NullPtr.h"
 #include "mozilla/StaticMutex.h"
 #include "mozilla/Util.h"
+
 #if defined(MOZ_WIDGET_GONK)
 #include "cutils/properties.h"
 #endif
 
 /**
  * Some rules for dealing with memory in DBus:
  * - A DBusError only needs to be deleted if it's been set, not just
  *   initialized. This is why LOG_AND_FREE... is called only when an error is
@@ -166,23 +167,42 @@ static const char* sBluetoothDBusSignals
   "type='signal',interface='org.bluez.Control'"
 };
 
 /**
  * DBus Connection held for the BluetoothCommandThread to use. Should never be
  * used by any other thread.
  */
 static nsRefPtr<RawDBusConnection> gThreadConnection;
-static nsDataHashtable<nsStringHashKey, DBusMessage* >* sPairingReqTable;
+
+// Only A2DP and HID are authorized.
 static nsTArray<uint32_t> sAuthorizedServiceClass;
+
+// The object path of adpater which should be updated after switching Bluetooth.
 static nsString sAdapterPath;
+
+/**
+ * The adapter name may not be ready whenever event 'AdapterAdded' is received,
+ * so we'd like to wait for a bit.
+ */
 static bool sAdapterNameIsReady = false;
+static int sWaitingForAdapterNameInterval = 1000; //unit: ms
+
+// Keep the pairing requests.
 static Atomic<int32_t> sIsPairing(0);
+static nsDataHashtable<nsStringHashKey, DBusMessage* >* sPairingReqTable;
+
+/**
+ * Disconnect all profiles before turning off Bluetooth. Please see Bug 891257
+ * for more details.
+ */
 static int sConnectedDeviceCount = 0;
 static StaticAutoPtr<Monitor> sStopBluetoothMonitor;
+
+// A quene for connect/disconnect request. See Bug 913372 for details.
 static nsTArray<nsRefPtr<BluetoothProfileController> > sControllerArray;
 
 typedef void (*UnpackFunc)(DBusMessage*, DBusError*, BluetoothValue&, nsAString&);
 typedef bool (*FilterFunc)(const BluetoothValue&);
 
 BluetoothDBusService::BluetoothDBusService()
 {
   sStopBluetoothMonitor = new Monitor("BluetoothService.sStopBluetoothMonitor");
@@ -330,32 +350,56 @@ public:
     hid->HandleInputPropertyChanged(mSignal);
     return NS_OK;
   }
 
 private:
   BluetoothSignal mSignal;
 };
 
-class TryFiringAdapterAddedTask : public nsRunnable
+class TryFiringAdapterAddedTask : public Task
 {
 public:
-  NS_IMETHOD
-  Run()
+  void Run() MOZ_OVERRIDE
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     BluetoothService* bs = BluetoothService::Get();
-    NS_ENSURE_TRUE(bs, NS_ERROR_FAILURE);
+    NS_ENSURE_TRUE_VOID(bs);
 
     bs->AdapterAddedReceived();
     bs->TryFiringAdapterAdded();
+  }
+};
+
+class TryFiringAdapterAddedRunnable : public nsRunnable
+{
+public:
+  TryFiringAdapterAddedRunnable(bool aDelay)
+    : mDelay(aDelay)
+  { }
+
+  nsresult Run()
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+
+    if (mDelay) {
+      MessageLoop::current()->
+        PostDelayedTask(FROM_HERE, new TryFiringAdapterAddedTask(),
+                        sWaitingForAdapterNameInterval);
+    } else {
+      MessageLoop::current()->
+        PostTask(FROM_HERE, new TryFiringAdapterAddedTask());
+    }
 
     return NS_OK;
   }
+
+private:
+  bool mDelay;
 };
 
 static bool
 IsDBusMessageError(DBusMessage* aMsg, DBusError* aErr, nsAString& aErrorStr)
 {
   if (aErr && dbus_error_is_set(aErr)) {
     aErrorStr = NS_ConvertUTF8toUTF16(aErr->message);
     LOG_AND_FREE_DBUS_ERROR(aErr);
@@ -722,17 +766,17 @@ GetProperty(DBusMessageIter aIter, Prope
   } else if (!sAdapterNameIsReady &&
              aPropertyTypes == sAdapterProperties &&
              propertyName.EqualsLiteral("Name")) {
     MOZ_ASSERT(propertyValue.type() == BluetoothValue::TnsString);
 
     // Notify BluetoothManager whenever adapter name is ready.
     if (!propertyValue.get_nsString().IsEmpty()) {
       sAdapterNameIsReady = true;
-      NS_DispatchToMainThread(new TryFiringAdapterAddedTask());
+      NS_DispatchToMainThread(new TryFiringAdapterAddedRunnable(false));
     }
   }
 
   aProperties.AppendElement(BluetoothNamedValue(propertyName, propertyValue));
   return true;
 }
 
 static void
@@ -1300,16 +1344,18 @@ class PrepareAdapterRunnable : public ns
 {
 public:
   PrepareAdapterRunnable(const nsAString& aAdapterPath)
     : mAdapterPath(aAdapterPath)
   { }
 
   NS_IMETHOD Run()
   {
+    MOZ_ASSERT(NS_IsMainThread());
+
     static const dbus_uint32_t sServices[] = {
       BluetoothServiceClass::HANDSFREE_AG,
       BluetoothServiceClass::HEADSET_AG,
       BluetoothServiceClass::OBJECT_PUSH
     };
 
     MOZ_ASSERT(NS_IsMainThread());
 
@@ -1571,16 +1617,17 @@ EventFilter(DBusConnection* aConn, DBusM
     const char* str;
     if (!dbus_message_get_args(aMsg, &err,
                                DBUS_TYPE_OBJECT_PATH, &str,
                                DBUS_TYPE_INVALID)) {
       LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, aMsg);
       errorStr.AssignLiteral("Cannot parse manager path!");
     } else {
       v = NS_ConvertUTF8toUTF16(str);
+      NS_DispatchToMainThread(new TryFiringAdapterAddedRunnable(true));
       NS_DispatchToMainThread(new PrepareAdapterRunnable(v.get_nsString()));
 
       /**
        * The adapter name isn't ready for the time being. Wait for the upcoming
        * signal PropertyChanged of adapter name, and then propagate signal
        * AdapterAdded to BluetoothManager.
        */
       return DBUS_HANDLER_RESULT_HANDLED;
@@ -3019,51 +3066,50 @@ BluetoothDBusService::ConfirmReceivingFi
 }
 
 void
 BluetoothDBusService::ConnectSco(BluetoothReplyRunnable* aRunnable)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
-  NS_ENSURE_TRUE_VOID(hfp);
-  if (!hfp->ConnectSco(aRunnable)) {
-    NS_NAMED_LITERAL_STRING(replyError,
-      "SCO socket exists or HFP is not connected");
+  if (!hfp || !hfp->ConnectSco(aRunnable)) {
+    NS_NAMED_LITERAL_STRING(replyError, "Calling ConnectSco() failed");
     DispatchBluetoothReply(aRunnable, BluetoothValue(), replyError);
   }
 }
 
 void
 BluetoothDBusService::DisconnectSco(BluetoothReplyRunnable* aRunnable)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
-  NS_ENSURE_TRUE_VOID(hfp);
-  if (hfp->DisconnectSco()) {
-    DispatchBluetoothReply(aRunnable,
-                           BluetoothValue(true), NS_LITERAL_STRING(""));
+  if (!hfp || !hfp->DisconnectSco()) {
+    NS_NAMED_LITERAL_STRING(replyError, "Calling DisconnectSco() failed");
+    DispatchBluetoothReply(aRunnable, BluetoothValue(), replyError);
     return;
   }
 
-  NS_NAMED_LITERAL_STRING(replyError,
-    "SCO socket doesn't exist or HFP is not connected");
-  DispatchBluetoothReply(aRunnable, BluetoothValue(), replyError);
+  DispatchBluetoothReply(aRunnable, BluetoothValue(true), EmptyString());
 }
 
 void
 BluetoothDBusService::IsScoConnected(BluetoothReplyRunnable* aRunnable)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
-  NS_ENSURE_TRUE_VOID(hfp);
-  DispatchBluetoothReply(aRunnable,
-                         hfp->IsScoConnected(), EmptyString());
+  if (!hfp) {
+    NS_NAMED_LITERAL_STRING(replyError, "Fail to get BluetoothHfpManager");
+    DispatchBluetoothReply(aRunnable, BluetoothValue(), replyError);
+    return;
+  }
+
+  DispatchBluetoothReply(aRunnable, hfp->IsScoConnected(), EmptyString());
 }
 
 void
 BluetoothDBusService::SendMetaData(const nsAString& aTitle,
                                    const nsAString& aArtist,
                                    const nsAString& aAlbum,
                                    int64_t aMediaNumber,
                                    int64_t aTotalMediaCount,
--- a/dom/browser-element/BrowserElementChildPreload.js
+++ b/dom/browser-element/BrowserElementChildPreload.js
@@ -834,28 +834,28 @@ BrowserElementChild.prototype = {
       sendAsyncMsg('visibilitychange', {visible: visible});
     }
   },
 
   _recvSendMouseEvent: function(data) {
     let json = data.json;
     let utils = content.QueryInterface(Ci.nsIInterfaceRequestor)
                        .getInterface(Ci.nsIDOMWindowUtils);
-    utils.sendMouseEvent(json.type, json.x, json.y, json.button,
-                         json.clickCount, json.modifiers);
+    utils.sendMouseEventToWindow(json.type, json.x, json.y, json.button,
+                                 json.clickCount, json.modifiers);
   },
 
   _recvSendTouchEvent: function(data) {
     let json = data.json;
     let utils = content.QueryInterface(Ci.nsIInterfaceRequestor)
                        .getInterface(Ci.nsIDOMWindowUtils);
-    utils.sendTouchEvent(json.type, json.identifiers, json.touchesX,
-                         json.touchesY, json.radiisX, json.radiisY,
-                         json.rotationAngles, json.forces, json.count,
-                         json.modifiers);
+    utils.sendTouchEventToWindow(json.type, json.identifiers, json.touchesX,
+                                 json.touchesY, json.radiisX, json.radiisY,
+                                 json.rotationAngles, json.forces, json.count,
+                                 json.modifiers);
   },
 
   _recvCanGoBack: function(data) {
     var webNav = docShell.QueryInterface(Ci.nsIWebNavigation);
     sendAsyncMsg('got-can-go-back', {
       id: data.json.id,
       successRv: webNav.canGoBack
     });
--- a/dom/browser-element/mochitest/Makefile.in
+++ b/dom/browser-element/mochitest/Makefile.in
@@ -227,30 +227,28 @@ MOCHITEST_FILES += \
 		test_browserElement_oop_BackForward.html \
 		test_browserElement_oop_Reload.html \
 		test_browserElement_oop_Stop.html \
 		test_browserElement_oop_ScrollEvent.html \
 		test_browserElement_oop_Auth.html \
 		test_browserElement_oop_RemoveBrowserElement.html \
 		test_browserElement_oop_DOMRequestError.html \
 		test_browserElement_oop_AppFramePermission.html \
-		test_browserElement_oop_ExposableURI.html \
 		test_browserElement_oop_FrameWrongURI.html \
 		test_browserElement_oop_ReloadPostRequest.html \
 		test_browserElement_oop_PurgeHistory.html \
 		test_browserElement_oop_DocumentFirstPaint.html \
 		test_browserElement_oop_VisibilityChange.html \
 		test_browserElement_oop_BrowserWindowResize.html \
 	$(NULL)
 
 # Disabled until bug 930449 makes it stop timing out
 #		test_browserElement_oop_ContextmenuEvents.html \
 
-# Disabled until bug 924771 makes it stop timing out
+# Disabled until bug 924771 makes them stop timing out
 # 		test_browserElement_oop_CloseFromOpener.html \
+#		test_browserElement_oop_CloseApp.html \
+#		test_browserElement_oop_ExposableURI.html \
 
 # Disabled until we fix bug 906096.
 #		test_browserElement_oop_SetInputMethodActive.html \
 
-# Disabled until we fix bug 925200
-#		test_browserElement_oop_CloseApp.html \
-
 endif #}
--- a/dom/icc/tests/marionette/manifest.ini
+++ b/dom/icc/tests/marionette/manifest.ini
@@ -2,17 +2,16 @@
 b2g = true
 browser = false
 qemu = true
 
 [test_stk_proactive_command.js]
 [test_icc_contact.js]
 [test_icc_card_lock.js]
 [test_icc_card_state.js]
-disabled = Bug 946178
 [test_stk_refresh.js]
 [test_stk_poll_off.js]
 [test_stk_setup_event_list.js]
 [test_stk_setup_call.js]
 [test_stk_send_ss.js]
 [test_stk_send_ussd.js]
 [test_stk_send_sms.js]
 [test_stk_send_dtmf.js]
@@ -20,11 +19,9 @@ disabled = Bug 946178
 [test_stk_display_text.js]
 [test_stk_get_inkey.js]
 [test_stk_get_input.js]
 [test_stk_select_item.js]
 [test_stk_setup_menu.js]
 [test_stk_setup_idle_mode_text.js]
 [test_stk_bip_command.js]
 [test_icc_access_invalid_object.js]
-disabled = Bug 946178
 [test_icc_detected_undetected_event.js]
-disabled = Bug 946178
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
@@ -38,17 +38,17 @@ interface nsIDOMFile;
 interface nsIFile;
 interface nsIDOMTouch;
 interface nsIDOMClientRect;
 interface nsIURI;
 interface nsIDOMEventTarget;
 interface nsIRunnable;
 interface nsICompositionStringSynthesizer;
 
-[scriptable, uuid(3772df78-905f-40cf-952f-e4954c63d0ec)]
+[scriptable, uuid(3d9bf70c-5b83-11e3-9090-3c970e9f4238)]
 interface nsIDOMWindowUtils : nsISupports {
 
   /**
    * Image animation mode of the window. When this attribute's value
    * is changed, the implementation should set all images in the window
    * to the given value. That is, when set to kDontAnimMode, all images
    * will stop animating. The attribute's value must be one of the
    * animationMode values from imgIContainer.
@@ -308,16 +308,31 @@ interface nsIDOMWindowUtils : nsISupport
                               in float aY,
                               in long aButton,
                               in long aClickCount,
                               in long aModifiers,
                               [optional] in boolean aIgnoreRootScrollFrame,
                               [optional] in float aPressure,
                               [optional] in unsigned short aInputSourceArg);
 
+  /** The same as sendTouchEvent but ensures that the event is dispatched to
+   *  this DOM window or one of its children.
+   */
+  boolean sendTouchEventToWindow(in AString aType,
+                                 [array, size_is(count)] in uint32_t aIdentifiers,
+                                 [array, size_is(count)] in int32_t aXs,
+                                 [array, size_is(count)] in int32_t aYs,
+                                 [array, size_is(count)] in uint32_t aRxs,
+                                 [array, size_is(count)] in uint32_t aRys,
+                                 [array, size_is(count)] in float aRotationAngles,
+                                 [array, size_is(count)] in float aForces,
+                                 in uint32_t count,
+                                 in long aModifiers,
+                                 [optional] in boolean aIgnoreRootScrollFrame);
+
   /** Synthesize a wheel event for a window. The event types supported is only
    *  wheel.
    *
    * Events are sent in coordinates offset by aX and aY from the window.
    *
    * Cannot be accessed from unprivileged context (not content-accessible)
    * Will throw a DOM security error if called without chrome privileges.
    *
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -1405,35 +1405,37 @@ ContentChild::RecvFilePathUpdate(const n
 }
 
 bool
 ContentChild::RecvFileSystemUpdate(const nsString& aFsName,
                                    const nsString& aVolumeName,
                                    const int32_t& aState,
                                    const int32_t& aMountGeneration,
                                    const bool& aIsMediaPresent,
-                                   const bool& aIsSharing)
+                                   const bool& aIsSharing,
+                                   const bool& aIsFormatting)
 {
 #ifdef MOZ_WIDGET_GONK
     nsRefPtr<nsVolume> volume = new nsVolume(aFsName, aVolumeName, aState,
                                              aMountGeneration, aIsMediaPresent,
-                                             aIsSharing);
+                                             aIsSharing, aIsFormatting);
 
     nsRefPtr<nsVolumeService> vs = nsVolumeService::GetSingleton();
     if (vs) {
         vs->UpdateVolume(volume);
     }
 #else
     // Remove warnings about unused arguments
     unused << aFsName;
     unused << aVolumeName;
     unused << aState;
     unused << aMountGeneration;
     unused << aIsMediaPresent;
     unused << aIsSharing;
+    unused << aIsFormatting;
 #endif
     return true;
 }
 
 bool
 ContentChild::RecvNotifyProcessPriorityChanged(
     const hal::ProcessPriority& aPriority)
 {
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -222,17 +222,18 @@ public:
                                     const nsString& aStorageName,
                                     const nsString& aPath,
                                     const nsCString& aReason);
     virtual bool RecvFileSystemUpdate(const nsString& aFsName,
                                       const nsString& aVolumeName,
                                       const int32_t& aState,
                                       const int32_t& aMountGeneration,
                                       const bool& aIsMediaPresent,
-                                      const bool& aIsSharing);
+                                      const bool& aIsSharing,
+                                      const bool& aIsFormatting);
 
     virtual bool RecvNuwaFork() MOZ_OVERRIDE;
 
     virtual bool RecvNotifyProcessPriorityChanged(const hal::ProcessPriority& aPriority);
     virtual bool RecvMinimizeMemoryUsage();
     virtual bool RecvCancelMinimizeMemoryUsage();
 
     virtual bool RecvLoadAndRegisterSheet(const URIParams& aURI, const uint32_t& aType);
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -1860,27 +1860,29 @@ ContentParent::Observe(nsISupports* aSub
         }
 
         nsString volName;
         nsString mountPoint;
         int32_t  state;
         int32_t  mountGeneration;
         bool     isMediaPresent;
         bool     isSharing;
+        bool     isFormatting;
 
         vol->GetName(volName);
         vol->GetMountPoint(mountPoint);
         vol->GetState(&state);
         vol->GetMountGeneration(&mountGeneration);
         vol->GetIsMediaPresent(&isMediaPresent);
         vol->GetIsSharing(&isSharing);
+        vol->GetIsFormatting(&isFormatting);
 
         unused << SendFileSystemUpdate(volName, mountPoint, state,
                                        mountGeneration, isMediaPresent,
-                                       isSharing);
+                                       isSharing, isFormatting);
     } else if (!strcmp(aTopic, "phone-state-changed")) {
         nsString state(aData);
         unused << SendNotifyPhoneStateChange(state);
     }
 #endif
 #ifdef ACCESSIBILITY
     // Make sure accessibility is running in content process when accessibility
     // gets initiated in chrome process.
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -304,17 +304,17 @@ child:
     // Notify child that last-pb-context-exited notification was observed
     LastPrivateDocShellDestroyed();
 
     FilePathUpdate(nsString storageType, nsString storageName, nsString filepath,
                    nsCString reasons);
 
     FileSystemUpdate(nsString fsName, nsString mountPoint, int32_t fsState,
                      int32_t mountGeneration, bool isMediaPresent,
-                     bool isSharing);
+                     bool isSharing, bool isFormatting);
 
     // Ask the Nuwa process to create a new child process.
     NuwaFork();
 
     NotifyProcessPriorityChanged(ProcessPriority priority);
     MinimizeMemoryUsage();
     CancelMinimizeMemoryUsage();
 
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -524,30 +524,29 @@ TabChild::HandlePossibleViewportChange()
   }
 
   nsCOMPtr<nsIDOMDocument> domDoc;
   mWebNav->GetDocument(getter_AddRefs(domDoc));
   nsCOMPtr<nsIDocument> document(do_QueryInterface(domDoc));
 
   nsCOMPtr<nsIDOMWindowUtils> utils(GetDOMWindowUtils());
 
+  nsViewportInfo viewportInfo = nsContentUtils::GetViewportInfo(document, mInnerSize);
   uint32_t presShellId;
   ViewID viewId;
-  if (!APZCCallbackHelper::GetScrollIdentifiers(document->GetDocumentElement(),
-                                                &presShellId, &viewId)) {
-    return;
+  if (APZCCallbackHelper::GetScrollIdentifiers(document->GetDocumentElement(),
+                                               &presShellId, &viewId)) {
+    SendUpdateZoomConstraints(presShellId,
+                              viewId,
+                              /* isRoot = */ true,
+                              viewportInfo.IsZoomAllowed(),
+                              viewportInfo.GetMinZoom(),
+                              viewportInfo.GetMaxZoom());
   }
 
-  nsViewportInfo viewportInfo = nsContentUtils::GetViewportInfo(document, mInnerSize);
-  SendUpdateZoomConstraints(presShellId,
-                            viewId,
-                            /* isRoot = */ true,
-                            viewportInfo.IsZoomAllowed(),
-                            viewportInfo.GetMinZoom(),
-                            viewportInfo.GetMaxZoom());
 
   float screenW = mInnerSize.width;
   float screenH = mInnerSize.height;
   CSSSize viewport(viewportInfo.GetSize());
 
   // We're not being displayed in any way; don't bother doing anything because
   // that will just confuse future adjustments.
   if (!screenW || !screenH) {
--- a/dom/network/tests/marionette/manifest.ini
+++ b/dom/network/tests/marionette/manifest.ini
@@ -14,9 +14,8 @@ disabled = Bug 808783
 [test_mobile_data_location.js]
 [test_mobile_data_state.js]
 [test_mobile_mmi.js]
 [test_mobile_roaming_preference.js]
 [test_call_barring_get_option.js]
 [test_call_barring_set_error.js]
 [test_call_barring_change_password.js]
 [test_mobile_set_radio.js]
-disabled = Bug 946178
--- a/dom/plugins/base/moz.build
+++ b/dom/plugins/base/moz.build
@@ -102,17 +102,17 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'andr
 MSVC_ENABLE_PGO = True
 
 LOCAL_INCLUDES += [
     '/content/base/src',
     '/dom/base',
     '/gfx/skia/include/config',
     '/gfx/skia/include/core',
     '/layout/generic',
-    '/layout/xul/base/src',
+    '/layout/xul',
     '/widget/android',
     '/widget/xpwidgets',
     '/xpcom/base',
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
     LOCAL_INCLUDES += [
         '/dom/plugins/base/android',
--- a/dom/plugins/base/nsJSNPRuntime.cpp
+++ b/dom/plugins/base/nsJSNPRuntime.cpp
@@ -339,19 +339,17 @@ NPVariantToJSVal(NPP npp, JSContext *cx,
       return ::JS_NumberValue(NPVARIANT_TO_DOUBLE(*variant));
     }
   case NPVariantType_String :
     {
       const NPString *s = &NPVARIANT_TO_STRING(*variant);
       NS_ConvertUTF8toUTF16 utf16String(s->UTF8Characters, s->UTF8Length);
 
       JSString *str =
-        ::JS_NewUCStringCopyN(cx, reinterpret_cast<const jschar*>
-                                                  (utf16String.get()),
-                              utf16String.Length());
+        ::JS_NewUCStringCopyN(cx, utf16String.get(), utf16String.Length());
 
       if (str) {
         return STRING_TO_JSVAL(str);
       }
 
       break;
     }
   case NPVariantType_Object:
@@ -466,18 +464,17 @@ ThrowJSException(JSContext *cx, const ch
     }
 
     AppendUTF8toUTF16(ex, ucex);
 
     if (message) {
       AppendASCIItoUTF16("].", ucex);
     }
 
-    JSString *str = ::JS_NewUCStringCopyN(cx, (jschar *)ucex.get(),
-                                          ucex.Length());
+    JSString *str = ::JS_NewUCStringCopyN(cx, ucex.get(), ucex.Length());
 
     if (str) {
       JS::Rooted<JS::Value> exn(cx, JS::StringValue(str));
       ::JS_SetPendingException(cx, exn);
     }
 
     PopException();
   } else {
--- a/dom/plugins/base/nsNPAPIPlugin.cpp
+++ b/dom/plugins/base/nsNPAPIPlugin.cpp
@@ -680,18 +680,17 @@ GetChannelFromNPP(NPP npp)
   return channel.forget();
 }
 
 static NPIdentifier
 doGetIdentifier(JSContext *cx, const NPUTF8* name)
 {
   NS_ConvertUTF8toUTF16 utf16name(name);
 
-  JSString *str = ::JS_InternUCStringN(cx, (jschar *)utf16name.get(),
-                                       utf16name.Length());
+  JSString *str = ::JS_InternUCStringN(cx, utf16name.get(), utf16name.Length());
 
   if (!str)
     return nullptr;
 
   return StringToNPIdentifier(cx, str);
 }
 
 #if defined(MOZ_MEMORY_WINDOWS)
--- a/dom/plugins/base/nsPluginsDirWin.cpp
+++ b/dom/plugins/base/nsPluginsDirWin.cpp
@@ -31,17 +31,17 @@
 #define SHOCKWAVE_BASE_FILENAME L"np32dsw"
 /**
  * Determines whether or not SetDllDirectory should be called for this plugin.
  *
  * @param pluginFilePath The full path of the plugin file
  * @return true if SetDllDirectory can be called for the plugin
  */
 bool
-ShouldProtectPluginCurrentDirectory(LPCWSTR pluginFilePath)
+ShouldProtectPluginCurrentDirectory(char16ptr_t pluginFilePath)
 {
   LPCWSTR passedInFilename = PathFindFileName(pluginFilePath);
   if (!passedInFilename) {
     return true;
   }
 
   // Somewhere in the middle of 11.6 version of Shockwave, naming of the DLL
   // after its version number is introduced.
@@ -173,17 +173,17 @@ static void FreeStringArray(uint32_t var
     if (array[i]) {
       PL_strfree(array[i]);
       array[i] = nullptr;
     }
   }
   PR_Free(array);
 }
 
-static bool CanLoadPlugin(const PRUnichar* aBinaryPath)
+static bool CanLoadPlugin(char16ptr_t aBinaryPath)
 {
 #if defined(_M_IX86) || defined(_M_X64) || defined(_M_IA64)
   bool canLoad = false;
 
   HANDLE file = CreateFileW(aBinaryPath, GENERIC_READ,
                             FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr,
                             OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
   if (file != INVALID_HANDLE_VALUE) {
--- a/dom/plugins/ipc/PluginInstanceChild.cpp
+++ b/dom/plugins/ipc/PluginInstanceChild.cpp
@@ -15,17 +15,17 @@
 #include "gfxContext.h"
 #include "nsNPAPIPluginInstance.h"
 #ifdef MOZ_X11
 #include "gfxXlibSurface.h"
 #endif
 #ifdef XP_WIN
 #include "mozilla/gfx/SharedDIBSurface.h"
 #include "nsCrashOnException.h"
-extern const PRUnichar* kFlashFullscreenClass;
+extern const wchar_t* kFlashFullscreenClass;
 using mozilla::gfx::SharedDIBSurface;
 #endif
 #include "gfxSharedImageSurface.h"
 #include "gfxUtils.h"
 #include "gfxAlphaRecovery.h"
 
 #include "mozilla/Util.h"
 #include "mozilla/ipc/MessageChannel.h"
@@ -1471,17 +1471,17 @@ PluginInstanceChild::PluginWindowProcInt
                                  lParam);
 
     // Make sure capture is released by the child on mouse events. Fixes a
     // problem with flash full screen mode mouse input. Appears to be
     // caused by a bug in flash, since we are not setting the capture
     // on the window.
     if (message == WM_LBUTTONDOWN &&
         self->GetQuirks() & PluginModuleChild::QUIRK_FLASH_FIXUP_MOUSE_CAPTURE) {
-      PRUnichar szClass[26];
+      wchar_t szClass[26];
       HWND hwnd = GetForegroundWindow();
       if (hwnd && GetClassNameW(hwnd, szClass,
                                 sizeof(szClass)/sizeof(PRUnichar)) &&
           !wcscmp(szClass, kFlashFullscreenClass)) {
         ReleaseCapture();
         SetFocus(hwnd);
       }
     }
@@ -1670,17 +1670,17 @@ PluginInstanceChild::TrackPopupHookProc(
   if (!sUser32TrackPopupMenuStub) {
       NS_ERROR("TrackPopupMenu stub isn't set! Badness!");
       return 0;
   }
 
   // Only change the parent when we know this is a context on the plugin
   // surface within the browser. Prevents resetting the parent on child ui
   // displayed by plugins that have working parent-child relationships.
-  PRUnichar szClass[21];
+  wchar_t szClass[21];
   bool haveClass = GetClassNameW(hWnd, szClass, ArrayLength(szClass));
   if (!haveClass || 
       (wcscmp(szClass, L"MozillaWindowClass") &&
        wcscmp(szClass, L"SWFlash_Placeholder"))) {
       // Unrecognized parent
       return sUser32TrackPopupMenuStub(hMenu, uFlags, x, y, nReserved,
                                        hWnd, prcRect);
   }
@@ -2056,17 +2056,17 @@ PluginInstanceChild::EnumThreadWindowsCa
                                                LPARAM aParam)
 {
     PluginInstanceChild* self = reinterpret_cast<PluginInstanceChild*>(aParam);
     if (!self) {
         NS_NOTREACHED("Enum befuddled!");
         return FALSE;
     }
 
-    PRUnichar className[64];
+    wchar_t className[64];
     if (!GetClassNameW(hWnd, className, sizeof(className)/sizeof(PRUnichar)))
       return TRUE;
     
     if (!wcscmp(className, L"SWFlash_PlaceholderX")) {
         WNDPROC oldWndProc =
             reinterpret_cast<WNDPROC>(GetWindowLongPtr(hWnd, GWLP_WNDPROC));
         // Only set this if we haven't already.
         if (oldWndProc != WinlessHiddenFlashWndProc) {
--- a/dom/plugins/ipc/PluginInstanceParent.cpp
+++ b/dom/plugins/ipc/PluginInstanceParent.cpp
@@ -37,20 +37,20 @@
 #endif
 
 #if defined(OS_WIN)
 #include <windowsx.h>
 #include "gfxWindowsPlatform.h"
 #include "mozilla/plugins/PluginSurfaceParent.h"
 
 // Plugin focus event for widget.
-extern const PRUnichar* kOOPPPluginFocusEventId;
+extern const wchar_t* kOOPPPluginFocusEventId;
 UINT gOOPPPluginFocusEvent =
     RegisterWindowMessage(kOOPPPluginFocusEventId);
-extern const PRUnichar* kFlashFullscreenClass;
+extern const wchar_t* kFlashFullscreenClass;
 #elif defined(MOZ_WIDGET_GTK)
 #include <gdk/gdk.h>
 #elif defined(XP_MACOSX)
 #include <ApplicationServices/ApplicationServices.h>
 #endif // defined(XP_MACOSX)
 
 using namespace mozilla::plugins;
 using namespace mozilla::layers;
@@ -1208,17 +1208,17 @@ PluginInstanceParent::NPP_HandleEvent(vo
             case WM_KILLFOCUS:
             {
               // When the user selects fullscreen mode in Flash video players,
               // WM_KILLFOCUS will be delayed by deferred event processing:
               // WM_LBUTTONUP results in a call to CreateWindow within Flash,
               // which fires WM_KILLFOCUS. Delayed delivery causes Flash to
               // misinterpret the event, dropping back out of fullscreen. Trap
               // this event and drop it.
-              PRUnichar szClass[26];
+              wchar_t szClass[26];
               HWND hwnd = GetForegroundWindow();
               if (hwnd && hwnd != mPluginHWND &&
                   GetClassNameW(hwnd, szClass,
                                 sizeof(szClass)/sizeof(PRUnichar)) &&
                   !wcscmp(szClass, kFlashFullscreenClass)) {
                   return 0;
               }
             }
@@ -1796,17 +1796,17 @@ PluginInstanceParent::RecvReleaseDXGISha
     that over ipc to the child which calls set focus on itself. 
 
   focus from child -> focus manager:
     Child picks up the local wm_setfocus and sends it via ipc over
     here. We then post a custom event to widget/windows/nswindow
     which fires off a gui event letting the browser know.
 */
 
-static const PRUnichar kPluginInstanceParentProperty[] =
+static const wchar_t kPluginInstanceParentProperty[] =
                          L"PluginInstanceParentProperty";
 
 // static
 LRESULT CALLBACK
 PluginInstanceParent::PluginWindowHookProc(HWND hWnd,
                                            UINT message,
                                            WPARAM wParam,
                                            LPARAM lParam)
--- a/dom/plugins/ipc/PluginModuleChild.cpp
+++ b/dom/plugins/ipc/PluginModuleChild.cpp
@@ -59,18 +59,18 @@
 #include "GeckoProfiler.h"
 
 using namespace mozilla;
 using namespace mozilla::plugins;
 using mozilla::dom::CrashReporterChild;
 using mozilla::dom::PCrashReporterChild;
 
 #if defined(XP_WIN)
-const PRUnichar * kFlashFullscreenClass = L"ShockwaveFlashFullScreen";
-const PRUnichar * kMozillaWindowClass = L"MozillaWindowClass";
+const wchar_t * kFlashFullscreenClass = L"ShockwaveFlashFullScreen";
+const wchar_t * kMozillaWindowClass = L"MozillaWindowClass";
 #endif
 
 namespace {
 PluginModuleChild* gInstance = nullptr;
 }
 
 #ifdef MOZ_WIDGET_QT
 typedef void (*_gtk_init_fn)(int argc, char **argv);
@@ -1905,17 +1905,17 @@ PMCGetWindowInfoHook(HWND hWnd, PWINDOWI
       return FALSE;
 
   if (!sGetWindowInfoPtrStub) {
      NS_ASSERTION(FALSE, "Something is horribly wrong in PMCGetWindowInfoHook!");
      return FALSE;
   }
 
   if (!sBrowserHwnd) {
-      PRUnichar szClass[20];
+      wchar_t szClass[20];
       if (GetClassNameW(hWnd, szClass, ArrayLength(szClass)) &&
           !wcscmp(szClass, kMozillaWindowClass)) {
           sBrowserHwnd = hWnd;
       }
   }
   // Oddity: flash does strange rect comparisons for mouse input destined for
   // it's internal settings window. Post removing sub widgets for tabs, touch
   // this up so they get the rect they expect.
@@ -2326,17 +2326,17 @@ PluginModuleChild::CallWindowProcHook(in
     if (nCode >= 0 &&
         (InSendMessageEx(nullptr)&(ISMEX_REPLIED|ISMEX_SEND)) == ISMEX_SEND) {
         CWPSTRUCT* pCwp = reinterpret_cast<CWPSTRUCT*>(lParam);
         if (pCwp->message == WM_KILLFOCUS) {
             // Fix for flash fullscreen window loosing focus. On single
             // core systems, sync killfocus events need to be handled
             // after the flash fullscreen window procedure processes this
             // message, otherwise fullscreen focus will not work correctly.
-            PRUnichar szClass[26];
+            wchar_t szClass[26];
             if (GetClassNameW(pCwp->hwnd, szClass,
                               sizeof(szClass)/sizeof(PRUnichar)) &&
                 !wcscmp(szClass, kFlashFullscreenClass)) {
                 gDelayFlashFocusReplyUntilEval = true;
             }
         }
     }
 
--- a/dom/plugins/ipc/PluginProcessChild.cpp
+++ b/dom/plugins/ipc/PluginProcessChild.cpp
@@ -10,17 +10,17 @@
 #include "prlink.h"
 
 #include "base/command_line.h"
 #include "base/string_util.h"
 #include "chrome/common/chrome_switches.h"
 
 #ifdef XP_WIN
 #include <objbase.h>
-bool ShouldProtectPluginCurrentDirectory(LPCWSTR pluginFilePath);
+bool ShouldProtectPluginCurrentDirectory(char16ptr_t pluginFilePath);
 #endif
 
 using mozilla::ipc::IOThreadChild;
 
 #ifdef OS_WIN
 #include "nsSetDllDirectory.h"
 #include <algorithm>
 
--- a/dom/system/gonk/nsVolume.h
+++ b/dom/system/gonk/nsVolume.h
@@ -24,26 +24,27 @@ public:
 
   // This constructor is used by the UpdateVolumeRunnable constructor
   nsVolume(const Volume* aVolume);
 
   // This constructor is used by ContentChild::RecvFileSystemUpdate which is
   // used to update the volume cache maintained in the child process.
   nsVolume(const nsAString& aName, const nsAString& aMountPoint,
            const int32_t& aState, const int32_t& aMountGeneration,
-           const bool& aIsMediaPresent, const bool& aIsSharing)
+           const bool& aIsMediaPresent, const bool& aIsSharing,
+           const bool& aIsFormatting)
     : mName(aName),
       mMountPoint(aMountPoint),
       mState(aState),
       mMountGeneration(aMountGeneration),
       mMountLocked(false),
       mIsFake(false),
       mIsMediaPresent(aIsMediaPresent),
       mIsSharing(aIsSharing),
-      mIsFormatting(false)
+      mIsFormatting(aIsFormatting)
   {
   }
 
   // This constructor is used by nsVolumeService::FindAddVolumeByName, and
   // will be followed shortly by a Set call.
   nsVolume(const nsAString& aName)
     : mName(aName),
       mState(STATE_INIT),
--- a/dom/system/gonk/nsVolumeService.cpp
+++ b/dom/system/gonk/nsVolumeService.cpp
@@ -243,17 +243,18 @@ nsVolumeService::CreateOrGetVolumeByPath
   }
 
   // In order to support queries by the updater, we will fabricate a volume
   // from the pathname, so that the caller can determine the volume size.
   nsCOMPtr<nsIVolume> vol = new nsVolume(NS_LITERAL_STRING("fake"),
                                          aPath, nsIVolume::STATE_MOUNTED,
                                          -1    /* generation */,
                                          true  /* isMediaPresent*/,
-                                         false /* isSharing */);
+                                         false /* isSharing */,
+                                         false /* isFormatting */);
   vol.forget(aResult);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsVolumeService::GetVolumeNames(nsTArray<nsString>& aVolNames)
 {
   MonitorAutoLock autoLock(mArrayMonitor);
@@ -375,17 +376,18 @@ nsVolumeService::UpdateVolume(nsIVolume*
 
 NS_IMETHODIMP
 nsVolumeService::CreateFakeVolume(const nsAString& name, const nsAString& path)
 {
   if (XRE_GetProcessType() == GeckoProcessType_Default) {
     nsRefPtr<nsVolume> vol = new nsVolume(name, path, nsIVolume::STATE_INIT,
                                           -1    /* mountGeneration */,
                                           true  /* isMediaPresent */,
-                                          false /* isSharing */);
+                                          false /* isSharing */,
+                                          false /* isFormatting */);
     vol->SetIsFake(true);
     vol->LogState();
     UpdateVolume(vol.get());
     return NS_OK;
   }
 
   ContentChild::GetSingleton()->SendCreateFakeVolume(nsString(name), nsString(path));
   return NS_OK;
--- a/dom/telephony/test/marionette/manifest.ini
+++ b/dom/telephony/test/marionette/manifest.ini
@@ -7,17 +7,16 @@ qemu = true
 [test_incoming_answer_hangup.js]
 [test_incoming_reject.js]
 [test_outgoing_answer_hangup.js]
 [test_incoming_answer_hangup_oncallschanged.js]
 [test_outgoing_answer_hangup_oncallschanged.js]
 [test_outgoing_hangup_alerting.js]
 [test_outgoing_hangup_held.js]
 [test_outgoing_radio_off.js]
-disabled = Bug 946178
 [test_outgoing_badNumber.js]
 [test_outgoing_busy.js]
 [test_outgoing_reject.js]
 [test_incoming_hold_resume.js]
 [test_outgoing_hold_resume.js]
 [test_incoming_already_connected.js]
 [test_incoming_answer_remote_hangup.js]
 [test_incoming_connecting_hangup.js]
@@ -37,13 +36,12 @@ disabled = Bug 820802
 disabled = Bug 820802
 [test_outgoing_onstatechange.js]
 disabled = Bug 821966
 [test_redundant_operations.js]
 disabled = Bug 821927
 [test_multiple_hold.js]
 disabled = Bug 821958
 [test_outgoing_emergency_in_airplane_mode.js]
-disabled = Bug 946178
 [test_emergency_label.js]
 [test_conference.js]
 [test_dsds_default_service_id.js]
 [test_call_mute.js]
--- a/editor/libeditor/html/moz.build
+++ b/editor/libeditor/html/moz.build
@@ -31,12 +31,12 @@ FAIL_ON_WARNINGS = True
 LOCAL_INCLUDES += [
     '../base',
     '../text',
     '/content/base/src',
     '/editor/txmgr/src',
     '/layout/generic',
     '/layout/style',
     '/layout/tables',
-    '/layout/xul/base/src',
+    '/layout/xul',
 ]
 
 FINAL_LIBRARY = 'gklayout'
--- a/gfx/harfbuzz/src/hb-atomic-private.hh
+++ b/gfx/harfbuzz/src/hb-atomic-private.hh
@@ -73,17 +73,17 @@ typedef LONG hb_atomic_int_t;
 
 typedef int32_t hb_atomic_int_t;
 #define hb_atomic_int_add(AI, V)	(OSAtomicAdd32Barrier ((V), &(AI)) - (V))
 
 #define hb_atomic_ptr_get(P)		(OSMemoryBarrier (), (void *) *(P))
 #if (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4 || __IPHONE_VERSION_MIN_REQUIRED >= 20100)
 #define hb_atomic_ptr_cmpexch(P,O,N)	OSAtomicCompareAndSwapPtrBarrier ((void *) (O), (void *) (N), (void **) (P))
 #else
-#if __ppc64__ || __x86_64__
+#if __ppc64__ || __x86_64__ || __arm64__
 #define hb_atomic_ptr_cmpexch(P,O,N)    OSAtomicCompareAndSwap64Barrier ((int64_t) (O), (int64_t) (N), (int64_t*) (P))
 #else
 #define hb_atomic_ptr_cmpexch(P,O,N)    OSAtomicCompareAndSwap32Barrier ((int32_t) (O), (int32_t) (N), (int32_t*) (P))
 #endif
 #endif
 
 
 #elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES)
--- a/gfx/harfbuzz/src/hb-buffer-private.hh
+++ b/gfx/harfbuzz/src/hb-buffer-private.hh
@@ -176,22 +176,23 @@ struct hb_buffer_t {
 				   unsigned int end);
   HB_INTERNAL void merge_out_clusters (unsigned int start,
 				       unsigned int end);
 
   /* Internal methods */
   HB_INTERNAL bool enlarge (unsigned int size);
 
   inline bool ensure (unsigned int size)
-  { return likely (size < allocated) ? true : enlarge (size); }
+  { return likely (!size || size < allocated) ? true : enlarge (size); }
 
   HB_INTERNAL bool make_room_for (unsigned int num_in, unsigned int num_out);
   HB_INTERNAL bool shift_forward (unsigned int count);
 
-  HB_INTERNAL void *get_scratch_buffer (unsigned int *size);
+  typedef long scratch_buffer_t;
+  HB_INTERNAL scratch_buffer_t *get_scratch_buffer (unsigned int *size);
 
   inline void clear_context (unsigned int side) { context_len[side] = 0; }
 };
 
 
 #define HB_BUFFER_XALLOCATE_VAR(b, func, var, owner) \
   b->func (offsetof (hb_glyph_info_t, var) - offsetof(hb_glyph_info_t, var1), \
 	   sizeof (b->info[0].var), owner)
--- a/gfx/harfbuzz/src/hb-buffer.cc
+++ b/gfx/harfbuzz/src/hb-buffer.cc
@@ -147,27 +147,28 @@ hb_buffer_t::shift_forward (unsigned int
 
   memmove (info + idx + count, info + idx, (len - idx) * sizeof (info[0]));
   len += count;
   idx += count;
 
   return true;
 }
 
-void *
+hb_buffer_t::scratch_buffer_t *
 hb_buffer_t::get_scratch_buffer (unsigned int *size)
 {
   have_output = false;
   have_positions = false;
 
   out_len = 0;
   out_info = info;
 
-  *size = allocated * sizeof (pos[0]);
-  return pos;
+  assert ((uintptr_t) pos % sizeof (scratch_buffer_t) == 0);
+  *size = allocated * sizeof (pos[0]) / sizeof (scratch_buffer_t);
+  return (scratch_buffer_t *) (void *) pos;
 }
 
 
 
 /* HarfBuzz-Internal API */
 
 void
 hb_buffer_t::reset (void)
@@ -1144,17 +1145,20 @@ hb_buffer_set_length (hb_buffer_t  *buff
     memset (buffer->info + buffer->len, 0, sizeof (buffer->info[0]) * (length - buffer->len));
     if (buffer->have_positions)
       memset (buffer->pos + buffer->len, 0, sizeof (buffer->pos[0]) * (length - buffer->len));
   }
 
   buffer->len = length;
 
   if (!length)
+  {
+    buffer->content_type = HB_BUFFER_CONTENT_TYPE_INVALID;
     buffer->clear_context (0);
+  }
   buffer->clear_context (1);
 
   return true;
 }
 
 /**
  * hb_buffer_get_length:
  * @buffer: a buffer.
--- a/gfx/harfbuzz/src/hb-coretext.cc
+++ b/gfx/harfbuzz/src/hb-coretext.cc
@@ -389,16 +389,17 @@ static int
 hb_bool_t
 _hb_coretext_shape (hb_shape_plan_t    *shape_plan,
 		    hb_font_t          *font,
                     hb_buffer_t        *buffer,
                     const hb_feature_t *features,
                     unsigned int        num_features)
 {
   hb_face_t *face = font->face;
+  hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
   hb_coretext_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
 
   /*
    * Set up features.
    * (copied + modified from code from hb-uniscribe.cc)
    */
   hb_auto_array_t<feature_record_t> feature_records;
   hb_auto_array_t<range_record_t> range_records;
@@ -548,21 +549,31 @@ hb_bool_t
 
 #define FAIL(...) \
   HB_STMT_START { \
     DEBUG_MSG (CORETEXT, NULL, __VA_ARGS__); \
     return false; \
   } HB_STMT_END;
 
   unsigned int scratch_size;
-  char *scratch = (char *) buffer->get_scratch_buffer (&scratch_size);
+  hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size);
+
+#define ALLOCATE_ARRAY(Type, name, len) \
+  Type *name = (Type *) scratch; \
+  { \
+    unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \
+    assert (_consumed <= scratch_size); \
+    scratch += _consumed; \
+    scratch_size -= _consumed; \
+  }
 
 #define utf16_index() var1.u32
 
-  UniChar *pchars = (UniChar *) scratch;
+  ALLOCATE_ARRAY (UniChar, pchars, buffer->len * 2);
+
   unsigned int chars_len = 0;
   for (unsigned int i = 0; i < buffer->len; i++) {
     hb_codepoint_t c = buffer->info[i].codepoint;
     buffer->info[i].utf16_index() = chars_len;
     if (likely (c < 0x10000))
       pchars[chars_len++] = c;
     else if (unlikely (c >= 0x110000))
       pchars[chars_len++] = 0xFFFD;
@@ -581,17 +592,17 @@ hb_bool_t
   CFMutableAttributedStringRef attr_string = CFAttributedStringCreateMutable (NULL, chars_len);
   CFAttributedStringReplaceString (attr_string, CFRangeMake (0, 0), string_ref);
   CFRelease (string_ref);
   CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len),
 				  kCTFontAttributeName, font_data->ct_font);
 
   if (num_features)
   {
-    unsigned int *log_clusters = (unsigned int *) (pchars + chars_len);
+    ALLOCATE_ARRAY (unsigned int, log_clusters, chars_len);
 
     /* Need log_clusters to assign features. */
     chars_len = 0;
     for (unsigned int i = 0; i < buffer->len; i++)
     {
       hb_codepoint_t c = buffer->info[i].codepoint;
       unsigned int cluster = buffer->info[i].cluster;
       log_clusters[chars_len++] = cluster;
@@ -633,36 +644,70 @@ hb_bool_t
 
   CFArrayRef glyph_runs = CTLineGetGlyphRuns (line);
   unsigned int num_runs = CFArrayGetCount (glyph_runs);
 
   buffer->len = 0;
 
   const CFRange range_all = CFRangeMake (0, 0);
 
-  for (unsigned int i = 0; i < num_runs; i++) {
+  for (unsigned int i = 0; i < num_runs; i++)
+  {
     CTRunRef run = (CTRunRef) CFArrayGetValueAtIndex (glyph_runs, i);
 
+    /* CoreText does automatic font fallback (AKA "cascading") for  characters
+     * not supported by the requested font, and provides no way to turn it off,
+     * so we detect if the returned run uses a font other than the requested
+     * one and fill in the buffer with .notdef glyphs instead of random glyph
+     * indices from a different font.
+     */
+    CFDictionaryRef attributes = CTRunGetAttributes (run);
+    CTFontRef run_ct_font = static_cast<CTFontRef>(CFDictionaryGetValue (attributes, kCTFontAttributeName));
+    CGFontRef run_cg_font = CTFontCopyGraphicsFont (run_ct_font, 0);
+    if (!CFEqual (run_cg_font, face_data->cg_font))
+    {
+        CFRelease (run_cg_font);
+
+	CFRange range = CTRunGetStringRange (run);
+	buffer->ensure (buffer->len + range.length);
+	if (buffer->in_error)
+	  FAIL ("Buffer resize failed");
+	hb_glyph_info_t *info = buffer->info + buffer->len;
+	buffer->len += range.length;
+
+        for (CFIndex j = 0; j < range.length; j++)
+	{
+            CGGlyph notdef = 0;
+            double advance = CTFontGetAdvancesForGlyphs (font_data->ct_font, kCTFontHorizontalOrientation, &notdef, NULL, 1);
+
+            info->codepoint = notdef;
+	    /* TODO We have to fixup clusters later.  See vis_clusters in
+	     * hb-uniscribe.cc for example. */
+            info->cluster = range.location + j;
+
+            info->mask = advance;
+            info->var1.u32 = 0;
+            info->var2.u32 = 0;
+
+	    info++;
+        }
+        continue;
+    }
+    CFRelease (run_cg_font);
+
     unsigned int num_glyphs = CTRunGetGlyphCount (run);
     if (num_glyphs == 0)
       continue;
 
     buffer->ensure (buffer->len + num_glyphs);
 
-    /* Testing indicates that CTRunGetGlyphsPtr (almost?) always succeeds,
-     * and so copying data to our own buffer with CTRunGetGlyphs will be
-     * extremely rare. */
+    scratch = buffer->get_scratch_buffer (&scratch_size);
 
-    unsigned int scratch_size;
-    char *scratch = (char *) buffer->get_scratch_buffer (&scratch_size);
-
-#define ALLOCATE_ARRAY(Type, name, len) \
-  Type *name = (Type *) scratch; \
-  scratch += (len) * sizeof ((name)[0]); \
-  scratch_size -= (len) * sizeof ((name)[0]);
+    /* Testing indicates that CTRunGetGlyphsPtr, etc (almost?) always
+     * succeed, and so copying data to our own buffer will be rare. */
 
     const CGGlyph* glyphs = CTRunGetGlyphsPtr (run);
     if (!glyphs) {
       ALLOCATE_ARRAY (CGGlyph, glyph_buf, num_glyphs);
       CTRunGetGlyphs (run, range_all, glyph_buf);
       glyphs = glyph_buf;
     }
 
--- a/gfx/harfbuzz/src/hb-fallback-shape.cc
+++ b/gfx/harfbuzz/src/hb-fallback-shape.cc
@@ -90,16 +90,26 @@ void
 
 hb_bool_t
 _hb_fallback_shape (hb_shape_plan_t    *shape_plan HB_UNUSED,
 		    hb_font_t          *font,
 		    hb_buffer_t        *buffer,
 		    const hb_feature_t *features HB_UNUSED,
 		    unsigned int        num_features HB_UNUSED)
 {
+  /* TODO
+   *
+   * - Apply fallback kern.
+   * - Handle Variation Selectors?
+   * - Apply normalization?
+   *
+   * This will make the fallback shaper into a dumb "TrueType"
+   * shaper which many people unfortunately still request.
+   */
+
   hb_codepoint_t space;
   font->get_glyph (' ', 0, &space);
 
   buffer->clear_positions ();
 
   unsigned int count = buffer->len;
 
   for (unsigned int i = 0; i < count; i++)
--- a/gfx/harfbuzz/src/hb-font-private.hh
+++ b/gfx/harfbuzz/src/hb-font-private.hh
@@ -113,22 +113,22 @@ struct hb_font_t {
 
   /* Convert from font-space to user-space */
   inline hb_position_t em_scale_x (int16_t v) { return em_scale (v, this->x_scale); }
   inline hb_position_t em_scale_y (int16_t v) { return em_scale (v, this->y_scale); }
 
   /* Convert from parent-font user-space to our user-space */
   inline hb_position_t parent_scale_x_distance (hb_position_t v) {
     if (unlikely (parent && parent->x_scale != x_scale))
-      return v * (int64_t) this->x_scale / this->parent->x_scale;
+      return (hb_position_t) (v * (int64_t) this->x_scale / this->parent->x_scale);
     return v;
   }
   inline hb_position_t parent_scale_y_distance (hb_position_t v) {
     if (unlikely (parent && parent->y_scale != y_scale))
-      return v * (int64_t) this->y_scale / this->parent->y_scale;
+      return (hb_position_t) (v * (int64_t) this->y_scale / this->parent->y_scale);
     return v;
   }
   inline hb_position_t parent_scale_x_position (hb_position_t v) {
     return parent_scale_x_distance (v);
   }
   inline hb_position_t parent_scale_y_position (hb_position_t v) {
     return parent_scale_y_distance (v);
   }
@@ -392,17 +392,17 @@ struct hb_font_t {
 	  get_glyph (unichar, 0, glyph))
 	return true;
     }
 
     return false;
   }
 
   private:
-  inline hb_position_t em_scale (int16_t v, int scale) { return v * (int64_t) scale / face->get_upem (); }
+  inline hb_position_t em_scale (int16_t v, int scale) { return (hb_position_t) (v * (int64_t) scale / face->get_upem ()); }
 };
 
 #define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, font);
 #include "hb-shaper-list.hh"
 #undef HB_SHAPER_IMPLEMENT
 #undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
 
--- a/gfx/harfbuzz/src/hb-ft.cc
+++ b/gfx/harfbuzz/src/hb-ft.cc
@@ -413,18 +413,18 @@ hb_ft_font_create (FT_Face           ft_
 
   face = hb_ft_face_create (ft_face, destroy);
   font = hb_font_create (face);
   hb_face_destroy (face);
   hb_font_set_funcs (font,
 		     _hb_ft_get_font_funcs (),
 		     ft_face, (hb_destroy_func_t) _do_nothing);
   hb_font_set_scale (font,
-		     ((uint64_t) ft_face->size->metrics.x_scale * (uint64_t) ft_face->units_per_EM + (1<<15)) >> 16,
-		     ((uint64_t) ft_face->size->metrics.y_scale * (uint64_t) ft_face->units_per_EM + (1<<15)) >> 16);
+		     (int) (((uint64_t) ft_face->size->metrics.x_scale * (uint64_t) ft_face->units_per_EM + (1<<15)) >> 16),
+		     (int) (((uint64_t) ft_face->size->metrics.y_scale * (uint64_t) ft_face->units_per_EM + (1<<15)) >> 16));
   hb_font_set_ppem (font,
 		    ft_face->size->metrics.x_ppem,
 		    ft_face->size->metrics.y_ppem);
 
   return font;
 }
 
 
--- a/gfx/harfbuzz/src/hb-graphite2.cc
+++ b/gfx/harfbuzz/src/hb-graphite2.cc
@@ -238,24 +238,19 @@ hb_bool_t
   }
 
   gr_segment *seg = NULL;
   const gr_slot *is;
   unsigned int ci = 0, ic = 0;
   float curradvx = 0., curradvy = 0.;
 
   unsigned int scratch_size;
-  char *scratch = (char *) buffer->get_scratch_buffer (&scratch_size);
+  hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size);
 
-#define ALLOCATE_ARRAY(Type, name, len) \
-  Type *name = (Type *) scratch; \
-  scratch += (len) * sizeof ((name)[0]); \
-  scratch_size -= (len) * sizeof ((name)[0]);
-
-  ALLOCATE_ARRAY (uint32_t, chars, buffer->len);
+  uint32_t *chars = (uint32_t *) scratch;
 
   for (unsigned int i = 0; i < buffer->len; ++i)
     chars[i] = buffer->info[i].codepoint;
 
   hb_tag_t script_tag[2];
   hb_ot_tags_from_script (hb_buffer_get_script (buffer), &script_tag[0], &script_tag[1]);
 
   seg = gr_make_seg (grfont, grface,
@@ -271,32 +266,43 @@ hb_bool_t
 
   unsigned int glyph_count = gr_seg_n_slots (seg);
   if (unlikely (!glyph_count)) {
     if (feats) gr_featureval_destroy (feats);
     gr_seg_destroy (seg);
     return false;
   }
 
-  scratch = (char *) buffer->get_scratch_buffer (&scratch_size);
-  while ((sizeof (hb_graphite2_cluster_t) * buffer->len +
-	  sizeof (hb_codepoint_t) * glyph_count) > scratch_size)
+  scratch = buffer->get_scratch_buffer (&scratch_size);
+  while ((DIV_CEIL (sizeof (hb_graphite2_cluster_t) * buffer->len, sizeof (*scratch)) +
+	  DIV_CEIL (sizeof (hb_codepoint_t) * glyph_count, sizeof (*scratch))) > scratch_size)
   {
     buffer->ensure (buffer->allocated * 2);
     if (unlikely (buffer->in_error)) {
       if (feats) gr_featureval_destroy (feats);
       gr_seg_destroy (seg);
       return false;
     }
-    scratch = (char *) buffer->get_scratch_buffer (&scratch_size);
+    scratch = buffer->get_scratch_buffer (&scratch_size);
+  }
+
+#define ALLOCATE_ARRAY(Type, name, len) \
+  Type *name = (Type *) scratch; \
+  { \
+    unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \
+    assert (_consumed <= scratch_size); \
+    scratch += _consumed; \
+    scratch_size -= _consumed; \
   }
 
   ALLOCATE_ARRAY (hb_graphite2_cluster_t, clusters, buffer->len);
   ALLOCATE_ARRAY (hb_codepoint_t, gids, glyph_count);
 
+#undef ALLOCATE_ARRAY
+
   memset (clusters, 0, sizeof (clusters[0]) * buffer->len);
 
   hb_codepoint_t *pg = gids;
   for (is = gr_seg_first_slot (seg), ic = 0; is; is = gr_slot_next_in_segment (is), ic++)
   {
     unsigned int before = gr_slot_before (is);
     unsigned int after = gr_slot_after (is);
     *pg = gr_slot_gid (is);
--- a/gfx/harfbuzz/src/hb-ot-layout-common-private.hh
+++ b/gfx/harfbuzz/src/hb-ot-layout-common-private.hh
@@ -372,17 +372,17 @@ struct FeatureParamsStylisticSet
 {
   inline bool sanitize (hb_sanitize_context_t *c) {
     TRACE_SANITIZE (this);
     /* Right now minorVersion is at zero.  Which means, any table supports
      * the uiNameID field. */
     return TRACE_RETURN (c->check_struct (this));
   }
 
-  USHORT	minorVersion;	/* (set to 0): This corresponds to a “minor”
+  USHORT	version;	/* (set to 0): This corresponds to a “minor”
 				 * version number. Additional data may be
 				 * added to the end of this Feature Parameters
 				 * table in the future. */
 
   USHORT	uiNameID;	/* The 'name' table name ID that specifies a
 				 * string (or strings, for multiple languages)
 				 * for a user-interface label for this
 				 * feature.  The values of uiLabelNameId and
@@ -395,16 +395,17 @@ struct FeatureParamsStylisticSet
 				 * English string should be included as a
 				 * fallback. The string should be kept to a
 				 * minimal length to fit comfortably with
 				 * different application interfaces. */
   public:
   DEFINE_SIZE_STATIC (4);
 };
 
+/* http://www.microsoft.com/typography/otspec/features_ae.htm#cv01-cv99 */
 struct FeatureParamsCharacterVariants
 {
   inline bool sanitize (hb_sanitize_context_t *c) {
     TRACE_SANITIZE (this);
     return TRACE_RETURN (c->check_struct (this) &&
 			 characters.sanitize (c));
   }
 
@@ -1107,17 +1108,17 @@ struct Device
   inline int get_delta (unsigned int ppem, int scale) const
   {
     if (!ppem) return 0;
 
     int pixels = get_delta_pixels (ppem);
 
     if (!pixels) return 0;
 
-    return pixels * (int64_t) scale / ppem;
+    return (int) (pixels * (int64_t) scale / ppem);
   }
 
 
   inline int get_delta_pixels (unsigned int ppem_size) const
   {
     unsigned int f = deltaFormat;
     if (unlikely (f < 1 || f > 3))
       return 0;
--- a/gfx/harfbuzz/src/hb-ot-shape-complex-myanmar-machine.hh
+++ b/gfx/harfbuzz/src/hb-ot-shape-complex-myanmar-machine.hh
@@ -29,247 +29,248 @@
 #ifndef HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH
 #define HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH
 
 #include "hb-private.hh"
 
 
 #line 36 "hb-ot-shape-complex-myanmar-machine.hh.tmp"
 static const unsigned char _myanmar_syllable_machine_trans_keys[] = {
-	1u, 30u, 3u, 30u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, 
+	1u, 31u, 3u, 30u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, 
 	3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 1u, 16u, 3u, 29u, 3u, 29u, 3u, 29u, 
 	3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 5u, 29u, 5u, 8u, 
 	5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 
 	3u, 30u, 3u, 29u, 1u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 
-	3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 0
+	3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 8u, 8u, 0
 };
 
 static const char _myanmar_syllable_machine_key_spans[] = {
-	30, 28, 25, 4, 25, 23, 21, 21, 
+	31, 28, 25, 4, 25, 23, 21, 21, 
 	27, 27, 27, 27, 16, 27, 27, 27, 
 	27, 27, 27, 27, 27, 27, 25, 4, 
 	25, 23, 21, 21, 27, 27, 27, 27, 
 	28, 27, 30, 27, 27, 27, 27, 27, 
-	27, 27, 27, 27
+	27, 27, 27, 27, 1
 };
 
 static const short _myanmar_syllable_machine_index_offsets[] = {
-	0, 31, 60, 86, 91, 117, 141, 163, 
-	185, 213, 241, 269, 297, 314, 342, 370, 
-	398, 426, 454, 482, 510, 538, 566, 592, 
-	597, 623, 647, 669, 691, 719, 747, 775, 
-	803, 832, 860, 891, 919, 947, 975, 1003, 
-	1031, 1059, 1087, 1115
+	0, 32, 61, 87, 92, 118, 142, 164, 
+	186, 214, 242, 270, 298, 315, 343, 371, 
+	399, 427, 455, 483, 511, 539, 567, 593, 
+	598, 624, 648, 670, 692, 720, 748, 776, 
+	804, 833, 861, 892, 920, 948, 976, 1004, 
+	1032, 1060, 1088, 1116, 1144
 };
 
 static const char _myanmar_syllable_machine_indicies[] = {
 	1, 1, 2, 3, 4, 4, 0, 5, 
 	0, 6, 0, 1, 0, 0, 0, 7, 
 	0, 8, 1, 0, 9, 10, 11, 12, 
-	13, 14, 15, 16, 17, 18, 0, 20, 
-	21, 22, 22, 19, 23, 19, 24, 19, 
-	19, 19, 19, 19, 19, 19, 25, 19, 
-	19, 26, 27, 28, 29, 30, 31, 32, 
-	33, 34, 35, 19, 22, 22, 19, 23, 
-	19, 19, 19, 19, 19, 19, 19, 19, 
-	19, 36, 19, 19, 19, 19, 19, 19, 
-	30, 19, 19, 19, 34, 19, 22, 22, 
-	19, 23, 19, 22, 22, 19, 23, 19, 
-	19, 19, 19, 19, 19, 19, 19, 19, 
-	19, 19, 19, 19, 19, 19, 19, 30, 
-	19, 19, 19, 34, 19, 37, 19, 22, 
-	22, 19, 23, 19, 30, 19, 19, 19, 
-	19, 19, 19, 19, 19, 19, 19, 19, 
-	19, 19, 19, 30, 19, 22, 22, 19, 
-	23, 19, 19, 19, 19, 19, 19, 19, 
-	19, 19, 38, 19, 19, 19, 19, 19, 
-	19, 30, 19, 22, 22, 19, 23, 19, 
-	19, 19, 19, 19, 19, 19, 19, 19, 
-	19, 19, 19, 19, 19, 19, 19, 30, 
-	19, 20, 19, 22, 22, 19, 23, 19, 
-	24, 19, 19, 19, 19, 19, 19, 19, 
-	39, 19, 19, 39, 19, 19, 19, 30, 
-	40, 19, 19, 34, 19, 20, 19, 22, 
-	22, 19, 23, 19, 24, 19, 19, 19, 
-	19, 19, 19, 19, 19, 19, 19, 19, 
-	19, 19, 19, 30, 19, 19, 19, 34, 
-	19, 20, 19, 22, 22, 19, 23, 19, 
-	24, 19, 19, 19, 19, 19, 19, 19, 
-	39, 19, 19, 19, 19, 19, 19, 30, 
-	40, 19, 19, 34, 19, 20, 19, 22, 
-	22, 19, 23, 19, 24, 19, 19, 19, 
-	19, 19, 19, 19, 19, 19, 19, 19, 
-	19, 19, 19, 30, 40, 19, 19, 34, 
-	19, 1, 1, 19, 19, 19, 19, 19, 
-	19, 19, 19, 19, 19, 19, 19, 19, 
-	1, 19, 20, 19, 22, 22, 19, 23, 
-	19, 24, 19, 19, 19, 19, 19, 19, 
-	19, 25, 19, 19, 26, 27, 28, 29, 
-	30, 31, 32, 33, 34, 19, 20, 19, 
-	22, 22, 19, 23, 19, 24, 19, 19, 
-	19, 19, 19, 19, 19, 33, 19, 19, 
-	19, 19, 19, 19, 30, 31, 32, 33, 
-	34, 19, 20, 19, 22, 22, 19, 23, 
-	19, 24, 19, 19, 19, 19, 19, 19, 
-	19, 19, 19, 19, 19, 19, 19, 19, 
-	30, 31, 32, 33, 34, 19, 20, 19, 
-	22, 22, 19, 23, 19, 24, 19, 19, 
-	19, 19, 19, 19, 19, 19, 19, 19, 
-	19, 19, 19, 19, 30, 31, 32, 19, 
-	34, 19, 20, 19, 22, 22, 19, 23, 
-	19, 24, 19, 19, 19, 19, 19, 19, 
-	19, 19, 19, 19, 19, 19, 19, 19, 
-	30, 19, 32, 19, 34, 19, 20, 19, 
-	22, 22, 19, 23, 19, 24, 19, 19, 
-	19, 19, 19, 19, 19, 19, 19, 19, 
-	26, 19, 28, 19, 30, 31, 32, 33, 
-	34, 19, 20, 19, 22, 22, 19, 23, 
-	19, 24, 19, 19, 19, 19, 19, 19, 
-	19, 33, 19, 19, 26, 19, 19, 19, 
-	30, 31, 32, 33, 34, 19, 20, 19, 
-	22, 22, 19, 23, 19, 24, 19, 19, 
-	19, 19, 19, 19, 19, 19, 19, 19, 
-	26, 27, 28, 19, 30, 31, 32, 33, 
-	34, 19, 20, 21, 22, 22, 19, 23, 
-	19, 24, 19, 19, 19, 19, 19, 19, 
-	19, 25, 19, 19, 26, 27, 28, 29, 
-	30, 31, 32, 33, 34, 19, 3, 3, 
-	41, 5, 41, 41, 41, 41, 41, 41, 
-	41, 41, 41, 42, 41, 41, 41, 41, 
-	41, 41, 13, 41, 41, 41, 17, 41, 
-	3, 3, 41, 5, 41, 3, 3, 41, 
-	5, 41, 41, 41, 41, 41, 41, 41, 
-	41, 41, 41, 41, 41, 41, 41, 41, 
-	41, 13, 41, 41, 41, 17, 41, 43, 
-	41, 3, 3, 41, 5, 41, 13, 41, 
-	41, 41, 41, 41, 41, 41, 41, 41, 
-	41, 41, 41, 41, 41, 13, 41, 3, 
-	3, 41, 5, 41, 41, 41, 41, 41, 
-	41, 41, 41, 41, 44, 41, 41, 41, 
-	41, 41, 41, 13, 41, 3, 3, 41, 
-	5, 41, 41, 41, 41, 41, 41, 41, 
-	41, 41, 41, 41, 41, 41, 41, 41, 
-	41, 13, 41, 2, 41, 3, 3, 41, 
-	5, 41, 6, 41, 41, 41, 41, 41, 
-	41, 41, 45, 41, 41, 45, 41, 41, 
-	41, 13, 46, 41, 41, 17, 41, 2, 
-	41, 3, 3, 41, 5, 41, 6, 41, 
-	41, 41, 41, 41, 41, 41, 41, 41, 
-	41, 41, 41, 41, 41, 13, 41, 41, 
-	41, 17, 41, 2, 41, 3, 3, 41, 
-	5, 41, 6, 41, 41, 41, 41, 41, 
-	41, 41, 45, 41, 41, 41, 41, 41, 
-	41, 13, 46, 41, 41, 17, 41, 2, 
-	41, 3, 3, 41, 5, 41, 6, 41, 
-	41, 41, 41, 41, 41, 41, 41, 41, 
-	41, 41, 41, 41, 41, 13, 46, 41, 
-	41, 17, 41, 20, 21, 22, 22, 19, 
-	23, 19, 24, 19, 19, 19, 19, 19, 
-	19, 19, 47, 19, 19, 26, 27, 28, 
-	29, 30, 31, 32, 33, 34, 35, 19, 
-	20, 48, 22, 22, 19, 23, 19, 24, 
-	19, 19, 19, 19, 19, 19, 19, 25, 
-	19, 19, 26, 27, 28, 29, 30, 31, 
-	32, 33, 34, 19, 1, 1, 2, 3, 
-	3, 3, 41, 5, 41, 6, 41, 1, 
-	41, 41, 41, 1, 41, 8, 1, 41, 
-	9, 10, 11, 12, 13, 14, 15, 16, 
-	17, 18, 41, 2, 41, 3, 3, 41, 
-	5, 41, 6, 41, 41, 41, 41, 41, 
-	41, 41, 8, 41, 41, 9, 10, 11, 
-	12, 13, 14, 15, 16, 17, 41, 2, 
-	41, 3, 3, 41, 5, 41, 6, 41, 
-	41, 41, 41, 41, 41, 41, 16, 41, 
-	41, 41, 41, 41, 41, 13, 14, 15, 
-	16, 17, 41, 2, 41, 3, 3, 41, 
-	5, 41, 6, 41, 41, 41, 41, 41, 
-	41, 41, 41, 41, 41, 41, 41, 41, 
-	41, 13, 14, 15, 16, 17, 41, 2, 
-	41, 3, 3, 41, 5, 41, 6, 41, 
-	41, 41, 41, 41, 41, 41, 41, 41, 
-	41, 41, 41, 41, 41, 13, 14, 15, 
-	41, 17, 41, 2, 41, 3, 3, 41, 
-	5, 41, 6, 41, 41, 41, 41, 41, 
-	41, 41, 41, 41, 41, 41, 41, 41, 
-	41, 13, 41, 15, 41, 17, 41, 2, 
-	41, 3, 3, 41, 5, 41, 6, 41, 
-	41, 41, 41, 41, 41, 41, 41, 41, 
-	41, 9, 41, 11, 41, 13, 14, 15, 
-	16, 17, 41, 2, 41, 3, 3, 41, 
-	5, 41, 6, 41, 41, 41, 41, 41, 
-	41, 41, 16, 41, 41, 9, 41, 41, 
-	41, 13, 14, 15, 16, 17, 41, 2, 
-	41, 3, 3, 41, 5, 41, 6, 41, 
-	41, 41, 41, 41, 41, 41, 41, 41, 
-	41, 9, 10, 11, 41, 13, 14, 15, 
-	16, 17, 41, 2, 3, 3, 3, 41, 
-	5, 41, 6, 41, 41, 41, 41, 41, 
-	41, 41, 8, 41, 41, 9, 10, 11, 
-	12, 13, 14, 15, 16, 17, 41, 0
+	13, 14, 15, 16, 17, 18, 19, 0, 
+	21, 22, 23, 23, 20, 24, 20, 25, 
+	20, 20, 20, 20, 20, 20, 20, 26, 
+	20, 20, 27, 28, 29, 30, 31, 32, 
+	33, 34, 35, 36, 20, 23, 23, 20, 
+	24, 20, 20, 20, 20, 20, 20, 20, 
+	20, 20, 37, 20, 20, 20, 20, 20, 
+	20, 31, 20, 20, 20, 35, 20, 23, 
+	23, 20, 24, 20, 23, 23, 20, 24, 
+	20, 20, 20, 20, 20, 20, 20, 20, 
+	20, 20, 20, 20, 20, 20, 20, 20, 
+	31, 20, 20, 20, 35, 20, 38, 20, 
+	23, 23, 20, 24, 20, 31, 20, 20, 
+	20, 20, 20, 20, 20, 39, 20, 20, 
+	20, 20, 20, 20, 31, 20, 23, 23, 
+	20, 24, 20, 20, 20, 20, 20, 20, 
+	20, 20, 20, 39, 20, 20, 20, 20, 
+	20, 20, 31, 20, 23, 23, 20, 24, 
+	20, 20, 20, 20, 20, 20, 20, 20, 
+	20, 20, 20, 20, 20, 20, 20, 20, 
+	31, 20, 21, 20, 23, 23, 20, 24, 
+	20, 25, 20, 20, 20, 20, 20, 20, 
+	20, 40, 20, 20, 40, 20, 20, 20, 
+	31, 41, 20, 20, 35, 20, 21, 20, 
+	23, 23, 20, 24, 20, 25, 20, 20, 
+	20, 20, 20, 20, 20, 20, 20, 20, 
+	20, 20, 20, 20, 31, 20, 20, 20, 
+	35, 20, 21, 20, 23, 23, 20, 24, 
+	20, 25, 20, 20, 20, 20, 20, 20, 
+	20, 40, 20, 20, 20, 20, 20, 20, 
+	31, 41, 20, 20, 35, 20, 21, 20, 
+	23, 23, 20, 24, 20, 25, 20, 20, 
+	20, 20, 20, 20, 20, 20, 20, 20, 
+	20, 20, 20, 20, 31, 41, 20, 20, 
+	35, 20, 1, 1, 20, 20, 20, 20, 
+	20, 20, 20, 20, 20, 20, 20, 20, 
+	20, 1, 20, 21, 20, 23, 23, 20, 
+	24, 20, 25, 20, 20, 20, 20, 20, 
+	20, 20, 26, 20, 20, 27, 28, 29, 
+	30, 31, 32, 33, 34, 35, 20, 21, 
+	20, 23, 23, 20, 24, 20, 25, 20, 
+	20, 20, 20, 20, 20, 20, 34, 20, 
+	20, 20, 20, 20, 20, 31, 32, 33, 
+	34, 35, 20, 21, 20, 23, 23, 20, 
+	24, 20, 25, 20, 20, 20, 20, 20, 
+	20, 20, 20, 20, 20, 20, 20, 20, 
+	20, 31, 32, 33, 34, 35, 20, 21, 
+	20, 23, 23, 20, 24, 20, 25, 20, 
+	20, 20, 20, 20, 20, 20, 20, 20, 
+	20, 20, 20, 20, 20, 31, 32, 33, 
+	20, 35, 20, 21, 20, 23, 23, 20, 
+	24, 20, 25, 20, 20, 20, 20, 20, 
+	20, 20, 20, 20, 20, 20, 20, 20, 
+	20, 31, 20, 33, 20, 35, 20, 21, 
+	20, 23, 23, 20, 24, 20, 25, 20, 
+	20, 20, 20, 20, 20, 20, 20, 20, 
+	20, 27, 20, 29, 20, 31, 32, 33, 
+	34, 35, 20, 21, 20, 23, 23, 20, 
+	24, 20, 25, 20, 20, 20, 20, 20, 
+	20, 20, 34, 20, 20, 27, 20, 20, 
+	20, 31, 32, 33, 34, 35, 20, 21, 
+	20, 23, 23, 20, 24, 20, 25, 20, 
+	20, 20, 20, 20, 20, 20, 20, 20, 
+	20, 27, 28, 29, 20, 31, 32, 33, 
+	34, 35, 20, 21, 22, 23, 23, 20, 
+	24, 20, 25, 20, 20, 20, 20, 20, 
+	20, 20, 26, 20, 20, 27, 28, 29, 
+	30, 31, 32, 33, 34, 35, 20, 3, 
+	3, 42, 5, 42, 42, 42, 42, 42, 
+	42, 42, 42, 42, 43, 42, 42, 42, 
+	42, 42, 42, 13, 42, 42, 42, 17, 
+	42, 3, 3, 42, 5, 42, 3, 3, 
+	42, 5, 42, 42, 42, 42, 42, 42, 
+	42, 42, 42, 42, 42, 42, 42, 42, 
+	42, 42, 13, 42, 42, 42, 17, 42, 
+	44, 42, 3, 3, 42, 5, 42, 13, 
+	42, 42, 42, 42, 42, 42, 42, 45, 
+	42, 42, 42, 42, 42, 42, 13, 42, 
+	3, 3, 42, 5, 42, 42, 42, 42, 
+	42, 42, 42, 42, 42, 45, 42, 42, 
+	42, 42, 42, 42, 13, 42, 3, 3, 
+	42, 5, 42, 42, 42, 42, 42, 42, 
+	42, 42, 42, 42, 42, 42, 42, 42, 
+	42, 42, 13, 42, 2, 42, 3, 3, 
+	42, 5, 42, 6, 42, 42, 42, 42, 
+	42, 42, 42, 46, 42, 42, 46, 42, 
+	42, 42, 13, 47, 42, 42, 17, 42, 
+	2, 42, 3, 3, 42, 5, 42, 6, 
+	42, 42, 42, 42, 42, 42, 42, 42, 
+	42, 42, 42, 42, 42, 42, 13, 42, 
+	42, 42, 17, 42, 2, 42, 3, 3, 
+	42, 5, 42, 6, 42, 42, 42, 42, 
+	42, 42, 42, 46, 42, 42, 42, 42, 
+	42, 42, 13, 47, 42, 42, 17, 42, 
+	2, 42, 3, 3, 42, 5, 42, 6, 
+	42, 42, 42, 42, 42, 42, 42, 42, 
+	42, 42, 42, 42, 42, 42, 13, 47, 
+	42, 42, 17, 42, 21, 22, 23, 23, 
+	20, 24, 20, 25, 20, 20, 20, 20, 
+	20, 20, 20, 48, 20, 20, 27, 28, 
+	29, 30, 31, 32, 33, 34, 35, 36, 
+	20, 21, 49, 23, 23, 20, 24, 20, 
+	25, 20, 20, 20, 20, 20, 20, 20, 
+	26, 20, 20, 27, 28, 29, 30, 31, 
+	32, 33, 34, 35, 20, 1, 1, 2, 
+	3, 3, 3, 42, 5, 42, 6, 42, 
+	1, 42, 42, 42, 1, 42, 8, 1, 
+	42, 9, 10, 11, 12, 13, 14, 15, 
+	16, 17, 18, 42, 2, 42, 3, 3, 
+	42, 5, 42, 6, 42, 42, 42, 42, 
+	42, 42, 42, 8, 42, 42, 9, 10, 
+	11, 12, 13, 14, 15, 16, 17, 42, 
+	2, 42, 3, 3, 42, 5, 42, 6, 
+	42, 42, 42, 42, 42, 42, 42, 16, 
+	42, 42, 42, 42, 42, 42, 13, 14, 
+	15, 16, 17, 42, 2, 42, 3, 3, 
+	42, 5, 42, 6, 42, 42, 42, 42, 
+	42, 42, 42, 42, 42, 42, 42, 42, 
+	42, 42, 13, 14, 15, 16, 17, 42, 
+	2, 42, 3, 3, 42, 5, 42, 6, 
+	42, 42, 42, 42, 42, 42, 42, 42, 
+	42, 42, 42, 42, 42, 42, 13, 14, 
+	15, 42, 17, 42, 2, 42, 3, 3, 
+	42, 5, 42, 6, 42, 42, 42, 42, 
+	42, 42, 42, 42, 42, 42, 42, 42, 
+	42, 42, 13, 42, 15, 42, 17, 42, 
+	2, 42, 3, 3, 42, 5, 42, 6, 
+	42, 42, 42, 42, 42, 42, 42, 42, 
+	42, 42, 9, 42, 11, 42, 13, 14, 
+	15, 16, 17, 42, 2, 42, 3, 3, 
+	42, 5, 42, 6, 42, 42, 42, 42, 
+	42, 42, 42, 16, 42, 42, 9, 42, 
+	42, 42, 13, 14, 15, 16, 17, 42, 
+	2, 42, 3, 3, 42, 5, 42, 6, 
+	42, 42, 42, 42, 42, 42, 42, 42, 
+	42, 42, 9, 10, 11, 42, 13, 14, 
+	15, 16, 17, 42, 2, 3, 3, 3, 
+	42, 5, 42, 6, 42, 42, 42, 42, 
+	42, 42, 42, 8, 42, 42, 9, 10, 
+	11, 12, 13, 14, 15, 16, 17, 42, 
+	51, 50, 0
 };
 
 static const char _myanmar_syllable_machine_trans_targs[] = {
 	0, 1, 22, 0, 0, 23, 29, 32, 
 	35, 36, 40, 41, 42, 25, 38, 39, 
-	37, 28, 43, 0, 2, 12, 0, 3, 
-	9, 13, 14, 18, 19, 20, 5, 16, 
-	17, 15, 8, 21, 4, 6, 7, 10, 
-	11, 0, 24, 26, 27, 30, 31, 33, 
-	34
+	37, 28, 43, 44, 0, 2, 12, 0, 
+	3, 9, 13, 14, 18, 19, 20, 5, 
+	16, 17, 15, 8, 21, 4, 6, 7, 
+	10, 11, 0, 24, 26, 27, 30, 31, 
+	33, 34, 0, 0
 };
 
 static const char _myanmar_syllable_machine_trans_actions[] = {
 	3, 0, 0, 4, 5, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 6, 0, 0, 7, 0, 
+	0, 0, 0, 0, 6, 0, 0, 7, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 8, 0, 0, 0, 0, 0, 0, 
-	0
+	0, 0, 8, 0, 0, 0, 0, 0, 
+	0, 0, 9, 10
 };
 
 static const char _myanmar_syllable_machine_to_state_actions[] = {
 	1, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0
+	0, 0, 0, 0, 0
 };
 
 static const char _myanmar_syllable_machine_from_state_actions[] = {
 	2, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
-	0, 0, 0, 0
+	0, 0, 0, 0, 0
 };
 
 static const short _myanmar_syllable_machine_eof_trans[] = {
-	0, 20, 20, 20, 20, 20, 20, 20, 
-	20, 20, 20, 20, 20, 20, 20, 20, 
-	20, 20, 20, 20, 20, 20, 42, 42, 
-	42, 42, 42, 42, 42, 42, 42, 42, 
-	20, 20, 42, 42, 42, 42, 42, 42, 
-	42, 42, 42, 42
+	0, 21, 21, 21, 21, 21, 21, 21, 
+	21, 21, 21, 21, 21, 21, 21, 21, 
+	21, 21, 21, 21, 21, 21, 43, 43, 
+	43, 43, 43, 43, 43, 43, 43, 43, 
+	21, 21, 43, 43, 43, 43, 43, 43, 
+	43, 43, 43, 43, 51
 };
 
 static const int myanmar_syllable_machine_start = 0;
 static const int myanmar_syllable_machine_first_final = 0;
 static const int myanmar_syllable_machine_error = -1;
 
 static const int myanmar_syllable_machine_en_main = 0;
 
 
 #line 36 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
 
 
 
-#line 90 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
+#line 93 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
 
 
 #define found_syllable(syllable_type) \
   HB_STMT_START { \
     if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \
     for (unsigned int i = last; i < p+1; i++) \
       info[i].syllable() = (syllable_serial << 4) | syllable_type; \
     last = p+1; \
@@ -279,48 +280,48 @@ static const int myanmar_syllable_machin
 
 static void
 find_syllables (hb_buffer_t *buffer)
 {
   unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED;
   int cs;
   hb_glyph_info_t *info = buffer->info;
   
-#line 288 "hb-ot-shape-complex-myanmar-machine.hh.tmp"
+#line 289 "hb-ot-shape-complex-myanmar-machine.hh.tmp"
 	{
 	cs = myanmar_syllable_machine_start;
 	ts = 0;
 	te = 0;
 	act = 0;
 	}
 
-#line 111 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
+#line 114 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
 
 
   p = 0;
   pe = eof = buffer->len;
 
   unsigned int last = 0;
   unsigned int syllable_serial = 1;
   
-#line 305 "hb-ot-shape-complex-myanmar-machine.hh.tmp"
+#line 306 "hb-ot-shape-complex-myanmar-machine.hh.tmp"
 	{
 	int _slen;
 	int _trans;
 	const unsigned char *_keys;
 	const char *_inds;
 	if ( p == pe )
 		goto _test_eof;
 _resume:
 	switch ( _myanmar_syllable_machine_from_state_actions[cs] ) {
 	case 2:
 #line 1 "NONE"
 	{ts = p;}
 	break;
-#line 319 "hb-ot-shape-complex-myanmar-machine.hh.tmp"
+#line 320 "hb-ot-shape-complex-myanmar-machine.hh.tmp"
 	}
 
 	_keys = _myanmar_syllable_machine_trans_keys + (cs<<1);
 	_inds = _myanmar_syllable_machine_indicies + _myanmar_syllable_machine_index_offsets[cs];
 
 	_slen = _myanmar_syllable_machine_key_spans[cs];
 	_trans = _inds[ _slen > 0 && _keys[0] <=( info[p].myanmar_category()) &&
 		( info[p].myanmar_category()) <= _keys[1] ?
@@ -329,63 +330,71 @@ find_syllables (hb_buffer_t *buffer)
 _eof_trans:
 	cs = _myanmar_syllable_machine_trans_targs[_trans];
 
 	if ( _myanmar_syllable_machine_trans_actions[_trans] == 0 )
 		goto _again;
 
 	switch ( _myanmar_syllable_machine_trans_actions[_trans] ) {
 	case 7:
-#line 83 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
+#line 85 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
 	{te = p+1;{ found_syllable (consonant_syllable); }}
 	break;
 	case 5:
-#line 84 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
+#line 86 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
 	{te = p+1;{ found_syllable (non_myanmar_cluster); }}
 	break;
+	case 10:
+#line 87 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
+	{te = p+1;{ found_syllable (punctuation_cluster); }}
+	break;
 	case 4:
-#line 85 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
+#line 88 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
 	{te = p+1;{ found_syllable (broken_cluster); }}
 	break;
 	case 3:
-#line 86 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
+#line 89 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
 	{te = p+1;{ found_syllable (non_myanmar_cluster); }}
 	break;
 	case 6:
-#line 83 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
+#line 85 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
 	{te = p;p--;{ found_syllable (consonant_syllable); }}
 	break;
 	case 8:
-#line 85 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
+#line 88 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
 	{te = p;p--;{ found_syllable (broken_cluster); }}
 	break;
-#line 361 "hb-ot-shape-complex-myanmar-machine.hh.tmp"
+	case 9:
+#line 89 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
+	{te = p;p--;{ found_syllable (non_myanmar_cluster); }}
+	break;
+#line 370 "hb-ot-shape-complex-myanmar-machine.hh.tmp"
 	}
 
 _again:
 	switch ( _myanmar_syllable_machine_to_state_actions[cs] ) {
 	case 1:
 #line 1 "NONE"
 	{ts = 0;}
 	break;
-#line 370 "hb-ot-shape-complex-myanmar-machine.hh.tmp"
+#line 379 "hb-ot-shape-complex-myanmar-machine.hh.tmp"
 	}
 
 	if ( ++p != pe )
 		goto _resume;
 	_test_eof: {}
 	if ( p == eof )
 	{
 	if ( _myanmar_syllable_machine_eof_trans[cs] > 0 ) {
 		_trans = _myanmar_syllable_machine_eof_trans[cs] - 1;
 		goto _eof_trans;
 	}
 	}
 
 	}
 
-#line 120 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
+#line 123 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
 
 }
 
 #undef found_syllable
 
 #endif /* HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH */
--- a/gfx/harfbuzz/src/hb-ot-shape-complex-myanmar-machine.rl
+++ b/gfx/harfbuzz/src/hb-ot-shape-complex-myanmar-machine.rl
@@ -56,37 +56,40 @@ V    = 8;
 VAbv = 26;
 VBlw = 27;
 VPre = 28;
 VPst = 29;
 VS   = 30;
 ZWJ  = 6;
 ZWNJ = 5;
 Ra   = 16;
+P    = 31;
 
 j = ZWJ|ZWNJ;			# Joiners
 k = (Ra As H);			# Kinzi
 
 c = C|Ra;			# is_consonant
 
 medial_group = MY? MR? ((MW MH? | MH) As?)?;
 main_vowel_group = VPre* VAbv* VBlw* A* (DB As?)?;
 post_vowel_group = VPst MH? As* VAbv* A* (DB As?)?;
-pwo_tone_group = PT A* (DB As?)?;
+pwo_tone_group = PT A* DB? As?;
 
 complex_syllable_tail = As* medial_group main_vowel_group post_vowel_group* pwo_tone_group* V* j?;
 syllable_tail = (H | complex_syllable_tail);
 
 consonant_syllable =	k? (c|IV|D|GB).VS? (H (c|IV).VS?)* syllable_tail;
+punctuation_cluster = 	P V;
 broken_cluster =	k? VS? syllable_tail;
 other =			any;
 
 main := |*
 	consonant_syllable	=> { found_syllable (consonant_syllable); };
 	j			=> { found_syllable (non_myanmar_cluster); };
+	punctuation_cluster	=> { found_syllable (punctuation_cluster); };
 	broken_cluster		=> { found_syllable (broken_cluster); };
 	other			=> { found_syllable (non_myanmar_cluster); };
 *|;
 
 
 }%%
 
 #define found_syllable(syllable_type) \
--- a/gfx/harfbuzz/src/hb-ot-shape-complex-myanmar.cc
+++ b/gfx/harfbuzz/src/hb-ot-shape-complex-myanmar.cc
@@ -114,16 +114,17 @@ static void
 override_features_myanmar (hb_ot_shape_planner_t *plan)
 {
   plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL);
 }
 
 
 enum syllable_type_t {
   consonant_syllable,
+  punctuation_cluster,
   broken_cluster,
   non_myanmar_cluster,
 };
 
 #include "hb-ot-shape-complex-myanmar-machine.hh"
 
 
 /* Note: This enum is duplicated in the -machine.rl source file.
@@ -138,17 +139,18 @@ enum myanmar_category_t {
   OT_MR  = 22, /* Various consonant medial types */
   OT_MW  = 23, /* Various consonant medial types */
   OT_MY  = 24, /* Various consonant medial types */
   OT_PT  = 25, /* Pwo and other tones */
   OT_VAbv = 26,
   OT_VBlw = 27,
   OT_VPre = 28,
   OT_VPst = 29,
-  OT_VS   = 30 /* Variation selectors */
+  OT_VS   = 30, /* Variation selectors */
+  OT_P    = 31  /* Punctuation */
 };
 
 
 static inline bool
 is_one_of (const hb_glyph_info_t &info, unsigned int flags)
 {
   /* If it ligated, all bets are off. */
   if (_hb_glyph_info_ligated (&info)) return false;
@@ -181,16 +183,20 @@ set_myanmar_properties (hb_glyph_info_t 
    */
   if (unlikely (hb_in_range<hb_codepoint_t> (u, 0xFE00, 0xFE0F)))
     cat = (indic_category_t) OT_VS;
   else if (unlikely (u == 0x200C)) cat = (indic_category_t) OT_ZWNJ;
   else if (unlikely (u == 0x200D)) cat = (indic_category_t) OT_ZWJ;
 
   switch (u)
   {
+    case 0x104E:
+      cat = (indic_category_t) OT_C; /* The spec says C, IndicSyllableCategory doesn't have. */
+      break;
+
     case 0x002D: case 0x00A0: case 0x00D7: case 0x2012:
     case 0x2013: case 0x2014: case 0x2015: case 0x2022:
     case 0x25CC: case 0x25FB: case 0x25FC: case 0x25FD:
     case 0x25FE:
       cat = (indic_category_t) OT_GB;
       break;
 
     case 0x1004: case 0x101B: case 0x105A:
@@ -238,16 +244,20 @@ set_myanmar_properties (hb_glyph_info_t 
       cat = (indic_category_t) OT_PT;
       break;
 
     case 0x1038: case 0x1087: case 0x1088: case 0x1089:
     case 0x108A: case 0x108B: case 0x108C: case 0x108D:
     case 0x108F: case 0x109A: case 0x109B: case 0x109C:
       cat = (indic_category_t) OT_SM;
       break;
+
+    case 0x104A: case 0x104B:
+      cat = (indic_category_t) OT_P;
+      break;
   }
 
   if (cat == OT_M)
   {
     switch ((int) pos)
     {
       case POS_PRE_C:	cat = (indic_category_t) OT_VPre;
 			pos = POS_PRE_M;                  break;
@@ -401,16 +411,26 @@ initial_reordering_broken_cluster (const
 				   hb_buffer_t *buffer,
 				   unsigned int start, unsigned int end)
 {
   /* We already inserted dotted-circles, so just call the consonant_syllable. */
   initial_reordering_consonant_syllable (plan, face, buffer, start, end);
 }
 
 static void
+initial_reordering_punctuation_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED,
+					hb_face_t *face HB_UNUSED,
+					hb_buffer_t *buffer HB_UNUSED,
+					unsigned int start HB_UNUSED, unsigned int end HB_UNUSED)
+{
+  /* Nothing to do right now.  If we ever switch to using the output
+   * buffer in the reordering process, we'd need to next_glyph() here. */
+}
+
+static void
 initial_reordering_non_myanmar_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED,
 					hb_face_t *face HB_UNUSED,
 					hb_buffer_t *buffer HB_UNUSED,
 					unsigned int start HB_UNUSED, unsigned int end HB_UNUSED)
 {
   /* Nothing to do right now.  If we ever switch to using the output
    * buffer in the reordering process, we'd need to next_glyph() here. */
 }
@@ -420,16 +440,17 @@ static void
 initial_reordering_syllable (const hb_ot_shape_plan_t *plan,
 			     hb_face_t *face,
 			     hb_buffer_t *buffer,
 			     unsigned int start, unsigned int end)
 {
   syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F);
   switch (syllable_type) {
   case consonant_syllable:	initial_reordering_consonant_syllable  (plan, face, buffer, start, end); return;
+  case punctuation_cluster:	initial_reordering_punctuation_cluster (plan, face, buffer, start, end); return;
   case broken_cluster:		initial_reordering_broken_cluster      (plan, face, buffer, start, end); return;
   case non_myanmar_cluster:	initial_reordering_non_myanmar_cluster (plan, face, buffer, start, end); return;
   }
 }
 
 static inline void
 insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
 		       hb_font_t *font,
--- a/gfx/harfbuzz/src/hb-ot-shape-private.hh
+++ b/gfx/harfbuzz/src/hb-ot-shape-private.hh
@@ -61,17 +61,17 @@ struct hb_ot_shape_planner_t
 {
   /* In the order that they are filled in. */
   hb_face_t *face;
   hb_segment_properties_t props;
   const struct hb_ot_complex_shaper_t *shaper;
   hb_ot_map_builder_t map;
 
   hb_ot_shape_planner_t (const hb_shape_plan_t *master_plan) :
-			 face (master_plan->face),
+			 face (master_plan->face_unsafe),
 			 props (master_plan->props),
 			 shaper (NULL),
 			 map (face, &props) {}
   ~hb_ot_shape_planner_t (void) { map.finish (); }
 
   inline void compile (hb_ot_shape_plan_t &plan)
   {
     plan.props = props;
--- a/gfx/harfbuzz/src/hb-ot-tag.cc
+++ b/gfx/harfbuzz/src/hb-ot-tag.cc
@@ -162,426 +162,608 @@ typedef struct {
 } LangTag;
 
 /*
  * Complete list at:
  * http://www.microsoft.com/typography/otspec/languagetags.htm
  *
  * Generated by intersecting the OpenType language tag list from
  * Draft OpenType 1.5 spec, with with the ISO 639-3 codes from
- * 2008/08/04, matching on name, and finally adjusted manually.
+ * 2008-08-04, matching on name, and finally adjusted manually.
  *
- * Updated on 2012/12/07 with more research into remaining codes.
+ * Updated on 2012-12-07 with more research into remaining codes.
+ *
+ * Updated on 2013-11-23 based on usage in SIL and Microsoft fonts,
+ * the new proposal from Microsoft, and latest ISO 639-3 names.
  *
  * Some items still missing.  Those are commented out at the end.
  * Keep sorted for bsearch.
  */
 
 static const LangTag ot_languages[] = {
   {"aa",	HB_TAG('A','F','R',' ')},	/* Afar */
   {"ab",	HB_TAG('A','B','K',' ')},	/* Abkhazian */
   {"abq",	HB_TAG('A','B','A',' ')},	/* Abaza */
+  {"ach",	HB_TAG('A','C','H',' ')},	/* Acoli */
   {"ada",	HB_TAG('D','N','G',' ')},	/* Dangme */
   {"ady",	HB_TAG('A','D','Y',' ')},	/* Adyghe */
   {"af",	HB_TAG('A','F','K',' ')},	/* Afrikaans */
   {"aii",	HB_TAG('S','W','A',' ')},	/* Swadaya Aramaic */
+  {"aio",	HB_TAG('A','I','O',' ')},	/* Aiton */
   {"aiw",	HB_TAG('A','R','I',' ')},	/* Aari */
+  {"ak",	HB_TAG('T','W','I',' ')},	/* Akan [macrolanguage] */
   {"alt",	HB_TAG('A','L','T',' ')},	/* [Southern] Altai */
   {"am",	HB_TAG('A','M','H',' ')},	/* Amharic */
   {"amf",	HB_TAG('H','B','N',' ')},	/* Hammer-Banna */
-  {"ar",	HB_TAG('A','R','A',' ')},	/* Arabic */
+  {"an",	HB_TAG('A','R','G',' ')},	/* Aragonese */
+  {"ang",	HB_TAG('A','N','G',' ')},	/* Old English (ca. 450-1100) */
+  {"ar",	HB_TAG('A','R','A',' ')},	/* Arabic [macrolanguage] */
+  {"arb",	HB_TAG('A','R','A',' ')},	/* Standard Arabic */
   {"arn",	HB_TAG('M','A','P',' ')},	/* Mapudungun */
+  {"ary",	HB_TAG('M','O','R',' ')},	/* Moroccan Arabic */
   {"as",	HB_TAG('A','S','M',' ')},	/* Assamese */
+  {"ast",	HB_TAG('A','S','T',' ')},	/* Asturian/Asturleonese/Bable/Leonese */
   {"ath",	HB_TAG('A','T','H',' ')},	/* Athapaskan [family] */
   {"atv",	HB_TAG('A','L','T',' ')},	/* [Northern] Altai */
   {"av",	HB_TAG('A','V','R',' ')},	/* Avaric */
   {"awa",	HB_TAG('A','W','A',' ')},	/* Awadhi */
-  {"ay",	HB_TAG('A','Y','M',' ')},	/* Aymara */
-  {"az",	HB_TAG('A','Z','E',' ')},	/* Azerbaijani */
+  {"ay",	HB_TAG('A','Y','M',' ')},	/* Aymara [macrolanguage] */
+  {"az",	HB_TAG('A','Z','E',' ')},	/* Azerbaijani [macrolanguage] */
+  {"azb",	HB_TAG('A','Z','B',' ')},	/* South Azerbaijani */
+  {"azj",	HB_TAG('A','Z','E',' ')},	/* North Azerbaijani */
   {"ba",	HB_TAG('B','S','H',' ')},	/* Bashkir */
   {"bai",	HB_TAG('B','M','L',' ')},	/* Bamileke [family] */
-  {"bal",	HB_TAG('B','L','I',' ')},	/* Baluchi */
-  {"bci",	HB_TAG('B','A','U',' ')},	/* Baule */
+  {"bal",	HB_TAG('B','L','I',' ')},	/* Baluchi [macrolangauge] */
+  {"ban",	HB_TAG('B','A','N',' ')},	/* Balinese */
+  {"bar",	HB_TAG('B','A','R',' ')},	/* Bavarian */
+  {"bbc",	HB_TAG('B','B','C',' ')},	/* Batak Toba */
+  {"bci",	HB_TAG('B','A','U',' ')},	/* Baoulé */
+  {"bcl",	HB_TAG('B','I','K',' ')},	/* Central Bikol */
   {"bcq",	HB_TAG('B','C','H',' ')},	/* Bench */
-  {"be",	HB_TAG('B','E','L',' ')},  	/* Belarussian */
+  {"be",	HB_TAG('B','E','L',' ')},  	/* Belarusian */
   {"bem",	HB_TAG('B','E','M',' ')},	/* Bemba (Zambia) */
   {"ber",	HB_TAG('B','E','R',' ')},  	/* Berber [family] */
   {"bfq",	HB_TAG('B','A','D',' ')},	/* Badaga */
   {"bft",	HB_TAG('B','L','T',' ')},	/* Balti */
   {"bfy",	HB_TAG('B','A','G',' ')},	/* Baghelkhandi */
   {"bg",	HB_TAG('B','G','R',' ')},	/* Bulgarian */
+  {"bgc",	HB_TAG('B','G','C',' ')},	/* Haryanvi */
+  {"bgq",	HB_TAG('B','G','Q',' ')},	/* Bagri */
   {"bhb",	HB_TAG('B','H','I',' ')},	/* Bhili */
+  {"bhk",	HB_TAG('B','I','K',' ')},	/* Albay Bicolano (retired code) */
   {"bho",	HB_TAG('B','H','O',' ')},	/* Bhojpuri */
-  {"bik",	HB_TAG('B','I','K',' ')},	/* Bikol */
+  {"bi",	HB_TAG('B','I','S',' ')},	/* Bislama */
+  {"bik",	HB_TAG('B','I','K',' ')},	/* Bikol [macrolanguage] */
   {"bin",	HB_TAG('E','D','O',' ')},	/* Bini */
+  {"bjj",	HB_TAG('B','J','J',' ')},	/* Kanauji */
   {"bjt",	HB_TAG('B','L','N',' ')},	/* Balanta-Ganja */
   {"bla",	HB_TAG('B','K','F',' ')},	/* Blackfoot */
   {"ble",	HB_TAG('B','L','N',' ')},	/* Balanta-Kentohe */
+  {"blk",	HB_TAG('B','L','K',' ')},	/* Pa'O/Pa'o Karen */
+  {"bln",	HB_TAG('B','I','K',' ')},	/* Southern Catanduanes Bikol */
   {"bm",	HB_TAG('B','M','B',' ')},	/* Bambara */
   {"bn",	HB_TAG('B','E','N',' ')},	/* Bengali */
   {"bo",	HB_TAG('T','I','B',' ')},	/* Tibetan */
+  {"bpy",	HB_TAG('B','P','Y',' ')},	/* Bishnupriya */
+  {"bqi",	HB_TAG('L','R','C',' ')},	/* Bakhtiari */
   {"br",	HB_TAG('B','R','E',' ')},	/* Breton */
   {"bra",	HB_TAG('B','R','I',' ')},	/* Braj Bhasha */
   {"brh",	HB_TAG('B','R','H',' ')},	/* Brahui */
+  {"brx",	HB_TAG('B','R','X',' ')},	/* Bodo (India) */
   {"bs",	HB_TAG('B','O','S',' ')},	/* Bosnian */
   {"btb",	HB_TAG('B','T','I',' ')},	/* Beti (Cameroon) */
+  {"bto",	HB_TAG('B','I','K',' ')},	/* Rinconada Bikol */
+  {"bts",	HB_TAG('B','T','S',' ')},	/* Batak Simalungun */
+  {"bug",	HB_TAG('B','U','G',' ')},	/* Buginese */
   {"bxr",	HB_TAG('R','B','U',' ')},	/* Russian Buriat */
   {"byn",	HB_TAG('B','I','L',' ')},	/* Bilen */
   {"ca",	HB_TAG('C','A','T',' ')},	/* Catalan */
+  {"cbk",	HB_TAG('C','B','K',' ')},	/* Chavacano */
   {"ce",	HB_TAG('C','H','E',' ')},	/* Chechen */
   {"ceb",	HB_TAG('C','E','B',' ')},	/* Cebuano */
+  {"cgg",	HB_TAG('C','G','G',' ')},	/* Chiga */
+  {"ch",	HB_TAG('C','H','A',' ')},	/* Chamorro */
+  {"cho",	HB_TAG('C','H','O',' ')},	/* Choctaw */
   {"chp",	HB_TAG('C','H','P',' ')},	/* Chipewyan */
   {"chr",	HB_TAG('C','H','R',' ')},	/* Cherokee */
+  {"chy",	HB_TAG('C','H','Y',' ')},	/* Cheyenne */
+  {"ckb",	HB_TAG('K','U','R',' ')},	/* Central Kurdish (Sorani) */
   {"ckt",	HB_TAG('C','H','K',' ')},	/* Chukchi */
   {"cop",	HB_TAG('C','O','P',' ')},	/* Coptic */
   {"cr",	HB_TAG('C','R','E',' ')},	/* Cree */
   {"crh",	HB_TAG('C','R','T',' ')},	/* Crimean Tatar */
   {"crj",	HB_TAG('E','C','R',' ')},	/* [Southern] East Cree */
   {"crl",	HB_TAG('E','C','R',' ')},	/* [Northern] East Cree */
   {"crm",	HB_TAG('M','C','R',' ')},	/* Moose Cree */
   {"crx",	HB_TAG('C','R','R',' ')},	/* Carrier */
   {"cs",	HB_TAG('C','S','Y',' ')},	/* Czech */
+  {"csb",	HB_TAG('C','S','B',' ')},	/* Kashubian */
+  {"ctg",	HB_TAG('C','T','G',' ')},	/* Chittagonian */
+  {"cts",	HB_TAG('B','I','K',' ')},	/* Northern Catanduanes Bikol */
   {"cu",	HB_TAG('C','S','L',' ')},	/* Church Slavic */
   {"cv",	HB_TAG('C','H','U',' ')},	/* Chuvash */
   {"cwd",	HB_TAG('D','C','R',' ')},	/* Woods Cree */
   {"cy",	HB_TAG('W','E','L',' ')},	/* Welsh */
   {"da",	HB_TAG('D','A','N',' ')},	/* Danish */
   {"dap",	HB_TAG('N','I','S',' ')},	/* Nisi (India) */
   {"dar",	HB_TAG('D','A','R',' ')},	/* Dargwa */
   {"de",	HB_TAG('D','E','U',' ')},	/* German */
-  {"din",	HB_TAG('D','N','K',' ')},	/* Dinka */
-  {"dje",	HB_TAG('D','J','R',' ')},	/* Djerma */
+  {"dgo",	HB_TAG('D','G','O',' ')},	/* Dogri */
+  {"dhd",	HB_TAG('M','A','W',' ')},	/* Dhundari */
+  {"din",	HB_TAG('D','N','K',' ')},	/* Dinka [macrolanguage] */
+  {"diq",	HB_TAG('D','I','Q',' ')},	/* Dimli */
+  {"dje",	HB_TAG('D','J','R',' ')},	/* Zarma */
   {"dng",	HB_TAG('D','U','N',' ')},	/* Dungan */
-  {"doi",	HB_TAG('D','G','R',' ')},	/* Dogri */
+  {"doi",	HB_TAG('D','G','R',' ')},	/* Dogri [macrolanguage] */
   {"dsb",	HB_TAG('L','S','B',' ')},	/* Lower Sorbian */
-  {"dv",	HB_TAG('D','I','V',' ')},	/* Dhivehi */
+  {"dv",	HB_TAG('D','I','V',' ')},	/* Dhivehi/Divehi/Maldivian */
   {"dyu",	HB_TAG('J','U','L',' ')},	/* Jula */
   {"dz",	HB_TAG('D','Z','N',' ')},	/* Dzongkha */
   {"ee",	HB_TAG('E','W','E',' ')},	/* Ewe */
   {"efi",	HB_TAG('E','F','I',' ')},	/* Efik */
+  {"ekk",	HB_TAG('E','T','I',' ')},	/* Standard Estonian */
   {"el",	HB_TAG('E','L','L',' ')},	/* Modern Greek (1453-) */
+  {"emk",	HB_TAG('M','N','K',' ')},	/* Eastern Maninkakan */
   {"en",	HB_TAG('E','N','G',' ')},	/* English */
   {"eo",	HB_TAG('N','T','O',' ')},	/* Esperanto */
   {"eot",	HB_TAG('B','T','I',' ')},	/* Beti (Côte d'Ivoire) */
   {"es",	HB_TAG('E','S','P',' ')},	/* Spanish */
-  {"et",	HB_TAG('E','T','I',' ')},	/* Estonian */
+  {"et",	HB_TAG('E','T','I',' ')},	/* Estonian [macrolanguage] */
   {"eu",	HB_TAG('E','U','Q',' ')},	/* Basque */
   {"eve",	HB_TAG('E','V','N',' ')},	/* Even */
   {"evn",	HB_TAG('E','V','K',' ')},	/* Evenki */
-  {"fa",	HB_TAG('F','A','R',' ')},	/* Persian */
-  {"ff",	HB_TAG('F','U','L',' ')},	/* Fulah */
+  {"fa",	HB_TAG('F','A','R',' ')},	/* Persian [macrolanguage] */
+  {"ff",	HB_TAG('F','U','L',' ')},	/* Fulah [macrolanguage] */
   {"fi",	HB_TAG('F','I','N',' ')},	/* Finnish */
   {"fil",	HB_TAG('P','I','L',' ')},	/* Filipino */
   {"fj",	HB_TAG('F','J','I',' ')},	/* Fijian */
   {"fo",	HB_TAG('F','O','S',' ')},	/* Faroese */
   {"fon",	HB_TAG('F','O','N',' ')},	/* Fon */
   {"fr",	HB_TAG('F','R','A',' ')},	/* French */
+  {"frc",	HB_TAG('F','R','C',' ')},	/* Cajun French */
+  {"frp",	HB_TAG('F','R','P',' ')},	/* Arpitan/Francoprovençal */
   {"fur",	HB_TAG('F','R','L',' ')},	/* Friulian */
+  {"fuv",	HB_TAG('F','U','V',' ')},	/* Nigerian Fulfulde */
   {"fy",	HB_TAG('F','R','I',' ')},	/* Western Frisian */
   {"ga",	HB_TAG('I','R','I',' ')},	/* Irish */
   {"gaa",	HB_TAG('G','A','D',' ')},	/* Ga */
   {"gag",	HB_TAG('G','A','G',' ')},	/* Gagauz */
   {"gbm",	HB_TAG('G','A','W',' ')},	/* Garhwali */
   {"gd",	HB_TAG('G','A','E',' ')},	/* Scottish Gaelic */
   {"gez",	HB_TAG('G','E','Z',' ')},	/* Ge'ez */
+  {"ggo",	HB_TAG('G','O','N',' ')},	/* Southern Gondi */
   {"gl",	HB_TAG('G','A','L',' ')},	/* Galician */
   {"gld",	HB_TAG('N','A','N',' ')},	/* Nanai */
-  {"gn",	HB_TAG('G','U','A',' ')},	/* Guarani */
-  {"gon",	HB_TAG('G','O','N',' ')},	/* Gondi */
+  {"glk",	HB_TAG('G','L','K',' ')},	/* Gilaki */
+  {"gn",	HB_TAG('G','U','A',' ')},	/* Guarani [macrolanguage] */
+  {"gno",	HB_TAG('G','O','N',' ')},	/* Northern Gondi */
+  {"gog",	HB_TAG('G','O','G',' ')},	/* Gogo */
+  {"gon",	HB_TAG('G','O','N',' ')},	/* Gondi [macrolanguage] */
   {"grt",	HB_TAG('G','R','O',' ')},	/* Garo */
   {"gru",	HB_TAG('S','O','G',' ')},	/* Sodo Gurage */
   {"gu",	HB_TAG('G','U','J',' ')},	/* Gujarati */
+  {"guc",	HB_TAG('G','U','C',' ')},	/* Wayuu */
   {"guk",	HB_TAG('G','M','Z',' ')},	/* Gumuz */
-  {"gv",	HB_TAG('M','N','X',' ')},	/* Manx Gaelic */
+/*{"guk",	HB_TAG('G','U','K',' ')},*/	/* Gumuz (in SIL fonts) */
+  {"guz",	HB_TAG('G','U','Z',' ')},	/* Ekegusii/Gusii */
+  {"gv",	HB_TAG('M','N','X',' ')},	/* Manx */
   {"ha",	HB_TAG('H','A','U',' ')},	/* Hausa */
   {"har",	HB_TAG('H','R','I',' ')},	/* Harari */
-  {"haw",	HB_TAG('H','A','W',' ')},  	/* Hawaiin */
+  {"haw",	HB_TAG('H','A','W',' ')},  	/* Hawaiian */
+  {"hay",	HB_TAG('H','A','Y',' ')},  	/* Haya */
+  {"haz",	HB_TAG('H','A','Z',' ')},  	/* Hazaragi */
   {"he",	HB_TAG('I','W','R',' ')},	/* Hebrew */
+  {"hz",	HB_TAG('H','E','R',' ')},	/* Herero */
   {"hi",	HB_TAG('H','I','N',' ')},	/* Hindi */
   {"hil",	HB_TAG('H','I','L',' ')},	/* Hiligaynon */
   {"hnd",	HB_TAG('H','N','D',' ')},	/* [Southern] Hindko */
   {"hne",	HB_TAG('C','H','H',' ')},	/* Chattisgarhi */
   {"hno",	HB_TAG('H','N','D',' ')},	/* [Northern] Hindko */
+  {"ho",	HB_TAG('H','M','O',' ')},	/* Hiri Motu */
   {"hoc",	HB_TAG('H','O',' ',' ')},	/* Ho */
   {"hoj",	HB_TAG('H','A','R',' ')},	/* Harauti */
   {"hr",	HB_TAG('H','R','V',' ')},	/* Croatian */
   {"hsb",	HB_TAG('U','S','B',' ')},	/* Upper Sorbian */
-  {"ht",	HB_TAG('H','A','I',' ')},	/* Haitian */
+  {"ht",	HB_TAG('H','A','I',' ')},	/* Haitian/Haitian Creole */
   {"hu",	HB_TAG('H','U','N',' ')},	/* Hungarian */
   {"hy",	HB_TAG('H','Y','E',' ')},	/* Armenian */
+  {"hz",	HB_TAG('H','E','R',' ')},	/* Herero */
+  {"ia",	HB_TAG('I','N','A',' ')},	/* Interlingua (International Auxiliary Language Association) */
+  {"ibb",	HB_TAG('I','B','B',' ')},	/* Ibibio */
   {"id",	HB_TAG('I','N','D',' ')},	/* Indonesian */
+  {"ie",	HB_TAG('I','L','E',' ')},	/* Interlingue/Occidental */
   {"ig",	HB_TAG('I','B','O',' ')},	/* Igbo */
   {"igb",	HB_TAG('E','B','I',' ')},	/* Ebira */
+  {"ijc",	HB_TAG('I','J','O',' ')},	/* Izon */
   {"ijo",	HB_TAG('I','J','O',' ')},	/* Ijo [family] */
+  {"ik",	HB_TAG('I','P','K',' ')},	/* Inupiaq [macrolanguage] */
   {"ilo",	HB_TAG('I','L','O',' ')},	/* Ilokano */
   {"inh",	HB_TAG('I','N','G',' ')},	/* Ingush */
+  {"io",	HB_TAG('I','D','O',' ')},	/* Ido */
   {"is",	HB_TAG('I','S','L',' ')},	/* Icelandic */
   {"it",	HB_TAG('I','T','A',' ')},	/* Italian */
-  {"iu",	HB_TAG('I','N','U',' ')},	/* Inuktitut */
+  {"iu",	HB_TAG('I','N','U',' ')},	/* Inuktitut [macrolanguage] */
   {"ja",	HB_TAG('J','A','N',' ')},	/* Japanese */
+  {"jam",	HB_TAG('J','A','M',' ')},	/* Jamaican Creole English */
+  {"jbo",	HB_TAG('J','B','O',' ')},	/* Lojban */
   {"jv",	HB_TAG('J','A','V',' ')},	/* Javanese */
   {"ka",	HB_TAG('K','A','T',' ')},	/* Georgian */
   {"kaa",	HB_TAG('K','R','K',' ')},	/* Karakalpak */
+  {"kab",	HB_TAG('K','A','B',' ')},	/* Kabyle */
   {"kam",	HB_TAG('K','M','B',' ')},	/* Kamba (Kenya) */
   {"kar",	HB_TAG('K','R','N',' ')},	/* Karen [family] */
   {"kbd",	HB_TAG('K','A','B',' ')},	/* Kabardian */
+  {"kde",	HB_TAG('K','D','E',' ')},	/* Makonde */
   {"kdr",	HB_TAG('K','R','M',' ')},	/* Karaim */
   {"kdt",	HB_TAG('K','U','Y',' ')},	/* Kuy */
   {"kex",	HB_TAG('K','K','N',' ')},	/* Kokni */
   {"kfr",	HB_TAG('K','A','C',' ')},	/* Kachchi */
   {"kfy",	HB_TAG('K','M','N',' ')},	/* Kumaoni */
+  {"kg",	HB_TAG('K','O','N',' ')},	/* Kongo [macrolanguage] */
   {"kha",	HB_TAG('K','S','I',' ')},	/* Khasi */
-  {"khb",	HB_TAG('X','B','D',' ')},	/* Tai Lue */
+  {"khb",	HB_TAG('X','B','D',' ')},	/* Lü */
+  {"kht",	HB_TAG('K','H','N',' ')},	/* Khamti (Microsoft fonts) */
+/*{"kht",	HB_TAG('K','H','T',' ')},*/	/* Khamti (OpenType spec and SIL fonts) */
   {"khw",	HB_TAG('K','H','W',' ')},	/* Khowar */
-  {"ki",	HB_TAG('K','I','K',' ')},	/* Kikuyu */
+  {"ki",	HB_TAG('K','I','K',' ')},	/* Gikuyu/Kikuyu */
+  {"kj",	HB_TAG('K','U','A',' ')},	/* Kuanyama/Kwanyama */
   {"kjh",	HB_TAG('K','H','A',' ')},	/* Khakass */
+  {"kjp",	HB_TAG('K','J','P',' ')},	/* Pwo Eastern Karen */
   {"kk",	HB_TAG('K','A','Z',' ')},	/* Kazakh */
   {"kl",	HB_TAG('G','R','N',' ')},	/* Kalaallisut */
   {"kln",	HB_TAG('K','A','L',' ')},	/* Kalenjin */
   {"km",	HB_TAG('K','H','M',' ')},	/* Central Khmer */
-  {"kmb",	HB_TAG('M','B','N',' ')},	/* [North] Mbundu */
+  {"kmb",	HB_TAG('M','B','N',' ')},	/* Kimbundu */
   {"kmw",	HB_TAG('K','M','O',' ')},	/* Komo (Democratic Republic of Congo) */
   {"kn",	HB_TAG('K','A','N',' ')},	/* Kannada */
+  {"knn",	HB_TAG('K','O','K',' ')},	/* Konkani */
   {"ko",	HB_TAG('K','O','R',' ')},	/* Korean */
   {"koi",	HB_TAG('K','O','P',' ')},	/* Komi-Permyak */
-  {"kok",	HB_TAG('K','O','K',' ')},	/* Konkani */
-  {"kpe",	HB_TAG('K','P','L',' ')},	/* Kpelle */
+  {"kok",	HB_TAG('K','O','K',' ')},	/* Konkani [macrolanguage] */
+  {"kpe",	HB_TAG('K','P','L',' ')},	/* Kpelle [macrolanguage] */
   {"kpv",	HB_TAG('K','O','Z',' ')},	/* Komi-Zyrian */
   {"kpy",	HB_TAG('K','Y','K',' ')},	/* Koryak */
   {"kqy",	HB_TAG('K','R','T',' ')},	/* Koorete */
-  {"kr",	HB_TAG('K','N','R',' ')},	/* Kanuri */
+  {"kr",	HB_TAG('K','N','R',' ')},	/* Kanuri [macrolanguage] */
   {"kri",	HB_TAG('K','R','I',' ')},	/* Krio */
   {"krl",	HB_TAG('K','R','L',' ')},	/* Karelian */
   {"kru",	HB_TAG('K','U','U',' ')},	/* Kurukh */
   {"ks",	HB_TAG('K','S','H',' ')},	/* Kashmiri */
-  {"ku",	HB_TAG('K','U','R',' ')},	/* Kurdish */
+  {"ksh",	HB_TAG('K','S','H',' ')},	/* Kölsch */
+/*{"ksw",	HB_TAG('K','R','N',' ')},*/	/* S'gaw Karen (Microsoft fonts?) */
+  {"ksw",	HB_TAG('K','S','W',' ')},	/* S'gaw Karen (OpenType spec and SIL fonts) */
+  {"ku",	HB_TAG('K','U','R',' ')},	/* Kurdish [macrolanguage] */
   {"kum",	HB_TAG('K','U','M',' ')},	/* Kumyk */
+  {"kv",	HB_TAG('K','O','M',' ')},	/* Komi [macrolanguage] */
   {"kvd",	HB_TAG('K','U','I',' ')},	/* Kui (Indonesia) */
+  {"kw",	HB_TAG('C','O','R',' ')},	/* Cornish */
   {"kxc",	HB_TAG('K','M','S',' ')},	/* Komso */
   {"kxu",	HB_TAG('K','U','I',' ')},	/* Kui (India) */
-  {"ky",	HB_TAG('K','I','R',' ')},	/* Kirghiz */
+  {"ky",	HB_TAG('K','I','R',' ')},	/* Kirghiz/Kyrgyz */
+  {"kyu",	HB_TAG('K','Y','U',' ')},	/* Western Kayah */
   {"la",	HB_TAG('L','A','T',' ')},	/* Latin */
   {"lad",	HB_TAG('J','U','D',' ')},	/* Ladino */
   {"lb",	HB_TAG('L','T','Z',' ')},	/* Luxembourgish */
   {"lbe",	HB_TAG('L','A','K',' ')},	/* Lak */
   {"lbj",	HB_TAG('L','D','K',' ')},	/* Ladakhi */
   {"lez",	HB_TAG('L','E','Z',' ')},	/* Lezgi */
-  {"lg",	HB_TAG('L','U','G',' ')},	/* Luganda */
+  {"lg",	HB_TAG('L','U','G',' ')},	/* Ganda */
+  {"li",	HB_TAG('L','I','M',' ')},	/* Limburgan/Limburger/Limburgish */
   {"lif",	HB_TAG('L','M','B',' ')},	/* Limbu */
+  {"lij",	HB_TAG('L','I','J',' ')},	/* Ligurian */
+  {"lis",	HB_TAG('L','I','S',' ')},	/* Lisu */
+  {"ljp",	HB_TAG('L','J','P',' ')},	/* Lampung Api */
+  {"lki",	HB_TAG('L','K','I',' ')},	/* Laki */
   {"lld",	HB_TAG('L','A','D',' ')},	/* Ladin */
   {"lmn",	HB_TAG('L','A','M',' ')},	/* Lambani */
+  {"lmo",	HB_TAG('L','M','O',' ')},	/* Lombard */
   {"ln",	HB_TAG('L','I','N',' ')},	/* Lingala */
   {"lo",	HB_TAG('L','A','O',' ')},	/* Lao */
+  {"lrc",	HB_TAG('L','R','C',' ')},	/* Northern Luri */
   {"lt",	HB_TAG('L','T','H',' ')},	/* Lithuanian */
   {"lu",	HB_TAG('L','U','B',' ')},	/* Luba-Katanga */
   {"lua",	HB_TAG('L','U','B',' ')},	/* Luba-Kasai */
   {"luo",	HB_TAG('L','U','O',' ')},	/* Luo (Kenya and Tanzania) */
   {"lus",	HB_TAG('M','I','Z',' ')},	/* Mizo */
-  {"luy",	HB_TAG('L','U','H',' ')},	/* Luhya [macrolanguage] */
+  {"luy",	HB_TAG('L','U','H',' ')},	/* Luyia/Oluluyia [macrolanguage] */
+  {"luz",	HB_TAG('L','R','C',' ')},	/* Southern Luri */
   {"lv",	HB_TAG('L','V','I',' ')},	/* Latvian */
   {"lzz",	HB_TAG('L','A','Z',' ')},	/* Laz */
+  {"mad",	HB_TAG('M','A','D',' ')},	/* Madurese */
+  {"mag",	HB_TAG('M','A','G',' ')},	/* Magahi */
   {"mai",	HB_TAG('M','T','H',' ')},	/* Maithili */
+  {"mak",	HB_TAG('M','K','R',' ')},	/* Makasar */
+  {"man",	HB_TAG('M','N','K',' ')},	/* Manding/Mandingo [macrolanguage] */
   {"mdc",	HB_TAG('M','L','E',' ')},	/* Male (Papua New Guinea) */
   {"mdf",	HB_TAG('M','O','K',' ')},	/* Moksha */
+  {"mdr",	HB_TAG('M','D','R',' ')},	/* Mandar */
   {"mdy",	HB_TAG('M','L','E',' ')},	/* Male (Ethiopia) */
   {"men",	HB_TAG('M','D','E',' ')},	/* Mende (Sierra Leone) */
-  {"mg",	HB_TAG('M','L','G',' ')},	/* Malagasy */
+  {"mer",	HB_TAG('M','E','R',' ')},	/* Meru */
+  {"mfe",	HB_TAG('M','F','E',' ')},	/* Morisyen */
+  {"mg",	HB_TAG('M','L','G',' ')},	/* Malagasy [macrolanguage] */
+  {"mh",	HB_TAG('M','A','H',' ')},	/* Marshallese */
   {"mhr",	HB_TAG('L','M','A',' ')},	/* Low Mari */
   {"mi",	HB_TAG('M','R','I',' ')},	/* Maori */
+  {"min",	HB_TAG('M','I','N',' ')},	/* Minangkabau */
   {"mk",	HB_TAG('M','K','D',' ')},	/* Macedonian */
+  {"mku",	HB_TAG('M','N','K',' ')},	/* Konyanka Maninka */
+  {"mkw",	HB_TAG('M','K','W',' ')},	/* Kituba (Congo) */
   {"ml",	HB_TAG('M','L','R',' ')},	/* Malayalam */
-  {"mn",	HB_TAG('M','N','G',' ')},	/* Mongolian */
+  {"mlq",	HB_TAG('M','N','K',' ')},	/* Western Maninkakan */
+  {"mn",	HB_TAG('M','N','G',' ')},	/* Mongolian [macrolanguage] */
   {"mnc",	HB_TAG('M','C','H',' ')},	/* Manchu */
   {"mni",	HB_TAG('M','N','I',' ')},	/* Manipuri */
   {"mnk",	HB_TAG('M','N','D',' ')},	/* Mandinka */
   {"mns",	HB_TAG('M','A','N',' ')},	/* Mansi */
   {"mnw",	HB_TAG('M','O','N',' ')},	/* Mon */
   {"mo",	HB_TAG('M','O','L',' ')},	/* Moldavian */
   {"moh",	HB_TAG('M','O','H',' ')},	/* Mohawk */
+  {"mos",	HB_TAG('M','O','S',' ')},	/* Mossi */
   {"mpe",	HB_TAG('M','A','J',' ')},	/* Majang */
   {"mr",	HB_TAG('M','A','R',' ')},	/* Marathi */
   {"mrj",	HB_TAG('H','M','A',' ')},	/* High Mari */
-  {"ms",	HB_TAG('M','L','Y',' ')},	/* Malay */
+  {"ms",	HB_TAG('M','L','Y',' ')},	/* Malay [macrolanguage] */
+  {"msc",	HB_TAG('M','N','K',' ')},	/* Sankaran Maninka */
   {"mt",	HB_TAG('M','T','S',' ')},	/* Maltese */
-  {"mwr",	HB_TAG('M','A','W',' ')},	/* Marwari */
+  {"mtr",	HB_TAG('M','A','W',' ')},	/* Mewari */
+  {"mus",	HB_TAG('M','U','S',' ')},	/* Creek */
+  {"mve",	HB_TAG('M','A','W',' ')},	/* Marwari (Pakistan) */
+  {"mwk",	HB_TAG('M','N','K',' ')},	/* Kita Maninkakan */
+  {"mwl",	HB_TAG('M','W','L',' ')},	/* Mirandese */
+  {"mwr",	HB_TAG('M','A','W',' ')},	/* Marwari [macrolanguage] */
+  {"mww",	HB_TAG('M','W','W',' ')},	/* Hmong Daw */
   {"my",	HB_TAG('B','R','M',' ')},	/* Burmese */
   {"mym",	HB_TAG('M','E','N',' ')},	/* Me'en */
+  {"myq",	HB_TAG('M','N','K',' ')},	/* Forest Maninka (retired code) */
   {"myv",	HB_TAG('E','R','Z',' ')},	/* Erzya */
+  {"mzn",	HB_TAG('M','Z','N',' ')},	/* Mazanderani */
+  {"na",	HB_TAG('N','A','U',' ')},	/* Nauru */
   {"nag",	HB_TAG('N','A','G',' ')},	/* Naga-Assamese */
+  {"nah",	HB_TAG('N','A','H',' ')},	/* Nahuatl [family] */
+  {"nap",	HB_TAG('N','A','P',' ')},	/* Neapolitan */
   {"nb",	HB_TAG('N','O','R',' ')},	/* Norwegian Bokmål */
   {"nco",	HB_TAG('S','I','B',' ')},	/* Sibe */
   {"nd",	HB_TAG('N','D','B',' ')},	/* [North] Ndebele */
+  {"ndc",	HB_TAG('N','D','C',' ')},	/* Ndau */
+  {"nds",	HB_TAG('N','D','S',' ')},	/* Low German/Low Saxon */
   {"ne",	HB_TAG('N','E','P',' ')},	/* Nepali */
   {"new",	HB_TAG('N','E','W',' ')},	/* Newari */
   {"ng",	HB_TAG('N','D','G',' ')},	/* Ndonga */
+  {"nga",	HB_TAG('N','G','A',' ')},	/* Ngabaka */
   {"ngl",	HB_TAG('L','M','W',' ')},	/* Lomwe */
   {"niu",	HB_TAG('N','I','U',' ')},	/* Niuean */
   {"niv",	HB_TAG('G','I','L',' ')},	/* Gilyak */
   {"nl",	HB_TAG('N','L','D',' ')},	/* Dutch */
   {"nn",	HB_TAG('N','Y','N',' ')},	/* Norwegian Nynorsk */
-  {"no",	HB_TAG('N','O','R',' ')},	/* Norwegian (deprecated) */
-  {"nod",	HB_TAG('N','T','A',' ')},	/* Northern Tai */
+  {"no",	HB_TAG('N','O','R',' ')},	/* Norwegian [macrolanguage] */
+  {"nod",	HB_TAG('N','T','A',' ')},	/* Northern Thai */
+  {"noe",	HB_TAG('N','O','E',' ')},	/* Nimadi */
   {"nog",	HB_TAG('N','O','G',' ')},	/* Nogai */
+  {"nov",	HB_TAG('N','O','V',' ')},	/* Novial */
   {"nqo",	HB_TAG('N','K','O',' ')},	/* N'Ko */
   {"nr",	HB_TAG('N','D','B',' ')},	/* [South] Ndebele */
   {"nsk",	HB_TAG('N','A','S',' ')},	/* Naskapi */
   {"nso",	HB_TAG('S','O','T',' ')},	/* [Northern] Sotho */
-  {"ny",	HB_TAG('C','H','I',' ')},	/* Nyanja */
-  {"nyn",	HB_TAG('N','K','L',' ')},	/* Nkole */
+  {"ny",	HB_TAG('C','H','I',' ')},	/* Chewa/Chichwa/Nyanja */
+  {"nym",	HB_TAG('N','Y','M',' ')},	/* Nyamwezi */
+  {"nyn",	HB_TAG('N','K','L',' ')},	/* Nyankole */
   {"oc",	HB_TAG('O','C','I',' ')},	/* Occitan (post 1500) */
-  {"oj",	HB_TAG('O','J','B',' ')},	/* Ojibwa */
+  {"oj",	HB_TAG('O','J','B',' ')},	/* Ojibwa [macrolanguage] */
   {"ojs",	HB_TAG('O','C','R',' ')},	/* Oji-Cree */
-  {"om",	HB_TAG('O','R','O',' ')},	/* Oromo */
+  {"om",	HB_TAG('O','R','O',' ')},	/* Oromo [macrolanguage] */
   {"or",	HB_TAG('O','R','I',' ')},	/* Oriya */
   {"os",	HB_TAG('O','S','S',' ')},	/* Ossetian */
   {"pa",	HB_TAG('P','A','N',' ')},	/* Panjabi */
+  {"pag",	HB_TAG('P','A','G',' ')},	/* Pangasinan */
+  {"pam",	HB_TAG('P','A','M',' ')},	/* Kapampangan/Pampanga */
+  {"pap",	HB_TAG('P','A','P',' ')},	/* Papiamento */
+  {"pcc",	HB_TAG('P','C','C',' ')},	/* Bouyei */
+  {"pcd",	HB_TAG('P','C','D',' ')},	/* Picard */
   {"pce",	HB_TAG('P','L','G',' ')},	/* [Ruching] Palaung */
+  {"pdc",	HB_TAG('P','D','C',' ')},	/* Pennsylvania German */
+  {"pes",	HB_TAG('F','A','R',' ')},	/* Iranian Persian */
+  {"phk",	HB_TAG('P','H','K',' ')},	/* Phake */
   {"pi",	HB_TAG('P','A','L',' ')},	/* Pali */
+  {"pih",	HB_TAG('P','I','H',' ')},	/* Pitcairn-Norfolk */
   {"pl",	HB_TAG('P','L','K',' ')},	/* Polish */
   {"pll",	HB_TAG('P','L','G',' ')},	/* [Shwe] Palaung */
   {"plp",	HB_TAG('P','A','P',' ')},	/* Palpa */
-  {"prs",	HB_TAG('D','R','I',' ')},	/* Dari */
-  {"ps",	HB_TAG('P','A','S',' ')},	/* Pushto */
+  {"pms",	HB_TAG('P','M','S',' ')},	/* Piemontese */
+  {"pnb",	HB_TAG('P','N','B',' ')},	/* Western Panjabi */
+  {"prs",	HB_TAG('D','R','I',' ')},	/* Afghan Persian/Dari */
+  {"ps",	HB_TAG('P','A','S',' ')},	/* Pashto/Pushto [macrolanguage] */
   {"pt",	HB_TAG('P','T','G',' ')},	/* Portuguese */
-  {"raj",	HB_TAG('R','A','J',' ')},	/* Rajasthani */
-  {"rbb",	HB_TAG('P','L','G',' ')},	/* [Rumai] Palaung */
+  {"pwo",	HB_TAG('P','W','O',' ')},	/* Pwo Western Karen */
+  {"qu",	HB_TAG('Q','U','Z',' ')},	/* Quechua [macrolanguage] */
+  {"quc",	HB_TAG('Q','U','C',' ')},	/* K'iche'/Quiché */
+  {"quz",	HB_TAG('Q','U','Z',' ')},	/* Cusco Quechua */
+  {"raj",	HB_TAG('R','A','J',' ')},	/* Rajasthani [macrolanguage] */
+  {"rbb",	HB_TAG('P','L','G',' ')},	/* Rumai Palaung */
+  {"rej",	HB_TAG('R','E','J',' ')},	/* Rejang */
   {"ria",	HB_TAG('R','I','A',' ')},	/* Riang (India) */
   {"ril",	HB_TAG('R','I','A',' ')},	/* Riang (Myanmar) */
-  {"rki",	HB_TAG('A','R','K',' ')},	/* Arakanese */
-  {"rm",	HB_TAG('R','M','S',' ')},	/* Rhaeto-Romanic */
+  {"rki",	HB_TAG('A','R','K',' ')},	/* Rakhine */
+  {"rm",	HB_TAG('R','M','S',' ')},	/* Romansh */
+  {"rmy",	HB_TAG('R','M','Y',' ')},	/* Vlax Romani */
+  {"rn",	HB_TAG('R','U','N',' ')},	/* Rundi */
   {"ro",	HB_TAG('R','O','M',' ')},	/* Romanian */
-  {"rom",	HB_TAG('R','O','Y',' ')},	/* Romany */
+  {"rom",	HB_TAG('R','O','Y',' ')},	/* Romany [macrolanguage] */
   {"ru",	HB_TAG('R','U','S',' ')},	/* Russian */
   {"rue",	HB_TAG('R','S','Y',' ')},	/* Rusyn */
-  {"rw",	HB_TAG('R','U','A',' ')},	/* Ruanda */
+  {"rup",	HB_TAG('R','U','P',' ')},	/* Aromanian/Arumanian/Macedo-Romanian */
+  {"rw",	HB_TAG('R','U','A',' ')},	/* Kinyarwanda */
+  {"rwr",	HB_TAG('M','A','W',' ')},	/* Marwari (India) */
   {"sa",	HB_TAG('S','A','N',' ')},	/* Sanskrit */
   {"sah",	HB_TAG('Y','A','K',' ')},	/* Yakut */
+  {"sas",	HB_TAG('S','A','S',' ')},	/* Sasak */
   {"sat",	HB_TAG('S','A','T',' ')},	/* Santali */
   {"sck",	HB_TAG('S','A','D',' ')},	/* Sadri */
+  {"sc",	HB_TAG('S','R','D',' ')},	/* Sardinian [macrolanguage] */
+  {"scn",	HB_TAG('S','C','N',' ')},	/* Sicilian */
+  {"sco",	HB_TAG('S','C','O',' ')},	/* Scots */
   {"scs",	HB_TAG('S','L','A',' ')},	/* [North] Slavey */
   {"sd",	HB_TAG('S','N','D',' ')},	/* Sindhi */
   {"se",	HB_TAG('N','S','M',' ')},	/* Northern Sami */
   {"seh",	HB_TAG('S','N','A',' ')},	/* Sena */
   {"sel",	HB_TAG('S','E','L',' ')},	/* Selkup */
   {"sg",	HB_TAG('S','G','O',' ')},	/* Sango */
+  {"sga",	HB_TAG('S','G','A',' ')},	/* Old Irish (to 900) */
+  {"sgs",	HB_TAG('S','G','S',' ')},	/* Samogitian */
+  {"sgw",	HB_TAG('C','H','G',' ')},	/* Sebat Bet Gurage */
+/*{"sgw",	HB_TAG('S','G','W',' ')},*/	/* Sebat Bet Gurage (in SIL fonts) */
   {"shn",	HB_TAG('S','H','N',' ')},	/* Shan */
   {"si",	HB_TAG('S','N','H',' ')},	/* Sinhala */
   {"sid",	HB_TAG('S','I','D',' ')},	/* Sidamo */
   {"sjd",	HB_TAG('K','S','M',' ')},	/* Kildin Sami */
   {"sk",	HB_TAG('S','K','Y',' ')},	/* Slovak */
   {"skr",	HB_TAG('S','R','K',' ')},	/* Seraiki */
   {"sl",	HB_TAG('S','L','V',' ')},	/* Slovenian */
   {"sm",	HB_TAG('S','M','O',' ')},	/* Samoan */
   {"sma",	HB_TAG('S','S','M',' ')},	/* Southern Sami */
   {"smj",	HB_TAG('L','S','M',' ')},	/* Lule Sami */
   {"smn",	HB_TAG('I','S','M',' ')},	/* Inari Sami */
   {"sms",	HB_TAG('S','K','S',' ')},	/* Skolt Sami */
+  {"sn",	HB_TAG('S','N','A',' ')},	/* Shona */
   {"snk",	HB_TAG('S','N','K',' ')},	/* Soninke */
   {"so",	HB_TAG('S','M','L',' ')},	/* Somali */
-  {"sq",	HB_TAG('S','Q','I',' ')},	/* Albanian */
+  {"sop",	HB_TAG('S','O','P',' ')},	/* Songe */
+  {"sq",	HB_TAG('S','Q','I',' ')},	/* Albanian [macrolanguage] */
   {"sr",	HB_TAG('S','R','B',' ')},	/* Serbian */
   {"srr",	HB_TAG('S','R','R',' ')},	/* Serer */
-  {"ss",	HB_TAG('S','W','Z',' ')},	/* Swazi */
+  {"ss",	HB_TAG('S','W','Z',' ')},	/* Swati */
   {"st",	HB_TAG('S','O','T',' ')},	/* [Southern] Sotho */
+  {"stq",	HB_TAG('S','T','Q',' ')},	/* Saterfriesisch */
+  {"stv",	HB_TAG('S','I','G',' ')},	/* Silt'e */
+  {"su",	HB_TAG('S','U','N',' ')},	/* Sundanese */
+  {"suk",	HB_TAG('S','U','K',' ')},	/* Sukama */
   {"suq",	HB_TAG('S','U','R',' ')},	/* Suri */
   {"sv",	HB_TAG('S','V','E',' ')},	/* Swedish */
   {"sva",	HB_TAG('S','V','A',' ')},	/* Svan */
-  {"sw",	HB_TAG('S','W','K',' ')},	/* Swahili */
+  {"sw",	HB_TAG('S','W','K',' ')},	/* Swahili [macrolanguage] */
   {"swb",	HB_TAG('C','M','R',' ')},	/* Comorian */
-  {"syr",	HB_TAG('S','Y','R',' ')},	/* Syriac */
+  {"swh",	HB_TAG('S','W','K',' ')},	/* Kiswahili/Swahili */
+  {"swv",	HB_TAG('M','A','W',' ')},	/* Shekhawati */
+  {"sxu",	HB_TAG('S','X','U',' ')},	/* Upper Saxon */
+  {"syl",	HB_TAG('S','Y','L',' ')},	/* Sylheti */
+  {"syr",	HB_TAG('S','Y','R',' ')},	/* Syriac [macrolanguage] */
+  {"szl",	HB_TAG('S','Z','L',' ')},	/* Silesian */
   {"ta",	HB_TAG('T','A','M',' ')},	/* Tamil */
   {"tab",	HB_TAG('T','A','B',' ')},	/* Tabasaran */
   {"tcy",	HB_TAG('T','U','L',' ')},	/* Tulu */
+  {"tdd",	HB_TAG('T','D','D',' ')},	/* Tai Nüa */
   {"te",	HB_TAG('T','E','L',' ')},	/* Telugu */
   {"tem",	HB_TAG('T','M','N',' ')},	/* Temne */
+  {"tet",	HB_TAG('T','E','T',' ')},	/* Tetum */
   {"tg",	HB_TAG('T','A','J',' ')},	/* Tajik */
   {"th",	HB_TAG('T','H','A',' ')},	/* Thai */
   {"ti",	HB_TAG('T','G','Y',' ')},	/* Tigrinya */
   {"tig",	HB_TAG('T','G','R',' ')},	/* Tigre */
+  {"tiv",	HB_TAG('T','I','V',' ')},	/* Tiv */
   {"tk",	HB_TAG('T','K','M',' ')},	/* Turkmen */
+  {"tl",	HB_TAG('T','G','L',' ')},	/* Tagalog */
+  {"tmh",	HB_TAG('t','m','h',' ')},	/* Tamashek [macrolanguage] */
   {"tn",	HB_TAG('T','N','A',' ')},	/* Tswana */
   {"to",	HB_TAG('T','G','N',' ')},	/* Tonga (Tonga Islands) */
+  {"tpi",	HB_TAG('T','P','I',' ')},	/* Tok Pisin */
   {"tr",	HB_TAG('T','R','K',' ')},	/* Turkish */
   {"tru",	HB_TAG('T','U','A',' ')},	/* Turoyo Aramaic */
   {"ts",	HB_TAG('T','S','G',' ')},	/* Tsonga */
   {"tt",	HB_TAG('T','A','T',' ')},	/* Tatar */
+  {"tum",	HB_TAG('T','U','M',' ')},	/* Tumbuka */
   {"tw",	HB_TAG('T','W','I',' ')},	/* Twi */
   {"ty",	HB_TAG('T','H','T',' ')},	/* Tahitian */
   {"tyv",	HB_TAG('T','U','V',' ')},	/* Tuvin */
+  {"tyz",	HB_TAG('T','Y','Z',' ')},	/* Tày */
+  {"tzm",	HB_TAG('T','Z','M',' ')},	/* Central Atlas Tamazight */
   {"udm",	HB_TAG('U','D','M',' ')},	/* Udmurt */
   {"ug",	HB_TAG('U','Y','G',' ')},	/* Uighur */
   {"uk",	HB_TAG('U','K','R',' ')},	/* Ukrainian */
-  {"umb",	HB_TAG('M','B','N',' ')},	/* [South] Mbundu */
+  {"umb",	HB_TAG('U','M','B',' ')},	/* Umbundu */
   {"unr",	HB_TAG('M','U','N',' ')},	/* Mundari */
   {"ur",	HB_TAG('U','R','D',' ')},	/* Urdu */
-  {"uz",	HB_TAG('U','Z','B',' ')},	/* Uzbek */
+  {"uz",	HB_TAG('U','Z','B',' ')},	/* Uzbek [macrolanguage] */
+  {"uzn",	HB_TAG('U','Z','B',' ')},	/* Northern Uzbek */
+  {"uzs",	HB_TAG('U','Z','B',' ')},	/* Southern Uzbek */
   {"ve",	HB_TAG('V','E','N',' ')},	/* Venda */
+  {"vec",	HB_TAG('V','E','C',' ')},	/* Venetian */
+  {"vls",	HB_TAG('F','L','E',' ')},	/* Vlaams */
   {"vi",	HB_TAG('V','I','T',' ')},	/* Vietnamese */
-  {"vmw",	HB_TAG('M','A','K',' ')},	/* Makua */
+  {"vmw",	HB_TAG('M','A','K',' ')},	/* Makhuwa */
+  {"vo",	HB_TAG('V','O','L',' ')},	/* Volapük */
+  {"vro",	HB_TAG('V','R','O',' ')},	/* Võro */
+  {"wa",	HB_TAG('W','L','N',' ')},	/* Walloon */
+  {"war",	HB_TAG('W','A','R',' ')},	/* Waray (Philippines) */
   {"wbm",	HB_TAG('W','A',' ',' ')},	/* Wa */
   {"wbr",	HB_TAG('W','A','G',' ')},	/* Wagdi */
+  {"wle",	HB_TAG('S','I','G',' ')},	/* Wolane */
+  {"wry",	HB_TAG('M','A','W',' ')},	/* Merwari */
+  {"wtm",	HB_TAG('W','T','M',' ')},	/* Mewati */
   {"wo",	HB_TAG('W','L','F',' ')},	/* Wolof */
   {"xal",	HB_TAG('K','L','M',' ')},	/* Kalmyk */
   {"xh",	HB_TAG('X','H','S',' ')},	/* Xhosa */
+  {"xog",	HB_TAG('X','O','G',' ')},	/* Soga */
   {"xom",	HB_TAG('K','M','O',' ')},	/* Komo (Sudan) */
   {"xsl",	HB_TAG('S','S','L',' ')},	/* South Slavey */
-  {"yi",	HB_TAG('J','I','I',' ')},	/* Yiddish */
+  {"xst",	HB_TAG('S','I','G',' ')},	/* Silt'e (retired code) */
+  {"xwo",	HB_TAG('T','O','D',' ')},	/* Written Oirat (Todo) */
+  {"yao",	HB_TAG('Y','A','O',' ')},	/* Yao */
+  {"yi",	HB_TAG('J','I','I',' ')},	/* Yiddish [macrolanguage] */
   {"yo",	HB_TAG('Y','B','A',' ')},	/* Yoruba */
   {"yso",	HB_TAG('N','I','S',' ')},	/* Nisi (China) */
+  {"za",	HB_TAG('Z','H','A',' ')},	/* Chuang/Zhuang [macrolanguage] */
+  {"zea",	HB_TAG('Z','E','A',' ')},	/* Zeeuws */
   {"zne",	HB_TAG('Z','N','D',' ')},	/* Zande */
-  {"zu",	HB_TAG('Z','U','L',' ')} 	/* Zulu */
+  {"zu",	HB_TAG('Z','U','L',' ')}, 	/* Zulu */
+  {"zum",	HB_TAG('L','R','C',' ')}	/* Kumzari */
 
   /* The corresponding languages IDs for the following IDs are unclear,
    * overlap, or are architecturally weird. Needs more research. */
 
 /*{"ahg/awn/xan?",	HB_TAG('A','G','W',' ')},*/	/* Agaw */
 /*{"gsw?/gsw-FR?",	HB_TAG('A','L','S',' ')},*/	/* Alsatian */
 /*{"krc",	HB_TAG('B','A','L',' ')},*/	/* Balkar */
 /*{"??",	HB_TAG('B','C','R',' ')},*/	/* Bible Cree */
-/*{"sgw?",	HB_TAG('C','H','G',' ')},*/	/* Chaha Gurage */
+/*{"zh?",	HB_TAG('C','H','N',' ')},*/	/* Chinese (seen in Microsoft fonts) */
 /*{"acf/gcf?",	HB_TAG('F','A','N',' ')},*/	/* French Antillean */
-/*{"vls/nl-be",	HB_TAG('F','L','E',' ')},*/	/* Flemish */
 /*{"enf?/yrk?",	HB_TAG('F','N','E',' ')},*/	/* Forest Nenets */
 /*{"fuf?",	HB_TAG('F','T','A',' ')},*/	/* Futa */
 /*{"ar-Syrc?",	HB_TAG('G','A','R',' ')},*/	/* Garshuni */
 /*{"cfm/rnl?",	HB_TAG('H','A','L',' ')},*/	/* Halam */
+/*{"fonipa",	HB_TAG('I','P','P','H')},*/	/* Phonetic transcription—IPA conventions */
 /*{"ga-Latg?/Latg?",	HB_TAG('I','R','T',' ')},*/	/* Irish Traditional */
 /*{"krc",	HB_TAG('K','A','R',' ')},*/	/* Karachay */
 /*{"alw?/ktb?",	HB_TAG('K','E','B',' ')},*/	/* Kebena */
 /*{"Geok",	HB_TAG('K','G','E',' ')},*/	/* Khutsuri Georgian */
 /*{"kca",	HB_TAG('K','H','K',' ')},*/	/* Khanty-Kazim */
 /*{"kca",	HB_TAG('K','H','S',' ')},*/	/* Khanty-Shurishkar */
 /*{"kca",	HB_TAG('K','H','V',' ')},*/	/* Khanty-Vakhi */
 /*{"guz?/kqs?/kss?",	HB_TAG('K','I','S',' ')},*/	/* Kisii */
 /*{"kfa/kfi?/kpb?/xua?/xuj?",	HB_TAG('K','O','D',' ')},*/	/* Kodagu */
 /*{"okm?/oko?",	HB_TAG('K','O','H',' ')},*/	/* Korean Old Hangul */
 /*{"kon?/ktu?/...",	HB_TAG('K','O','N',' ')},*/	/* Kikongo */
 /*{"kfx?",	HB_TAG('K','U','L',' ')},*/	/* Kulvi */
 /*{"??",	HB_TAG('L','A','H',' ')},*/	/* Lahuli */
 /*{"??",	HB_TAG('L','C','R',' ')},*/	/* L-Cree */
 /*{"??",	HB_TAG('M','A','L',' ')},*/	/* Malayalam Traditional */
 /*{"mnk?/mlq?/...",	HB_TAG('M','L','N',' ')},*/	/* Malinke */
-/*{"man?/myq?/mku?/msc?/...",	HB_TAG('M','N','K',' ')},*/	/* Maninka */
-/*{"??",	HB_TAG('M','O','R',' ')},*/	/* Moroccan */
 /*{"??",	HB_TAG('N','C','R',' ')},*/	/* N-Cree */
 /*{"??",	HB_TAG('N','H','C',' ')},*/	/* Norway House Cree */
 /*{"jpa?/sam?",	HB_TAG('P','A','A',' ')},*/	/* Palestinian Aramaic */
 /*{"polyton",	HB_TAG('P','G','R',' ')},*/	/* Polytonic Greek */
 /*{"??",	HB_TAG('Q','I','N',' ')},*/	/* Asho Chin */
 /*{"??",	HB_TAG('R','C','R',' ')},*/	/* R-Cree */
 /*{"chp?",	HB_TAG('S','A','Y',' ')},*/	/* Sayisi */
 /*{"xan?",	HB_TAG('S','E','K',' ')},*/	/* Sekota */
-/*{"stv/wle?/xst?",	HB_TAG('S','I','G',' ')},*/	/* Silte Gurage */
 /*{"ngo?",	HB_TAG('S','X','T',' ')},*/	/* Sutu */
 /*{"??",	HB_TAG('T','C','R',' ')},*/	/* TH-Cree */
 /*{"tnz?/tog?/toi?",	HB_TAG('T','N','G',' ')},*/	/* Tonga */
 /*{"enh?/yrk?",	HB_TAG('T','N','E',' ')},*/	/* Tundra Nenets */
-/*{"??",	HB_TAG('T','O','D',' ')},*/	/* Todo */
 /*{"??",	HB_TAG('W','C','R',' ')},*/	/* West-Cree */
-/*{"??",	HB_TAG('Y','C','R',' ')},*/	/* Y-Cree */
+/*{"cre?",	HB_TAG('Y','C','R',' ')},*/	/* Y-Cree */
 /*{"??",	HB_TAG('Y','I','C',' ')},*/	/* Yi Classic */
 /*{"ii?/Yiii?",	HB_TAG('Y','I','M',' ')},*/	/* Yi Modern */
 /*{"??",	HB_TAG('Z','H','P',' ')},*/	/* Chinese Phonetic */
 };
 
 static const LangTag ot_languages_zh[] = {
   {"zh-cn",	HB_TAG('Z','H','S',' ')},	/* Chinese (China) */
   {"zh-hk",	HB_TAG('Z','H','H',' ')},	/* Chinese (Hong Kong) */
--- a/gfx/harfbuzz/src/hb-private.hh
+++ b/gfx/harfbuzz/src/hb-private.hh
@@ -74,16 +74,19 @@ typedef const _hb_void_t &hb_void_t;
 #undef MIN
 template <typename Type>
 static inline Type MIN (const Type &a, const Type &b) { return a < b ? a : b; }
 
 #undef MAX
 template <typename Type>
 static inline Type MAX (const Type &a, const Type &b) { return a > b ? a : b; }
 
+static inline unsigned int DIV_CEIL (const unsigned int a, unsigned int b)
+{ return (a + (b - 1)) / b; }
+
 
 #undef  ARRAY_LENGTH
 template <typename Type, unsigned int n>
 static inline unsigned int ARRAY_LENGTH (const Type (&)[n]) { return n; }
 /* A const version, but does not detect erratically being called on pointers. */
 #define ARRAY_LENGTH_CONST(__array) ((signed int) (sizeof (__array) / sizeof (__array[0])))
 
 #define HB_STMT_START do
--- a/gfx/harfbuzz/src/hb-shape-plan-private.hh
+++ b/gfx/harfbuzz/src/hb-shape-plan-private.hh
@@ -34,22 +34,25 @@
 
 
 struct hb_shape_plan_t
 {
   hb_object_header_t header;
   ASSERT_POD ();
 
   hb_bool_t default_shaper_list;
-  hb_face_t *face;
+  hb_face_t *face_unsafe; /* We don't carry a reference to face. */
   hb_segment_properties_t props;
 
   hb_shape_func_t *shaper_func;
   const char *shaper_name;
 
+  hb_feature_t *user_features;
+  unsigned int num_user_features;
+
   struct hb_shaper_data_t shaper_data;
 };
 
 #define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS \
 	, const hb_feature_t            *user_features \
 	, unsigned int                   num_user_features
 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, shape_plan);
 #include "hb-shaper-list.hh"
--- a/gfx/harfbuzz/src/hb-shape-plan.cc
+++ b/gfx/harfbuzz/src/hb-shape-plan.cc
@@ -41,17 +41,17 @@ hb_shape_plan_plan (hb_shape_plan_t    *
 		    const hb_feature_t *user_features,
 		    unsigned int        num_user_features,
 		    const char * const *shaper_list)
 {
   const hb_shaper_pair_t *shapers = _hb_shapers_get ();
 
 #define HB_SHAPER_PLAN(shaper) \
 	HB_STMT_START { \
-	  if (hb_##shaper##_shaper_face_data_ensure (shape_plan->face)) { \
+	  if (hb_##shaper##_shaper_face_data_ensure (shape_plan->face_unsafe)) { \
 	    HB_SHAPER_DATA (shaper, shape_plan) = \
 	      HB_SHAPER_DATA_CREATE_FUNC (shaper, shape_plan) (shape_plan, user_features, num_user_features); \
 	    shape_plan->shaper_func = _hb_##shaper##_shape; \
 	    shape_plan->shaper_name = #shaper; \
 	    return; \
 	  } \
 	} HB_STMT_END
 
@@ -102,28 +102,37 @@ hb_shape_plan_create (hb_face_t         
 		      const hb_segment_properties_t *props,
 		      const hb_feature_t            *user_features,
 		      unsigned int                   num_user_features,
 		      const char * const            *shaper_list)
 {
   assert (props->direction != HB_DIRECTION_INVALID);
 
   hb_shape_plan_t *shape_plan;
+  hb_feature_t *features = NULL;
 
   if (unlikely (!face))
     face = hb_face_get_empty ();
   if (unlikely (!props || hb_object_is_inert (face)))
     return hb_shape_plan_get_empty ();
-  if (!(shape_plan = hb_object_create<hb_shape_plan_t> ()))
+  if (num_user_features && !(features = (hb_feature_t *) malloc (num_user_features * sizeof (hb_feature_t))))
     return hb_shape_plan_get_empty ();
+  if (!(shape_plan = hb_object_create<hb_shape_plan_t> ())) {
+    free (features);
+    return hb_shape_plan_get_empty ();
+  }
 
   hb_face_make_immutable (face);
   shape_plan->default_shaper_list = shaper_list == NULL;
-  shape_plan->face = hb_face_reference (face);
+  shape_plan->face_unsafe = face;
   shape_plan->props = *props;
+  shape_plan->num_user_features = num_user_features;
+  shape_plan->user_features = features;
+  if (num_user_features)
+    memcpy (features, user_features, num_user_features * sizeof (hb_feature_t));
 
   hb_shape_plan_plan (shape_plan, user_features, num_user_features, shaper_list);
 
   return shape_plan;
 }
 
 /**
  * hb_shape_plan_get_empty:
@@ -142,16 +151,19 @@ hb_shape_plan_get_empty (void)
 
     true, /* default_shaper_list */
     NULL, /* face */
     HB_SEGMENT_PROPERTIES_DEFAULT, /* props */
 
     NULL, /* shaper_func */
     NULL, /* shaper_name */
 
+    NULL, /* user_features */
+    0,    /* num_user_featurs */
+
     {
 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
 #include "hb-shaper-list.hh"
 #undef HB_SHAPER_IMPLEMENT
     }
   };
 
   return const_cast<hb_shape_plan_t *> (&_hb_shape_plan_nil);
@@ -185,17 +197,17 @@ void
 hb_shape_plan_destroy (hb_shape_plan_t *shape_plan)
 {
   if (!hb_object_destroy (shape_plan)) return;
 
 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, shape_plan);
 #include "hb-shaper-list.hh"
 #undef HB_SHAPER_IMPLEMENT
 
-  hb_face_destroy (shape_plan->face);
+  free (shape_plan->user_features);
 
   free (shape_plan);
 }
 
 /**
  * hb_shape_plan_set_user_data: (skip)
  * @shape_plan: a shape plan.
  * @key: 
@@ -259,17 +271,17 @@ hb_shape_plan_execute (hb_shape_plan_t  
 		       const hb_feature_t *features,
 		       unsigned int        num_features)
 {
   if (unlikely (hb_object_is_inert (shape_plan) ||
 		hb_object_is_inert (font) ||
 		hb_object_is_inert (buffer)))
     return false;
 
-  assert (shape_plan->face == font->face);
+  assert (shape_plan->face_unsafe == font->face);
   assert (hb_segment_properties_equal (&shape_plan->props, &buffer->props));
 
 #define HB_SHAPER_EXECUTE(shaper) \
 	HB_STMT_START { \
 	  return HB_SHAPER_DATA (shaper, shape_plan) && \
 		 hb_##shaper##_shaper_font_data_ensure (font) && \
 		 _hb_##shaper##_shape (shape_plan, font, buffer, features, num_features); \
 	} HB_STMT_END
@@ -296,33 +308,65 @@ hb_shape_plan_execute (hb_shape_plan_t  
 static unsigned int
 hb_shape_plan_hash (const hb_shape_plan_t *shape_plan)
 {
   return hb_segment_properties_hash (&shape_plan->props) +
 	 shape_plan->default_shaper_list ? 0 : (intptr_t) shape_plan->shaper_func;
 }
 #endif
 
-/* TODO no user-feature caching for now. */
+/* User-feature caching is currently somewhat dumb:
+ * it only finds matches where the feature array is identical,
+ * not cases where the feature lists would be compatible for plan purposes
+ * but have different ranges, for example.
+ */
 struct hb_shape_plan_proposal_t
 {
   const hb_segment_properties_t  props;
   const char * const            *shaper_list;
+  const hb_feature_t            *user_features;
+  unsigned int                   num_user_features;
   hb_shape_func_t               *shaper_func;
 };
 
+static inline hb_bool_t
+hb_shape_plan_user_features_match (const hb_shape_plan_t          *shape_plan,
+				   const hb_shape_plan_proposal_t *proposal)
+{
+  if (proposal->num_user_features != shape_plan->num_user_features) return false;
+  for (unsigned int i = 0, n = proposal->num_user_features; i < n; i++)
+    if (proposal->user_features[i].tag   != shape_plan->user_features[i].tag   ||
+        proposal->user_features[i].value != shape_plan->user_features[i].value ||
+        proposal->user_features[i].start != shape_plan->user_features[i].start ||
+        proposal->user_features[i].end   != shape_plan->user_features[i].end) return false;
+  return true;
+}
+
 static hb_bool_t
 hb_shape_plan_matches (const hb_shape_plan_t          *shape_plan,
 		       const hb_shape_plan_proposal_t *proposal)
 {
   return hb_segment_properties_equal (&shape_plan->props, &proposal->props) &&
+	 hb_shape_plan_user_features_match (shape_plan, proposal) &&
 	 ((shape_plan->default_shaper_list && proposal->shaper_list == NULL) ||
 	  (shape_plan->shaper_func == proposal->shaper_func));
 }
 
+static inline hb_bool_t
+hb_non_global_user_features_present (const hb_feature_t *user_features,
+				     unsigned int        num_user_features)
+{
+  while (num_user_features)
+    if (user_features->start != 0 || user_features->end != (unsigned int) -1)
+      return true;
+    else
+      num_user_features--, user_features++;
+  return false;
+}
+
 /**
  * hb_shape_plan_create_cached:
  * @face: 
  * @props: 
  * @user_features: (array length=num_user_features):
  * @num_user_features: 
  * @shaper_list: (array zero-terminated=1):
  *
@@ -334,22 +378,21 @@ hb_shape_plan_matches (const hb_shape_pl
  **/
 hb_shape_plan_t *
 hb_shape_plan_create_cached (hb_face_t                     *face,
 			     const hb_segment_properties_t *props,
 			     const hb_feature_t            *user_features,
 			     unsigned int                   num_user_features,
 			     const char * const            *shaper_list)
 {
-  if (num_user_features)
-    return hb_shape_plan_create (face, props, user_features, num_user_features, shaper_list);
-
   hb_shape_plan_proposal_t proposal = {
     *props,
     shaper_list,
+    user_features,
+    num_user_features,
     NULL
   };
 
   if (shaper_list) {
     /* Choose shaper.  Adapted from hb_shape_plan_plan(). */
 #define HB_SHAPER_PLAN(shaper) \
 	  HB_STMT_START { \
 	    if (hb_##shaper##_shaper_face_data_ensure (face)) \
@@ -377,32 +420,34 @@ retry:
   for (hb_face_t::plan_node_t *node = cached_plan_nodes; node; node = node->next)
     if (hb_shape_plan_matches (node->shape_plan, &proposal))
       return hb_shape_plan_reference (node->shape_plan);
 
   /* Not found. */
 
   hb_shape_plan_t *shape_plan = hb_shape_plan_create (face, props, user_features, num_user_features, shaper_list);
 
+  /* Don't add the plan to the cache if there were user features with non-global ranges */
+
+  if (hb_non_global_user_features_present (user_features, num_user_features))
+    return shape_plan;
+
   hb_face_t::plan_node_t *node = (hb_face_t::plan_node_t *) calloc (1, sizeof (hb_face_t::plan_node_t));
   if (unlikely (!node))
     return shape_plan;
 
   node->shape_plan = shape_plan;
   node->next = cached_plan_nodes;
 
   if (!hb_atomic_ptr_cmpexch (&face->shape_plans, cached_plan_nodes, node)) {
     hb_shape_plan_destroy (shape_plan);
     free (node);
     goto retry;
   }
 
-  /* Release our reference on face. */
-  hb_face_destroy (face);
-
   return hb_shape_plan_reference (shape_plan);
 }
 
 /**
  * hb_shape_plan_get_shaper:
  * @shape_plan: a shape plan.
  *
  * 
--- a/gfx/harfbuzz/src/hb-uniscribe.cc
+++ b/gfx/harfbuzz/src/hb-uniscribe.cc
@@ -724,44 +724,46 @@ hb_bool_t
     return false; \
   } HB_STMT_END;
 
   HRESULT hr;
 
 retry:
 
   unsigned int scratch_size;
-  char *scratch = (char *) buffer->get_scratch_buffer (&scratch_size);
-
-  /* Allocate char buffers; they all fit */
+  hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size);
 
 #define ALLOCATE_ARRAY(Type, name, len) \
   Type *name = (Type *) scratch; \
-  scratch += (len) * sizeof ((name)[0]); \
-  scratch_size -= (len) * sizeof ((name)[0]);
+  { \
+    unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \
+    assert (_consumed <= scratch_size); \
+    scratch += _consumed; \
+    scratch_size -= _consumed; \
+  }
 
 #define utf16_index() var1.u32
 
-  WCHAR *pchars = (WCHAR *) scratch;
+  ALLOCATE_ARRAY (WCHAR, pchars, buffer->len * 2);
+
   unsigned int chars_len = 0;
   for (unsigned int i = 0; i < buffer->len; i++)
   {
     hb_codepoint_t c = buffer->info[i].codepoint;
     buffer->info[i].utf16_index() = chars_len;
     if (likely (c < 0x10000))
       pchars[chars_len++] = c;
     else if (unlikely (c >= 0x110000))
       pchars[chars_len++] = 0xFFFD;
     else {
       pchars[chars_len++] = 0xD800 + ((c - 0x10000) >> 10);
       pchars[chars_len++] = 0xDC00 + ((c - 0x10000) & ((1 << 10) - 1));
     }
   }
 
-  ALLOCATE_ARRAY (WCHAR, wchars, chars_len);
   ALLOCATE_ARRAY (WORD, log_clusters, chars_len);
   ALLOCATE_ARRAY (SCRIPT_CHARPROP, char_props, chars_len);
 
   if (num_features)
   {
     /* Need log_clusters to assign features. */
     chars_len = 0;
     for (unsigned int i = 0; i < buffer->len; i++)
@@ -769,22 +771,23 @@ retry:
       hb_codepoint_t c = buffer->info[i].codepoint;
       unsigned int cluster = buffer->info[i].cluster;
       log_clusters[chars_len++] = cluster;
       if (c >= 0x10000 && c < 0x110000)
 	log_clusters[chars_len++] = cluster; /* Surrogates. */
     }
   }
 
-  /* On Windows, we don't care about alignment...*/
-  unsigned int glyphs_size = scratch_size / (sizeof (WORD) +
-					     sizeof (SCRIPT_GLYPHPROP) +
-					     sizeof (int) +
-					     sizeof (GOFFSET) +
-					     sizeof (uint32_t));
+  /* All the following types are sized in multiples of sizeof(int). */
+  unsigned int glyphs_size = scratch_size / ((sizeof (WORD) +
+					      sizeof (SCRIPT_GLYPHPROP) +
+					      sizeof (int) +
+					      sizeof (GOFFSET) +
+					      sizeof (uint32_t))
+					     / sizeof (int));
 
   ALLOCATE_ARRAY (WORD, glyphs, glyphs_size);
   ALLOCATE_ARRAY (SCRIPT_GLYPHPROP, glyph_props, glyphs_size);
   ALLOCATE_ARRAY (int, advances, glyphs_size);
   ALLOCATE_ARRAY (GOFFSET, offsets, glyphs_size);
   ALLOCATE_ARRAY (uint32_t, vis_clusters, glyphs_size);
 
   /* Note:
@@ -807,17 +810,17 @@ retry:
 
   /* MinGW32 doesn't define fMergeNeutralItems, so we bruteforce */
   //bidi_control.fMergeNeutralItems = true;
   *(uint32_t*)&bidi_control |= 1<<24;
 
   bidi_state.uBidiLevel = HB_DIRECTION_IS_FORWARD (buffer->props.direction) ? 0 : 1;
   bidi_state.fOverrideDirection = 1;
 
-  hr = funcs->ScriptItemizeOpenType (wchars,
+  hr = funcs->ScriptItemizeOpenType (pchars,
 				     chars_len,
 				     MAX_ITEMS,
 				     &bidi_control,
 				     &bidi_state,
 				     items,
 				     script_tags,
 				     &item_count);
   if (unlikely (FAILED (hr)))
@@ -882,17 +885,17 @@ retry:
     hr = funcs->ScriptShapeOpenType (font_data->hdc,
 				     &font_data->script_cache,
 				     &items[i].a,
 				     script_tags[i],
 				     language_tag,
 				     range_char_counts.array,
 				     range_properties.array,
 				     range_properties.len,
-				     wchars + chars_offset,
+				     pchars + chars_offset,
 				     item_chars_len,
 				     glyphs_size - glyphs_offset,
 				     /* out */
 				     log_clusters + chars_offset,
 				     char_props + chars_offset,
 				     glyphs + glyphs_offset,
 				     glyph_props + glyphs_offset,
 				     (int *) &glyphs_len);
@@ -924,17 +927,17 @@ retry:
     hr = funcs->ScriptPlaceOpenType (font_data->hdc,
 				     &font_data->script_cache,
 				     &items[i].a,
 				     script_tags[i],
 				     language_tag,
 				     range_char_counts.array,
 				     range_properties.array,
 				     range_properties.len,
-				     wchars + chars_offset,
+				     pchars + chars_offset,
 				     log_clusters + chars_offset,
 				     char_props + chars_offset,
 				     item_chars_len,
 				     glyphs + glyphs_offset,
 				     glyph_props + glyphs_offset,
 				     glyphs_len,
 				     /* out */
 				     advances + glyphs_offset,
--- a/gfx/harfbuzz/src/hb-version.h
+++ b/gfx/harfbuzz/src/hb-version.h
@@ -33,19 +33,19 @@
 
 #include "hb-common.h"
 
 HB_BEGIN_DECLS
 
 
 #define HB_VERSION_MAJOR 0
 #define HB_VERSION_MINOR 9
-#define HB_VERSION_MICRO 23
+#define HB_VERSION_MICRO 24
 
-#define HB_VERSION_STRING "0.9.23"
+#define HB_VERSION_STRING "0.9.24"
 
 #define HB_VERSION_CHECK(major,minor,micro) \
 	((major)*10000+(minor)*100+(micro) >= \
 	 HB_VERSION_MAJOR*10000+HB_VERSION_MINOR*100+HB_VERSION_MICRO)
 
 
 void
 hb_version (unsigned int *major,
--- a/gfx/skia/include/utils/SkCondVar.h
+++ b/gfx/skia/include/utils/SkCondVar.h
@@ -6,17 +6,17 @@
  */
 
 #ifndef SkCondVar_DEFINED
 #define SkCondVar_DEFINED
 
 #ifdef SK_USE_POSIX_THREADS
 #include <pthread.h>
 #elif defined(SK_BUILD_FOR_WIN32)
-#include <Windows.h>
+#include <windows.h>
 #endif
 
 /**
  * Condition variable for blocking access to shared data from other threads and
  * controlling which threads are awake.
  *
  * Currently only supported on platforms with posix threads and Windows Vista and
  * above.
--- a/js/src/gc/StoreBuffer.h
+++ b/js/src/gc/StoreBuffer.h
@@ -393,17 +393,18 @@ class StoreBuffer
     bool aboutToOverflow_;
     bool enabled_;
     mozilla::DebugOnly<bool> entered; /* For ReentrancyGuard. */
 
   public:
     explicit StoreBuffer(JSRuntime *rt, const Nursery &nursery)
       : bufferVal(), bufferCell(), bufferSlot(), bufferWholeCell(),
         bufferRelocVal(), bufferRelocCell(), bufferGeneric(),
-        runtime_(rt), nursery_(nursery), aboutToOverflow_(false), enabled_(false)
+        runtime_(rt), nursery_(nursery), aboutToOverflow_(false), enabled_(false),
+        entered(false)
     {
     }
 
     bool enable();
     void disable();
     bool isEnabled() const { return enabled_; }
 
     bool clear();
--- a/js/src/jit/TypeRepresentationSet.cpp
+++ b/js/src/jit/TypeRepresentationSet.cpp
@@ -77,17 +77,17 @@ TypeRepresentationSetBuilder::insert(Typ
         size_t i = min + ((max - min) >> 1); // average w/o fear of overflow
 
         uintptr_t entryiaddr = (uintptr_t) entries_[i];
         if (entryiaddr == typeReprAddr)
             return true; // typeRepr already present in the set
 
         if (entryiaddr < typeReprAddr) {
             // typeRepr lies to the right of entry i
-            min = i;
+            min = i + 1;
         } else {
             // typeRepr lies to the left of entry i
             max = i;
         }
     }
 
     // As a sanity check, give up if the TypeRepresentationSet grows too large.
     if (entries_.length() >= 512) {
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -1048,17 +1048,21 @@ js_HandleExecutionInterrupt(JSContext *c
     return true;
 }
 
 js::ThreadSafeContext::ThreadSafeContext(JSRuntime *rt, PerThreadData *pt, ContextKind kind)
   : ContextFriendFields(rt),
     contextKind_(kind),
     perThreadData(pt),
     allocator_(nullptr)
-{ }
+{
+#ifdef JS_WORKER_THREADS
+    JS_ASSERT_IF(kind == Context_Exclusive, rt->workerThreadState != nullptr);
+#endif
+}
 
 bool
 ThreadSafeContext::isForkJoinSlice() const
 {
     return contextKind_ == Context_ForkJoin;
 }
 
 ForkJoinSlice *
--- a/js/src/jsweakmap.cpp
+++ b/js/src/jsweakmap.cpp
@@ -272,17 +272,17 @@ static inline void
 WeakMapPostWriteBarrier(JSRuntime *rt, ObjectValueMap *map, JSObject *key)
 {
 #ifdef JSGC_GENERATIONAL
     /*
      * Strip the barriers from the type before inserting into the store buffer.
      * This will automatically ensure that barriers do not fire during GC.
      */
     typedef WeakMap<JSObject *, Value> UnbarrieredObjectValueMap;
-    typedef HashKeyRef<UnbarrieredObjectValueMap, JSObject *> Ref;
+    typedef gc::HashKeyRef<UnbarrieredObjectValueMap, JSObject *> Ref;
     if (key && IsInsideNursery(rt, key))
         rt->gcStoreBuffer.putGeneric(Ref(reinterpret_cast<UnbarrieredObjectValueMap *>(map), key));
 #endif
 }
 
 JS_ALWAYS_INLINE bool
 WeakMap_set_impl(JSContext *cx, CallArgs args)
 {
--- a/layout/base/moz.build
+++ b/layout/base/moz.build
@@ -121,17 +121,17 @@ LOCAL_INCLUDES += [
     '../../view/src',
     '../forms',
     '../generic',
     '../mathml',
     '../printing',
     '../style',
     '../svg',
     '../tables',
-    '../xul/base/src',
+    '../xul',
     '../xul/tree/',
     '/docshell/base',
     '/xpcom/ds',
 ]
 
 FINAL_LIBRARY = 'gklayout'
 
 MOCHITEST_MANIFESTS += ['tests/mochitest.ini']
--- a/layout/base/nsCSSColorUtils.cpp
+++ b/layout/base/nsCSSColorUtils.cpp
@@ -235,28 +235,25 @@ void NS_HSV2RGB(nscolor &aColor, uint16_
   }
   aColor = NS_RGBA(r, g, b, aAlpha);
 }
 
 #undef RED_LUMINOSITY
 #undef GREEN_LUMINOSITY
 #undef BLUE_LUMINOSITY
 #undef INTENSITY_FACTOR
-#undef LIGHT_FACTOR
 #undef LUMINOSITY_FACTOR
 
 #undef MAX_COLOR
 #undef COLOR_DARK_THRESHOLD
 #undef COLOR_LIGHT_THRESHOLD
 
 #undef COLOR_LITE_BS_FACTOR
 #undef COLOR_LITE_TS_FACTOR
 
 #undef COLOR_DARK_BS_FACTOR
 #undef COLOR_DARK_TS_FACTOR
 
 #undef LIGHT_GRAY
 #undef DARK_GRAY
-#undef WHITE
-#undef BLACK
 
 #undef MAX_BRIGHTNESS
 #undef MAX_DARKNESS
--- a/layout/build/moz.build
+++ b/layout/build/moz.build
@@ -28,21 +28,21 @@ MSVC_ENABLE_PGO = True
 LIBRARY_NAME = 'gklayout'
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 LOCAL_INCLUDES += [
     '../base',
     '../forms',
     '../generic',
-    '../inspector/src',
+    '../inspector',
     '../mathml',
     '../style',
     '../tables',
-    '../xul/base/src',
+    '../xul',
     '/caps/include',
     '/content/base/src',
     '/content/canvas/src',
     '/content/events/src',
     '/content/html/content/src',
     '/content/html/document/src',
     '/content/svg/content/src',
     '/content/xbl/src',
--- a/layout/forms/moz.build
+++ b/layout/forms/moz.build
@@ -45,10 +45,10 @@ FINAL_LIBRARY = 'gklayout'
 LOCAL_INCLUDES += [
     '../../content/base/src',
     '../../content/html/content/src',
     '../../editor/libeditor/base',
     '../../editor/libeditor/text',
     '../../editor/txmgr/src',
     '../base',
     '../generic',
-    '../xul/base/src',
+    '../xul',
 ]
--- a/layout/generic/moz.build
+++ b/layout/generic/moz.build
@@ -114,10 +114,10 @@ LOCAL_INCLUDES += [
     '../../content/xul/content/src',
     '../../dom/base',
     '../../dom/plugins/base',
     '../base',
     '../forms',
     '../style',
     '../svg',
     '../tables',
-    '../xul/base/src',
+    '../xul',
 ]
rename from layout/inspector/src/inCSSValueSearch.cpp
rename to layout/inspector/inCSSValueSearch.cpp
rename from layout/inspector/src/inCSSValueSearch.h
rename to layout/inspector/inCSSValueSearch.h
rename from layout/inspector/src/inDOMUtils.cpp
rename to layout/inspector/inDOMUtils.cpp
rename from layout/inspector/src/inDOMUtils.h
rename to layout/inspector/inDOMUtils.h
rename from layout/inspector/src/inDOMView.cpp
rename to layout/inspector/inDOMView.cpp
rename from layout/inspector/src/inDOMView.h
rename to layout/inspector/inDOMView.h
rename from layout/inspector/src/inDeepTreeWalker.cpp
rename to layout/inspector/inDeepTreeWalker.cpp
rename from layout/inspector/src/inDeepTreeWalker.h
rename to layout/inspector/inDeepTreeWalker.h
rename from layout/inspector/src/inFlasher.cpp
rename to layout/inspector/inFlasher.cpp
rename from layout/inspector/src/inFlasher.h
rename to layout/inspector/inFlasher.h
rename from layout/inspector/public/inICSSValueSearch.idl
rename to layout/inspector/inICSSValueSearch.idl
rename from layout/inspector/public/inIDOMUtils.idl
rename to layout/inspector/inIDOMUtils.idl
rename from layout/inspector/public/inIDOMView.idl
rename to layout/inspector/inIDOMView.idl
rename from layout/inspector/public/inIDeepTreeWalker.idl
rename to layout/inspector/inIDeepTreeWalker.idl
rename from layout/inspector/public/inIFlasher.idl
rename to layout/inspector/inIFlasher.idl
rename from layout/inspector/public/inISearchObserver.idl
rename to layout/inspector/inISearchObserver.idl
rename from layout/inspector/public/inISearchProcess.idl
rename to layout/inspector/inISearchProcess.idl
rename from layout/inspector/src/inLayoutUtils.cpp
rename to layout/inspector/inLayoutUtils.cpp
rename from layout/inspector/src/inLayoutUtils.h
rename to layout/inspector/inLayoutUtils.h
rename from layout/inspector/src/inSearchLoop.cpp
rename to layout/inspector/inSearchLoop.cpp
rename from layout/inspector/src/inSearchLoop.h
rename to layout/inspector/inSearchLoop.h
rename from layout/inspector/src/moz.build
rename to layout/inspector/moz.build
--- a/layout/inspector/src/moz.build
+++ b/layout/inspector/moz.build
@@ -1,14 +1,28 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+XPIDL_SOURCES += [
+    'inICSSValueSearch.idl',
+    'inIDeepTreeWalker.idl',
+    'inIDOMUtils.idl',
+    'inIDOMView.idl',
+    'inIFlasher.idl',
+    'inISearchObserver.idl',
+    'inISearchProcess.idl',
+    'nsIDOMFontFace.idl',
+    'nsIDOMFontFaceList.idl',
+]
+
+XPIDL_MODULE = 'inspector'
+
 EXPORTS += [
     'nsFontFace.h',
     'nsFontFaceList.h',
 ]
 
 UNIFIED_SOURCES += [
     'inCSSValueSearch.cpp',
     'inDeepTreeWalker.cpp',
@@ -24,13 +38,18 @@ if CONFIG['MOZ_XUL']:
     UNIFIED_SOURCES += [
         'inDOMView.cpp',
     ]
 
 FAIL_ON_WARNINGS = True
 
 FINAL_LIBRARY = 'gklayout'
 LOCAL_INCLUDES += [
-    '../../style',
+    '../style',
     '/content/base/src',
     '/content/xbl/src',
 ]
 
+if CONFIG['ENABLE_TESTS']:
+    PARALLEL_DIRS += [
+        'tests',
+        'tests/chrome',
+    ]
rename from layout/inspector/src/nsFontFace.cpp
rename to layout/inspector/nsFontFace.cpp
rename from layout/inspector/src/nsFontFace.h
rename to layout/inspector/nsFontFace.h
rename from layout/inspector/src/nsFontFaceList.cpp
rename to layout/inspector/nsFontFaceList.cpp
rename from layout/inspector/src/nsFontFaceList.h
rename to layout/inspector/nsFontFaceList.h
rename from layout/inspector/public/nsIDOMFontFace.idl
rename to layout/inspector/nsIDOMFontFace.idl
rename from layout/inspector/public/nsIDOMFontFaceList.idl
rename to layout/inspector/nsIDOMFontFaceList.idl
deleted file mode 100644
--- a/layout/inspector/public/moz.build
+++ /dev/null
@@ -1,20 +0,0 @@
-# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-XPIDL_SOURCES += [
-    'inICSSValueSearch.idl',
-    'inIDeepTreeWalker.idl',
-    'inIDOMUtils.idl',
-    'inIDOMView.idl',
-    'inIFlasher.idl',
-    'inISearchObserver.idl',
-    'inISearchProcess.idl',
-    'nsIDOMFontFace.idl',
-    'nsIDOMFontFaceList.idl',
-]
-
-XPIDL_MODULE = 'inspector'
-
--- a/layout/ipc/moz.build
+++ b/layout/ipc/moz.build
@@ -24,10 +24,10 @@ FAIL_ON_WARNINGS = True
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'gklayout'
 
 LOCAL_INCLUDES += [
     '/content/base/src',
     '/layout/base',
     '/layout/generic',
-    '/layout/xul/base/src',
+    '/layout/xul',
 ]
--- a/layout/mathml/moz.build
+++ b/layout/mathml/moz.build
@@ -32,13 +32,17 @@ UNIFIED_SOURCES += [
 FAIL_ON_WARNINGS = True
 
 FINAL_LIBRARY = 'gklayout'
 LOCAL_INCLUDES += [
     '../base',
     '../generic',
     '../style',
     '../tables',
-    '../xul/base/src',
+    '../xul',
     '/content/base/src',
     '/content/mathml/content/src',
 ]
 
+if CONFIG['ENABLE_TESTS']:
+    PARALLEL_DIRS += [
+        'tests',
+    ]
--- a/layout/moz.build
+++ b/layout/moz.build
@@ -6,40 +6,26 @@
 
 PARALLEL_DIRS += [
     'style',
     'base',
     'generic',
     'forms',
     'tables',
     'svg',
-    'xul/base/public',
-    'xul/base/src',
+    'xul',
     'ipc',
     'mathml',
-    'inspector/public',
-    'inspector/src',
+    'inspector',
     'tools/recording',
 ]
 
 if CONFIG['NS_PRINTING']:
     PARALLEL_DIRS += ['printing']
 
-if CONFIG['MOZ_XUL']:
-    PARALLEL_DIRS += ['xul/tree', 'xul/grid']
-
-if CONFIG['ENABLE_TESTS']:
-    PARALLEL_DIRS += [
-        'inspector/tests',
-        'inspector/tests/chrome',
-        'mathml/tests',
-        'xul/test',
-        'xul/base/test',
-    ]
-
 TEST_TOOL_DIRS += [
     'tools/reftest',
     'reftests/fonts',
     'reftests/fonts/mplus',
 ]
 
 DIRS += ['build', 'media']
 
--- a/layout/reftests/reftest.list
+++ b/layout/reftests/reftest.list
@@ -323,17 +323,17 @@ skip-if(B2G) include xul-document-load/r
 
 # xul/
 skip-if(B2G) include xul/reftest.list
 
 # webcomonents/
 include webcomponents/reftest.list
 
 # xul
-skip-if(B2G) include ../xul/base/reftest/reftest.list
+skip-if(B2G) include ../xul/reftest/reftest.list
 
 # xul grid
 skip-if(B2G) include ../xul/grid/reftests/reftest.list
 
 # z-index/
 skip-if(B2G) include z-index/reftest.list
 
 # reftest(s) to verify content bugfixes
--- a/layout/style/moz.build
+++ b/layout/style/moz.build
@@ -136,11 +136,11 @@ FINAL_LIBRARY = 'gklayout'
 
 LOCAL_INCLUDES += [
     '../../content/base/src',
     '../../content/html/content/src',
     '../../content/xbl/src',
     '../../content/xul/document/src',
     '../base',
     '../generic',
-    '../xul/base/src',
+    '../xul',
     '/dom/base',
 ]
--- a/layout/svg/moz.build
+++ b/layout/svg/moz.build
@@ -51,11 +51,11 @@ FAIL_ON_WARNINGS = True
 FINAL_LIBRARY = 'gklayout'
 LOCAL_INCLUDES += [
     '../../content/base/src',
     '../../content/svg/content/src',
     '../../widget',
     '../base',
     '../generic',
     '../style',
-    '../xul/base/src',
+    '../xul',
 ]
 
--- a/layout/tables/moz.build
+++ b/layout/tables/moz.build
@@ -33,12 +33,12 @@ FINAL_LIBRARY = 'gklayout'
 
 LOCAL_INCLUDES += [
     '../../content/base/src',
     '../../content/html/content/src',
     '../../intl/unicharutil/util',
     '../base',
     '../generic',
     '../style',
-    '../xul/base/src',
+    '../xul',
 ]
 
 DEFINES['DEBUG_TABLE_STRATEGY_off'] = True
deleted file mode 100644
--- a/layout/xul/base/public/moz.build
+++ /dev/null
@@ -1,27 +0,0 @@
-# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-XPIDL_SOURCES += [
-    'nsIBoxObject.idl',
-    'nsIBrowserBoxObject.idl',
-    'nsIContainerBoxObject.idl',
-    'nsIEditorBoxObject.idl',
-    'nsIIFrameBoxObject.idl',
-    'nsIListBoxObject.idl',
-    'nsIMenuBoxObject.idl',
-    'nsIPopupBoxObject.idl',
-    'nsIScrollBoxObject.idl',
-    'nsISliderListener.idl',
-]
-
-XPIDL_MODULE = 'layout_xul'
-
-EXPORTS += [
-    'nsIScrollbarMediator.h',
-    'nsPIBoxObject.h',
-    'nsXULPopupManager.h',
-]
-
deleted file mode 100644
--- a/layout/xul/base/test/chrome.ini
+++ /dev/null
@@ -1,12 +0,0 @@
-[DEFAULT]
-support-files =
-  window_resizer.xul
-  window_resizer_element.xul
-
-[test_bug381167.xhtml]
-[test_bug393970.xul]
-[test_bug477754.xul]
-[test_popupSizeTo.xul]
-[test_resizer.xul]
-[test_stack.xul]
-[test_windowminmaxsize.xul]
deleted file mode 100644
--- a/layout/xul/base/test/mochitest.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[DEFAULT]
-
-[test_bug511075.html]
-[test_resizer_incontent.xul]
-[test_splitter.xul]
deleted file mode 100644
--- a/layout/xul/base/test/moz.build
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-MOCHITEST_MANIFESTS += ['mochitest.ini']
-
-MOCHITEST_CHROME_MANIFESTS += ['chrome.ini']
-
rename from layout/xul/base/src/crashtests/131008-1.xul
rename to layout/xul/crashtests/131008-1.xul
rename from layout/xul/base/src/crashtests/137216-1.xul
rename to layout/xul/crashtests/137216-1.xul
rename from layout/xul/base/src/crashtests/140218-1.xml
rename to layout/xul/crashtests/140218-1.xml
rename from layout/xul/base/src/crashtests/151826-1.xul
rename to layout/xul/crashtests/151826-1.xul
rename from layout/xul/base/src/crashtests/168724-1.xul
rename to layout/xul/crashtests/168724-1.xul
rename from layout/xul/base/src/crashtests/189814-1.xul
rename to layout/xul/crashtests/189814-1.xul
rename from layout/xul/base/src/crashtests/237787-1.xul
rename to layout/xul/crashtests/237787-1.xul
rename from layout/xul/base/src/crashtests/265161-1.xul
rename to layout/xul/crashtests/265161-1.xul
rename from layout/xul/base/src/crashtests/289410-1.xul
rename to layout/xul/crashtests/289410-1.xul
rename from layout/xul/base/src/crashtests/291702-1.xul
rename to layout/xul/crashtests/291702-1.xul
rename from layout/xul/base/src/crashtests/291702-2.xul
rename to layout/xul/crashtests/291702-2.xul
rename from layout/xul/base/src/crashtests/291702-3.xul
rename to layout/xul/crashtests/291702-3.xul
rename from layout/xul/base/src/crashtests/294371-1.xul
rename to layout/xul/crashtests/294371-1.xul
rename from layout/xul/base/src/crashtests/311457-1.html
rename to layout/xul/crashtests/311457-1.html
rename from layout/xul/base/src/crashtests/321056-1.xhtml
rename to layout/xul/crashtests/321056-1.xhtml
rename from layout/xul/base/src/crashtests/322786-1.xul
rename to layout/xul/crashtests/322786-1.xul
rename from layout/xul/base/src/crashtests/325377.xul
rename to layout/xul/crashtests/325377.xul
rename from layout/xul/base/src/crashtests/326834-1-inner.xul
rename to layout/xul/crashtests/326834-1-inner.xul
rename from layout/xul/base/src/crashtests/326834-1.html
rename to layout/xul/crashtests/326834-1.html
rename from layout/xul/base/src/crashtests/326879-1.xul
rename to layout/xul/crashtests/326879-1.xul
rename from layout/xul/base/src/crashtests/327776-1.xul
rename to layout/xul/crashtests/327776-1.xul
rename from layout/xul/base/src/crashtests/328135-1.xul
rename to layout/xul/crashtests/328135-1.xul
rename from layout/xul/base/src/crashtests/329327-1.xul
rename to layout/xul/crashtests/329327-1.xul
rename from layout/xul/base/src/crashtests/329407-1.xml
rename to layout/xul/crashtests/329407-1.xml
rename from layout/xul/base/src/crashtests/329477-1.xhtml
rename to layout/xul/crashtests/329477-1.xhtml
rename from layout/xul/base/src/crashtests/336962-1.xul
rename to layout/xul/crashtests/336962-1.xul
rename from layout/xul/base/src/crashtests/344228-1.xul
rename to layout/xul/crashtests/344228-1.xul
rename from layout/xul/base/src/crashtests/346083-1.xul
rename to layout/xul/crashtests/346083-1.xul
rename from layout/xul/base/src/crashtests/346281-1.xul
rename to layout/xul/crashtests/346281-1.xul
rename from layout/xul/base/src/crashtests/350460.xul
rename to layout/xul/crashtests/350460.xul
rename from layout/xul/base/src/crashtests/360642-1.xul
rename to layout/xul/crashtests/360642-1.xul
rename from layout/xul/base/src/crashtests/365151.xul
rename to layout/xul/crashtests/365151.xul
rename from layout/xul/base/src/crashtests/366112-1.xul
rename to layout/xul/crashtests/366112-1.xul
rename from layout/xul/base/src/crashtests/369942-1.xhtml
rename to layout/xul/crashtests/369942-1.xhtml
rename from layout/xul/base/src/crashtests/374102-1.xul
rename to layout/xul/crashtests/374102-1.xul
rename from layout/xul/base/src/crashtests/376137-1.html
rename to layout/xul/crashtests/376137-1.html
rename from layout/xul/base/src/crashtests/376137-2.html
rename to layout/xul/crashtests/376137-2.html
rename from layout/xul/base/src/crashtests/377592-1.svg
rename to layout/xul/crashtests/377592-1.svg
rename from layout/xul/base/src/crashtests/381862.html
rename to layout/xul/crashtests/381862.html
rename from layout/xul/base/src/crashtests/382746-1.xul
rename to layout/xul/crashtests/382746-1.xul
rename from layout/xul/base/src/crashtests/382899-1.xul
rename to layout/xul/crashtests/382899-1.xul
rename from layout/xul/base/src/crashtests/383236-1.xul
rename to layout/xul/crashtests/383236-1.xul
rename from layout/xul/base/src/crashtests/384037-1.xhtml
rename to layout/xul/crashtests/384037-1.xhtml
rename from layout/xul/base/src/crashtests/384105-1-inner.xul
rename to layout/xul/crashtests/384105-1-inner.xul
rename from layout/xul/base/src/crashtests/384105-1.html
rename to layout/xul/crashtests/384105-1.html
rename from layout/xul/base/src/crashtests/384491-1.xhtml
rename to layout/xul/crashtests/384491-1.xhtml
rename from layout/xul/base/src/crashtests/384871-1-inner.xul
rename to layout/xul/crashtests/384871-1-inner.xul
rename from layout/xul/base/src/crashtests/384871-1.html
rename to layout/xul/crashtests/384871-1.html
rename from layout/xul/base/src/crashtests/387033-1.xhtml
rename to layout/xul/crashtests/387033-1.xhtml
rename from layout/xul/base/src/crashtests/387080-1.xul
rename to layout/xul/crashtests/387080-1.xul
rename from layout/xul/base/src/crashtests/391974-1-inner.xul
rename to layout/xul/crashtests/391974-1-inner.xul
rename from layout/xul/base/src/crashtests/391974-1.html
rename to layout/xul/crashtests/391974-1.html
rename from layout/xul/base/src/crashtests/394120-1.xhtml
rename to layout/xul/crashtests/394120-1.xhtml
rename from layout/xul/base/src/crashtests/397293.xhtml
rename to layout/xul/crashtests/397293.xhtml
rename from layout/xul/base/src/crashtests/397304-1.html
rename to layout/xul/crashtests/397304-1.html
rename from layout/xul/base/src/crashtests/398326-1.xhtml
rename to layout/xul/crashtests/398326-1.xhtml
rename from layout/xul/base/src/crashtests/399013.xul
rename to layout/xul/crashtests/399013.xul
rename from layout/xul/base/src/crashtests/400779-1.xhtml
rename to layout/xul/crashtests/400779-1.xhtml
rename from layout/xul/base/src/crashtests/402912-1.xhtml
rename to layout/xul/crashtests/402912-1.xhtml
rename from layout/xul/base/src/crashtests/408904-1.xul
rename to layout/xul/crashtests/408904-1.xul
rename from layout/xul/base/src/crashtests/412479-1.xhtml
rename to layout/xul/crashtests/412479-1.xhtml
rename from layout/xul/base/src/crashtests/415394-1.xhtml
rename to layout/xul/crashtests/415394-1.xhtml
rename from layout/xul/base/src/crashtests/420424-1.xul
rename to layout/xul/crashtests/420424-1.xul
rename from layout/xul/base/src/crashtests/430356-1.xhtml
rename to layout/xul/crashtests/430356-1.xhtml
rename from layout/xul/base/src/crashtests/431738.xhtml
rename to layout/xul/crashtests/431738.xhtml
rename from layout/xul/base/src/crashtests/432058-1.xul
rename to layout/xul/crashtests/432058-1.xul
rename from layout/xul/base/src/crashtests/432068-1.xul
rename to layout/xul/crashtests/432068-1.xul
rename from layout/xul/base/src/crashtests/432068-2.xul
rename to layout/xul/crashtests/432068-2.xul
rename from layout/xul/base/src/crashtests/433296-1.xul
rename to layout/xul/crashtests/433296-1.xul
rename from layout/xul/base/src/crashtests/433429.xul
rename to layout/xul/crashtests/433429.xul
rename from layout/xul/base/src/crashtests/434458-1.xul
rename to layout/xul/crashtests/434458-1.xul
rename from layout/xul/base/src/crashtests/452185.html
rename to layout/xul/crashtests/452185.html
rename from layout/xul/base/src/crashtests/452185.xml
rename to layout/xul/crashtests/452185.xml
rename from layout/xul/base/src/crashtests/460900-1.xul
rename to layout/xul/crashtests/460900-1.xul
rename from layout/xul/base/src/crashtests/464149-1.xul
rename to layout/xul/crashtests/464149-1.xul
rename from layout/xul/base/src/crashtests/464407-1.xhtml
rename to layout/xul/crashtests/464407-1.xhtml
rename from layout/xul/base/src/crashtests/467080.xul
rename to layout/xul/crashtests/467080.xul
rename from layout/xul/base/src/crashtests/467481-1.xul
rename to layout/xul/crashtests/467481-1.xul
rename from layout/xul/base/src/crashtests/470063-1.html
rename to layout/xul/crashtests/470063-1.html
rename from layout/xul/base/src/crashtests/470272.html
rename to layout/xul/crashtests/470272.html
rename from layout/xul/base/src/crashtests/472189.xul
rename to layout/xul/crashtests/472189.xul
rename from layout/xul/base/src/crashtests/475133.html
rename to layout/xul/crashtests/475133.html
rename from layout/xul/base/src/crashtests/488210-1.xhtml
rename to layout/xul/crashtests/488210-1.xhtml
rename from layout/xul/base/src/crashtests/495728-1.xul
rename to layout/xul/crashtests/495728-1.xul
rename from layout/xul/base/src/crashtests/508927-1.xul
rename to layout/xul/crashtests/508927-1.xul
rename from layout/xul/base/src/crashtests/508927-2.xul
rename to layout/xul/crashtests/508927-2.xul
rename from layout/xul/base/src/crashtests/514300-1.xul
rename to layout/xul/crashtests/514300-1.xul
rename from layout/xul/base/src/crashtests/536931-1.xhtml
rename to layout/xul/crashtests/536931-1.xhtml
rename from layout/xul/base/src/crashtests/538308-1.xul
rename to layout/xul/crashtests/538308-1.xul
rename from layout/xul/base/src/crashtests/557174-1.xml
rename to layout/xul/crashtests/557174-1.xml
rename from layout/xul/base/src/crashtests/564705-1.xul
rename to layout/xul/crashtests/564705-1.xul
rename from layout/xul/base/src/crashtests/583957-1.html
rename to layout/xul/crashtests/583957-1.html
rename from layout/xul/base/src/crashtests/crashtests.list
rename to layout/xul/crashtests/crashtests.list
rename from layout/xul/base/src/crashtests/menulist-focused.xhtml
rename to layout/xul/crashtests/menulist-focused.xhtml
--- a/layout/xul/grid/moz.build
+++ b/layout/xul/grid/moz.build
@@ -27,14 +27,14 @@ UNIFIED_SOURCES += [
     'nsGridRowLeafFrame.cpp',
     'nsGridRowLeafLayout.cpp',
 ]
 
 FAIL_ON_WARNINGS = True
 
 FINAL_LIBRARY = 'gklayout'
 LOCAL_INCLUDES += [
+    '..',
     '../../forms',
     '../../generic',
     '../../style',
-    '../base/src',
 ]
 
rename from layout/xul/base/src/moz.build
rename to layout/xul/moz.build
--- a/layout/xul/base/src/moz.build
+++ b/layout/xul/moz.build
@@ -1,14 +1,35 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+XPIDL_SOURCES += [
+    'nsIBoxObject.idl',
+    'nsIBrowserBoxObject.idl',
+    'nsIContainerBoxObject.idl',
+    'nsIEditorBoxObject.idl',
+    'nsIIFrameBoxObject.idl',
+    'nsIListBoxObject.idl',
+    'nsIMenuBoxObject.idl',
+    'nsIPopupBoxObject.idl',
+    'nsIScrollBoxObject.idl',
+    'nsISliderListener.idl',
+]
+
+XPIDL_MODULE = 'layout_xul'
+
+EXPORTS += [
+    'nsIScrollbarMediator.h',
+    'nsPIBoxObject.h',
+    'nsXULPopupManager.h',
+]
+
 UNIFIED_SOURCES += [
     'nsBox.cpp',
     'nsBoxFrame.cpp',
     'nsBoxLayout.cpp',
     'nsBoxLayoutState.cpp',
     'nsBoxObject.cpp',
     'nsButtonBoxFrame.cpp',
     'nsRepeatService.cpp',
@@ -47,21 +68,29 @@ if CONFIG['MOZ_XUL']:
         'nsScrollBoxObject.cpp',
         'nsSplitterFrame.cpp',
         'nsTextBoxFrame.cpp',
         'nsTitleBarFrame.cpp',
         'nsXULLabelFrame.cpp',
         'nsXULPopupManager.cpp',
     ]
 
+if CONFIG['ENABLE_TESTS']:
+    PARALLEL_DIRS += [
+        'test',
+    ]
+
+if CONFIG['MOZ_XUL']:
+    PARALLEL_DIRS += ['tree', 'grid']
+
 FAIL_ON_WARNINGS = True
 
 MSVC_ENABLE_PGO = True
 
 FINAL_LIBRARY = 'gklayout'
 LOCAL_INCLUDES += [
-    '../../../../content/base/src',
-    '../../../../content/events/src',
-    '../../../base',
-    '../../../generic',
-    '../../../style',
+    '../../content/base/src',
+    '../../content/events/src',
+    '../base',
+    '../generic',
+    '../style',
 ]
 
rename from layout/xul/base/src/nsBox.cpp
rename to layout/xul/nsBox.cpp
rename from layout/xul/base/src/nsBox.h
rename to layout/xul/nsBox.h
rename from layout/xul/base/src/nsBoxFrame.cpp
rename to layout/xul/nsBoxFrame.cpp
rename from layout/xul/base/src/nsBoxFrame.h
rename to layout/xul/nsBoxFrame.h
rename from layout/xul/base/src/nsBoxLayout.cpp
rename to layout/xul/nsBoxLayout.cpp
rename from layout/xul/base/src/nsBoxLayout.h
rename to layout/xul/nsBoxLayout.h
rename from layout/xul/base/src/nsBoxLayoutState.cpp
rename to layout/xul/nsBoxLayoutState.cpp
rename from layout/xul/base/src/nsBoxLayoutState.h
rename to layout/xul/nsBoxLayoutState.h
rename from layout/xul/base/src/nsBoxObject.cpp
rename to layout/xul/nsBoxObject.cpp
rename from layout/xul/base/src/nsBoxObject.h
rename to layout/xul/nsBoxObject.h
rename from layout/xul/base/src/nsButtonBoxFrame.cpp
rename to layout/xul/nsButtonBoxFrame.cpp
rename from layout/xul/base/src/nsButtonBoxFrame.h
rename to layout/xul/nsButtonBoxFrame.h
rename from layout/xul/base/src/nsContainerBoxObject.cpp
rename to layout/xul/nsContainerBoxObject.cpp
rename from layout/xul/base/src/nsDeckFrame.cpp
rename to layout/xul/nsDeckFrame.cpp
rename from layout/xul/base/src/nsDeckFrame.h
rename to layout/xul/nsDeckFrame.h
rename from layout/xul/base/src/nsDocElementBoxFrame.cpp
rename to layout/xul/nsDocElementBoxFrame.cpp
rename from layout/xul/base/src/nsGroupBoxFrame.cpp
rename to layout/xul/nsGroupBoxFrame.cpp
rename from layout/xul/base/public/nsIBoxObject.idl
rename to layout/xul/nsIBoxObject.idl
rename from layout/xul/base/public/nsIBrowserBoxObject.idl
rename to layout/xul/nsIBrowserBoxObject.idl
rename from layout/xul/base/public/nsIContainerBoxObject.idl
rename to layout/xul/nsIContainerBoxObject.idl
rename from layout/xul/base/public/nsIEditorBoxObject.idl
rename to layout/xul/nsIEditorBoxObject.idl
rename from layout/xul/base/public/nsIIFrameBoxObject.idl
rename to layout/xul/nsIIFrameBoxObject.idl
rename from layout/xul/base/public/nsIListBoxObject.idl
rename to layout/xul/nsIListBoxObject.idl
rename from layout/xul/base/public/nsIMenuBoxObject.idl
rename to layout/xul/nsIMenuBoxObject.idl
rename from layout/xul/base/public/nsIPopupBoxObject.idl
rename to layout/xul/nsIPopupBoxObject.idl
rename from layout/xul/base/src/nsIRootBox.h
rename to layout/xul/nsIRootBox.h
rename from layout/xul/base/public/nsIScrollBoxObject.idl
rename to layout/xul/nsIScrollBoxObject.idl
rename from layout/xul/base/public/nsIScrollbarMediator.h
rename to layout/xul/nsIScrollbarMediator.h
rename from layout/xul/base/public/nsISliderListener.idl
rename to layout/xul/nsISliderListener.idl
rename from layout/xul/base/src/nsImageBoxFrame.cpp
rename to layout/xul/nsImageBoxFrame.cpp
rename from layout/xul/base/src/nsImageBoxFrame.h
rename to layout/xul/nsImageBoxFrame.h
rename from layout/xul/base/src/nsLeafBoxFrame.cpp
rename to layout/xul/nsLeafBoxFrame.cpp
rename from layout/xul/base/src/nsLeafBoxFrame.h
rename to layout/xul/nsLeafBoxFrame.h
rename from layout/xul/base/src/nsListBoxBodyFrame.cpp
rename to layout/xul/nsListBoxBodyFrame.cpp
rename from layout/xul/base/src/nsListBoxBodyFrame.h
rename to layout/xul/nsListBoxBodyFrame.h
rename from layout/xul/base/src/nsListBoxLayout.cpp
rename to layout/xul/nsListBoxLayout.cpp
rename from layout/xul/base/src/nsListBoxLayout.h
rename to layout/xul/nsListBoxLayout.h
rename from layout/xul/base/src/nsListBoxObject.cpp
rename to layout/xul/nsListBoxObject.cpp
rename from layout/xul/base/src/nsListItemFrame.cpp
rename to layout/xul/nsListItemFrame.cpp
rename from layout/xul/base/src/nsListItemFrame.h
rename to layout/xul/nsListItemFrame.h
rename from layout/xul/base/src/nsMenuBarFrame.cpp
rename to layout/xul/nsMenuBarFrame.cpp
rename from layout/xul/base/src/nsMenuBarFrame.h
rename to layout/xul/nsMenuBarFrame.h
rename from layout/xul/base/src/nsMenuBarListener.cpp
rename to layout/xul/nsMenuBarListener.cpp
rename from layout/xul/base/src/nsMenuBarListener.h
rename to layout/xul/nsMenuBarListener.h
rename from layout/xul/base/src/nsMenuBoxObject.cpp
rename to layout/xul/nsMenuBoxObject.cpp
rename from layout/xul/base/src/nsMenuFrame.cpp
rename to layout/xul/nsMenuFrame.cpp
rename from layout/xul/base/src/nsMenuFrame.h
rename to layout/xul/nsMenuFrame.h
rename from layout/xul/base/src/nsMenuParent.h
rename to layout/xul/nsMenuParent.h
rename from layout/xul/base/src/nsMenuPopupFrame.cpp
rename to layout/xul/nsMenuPopupFrame.cpp
rename from layout/xul/base/src/nsMenuPopupFrame.h
rename to layout/xul/nsMenuPopupFrame.h
rename from layout/xul/base/public/nsPIBoxObject.h
rename to layout/xul/nsPIBoxObject.h
rename from layout/xul/base/src/nsPIListBoxObject.h
rename to layout/xul/nsPIListBoxObject.h
rename from layout/xul/base/src/nsPopupBoxObject.cpp
rename to layout/xul/nsPopupBoxObject.cpp
rename from layout/xul/base/src/nsPopupSetFrame.cpp
rename to layout/xul/nsPopupSetFrame.cpp
rename from layout/xul/base/src/nsPopupSetFrame.h
rename to layout/xul/nsPopupSetFrame.h
rename from layout/xul/base/src/nsProgressMeterFrame.cpp
rename to layout/xul/nsProgressMeterFrame.cpp
rename from layout/xul/base/src/nsProgressMeterFrame.h
rename to layout/xul/nsProgressMeterFrame.h
rename from layout/xul/base/src/nsRepeatService.cpp
rename to layout/xul/nsRepeatService.cpp
rename from layout/xul/base/src/nsRepeatService.h
rename to layout/xul/nsRepeatService.h
rename from layout/xul/base/src/nsResizerFrame.cpp
rename to layout/xul/nsResizerFrame.cpp
rename from layout/xul/base/src/nsResizerFrame.h
rename to layout/xul/nsResizerFrame.h
rename from layout/xul/base/src/nsRootBoxFrame.cpp
rename to layout/xul/nsRootBoxFrame.cpp
rename from layout/xul/base/src/nsScrollBoxFrame.cpp
rename to layout/xul/nsScrollBoxFrame.cpp
rename from layout/xul/base/src/nsScrollBoxObject.cpp
rename to layout/xul/nsScrollBoxObject.cpp
rename from layout/xul/base/src/nsScrollbarButtonFrame.cpp
rename to layout/xul/nsScrollbarButtonFrame.cpp
rename from layout/xul/base/src/nsScrollbarButtonFrame.h
rename to layout/xul/nsScrollbarButtonFrame.h
rename from layout/xul/base/src/nsScrollbarFrame.cpp
rename to layout/xul/nsScrollbarFrame.cpp
rename from layout/xul/base/src/nsScrollbarFrame.h
rename to layout/xul/nsScrollbarFrame.h
rename from layout/xul/base/src/nsSliderFrame.cpp
rename to layout/xul/nsSliderFrame.cpp
rename from layout/xul/base/src/nsSliderFrame.h
rename to layout/xul/nsSliderFrame.h
rename from layout/xul/base/src/nsSplitterFrame.cpp
rename to layout/xul/nsSplitterFrame.cpp
rename from layout/xul/base/src/nsSplitterFrame.h
rename to layout/xul/nsSplitterFrame.h
rename from layout/xul/base/src/nsSprocketLayout.cpp
rename to layout/xul/nsSprocketLayout.cpp
rename from layout/xul/base/src/nsSprocketLayout.h
rename to layout/xul/nsSprocketLayout.h
rename from layout/xul/base/src/nsStackFrame.cpp
rename to layout/xul/nsStackFrame.cpp
rename from layout/xul/base/src/nsStackFrame.h
rename to layout/xul/nsStackFrame.h
rename from layout/xul/base/src/nsStackLayout.cpp
rename to layout/xul/nsStackLayout.cpp
rename from layout/xul/base/src/nsStackLayout.h
rename to layout/xul/nsStackLayout.h
rename from layout/xul/base/src/nsTextBoxFrame.cpp
rename to layout/xul/nsTextBoxFrame.cpp
rename from layout/xul/base/src/nsTextBoxFrame.h
rename to layout/xul/nsTextBoxFrame.h
rename from layout/xul/base/src/nsTitleBarFrame.cpp
rename to layout/xul/nsTitleBarFrame.cpp
rename from layout/xul/base/src/nsTitleBarFrame.h
rename to layout/xul/nsTitleBarFrame.h
rename from layout/xul/base/src/nsXULLabelFrame.cpp
rename to layout/xul/nsXULLabelFrame.cpp
rename from layout/xul/base/src/nsXULLabelFrame.h
rename to layout/xul/nsXULLabelFrame.h
rename from layout/xul/base/src/nsXULPopupManager.cpp
rename to layout/xul/nsXULPopupManager.cpp
rename from layout/xul/base/public/nsXULPopupManager.h
rename to layout/xul/nsXULPopupManager.h
rename from layout/xul/base/src/nsXULTooltipListener.cpp
rename to layout/xul/nsXULTooltipListener.cpp
rename from layout/xul/base/src/nsXULTooltipListener.h
rename to layout/xul/nsXULTooltipListener.h
rename from layout/xul/base/reftest/image-scaling-min-height-1-ref.xul
rename to layout/xul/reftest/image-scaling-min-height-1-ref.xul
rename from layout/xul/base/reftest/image-scaling-min-height-1.xul
rename to layout/xul/reftest/image-scaling-min-height-1.xul
rename from layout/xul/base/reftest/image-size-ref.xul
rename to layout/xul/reftest/image-size-ref.xul
rename from layout/xul/base/reftest/image-size.xul
rename to layout/xul/reftest/image-size.xul
rename from layout/xul/base/reftest/image4x3.png
rename to layout/xul/reftest/image4x3.png
rename from layout/xul/base/reftest/popup-explicit-size-ref.xul
rename to layout/xul/reftest/popup-explicit-size-ref.xul
rename from layout/xul/base/reftest/popup-explicit-size.xul
rename to layout/xul/reftest/popup-explicit-size.xul
rename from layout/xul/base/reftest/reftest.list
rename to layout/xul/reftest/reftest.list
rename from layout/xul/base/reftest/textbox-multiline-noresize.xul
rename to layout/xul/reftest/textbox-multiline-noresize.xul
rename from layout/xul/base/reftest/textbox-multiline-ref.xul
rename to layout/xul/reftest/textbox-multiline-ref.xul
rename from layout/xul/base/reftest/textbox-multiline-resize.xul
rename to layout/xul/reftest/textbox-multiline-resize.xul
--- a/layout/xul/test/chrome.ini
+++ b/layout/xul/test/chrome.ini
@@ -1,7 +1,17 @@
 [DEFAULT]
+support-files =
+  window_resizer.xul
+  window_resizer_element.xul
 
 [test_bug159346.xul]
 [test_bug372685.xul]
+[test_bug381167.xhtml]
+[test_bug393970.xul]
 [test_bug398982-1.xul]
 [test_bug398982-2.xul]
+[test_bug477754.xul]
 [test_bug703150.xul]
+[test_popupSizeTo.xul]
+[test_resizer.xul]
+[test_stack.xul]
+[test_windowminmaxsize.xul]
--- a/layout/xul/test/mochitest.ini
+++ b/layout/xul/test/mochitest.ini
@@ -1,5 +1,8 @@
 [DEFAULT]
 
 [test_bug386386.html]
 [test_bug394800.xhtml]
+[test_bug511075.html]
 [test_bug563416.html]
+[test_resizer_incontent.xul]
+[test_splitter.xul]
rename from layout/xul/base/test/test_bug381167.xhtml
rename to layout/xul/test/test_bug381167.xhtml
rename from layout/xul/base/test/test_bug393970.xul
rename to layout/xul/test/test_bug393970.xul
rename from layout/xul/base/test/test_bug477754.xul
rename to layout/xul/test/test_bug477754.xul
rename from layout/xul/base/test/test_bug511075.html
rename to layout/xul/test/test_bug511075.html
rename from layout/xul/base/test/test_popupSizeTo.xul
rename to layout/xul/test/test_popupSizeTo.xul
rename from layout/xul/base/test/test_resizer.xul
rename to layout/xul/test/test_resizer.xul
rename from layout/xul/base/test/test_resizer_incontent.xul
rename to layout/xul/test/test_resizer_incontent.xul
rename from layout/xul/base/test/test_splitter.xul
rename to layout/xul/test/test_splitter.xul
rename from layout/xul/base/test/test_stack.xul
rename to layout/xul/test/test_stack.xul
rename from layout/xul/base/test/test_windowminmaxsize.xul
rename to layout/xul/test/test_windowminmaxsize.xul
rename from layout/xul/base/test/window_resizer.xul
rename to layout/xul/test/window_resizer.xul
rename from layout/xul/base/test/window_resizer_element.xul
rename to layout/xul/test/window_resizer_element.xul
--- a/layout/xul/tree/moz.build
+++ b/layout/xul/tree/moz.build
@@ -30,17 +30,17 @@ UNIFIED_SOURCES += [
     'nsTreeStyleCache.cpp',
     'nsTreeUtils.cpp',
 ]
 
 FAIL_ON_WARNINGS = True
 
 FINAL_LIBRARY = 'gklayout'
 LOCAL_INCLUDES += [
+    '..',
     '../../base',
     '../../forms',
     '../../generic',
     '../../style',
-    '../base/src',
     '/content/base/src',
     '/content/events/src',
 ]
 
--- a/media/webrtc/signaling/test/mediaconduit_unittests.cpp
+++ b/media/webrtc/signaling/test/mediaconduit_unittests.cpp
@@ -825,40 +825,47 @@ class TransportConduitTest : public ::te
     orig_width = 160;
     orig_height = 8;
     max_fs = 5;
     GetVideoResolutionWithMaxFs(orig_width, orig_height, max_fs, &width, &height);
     DumpMaxFs(orig_width, orig_height, max_fs, width, height);
     ASSERT_EQ(width, 80);
     ASSERT_EQ(height, 4);
 
+     // Extremely small width and height(see bug 919979).
+    cerr << "Test with extremely small width and height" << endl;
+    orig_width = 2;
+    orig_height = 2;
+    max_fs = 5;
+    GetVideoResolutionWithMaxFs(orig_width, orig_height, max_fs, &width, &height);
+    DumpMaxFs(orig_width, orig_height, max_fs, width, height);
+    ASSERT_EQ(width, 2);
+    ASSERT_EQ(height, 2);
+
     // Random values.
+    cerr << "Test with random values" << endl;
     for (int i = 0; i < 30; i++) {
+      cerr << ".";
       max_fs = rand() % 1000;
       orig_width = ((rand() % 2000) & ~1) + 2;
       orig_height = ((rand() % 2000) & ~1) + 2;
-      // Potential crash on small resolution, see bug 919979.
-      if (orig_width * orig_height <= 20) {
-        cerr << "Temporarily skip resolution " << orig_width << "x" <<
-             orig_height << endl;
-        continue;
-      }
 
       GetVideoResolutionWithMaxFs(orig_width, orig_height, max_fs,
                                   &width, &height);
       if (max_fs > 0 &&
           ceil(width / 16.) * ceil(height / 16.) > max_fs) {
         DumpMaxFs(orig_width, orig_height, max_fs, width, height);
         ADD_FAILURE();
       }
       if ((width & 1) || (height & 1)) {
         DumpMaxFs(orig_width, orig_height, max_fs, width, height);
         ADD_FAILURE();
       }
     }
+    cerr << endl;
  }
 
 private:
   //Audio Conduit Test Objects
   mozilla::RefPtr<mozilla::AudioSessionConduit> mAudioSession;
   mozilla::RefPtr<mozilla::AudioSessionConduit> mAudioSession2;
   mozilla::RefPtr<mozilla::TransportInterface> mAudioTransport;
   AudioSendAndReceive audioTester;
--- a/media/webrtc/trunk/webrtc/modules/video_coding/codecs/vp8/vp8_impl.cc
+++ b/media/webrtc/trunk/webrtc/modules/video_coding/codecs/vp8/vp8_impl.cc
@@ -166,17 +166,19 @@ int VP8EncoderImpl::InitEncode(const Vid
                          .Create(num_temporal_layers, rand());
   // random start 16 bits is enough.
   picture_id_ = static_cast<uint16_t>(rand()) & 0x7FFF;
 
   // allocate memory for encoded image
   if (encoded_image_._buffer != NULL) {
     delete [] encoded_image_._buffer;
   }
-  encoded_image_._size = CalcBufferSize(kI420, codec_.width, codec_.height);
+  // Reserve 100 extra bytes for overhead at small resolutions.
+  encoded_image_._size = CalcBufferSize(kI420, codec_.width, codec_.height)
+                         + 100;
   encoded_image_._buffer = new uint8_t[encoded_image_._size];
   encoded_image_._completeFrame = true;
 
   // Creating a wrapper to the image - setting image data to NULL. Actual
   // pointer will be set in encode. Setting align to 1, as it is meaningless
   // (actual memory is not allocated).
   raw_ = vpx_img_wrap(NULL, IMG_FMT_I420, codec_.width, codec_.height,
                       1, NULL);
--- a/mobile/android/base/NotificationHelper.java
+++ b/mobile/android/base/NotificationHelper.java
@@ -232,17 +232,17 @@ public final class NotificationHelper im
                 Log.i(LOGTAG, "Error parsing", ex);
             }
         }
 
         boolean ongoing = message.optBoolean(ONGOING_ATTR);
         builder.setOngoing(ongoing);
 
         if (message.has(WHEN_ATTR)) {
-            int when = message.optInt(WHEN_ATTR);
+            long when = message.optLong(WHEN_ATTR);
             builder.setWhen(when);
         }
 
         if (message.has(PRIORITY_ATTR)) {
             int priority = message.optInt(PRIORITY_ATTR);
             builder.setPriority(priority);
         }
 
--- a/netwerk/base/src/nsBaseChannel.cpp
+++ b/netwerk/base/src/nsBaseChannel.cpp
@@ -143,18 +143,17 @@ nsBaseChannel::ContinueRedirect()
     if (NS_FAILED(rv))
       return rv;
   }
 
   mRedirectChannel = nullptr;
 
   // close down this channel
   Cancel(NS_BINDING_REDIRECTED);
-  mListener = nullptr;
-  mListenerContext = nullptr;
+  ChannelDone();
 
   return NS_OK;
 }
 
 bool
 nsBaseChannel::HasContentTypeHint() const
 {
   NS_ASSERTION(!IsPending(), "HasContentTypeHint called too late");
@@ -249,18 +248,17 @@ nsBaseChannel::ContinueHandleAsyncRedire
 
   if (NS_FAILED(result))
     Cancel(result);
 
   if (NS_FAILED(result) && mListener) {
     // Notify our consumer ourselves
     mListener->OnStartRequest(this, mListenerContext);
     mListener->OnStopRequest(this, mListenerContext, mStatus);
-    mListener = nullptr;
-    mListenerContext = nullptr;
+    ChannelDone();
   }
 
   if (mLoadGroup)
     mLoadGroup->RemoveRequest(this, nullptr, mStatus);
 
   // Drop notification callbacks to prevent cycles.
   mCallbacks = nullptr;
   CallbacksChanged();
@@ -593,18 +591,17 @@ nsBaseChannel::AsyncOpen(nsIStreamListen
   mListener = listener;
   mListenerContext = ctxt;
 
   // This method assigns mPump as a side-effect.  We need to clear mPump if
   // this method fails.
   rv = BeginPumpingData();
   if (NS_FAILED(rv)) {
     mPump = nullptr;
-    mListener = nullptr;
-    mListenerContext = nullptr;
+    ChannelDone();
     mCallbacks = nullptr;
     return rv;
   }
 
   // At this point, we are going to return success no matter what.
 
   mWasOpened = true;
 
@@ -728,18 +725,17 @@ nsBaseChannel::OnStopRequest(nsIRequest 
   if (NS_SUCCEEDED(mStatus))
     mStatus = status;
 
   // Cause IsPending to return false.
   mPump = nullptr;
 
   if (mListener) // null in case of redirect
       mListener->OnStopRequest(this, mListenerContext, mStatus);
-  mListener = nullptr;
-  mListenerContext = nullptr;
+  ChannelDone();
 
   // No need to suspend pump in this scope since we will not be receiving
   // any more events from it.
 
   if (mLoadGroup)
     mLoadGroup->RemoveRequest(this, nullptr, mStatus);
 
   // Drop notification callbacks to prevent cycles.
--- a/netwerk/base/src/nsBaseChannel.h
+++ b/netwerk/base/src/nsBaseChannel.h
@@ -97,16 +97,20 @@ private:
   virtual bool GetStatusArg(nsresult status, nsString &statusArg) {
     return false;
   }
 
   // Called when the callbacks available to this channel may have changed.
   virtual void OnCallbacksChanged() {
   }
 
+  // Called when our channel is done, to allow subclasses to drop resources.
+  virtual void OnChannelDone() {
+  }
+
 public:
   // ----------------------------------------------
   // Methods provided for use by the derived class:
 
   // Redirect to another channel.  This method takes care of notifying
   // observers of this redirect as well as of opening the new channel, if asked
   // to do so.  It also cancels |this| with the status code
   // NS_BINDING_REDIRECTED.  A failure return from this method means that the
@@ -208,16 +212,23 @@ private:
 
   // Called when the callbacks available to this channel may have changed.
   void CallbacksChanged() {
     mProgressSink = nullptr;
     mQueriedProgressSink = false;
     OnCallbacksChanged();
   }
 
+  // Called when our channel is done.  This should drop no-longer-needed pointers.
+  void ChannelDone() {
+      mListener = nullptr;
+      mListenerContext = nullptr;
+      OnChannelDone();
+  }
+
   // Handle an async redirect callback.  This will only be called if we
   // returned success from AsyncOpen while posting a redirect runnable.
   void HandleAsyncRedirect(nsIChannel* newChannel);
   void ContinueHandleAsyncRedirect(nsresult result);
   nsresult ContinueRedirect();
 
   // start URI classifier if requested
   void ClassifyURI();
--- a/netwerk/base/src/nsInputStreamChannel.h
+++ b/netwerk/base/src/nsInputStreamChannel.h
@@ -22,15 +22,19 @@ public:
       mIsSrcdocChannel(false) {}
 
 protected:
     virtual ~nsInputStreamChannel() {}
 
     virtual nsresult OpenContentStream(bool async, nsIInputStream **result,
                                        nsIChannel** channel);
 
+    virtual void OnChannelDone() MOZ_OVERRIDE {
+        mContentStream = nullptr;
+    }
+
 private:
     nsCOMPtr<nsIInputStream> mContentStream;
     nsString mSrcdocData;
     bool mIsSrcdocChannel;
 };
 
 #endif // !nsInputStreamChannel_h__
--- a/testing/crashtest/crashtests.list
+++ b/testing/crashtest/crashtests.list
@@ -46,17 +46,17 @@ include ../../js/xpconnect/crashtests/cr
 include ../../layout/base/crashtests/crashtests.list
 include ../../layout/forms/crashtests/crashtests.list
 include ../../layout/generic/crashtests/crashtests.list
 include ../../layout/printing/crashtests/crashtests.list
 include ../../layout/mathml/crashtests/crashtests.list
 include ../../layout/style/crashtests/crashtests.list
 include ../../layout/svg/crashtests/crashtests.list
 include ../../layout/tables/crashtests/crashtests.list
-include ../../layout/xul/base/src/crashtests/crashtests.list
+include ../../layout/xul/crashtests/crashtests.list
 include ../../layout/xul/grid/crashtests/crashtests.list
 include ../../layout/xul/tree/crashtests/crashtests.list
 
 include ../../gfx/tests/crashtests/crashtests.list
 
 include ../../image/test/crashtests/crashtests.list
 include ../../dom/plugins/test/crashtests/crashtests.list
 
--- a/testing/mochitest/android.json
+++ b/testing/mochitest/android.json
@@ -269,17 +269,17 @@
  "layout/style/test/test_transitions_per_property.html": "bug 775227",
  "layout/style/test/test_value_cloning.html": "bug 775227", 
  "layout/style/test/test_value_computation.html": "",
  "layout/style/test/test_visited_image_loading.html": "TIMED_OUT",
  "layout/style/test/test_visited_image_loading_empty.html": "TIMED_OUT",
  "layout/style/test/test_visited_lying.html": "",
  "layout/style/test/test_visited_pref.html": "TIMED_OUT",
  "layout/style/test/test_visited_reftests.html": "TIMED_OUT",
- "layout/xul/base/test/test_bug511075.html": "bug 798806",
+ "layout/xul/test/test_bug511075.html": "bug 798806",
  "parser/htmlparser/tests/mochitest/test_html5_tree_construction.html": "TIMED_OUT",
  "parser/htmlparser/tests/mochitest/test_html5_tree_construction_part2.html": "TIMED_OUT",
  "robocop": "TIMED_OUT",
  "security/manager/ssl/tests/mochitest/bugs/test_bug480509.html": "",
  "security/manager/ssl/tests/mochitest/bugs/test_bug483440.html": "",
  "security/manager/ssl/tests/mochitest/bugs/test_bug484111.html": "",
  "security/manager/ssl/tests/mochitest/bugs/test_ev_validation.html": "TIMED_OUT",
  "security/manager/ssl/tests/mochitest/mixedcontent": "TIMED_OUT",
--- a/testing/mochitest/androidx86.json
+++ b/testing/mochitest/androidx86.json
@@ -351,17 +351,17 @@
  "layout/style/test/test_transitions_per_property.html": "bug 775227",
  "layout/style/test/test_value_cloning.html": "bug 775227", 
  "layout/style/test/test_value_computation.html": "",
  "layout/style/test/test_visited_image_loading.html": "TIMED_OUT",
  "layout/style/test/test_visited_image_loading_empty.html": "TIMED_OUT",
  "layout/style/test/test_visited_lying.html": "",
  "layout/style/test/test_visited_pref.html": "TIMED_OUT",
  "layout/style/test/test_visited_reftests.html": "TIMED_OUT",
- "layout/xul/base/test/test_bug511075.html": "bug 798806",
+ "layout/xul/test/test_bug511075.html": "bug 798806",
  "parser/htmlparser/tests/mochitest/test_html5_tree_construction.html": "TIMED_OUT",
  "parser/htmlparser/tests/mochitest/test_html5_tree_construction_part2.html": "TIMED_OUT",
  "robocop": "TIMED_OUT",
  "security/manager/ssl/tests/mochitest/bugs/test_bug480509.html": "",
  "security/manager/ssl/tests/mochitest/bugs/test_bug483440.html": "",
  "security/manager/ssl/tests/mochitest/bugs/test_bug484111.html": "",
  "security/manager/ssl/tests/mochitest/bugs/test_ev_validation.html": "TIMED_OUT",
  "security/manager/ssl/tests/mochitest/mixedcontent": "TIMED_OUT",
--- a/toolkit/devtools/server/main.js
+++ b/toolkit/devtools/server/main.js
@@ -153,17 +153,17 @@ var DebuggerServer = {
   _socketConnections: 0,
   // Map of global actor names to actor constructors provided by extensions.
   globalActorFactories: {},
   // Map of tab actor names to actor constructors provided by extensions.
   tabActorFactories: {},
 
   LONG_STRING_LENGTH: 10000,
   LONG_STRING_INITIAL_LENGTH: 1000,
-  LONG_STRING_READ_LENGTH: 1000,
+  LONG_STRING_READ_LENGTH: 65 * 1024,
 
   /**
    * A handler function that prompts the user to accept or decline the incoming
    * connection.
    */
   _allowConnection: null,
 
   /**
--- a/uriloader/exthandler/tests/mochitest/handlerApps.js
+++ b/uriloader/exthandler/tests/mochitest/handlerApps.js
@@ -5,18 +5,19 @@
 // handlerApp.xhtml grabs this for verification purposes via window.opener
 var testURI = "webcal://127.0.0.1/rheeeeet.html";
 
 const Cc = SpecialPowers.Cc;
 
 function test() {
 
   const isOSXMtnLion = navigator.userAgent.indexOf("Mac OS X 10.8") != -1;
-  if (isOSXMtnLion) {
-    todo(false, "This test fails on OS X 10.8, see bug 786938");
+  const isOSXMavericks = navigator.userAgent.indexOf("Mac OS X 10.9") != -1;
+  if (isOSXMtnLion || isOSXMavericks) {
+    todo(false, "This test fails on OS X 10.8 and 10.9, see bug 786938");
     SimpleTest.finish();
     return;
   }
 
   // set up the web handler object
   var webHandler = Cc["@mozilla.org/uriloader/web-handler-app;1"].
     createInstance(SpecialPowers.Ci.nsIWebHandlerApp);
   webHandler.name = "Test Web Handler App";
--- a/widget/cocoa/moz.build
+++ b/widget/cocoa/moz.build
@@ -70,11 +70,11 @@ if CONFIG['TARGET_CPU'] == 'x86_64':
     ]
 
 FINAL_LIBRARY = 'xul'
 LOCAL_INCLUDES += [
     '../shared',
     '../xpwidgets',
     '/layout/forms',
     '/layout/generic',
-    '/layout/xul/base/src',
+    '/layout/xul',
 ]
 
--- a/widget/gtk/maiRedundantObjectFactory.c
+++ b/widget/gtk/maiRedundantObjectFactory.c
@@ -10,18 +10,16 @@
 
 static void mai_redundant_object_factory_class_init (
                               maiRedundantObjectFactoryClass *klass);
 
 static AtkObject* mai_redundant_object_factory_create_accessible (
                               GObject *obj);
 static GType mai_redundant_object_factory_get_accessible_type (void);
 
-static gpointer parent_class = NULL;
-
 GType
 mai_redundant_object_factory_get_type (void)
 {
   static GType type = 0;
 
   if (!type)
   {
     static const GTypeInfo tinfo =
@@ -45,18 +43,16 @@ mai_redundant_object_factory_get_type (v
   return type;
 }
 
 static void
 mai_redundant_object_factory_class_init (maiRedundantObjectFactoryClass *klass)
 {
   AtkObjectFactoryClass *class = ATK_OBJECT_FACTORY_CLASS (klass);
 
-  parent_class = g_type_class_peek_parent (klass);
-
   class->create_accessible = mai_redundant_object_factory_create_accessible;
   class->get_accessible_type = mai_redundant_object_factory_get_accessible_type;
 }
 
 /**
  * mai_redundant_object_factory_new:
  *
  * Creates an instance of an #AtkObjectFactory which generates primitive
--- a/widget/gtk/moz.build
+++ b/widget/gtk/moz.build
@@ -10,87 +10,94 @@ else:
     LIBRARY_NAME = 'widget_gtk3'
 
 EXPORTS += [
     'mozcontainer.h',
     'nsGTKToolkit.h',
     'nsIImageToPixbuf.h',
 ]
 
-SOURCES += [
-    'nsAppShell.cpp',
+UNIFIED_SOURCES += [
+    'mozcontainer.c',
     'nsBidiKeyboard.cpp',
     'nsColorPicker.cpp',
     'nsFilePicker.cpp',
-    'nsGtkIMModule.cpp',
     'nsGtkKeyUtils.cpp',
     'nsImageToPixbuf.cpp',
     'nsLookAndFeel.cpp',
     'nsNativeKeyBindings.cpp',
     'nsNativeThemeGTK.cpp',
     'nsScreenGtk.cpp',
     'nsScreenManagerGtk.cpp',
     'nsSound.cpp',
     'nsToolkit.cpp',
-    'nsWidgetFactory.cpp',
-    'nsWindow.cpp',
     'WidgetTraceEvent.cpp',
 ]
 
+# These files force-enable NSPR logging and thus cannot be built in unified mode
+SOURCES += [
+    'nsAppShell.cpp',
+    'nsGtkIMModule.cpp',
+    'nsWidgetFactory.cpp',
+    'nsWindow.cpp',
+]
+
 if CONFIG['MOZ_X11']:
-    SOURCES += [
+    UNIFIED_SOURCES += [
         'nsIdleServiceGTK.cpp',
     ]
 
 if CONFIG['NS_PRINTING']:
-    SOURCES += [
+    UNIFIED_SOURCES += [
         'nsCUPSShim.cpp',
-        'nsDeviceContextSpecG.cpp',
         'nsPaperPS.cpp',
         'nsPrintDialogGTK.cpp',
         'nsPrintOptionsGTK.cpp',
         'nsPrintSettingsGTK.cpp',
         'nsPSPrinters.cpp',
     ]
+    # This file force-enables NSPR logging and thus cannot be built in unified mode
+    SOURCES += [
+        'nsDeviceContextSpecG.cpp',
+    ]
 
 if CONFIG['MOZ_X11']:
+    UNIFIED_SOURCES += [
+        'nsClipboard.cpp',
+    ]
+    # This file force-enables NSPR logging and thus cannot be built in unified mode
     SOURCES += [
-        'nsClipboard.cpp',
         'nsDragService.cpp',
     ]
 
 FAIL_ON_WARNINGS = True
 
-SOURCES += [
-    'mozcontainer.c',
-]
-
 if CONFIG['ACCESSIBILITY']:
-    SOURCES += [
+    UNIFIED_SOURCES += [
         'maiRedundantObjectFactory.c',
     ]
 
 if CONFIG['MOZ_ENABLE_GTK2']:
-    SOURCES += [
+    UNIFIED_SOURCES += [
         'gtk2drawing.c',
     ]
 else:
-    SOURCES += [
+    UNIFIED_SOURCES += [
         'gtk3drawing.c',
     ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
 
 LOCAL_INCLUDES += [
     '../shared',
     '../xpwidgets',
     '/layout/generic',
-    '/layout/xul/base/src',
+    '/layout/xul',
     '/other-licenses/atk-1.0',
 ]
 
 if CONFIG['MOZ_X11']:
     LOCAL_INCLUDES += [
         '../shared/x11',
     ]
 
--- a/widget/gtk/mozcontainer.c
+++ b/widget/gtk/mozcontainer.c
@@ -43,18 +43,16 @@ struct _MozContainerChild {
     gint y;
 };
 
 static void moz_container_allocate_child (MozContainer      *container,
                                           MozContainerChild *child);
 static MozContainerChild *
 moz_container_get_child (MozContainer *container, GtkWidget *child);
 
-static GtkContainerClass *parent_class = NULL;
-
 /* public methods */
 
 GType
 moz_container_get_type(void)
 {
     static GType moz_container_type = 0;
 
     if (!moz_container_type) {
@@ -148,18 +146,16 @@ moz_container_move (MozContainer *contai
 void
 moz_container_class_init (MozContainerClass *klass)
 {
     /*GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
       GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass); */
     GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
     GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 
-    parent_class = g_type_class_peek_parent (klass);
-
     widget_class->map = moz_container_map;
     widget_class->unmap = moz_container_unmap;
     widget_class->realize = moz_container_realize;
     widget_class->size_allocate = moz_container_size_allocate;
 
     container_class->remove = moz_container_remove;
     container_class->forall = moz_container_forall;
     container_class->add = moz_container_add;
--- a/widget/windows/moz.build
+++ b/widget/windows/moz.build
@@ -89,17 +89,17 @@ include('/ipc/chromium/chromium-config.m
 
 FINAL_LIBRARY = 'xul'
 
 LOCAL_INCLUDES += [
     '../shared',
     '../xpwidgets',
     '/content/events/src',
     '/layout/generic',
-    '/layout/xul/base/src',
+    '/layout/xul',
     '/toolkit/xre',
     '/xpcom/base',
 ]
 
 DEFINES['MOZ_UNICODE'] = True
 
 for var in ('MOZ_ENABLE_D3D9_LAYER', 'MOZ_ENABLE_D3D10_LAYER'):
     if CONFIG[var]:
--- a/widget/windows/winrt/moz.build
+++ b/widget/windows/winrt/moz.build
@@ -29,17 +29,17 @@ include('/ipc/chromium/chromium-config.m
 
 FINAL_LIBRARY = 'xul'
 
 LOCAL_INCLUDES += [
     '../',
     '../../shared',
     '../../xpwidgets',
     '/layout/generic',
-    '/layout/xul/base/src',
+    '/layout/xul',
     '/toolkit/xre',
     '/xpcom/base',
 ]
 
 DEFINES['MOZ_UNICODE'] = True
 
 for var in ('MOZ_ENABLE_D3D9_LAYER', 'MOZ_ENABLE_D3D10_LAYER'):
     if CONFIG[var]:
--- a/widget/xpwidgets/moz.build
+++ b/widget/xpwidgets/moz.build
@@ -69,17 +69,17 @@ LIBRARY_NAME = 'xpwidgets_s'
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 LOCAL_INCLUDES += [
     '../shared',
     '/layout/base',
     '/layout/forms',
     '/layout/generic',
-    '/layout/xul/base/src',
+    '/layout/xul',
     '/view/src',
 ]
 
 widget_dir = CONFIG['MOZ_WIDGET_TOOLKIT']
 if widget_dir in ('gtk3', 'gtk2'):
     # gtk3 shares includes with gtk2
     widget_dir = 'gtk'
 
--- a/xpcom/base/nsDebugImpl.cpp
+++ b/xpcom/base/nsDebugImpl.cpp
@@ -473,33 +473,33 @@ Break(const char *aMsg)
 
     /* Create the debug dialog out of process to avoid the crashes caused by 
      * Windows events leaking into our event loop from an in process dialog.
      * We do this by launching windbgdlg.exe (built in xpcom/windbgdlg).
      * See http://bugzilla.mozilla.org/show_bug.cgi?id=54792
      */
     PROCESS_INFORMATION pi;
     STARTUPINFOW si;
-    PRUnichar executable[MAX_PATH];
-    PRUnichar* pName;
+    wchar_t executable[MAX_PATH];
+    wchar_t* pName;
 
     memset(&pi, 0, sizeof(pi));
 
     memset(&si, 0, sizeof(si));
     si.cb          = sizeof(si);
     si.wShowWindow = SW_SHOW;
 
     // 2nd arg of CreateProcess is in/out
-    PRUnichar *msgCopy = (PRUnichar*) _alloca((strlen(aMsg) + 1)*sizeof(PRUnichar));
-    wcscpy(msgCopy  , (PRUnichar*)NS_ConvertUTF8toUTF16(aMsg).get());
+    wchar_t *msgCopy = (wchar_t*) _alloca((strlen(aMsg) + 1)*sizeof(wchar_t));
+    wcscpy(msgCopy, NS_ConvertUTF8toUTF16(aMsg).get());
 
-    if(GetModuleFileNameW(GetModuleHandleW(L"xpcom.dll"), (LPWCH)executable, MAX_PATH) &&
+    if(GetModuleFileNameW(GetModuleHandleW(L"xpcom.dll"), executable, MAX_PATH) &&
        nullptr != (pName = wcsrchr(executable, '\\')) &&
-       nullptr != wcscpy((WCHAR*)pName + 1, L"windbgdlg.exe") &&
-       CreateProcessW((LPCWSTR)executable, (LPWSTR)msgCopy, nullptr, nullptr,
+       nullptr != wcscpy(pName + 1, L"windbgdlg.exe") &&
+       CreateProcessW(executable, msgCopy, nullptr, nullptr,
                       false, DETACHED_PROCESS | NORMAL_PRIORITY_CLASS,
                       nullptr, nullptr, &si, &pi)) {
       WaitForSingleObject(pi.hProcess, INFINITE);
       GetExitCodeProcess(pi.hProcess, &code);
       CloseHandle(pi.hProcess);
       CloseHandle(pi.hThread);
     }
 
--- a/xpcom/build/BinaryPath.h
+++ b/xpcom/build/BinaryPath.h
@@ -17,27 +17,27 @@
 
 namespace mozilla {
 
 class BinaryPath {
 public:
 #ifdef XP_WIN
   static nsresult Get(const char *argv0, char aResult[MAXPATHLEN])
   {
-    PRUnichar wide_path[MAXPATHLEN];
+    wchar_t wide_path[MAXPATHLEN];
     nsresult rv = GetW(argv0, wide_path);
     if (NS_FAILED(rv))
       return rv;
     WideCharToMultiByte(CP_UTF8, 0, wide_path, -1,
                         aResult, MAXPATHLEN, nullptr, nullptr);
     return NS_OK;
   }
 
 private:
-  static nsresult GetW(const char *argv0, PRUnichar aResult[MAXPATHLEN])
+  static nsresult GetW(const char *argv0, wchar_t aResult[MAXPATHLEN])
   {
     if (::GetModuleFileNameW(0, aResult, MAXPATHLEN))
       return NS_OK;
     return NS_ERROR_FAILURE;
   }
 
 #elif defined(XP_MACOSX)
   static nsresult Get(const char *argv0, char aResult[MAXPATHLEN])
@@ -133,17 +133,17 @@ private:
 #error Oops, you need platform-specific code here
 #endif
 
 public:
   static nsresult GetFile(const char *argv0, nsIFile* *aResult)
   {
     nsCOMPtr<nsIFile> lf;
 #ifdef XP_WIN
-    PRUnichar exePath[MAXPATHLEN];
+    wchar_t exePath[MAXPATHLEN];
     nsresult rv = GetW(argv0, exePath);
 #else
     char exePath[MAXPATHLEN];
     nsresult rv = Get(argv0, exePath);
 #endif
     if (NS_FAILED(rv))
       return rv;
 #ifdef XP_WIN
--- a/xpcom/ds/moz.build
+++ b/xpcom/ds/moz.build
@@ -111,15 +111,17 @@ elif CONFIG['OS_ARCH'] == 'Darwin':
 elif CONFIG['COMPILE_ENVIRONMENT']:
     error('No TimeStamp implementation on this platform.  Build will not succeed')
 
 EXTRA_COMPONENTS += [
     'nsINIProcessor.js',
     'nsINIProcessor.manifest',
 ]
 
+FAIL_ON_WARNINGS = True
+
 MSVC_ENABLE_PGO = True
 
 LOCAL_INCLUDES += [
     '../io',
 ]
 
 FINAL_LIBRARY = 'xpcom_core'
--- a/xpcom/ds/nsAtomTable.cpp
+++ b/xpcom/ds/nsAtomTable.cpp
@@ -19,16 +19,20 @@
 #include "nsThreadUtils.h"
 #include "nsDataHashtable.h"
 #include "nsHashKeys.h"
 #include "nsAutoPtr.h"
 #include "nsUnicharUtils.h"
 
 using namespace mozilla;
 
+#ifdef __GNUC__
+#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
+#endif
+
 /**
  * The shared hash table for atom lookups.
  *
  * XXX This should be manipulated in a threadsafe way or we should make
  * sure it's only manipulated from the main thread.  Probably the latter
  * is better, since the former would hurt performance.
  *
  * If |gAtomTable.ops| is 0, then the table is uninitialized.
--- a/xpcom/ds/nsHashtable.cpp
+++ b/xpcom/ds/nsHashtable.cpp
@@ -581,17 +581,17 @@ nsStringKey::nsStringKey(const nsStringK
     }
 #ifdef DEBUG
     mKeyType = StringKey;
 #endif
     MOZ_COUNT_CTOR(nsStringKey);
 }
 
 nsStringKey::nsStringKey(const nsAFlatString& str)
-    : mStr(const_cast<PRUnichar*>(str.get())),
+    : mStr((PRUnichar*)str.get()),
       mStrLen(str.Length()),
       mOwnership(OWN_CLONE)
 {
     NS_ASSERTION(mStr, "null string key");
 #ifdef DEBUG
     mKeyType = StringKey;
 #endif
     MOZ_COUNT_CTOR(nsStringKey);
--- a/xpcom/ds/nsIAtom.idl
+++ b/xpcom/ds/nsIAtom.idl
@@ -39,17 +39,17 @@ interface nsIAtom : nsISupports
   [noscript, notxpcom] boolean isStaticAtom();
 
 %{C++
   // note this is NOT virtual so this won't muck with the vtable!
   inline bool Equals(const nsAString& aString) const {
     return aString.Equals(nsDependentString(mString, mLength));
   }
 
-  inline const PRUnichar* GetUTF16String() const {
+  inline char16ptr_t GetUTF16String() const {
     return mString;
   }
 
   inline const uint32_t GetLength() const {
     return mLength;
   }
 
   inline void ToString(nsAString& aBuf) {
--- a/xpcom/ds/nsWindowsRegKey.cpp
+++ b/xpcom/ds/nsWindowsRegKey.cpp
@@ -153,17 +153,17 @@ nsWindowsRegKey::GetChildCount(uint32_t 
 NS_IMETHODIMP
 nsWindowsRegKey::GetChildName(uint32_t index, nsAString &result)
 {
   if (NS_WARN_IF(!mKey))
     return NS_ERROR_NOT_INITIALIZED;
 
   FILETIME lastWritten;
 
-  PRUnichar nameBuf[MAX_KEY_NAME_LEN + 1];
+  wchar_t nameBuf[MAX_KEY_NAME_LEN + 1];
   DWORD nameLen = sizeof(nameBuf) / sizeof(nameBuf[0]);
 
   LONG rv = RegEnumKeyExW(mKey, index, nameBuf, &nameLen, nullptr, nullptr,
                           nullptr, &lastWritten);
   if (rv != ERROR_SUCCESS)
     return NS_ERROR_NOT_AVAILABLE;  // XXX what's the best error code here?
 
   result.Assign(nameBuf, nameLen);
@@ -208,17 +208,17 @@ nsWindowsRegKey::GetValueCount(uint32_t 
 }
 
 NS_IMETHODIMP
 nsWindowsRegKey::GetValueName(uint32_t index, nsAString &result)
 {
   if (NS_WARN_IF(!mKey))
     return NS_ERROR_NOT_INITIALIZED;
 
-  PRUnichar nameBuf[MAX_VALUE_NAME_LEN];
+  wchar_t nameBuf[MAX_VALUE_NAME_LEN];
   DWORD nameLen = sizeof(nameBuf) / sizeof(nameBuf[0]);
 
   LONG rv = RegEnumValueW(mKey, index, nameBuf, &nameLen, nullptr, nullptr,
                           nullptr, nullptr);
   if (rv != ERROR_SUCCESS)
     return NS_ERROR_NOT_AVAILABLE;  // XXX what's the best error code here?
 
   result.Assign(nameBuf, nameLen);
--- a/xpcom/glue/nsVersionComparator.cpp
+++ b/xpcom/glue/nsVersionComparator.cpp
@@ -22,22 +22,22 @@ struct VersionPart {
 
   char       *extraD;  // null-terminated
 };
 
 #ifdef XP_WIN
 struct VersionPartW {
   int32_t     numA;
 
-  const PRUnichar *strB;    // NOT null-terminated, can be a null pointer
+  wchar_t    *strB;    // NOT null-terminated, can be a null pointer
   uint32_t    strBlen;
 
   int32_t     numC;
 
-  PRUnichar       *extraD;  // null-terminated
+  wchar_t    *extraD;  // null-terminated
 
 };
 #endif
 
 /**
  * Parse a version part into a number and "extra text".
  *
  * @returns A pointer to the next versionpart, or null if none.
@@ -107,21 +107,21 @@ ParseVP(char *part, VersionPart &result)
 
 
 /**
  * Parse a version part into a number and "extra text".
  *
  * @returns A pointer to the next versionpart, or null if none.
  */
 #ifdef XP_WIN
-static PRUnichar*
-ParseVP(PRUnichar *part, VersionPartW &result)
+static wchar_t*
+ParseVP(wchar_t *part, VersionPartW &result)
 {
 
-  PRUnichar *dot;
+  wchar_t *dot;
 
   result.numA = 0;
   result.strB = nullptr;
   result.strBlen = 0;
   result.numC = 0;
   result.extraD = nullptr;
 
   if (!part)
@@ -131,33 +131,33 @@ ParseVP(PRUnichar *part, VersionPartW &r
   if (dot)
     *dot = '\0';
 
   if (part[0] == '*' && part[1] == '\0') {
     result.numA = INT32_MAX;
     result.strB = L"";
   }
   else {
-    result.numA = wcstol(part, const_cast<PRUnichar**>(&result.strB), 10);
+    result.numA = wcstol(part, const_cast<wchar_t**>(&result.strB), 10);
   }
 
   if (!*result.strB) {
     result.strB = nullptr;
     result.strBlen = 0;
   }
   else {
     if (result.strB[0] == '+') {
-      static const PRUnichar kPre[] = L"pre";
+      static wchar_t kPre[] = L"pre";
 
       ++result.numA;
       result.strB = kPre;
       result.strBlen = sizeof(kPre) - 1;
     }
     else {
-      const PRUnichar *numstart = wcspbrk(result.strB, L"0123456789+-");
+      const wchar_t *numstart = wcspbrk(result.strB, L"0123456789+-");
       if (!numstart) {
 	result.strBlen = wcslen(result.strB);
       }
       else {
 	result.strBlen = numstart - result.strB;
 
 	result.numC = wcstol(numstart, &result.extraD, 10);
 	if (!*result.extraD)
@@ -277,28 +277,28 @@ CompareVP(VersionPartW &v1, VersionPartW
 #endif
 
 namespace mozilla {
 
 #ifdef XP_WIN
 int32_t
 CompareVersions(const PRUnichar *A, const PRUnichar *B)
 {
-  PRUnichar *A2 = wcsdup(A);
+  wchar_t *A2 = wcsdup(char16ptr_t(A));
   if (!A2)
     return 1;
 
-  PRUnichar *B2 = wcsdup(B);
+  wchar_t *B2 = wcsdup(char16ptr_t(B));
   if (!B2) {
     free(A2);
     return 1;
   }
 
   int32_t result;
-  PRUnichar *a = A2, *b = B2;
+  wchar_t *a = A2, *b = B2;
 
   do {
     VersionPartW va, vb;
 
     a = ParseVP(a, va);
     b = ParseVP(b, vb);
 
     result = CompareVP(va, vb);
--- a/xpcom/io/SpecialSystemDirectory.cpp
+++ b/xpcom/io/SpecialSystemDirectory.cpp
@@ -165,17 +165,17 @@ GetLibrarySaveToPath(int aFallbackFolder
     nsRefPtr<IShellItem> savePath;
     HRESULT hr =
         SHLoadLibraryFromKnownFolder(aFolderId, STGM_READ,
                                      IID_IShellLibrary, getter_AddRefs(shellLib));
 
     if (shellLib &&
         SUCCEEDED(shellLib->GetDefaultSaveFolder(DSFT_DETECT, IID_IShellItem,
                                                  getter_AddRefs(savePath)))) {
-        PRUnichar* str = nullptr;
+        wchar_t* str = nullptr;
         if (SUCCEEDED(savePath->GetDisplayName(SIGDN_FILESYSPATH, &str))) {
             nsAutoString path;
             path.Assign(str);
             path.AppendLiteral("\\");
             nsresult rv =
                 NS_NewLocalFile(path, false, aFile);
             CoTaskMemFree(str);
             return rv;
--- a/xpcom/io/nsDirectoryService.cpp
+++ b/xpcom/io/nsDirectoryService.cpp
@@ -92,22 +92,22 @@ nsDirectoryService::GetCurrentProcessDir
 
     if (localFile == nullptr)
         return NS_ERROR_OUT_OF_MEMORY;
     NS_ADDREF(localFile);
 
 
 
 #ifdef XP_WIN
-    PRUnichar buf[MAX_PATH + 1];
+    wchar_t buf[MAX_PATH + 1];
     SetLastError(ERROR_SUCCESS);
     if (GetModuleFileNameW(0, buf, mozilla::ArrayLength(buf)) &&
         GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
         // chop off the executable name by finding the rightmost backslash
-        PRUnichar* lastSlash = wcsrchr(buf, L'\\');
+        wchar_t* lastSlash = wcsrchr(buf, L'\\');
         if (lastSlash)
             *(lastSlash + 1) = L'\0';
 
         localFile->InitWithPath(nsDependentString(buf));
         *aFile = localFile;
         return NS_OK;
     }
 
--- a/xpcom/io/nsLocalFileCommon.cpp
+++ b/xpcom/io/nsLocalFileCommon.cpp
@@ -218,17 +218,17 @@ nsLocalFile::GetRelativeDes