Merge m-c to b2g-inbound a=merge
authorWes Kocher <wkocher@mozilla.com>
Thu, 18 Sep 2014 16:11:23 -0700
changeset 206102 f6b1cf6fb33f3e704fbc37ac37c3a9c42fb46188
parent 206101 b030bb382b31903cbf8d20e2f598b414c6daaeca (current diff)
parent 206094 c8e325eee9e1ca005bd1727672fefdca37e241c9 (diff)
child 206103 4873a806f48f4525eac672cbd0e740e0c4558893
push id27512
push usercbook@mozilla.com
push dateFri, 19 Sep 2014 12:07:02 +0000
treeherdermozilla-central@c8dee1c9cc3d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone35.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge m-c to b2g-inbound a=merge
intl/uconv/ucvja/nsUnicodeToJISx0201.cpp
intl/uconv/ucvja/nsUnicodeToJISx0201.h
intl/uconv/ucvlatin/iso-ir-111.uf
intl/uconv/ucvlatin/iso-ir-111.ut
intl/uconv/ucvlatin/nsISO88596EToUnicode.cpp
intl/uconv/ucvlatin/nsISO88596EToUnicode.h
intl/uconv/ucvlatin/nsISO88596IToUnicode.cpp
intl/uconv/ucvlatin/nsISO88596IToUnicode.h
intl/uconv/ucvlatin/nsISO88598EToUnicode.cpp
intl/uconv/ucvlatin/nsISO88598EToUnicode.h
intl/uconv/ucvlatin/nsISOIR111ToUnicode.cpp
intl/uconv/ucvlatin/nsISOIR111ToUnicode.h
intl/uconv/ucvlatin/nsUnicodeToISO88596E.cpp
intl/uconv/ucvlatin/nsUnicodeToISO88596E.h
intl/uconv/ucvlatin/nsUnicodeToISO88596I.cpp
intl/uconv/ucvlatin/nsUnicodeToISO88596I.h
intl/uconv/ucvlatin/nsUnicodeToISO88598E.cpp
intl/uconv/ucvlatin/nsUnicodeToISO88598E.h
intl/uconv/ucvlatin/nsUnicodeToISOIR111.cpp
intl/uconv/ucvlatin/nsUnicodeToISOIR111.h
intl/uconv/ucvtw/nsUnicodeToHKSCS.cpp
intl/uconv/ucvtw/nsUnicodeToHKSCS.h
--- a/accessible/generic/Accessible.cpp
+++ b/accessible/generic/Accessible.cpp
@@ -229,28 +229,27 @@ Accessible::Description(nsString& aDescr
              childElm = childElm->GetNextSibling()) {
           if (childElm->IsSVG(nsGkAtoms::desc)) {
             nsTextEquivUtils::AppendTextEquivFromContent(this, childElm,
                                                          &aDescription);
             break;
           }
         }
       }
-
-      if (!aDescription.IsEmpty()) {
-        nsAutoString name;
-        ENameValueFlag nameFlag = Name(name);
-
-        // Don't use tooltip for a description if it was used for a name.
-        if (nameFlag == eNameFromTooltip)
-          aDescription.Truncate();
-      }
     }
   }
-  aDescription.CompressWhitespace();
+
+  if (!aDescription.IsEmpty()) {
+    aDescription.CompressWhitespace();
+    nsAutoString name;
+    ENameValueFlag nameFlag = Name(name);
+    // Don't expose a description if it is the same as the name.
+    if (aDescription.Equals(name))
+      aDescription.Truncate();
+  }
 }
 
 KeyBinding
 Accessible::AccessKey() const
 {
   if (!HasOwnContent())
     return KeyBinding();
 
--- a/accessible/tests/mochitest/test_descr.html
+++ b/accessible/tests/mochitest/test_descr.html
@@ -20,28 +20,40 @@
       // No description from @title attribute because it is used to generate
       // name.
       testDescr("img2", "");
 
       // Description from @title attribute, name is generated from @alt
       // attribute.
       testDescr("img3", "description");
 
+      // No description from aria-describedby since it is the same as the
+      // @alt attribute which is used as the name
+      testDescr("img4", "");
+
+      // No description from @title attribute since it is the same as the
+      // @alt attribute which is used as the name
+      testDescr("img5", "");
+
       // Description from content of h2.
       testDescr("p", "heading");
 
       // From table summary (caption is used as a name)
       testDescr("table1", "summary");
 
       // Empty (summary is used as a name)
       testDescr("table2", "");
 
       // From title (summary is used as a name)
       testDescr("table3", "title");
 
+      // No description from <desc> element since it is the same as the
+      // <title> element.
+      testDescr("svg", "");
+
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 
 </head>
@@ -53,35 +65,57 @@
      title="@title attribute no longer exposed on accDescription">
     Mozilla Bug 489944
   </a>
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=666212"
      title="summary attribute content mapped to accessible name in MSAA">
     Mozilla Bug 666212
   </a>
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi/id=1031188"
+     title="Ensure that accDescription never duplicates AccessibleName">
+    Mozilla Bug 1031188
+  </a>
+
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <p id="description">aria description</p>
   <img id="img1" aria-describedby="description" />
   <img id="img2" title="title" />
   <img id="img3" alt="name" title="description" />
+  <img id="img4" alt="aria description" aria-describedby="description">
+  <img id="img5" alt="image" title="image">
 
   <h2 id="heading">heading</h2>
   <p id="p" aria-describedby="heading" role="button">click me</p>
 
   <table id="table1" summary="summary">
     <caption>caption</caption>
     <tr><td>cell</td></tr>
   </table>
 
   <table id="table2" summary="summary">
     <tr><td>cell</td></tr>
   </table>
 
   <table id="table3" summary="summary" title="title">
     <tr><td>cell</td></tr>
   </table>
+  
+  <svg xmlns="http://www.w3.org/2000/svg" version="1.1"
+       viewBox="0 0 100 100" preserveAspectRatio="xMidYMid slice"
+       id="svg"
+       style="width:100px; height:100px;">
+    <title>SVG Image</title>
+    <desc>SVG Image</desc>
+    <linearGradient id="gradient">
+      <stop class="begin" offset="0%"/>
+      <stop class="end" offset="100%"/>
+    </linearGradient>
+    <rect x="0" y="0" width="100" height="100" style="fill:url(#gradient)" />
+    <circle cx="50" cy="50" r="30" style="fill:url(#gradient)" />
+  </svg>
 </body>
 </html>
--- a/b2g/components/ProcessGlobal.js
+++ b/b2g/components/ProcessGlobal.js
@@ -25,16 +25,22 @@ Cu.import('resource://gre/modules/XPCOMU
 function debug(msg) {
   log(msg);
 }
 function log(msg) {
   // This file implements console.log(), so use dump().
   //dump('ProcessGlobal: ' + msg + '\n');
 }
 
+function formatStackFrame(aFrame) {
+  let functionName = aFrame.functionName || '<anonymous>';
+  return '    at ' + functionName +
+         ' (' + aFrame.filename + ':' + aFrame.lineNumber + ')';
+}
+
 const gFactoryResetFile = "/persist/__post_reset_cmd__";
 
 function ProcessGlobal() {}
 ProcessGlobal.prototype = {
   classID: Components.ID('{1a94c87a-5ece-4d11-91e1-d29c29f21b28}'),
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
                                          Ci.nsISupportsWeakReference]),
 
@@ -107,20 +113,30 @@ ProcessGlobal.prototype = {
         this.cleanupAfterFactoryReset();
       }
       break;
     }
     case 'console-api-log-event': {
       // Pipe `console` log messages to the nsIConsoleService which
       // writes them to logcat on Gonk.
       let message = subject.wrappedJSObject;
-      let prefix = ('Content JS ' + message.level.toUpperCase() +
-                    ' at ' + message.filename + ':' + message.lineNumber +
-                    ' in ' + (message.functionName || 'anonymous') + ': ');
-      Services.console.logStringMessage(prefix + Array.join(message.arguments,
-                                                            ' '));
+      let args = message.arguments;
+      let stackTrace = '';
+
+      if (message.level == 'assert' || message.level == 'error' || message.level == 'trace') {
+        stackTrace = Array.map(message.stacktrace, formatStackFrame).join('\n');
+      } else {
+        stackTrace = formatStackFrame(message);
+      }
+
+      if (stackTrace) {
+        args.push('\n' + stackTrace);
+      }
+
+      let prefix = 'Content JS ' + message.level.toUpperCase() + ': ';
+      Services.console.logStringMessage(prefix + Array.join(args, ' '));
       break;
     }
     }
   },
 };
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ProcessGlobal]);
--- a/browser/base/content/browser-sets.inc
+++ b/browser/base/content/browser-sets.inc
@@ -341,21 +341,21 @@
     <key id="goForwardKb" keycode="VK_RIGHT" command="Browser:Forward" modifiers="accel" />
 #endif
 #ifdef XP_UNIX
     <key id="goBackKb2" key="&goBackCmd.commandKey;" command="Browser:Back" modifiers="accel"/>
     <key id="goForwardKb2" key="&goForwardCmd.commandKey;" command="Browser:Forward" modifiers="accel"/>
 #endif
     <key id="goHome" keycode="VK_HOME" command="Browser:Home" modifiers="alt"/>
     <key keycode="VK_F5" command="Browser:Reload"/>
+    <key keycode="VK_F6" command="Browser:FocusNextFrame"/>
+    <key keycode="VK_F6" command="Browser:FocusNextFrame" modifiers="shift"/>
 #ifndef XP_MACOSX
     <key id="showAllHistoryKb" key="&showAllHistoryCmd.commandkey;" command="Browser:ShowAllHistory" modifiers="accel,shift"/>
     <key keycode="VK_F5" command="Browser:ReloadSkipCache" modifiers="accel"/>
-    <key keycode="VK_F6" command="Browser:FocusNextFrame"/>
-    <key keycode="VK_F6" command="Browser:FocusNextFrame" modifiers="shift"/>
     <key id="key_fullScreen" keycode="VK_F11" command="View:FullScreen"/>
 #else
     <key id="key_fullScreen" key="&fullScreenCmd.macCommandKey;" command="View:FullScreen" modifiers="accel,control"/>
     <key id="key_fullScreen_old" key="&fullScreenCmd.macCommandKey;" command="View:FullScreen" modifiers="accel,shift"/>
     <key keycode="VK_F11" command="View:FullScreen"/>
 #endif
     <key key="&reloadCmd.commandkey;" command="Browser:Reload" modifiers="accel" id="key_reload"/>
     <key key="&reloadCmd.commandkey;" command="Browser:ReloadSkipCache" modifiers="accel,shift"/>
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -7259,17 +7259,19 @@ var MousePosTracker = {
     }
   }
 };
 
 function focusNextFrame(event) {
   let fm = Services.focus;
   let dir = event.shiftKey ? fm.MOVEFOCUS_BACKWARDDOC : fm.MOVEFOCUS_FORWARDDOC;
   let element = fm.moveFocus(window, null, dir, fm.FLAG_BYKEY);
-  if (element.ownerDocument == document)
+  let panelOrNotificationSelector = "popupnotification " + element.localName + ", " +
+                                    "panel " + element.localName;
+  if (element.ownerDocument == document && !element.matches(panelOrNotificationSelector))
     focusAndSelectUrlBar();
 }
 
 function BrowserOpenNewTabOrWindow(event) {
   if (event.shiftKey) {
     OpenBrowserWindow();
   } else {
     BrowserOpenTab();
--- a/browser/base/content/searchSuggestionUI.js
+++ b/browser/base/content/searchSuggestionUI.js
@@ -91,46 +91,46 @@ SearchSuggestionUIController.prototype =
     // Update the table's rows, and the input when there is a selection.
     this._table.removeAttribute("aria-activedescendant");
     for (let i = 0; i < this._table.children.length; i++) {
       let row = this._table.children[i];
       if (i == idx) {
         row.classList.add("selected");
         row.firstChild.setAttribute("aria-selected", "true");
         this._table.setAttribute("aria-activedescendant", row.firstChild.id);
-        this.input.value = this.suggestionAtIndex(i);
       }
       else {
         row.classList.remove("selected");
         row.firstChild.setAttribute("aria-selected", "false");
       }
     }
-
-    // Update the input when there is no selection.
-    if (idx < 0) {
-      this.input.value = this._stickyInputValue;
-    }
   },
 
   get numSuggestions() {
     return this._table.children.length;
   },
 
+  selectAndUpdateInput: function (idx) {
+    this.selectedIndex = idx;
+    this.input.value = idx >= 0 ? this.suggestionAtIndex(idx) :
+                       this._stickyInputValue;
+  },
+
   suggestionAtIndex: function (idx) {
     let row = this._table.children[idx];
     return row ? row.textContent : null;
   },
 
   deleteSuggestionAtIndex: function (idx) {
     // Only form history suggestions can be deleted.
     if (this.isFormHistorySuggestionAtIndex(idx)) {
       let suggestionStr = this.suggestionAtIndex(idx);
       this._sendMsg("RemoveFormHistoryEntry", suggestionStr);
       this._table.children[idx].remove();
-      this.selectedIndex = -1;
+      this.selectAndUpdateInput(-1);
     }
   },
 
   isFormHistorySuggestionAtIndex: function (idx) {
     let row = this._table.children[idx];
     return row && row.classList.contains("formHistory");
   },
 
@@ -145,17 +145,17 @@ SearchSuggestionUIController.prototype =
   _onInput: function () {
     if (this.input.value) {
       this._getSuggestions();
     }
     else {
       this._stickyInputValue = "";
       this._hideSuggestions();
     }
-    this.selectedIndex = -1;
+    this.selectAndUpdateInput(-1);
   },
 
   _onKeypress: function (event) {
     let selectedIndexDelta = 0;
     switch (event.keyCode) {
     case event.DOM_VK_UP:
       if (this.numSuggestions) {
         selectedIndexDelta = -1;
@@ -203,31 +203,35 @@ SearchSuggestionUIController.prototype =
       // Update the selection.
       let newSelectedIndex = this.selectedIndex + selectedIndexDelta;
       if (newSelectedIndex < -1) {
         newSelectedIndex = this.numSuggestions - 1;
       }
       else if (this.numSuggestions <= newSelectedIndex) {
         newSelectedIndex = -1;
       }
-      this.selectedIndex = newSelectedIndex;
+      this.selectAndUpdateInput(newSelectedIndex);
 
       // Prevent the input's caret from moving.
       event.preventDefault();
     }
   },
 
   _onFocus: function () {
     this._speculativeConnect();
   },
 
   _onBlur: function () {
     this._hideSuggestions();
   },
 
+  _onMousemove: function (event) {
+    this.selectedIndex = this._indexOfTableRowOrDescendent(event.target);
+  },
+
   _onMousedown: function (event) {
     let idx = this._indexOfTableRowOrDescendent(event.target);
     let suggestion = this.suggestionAtIndex(idx);
     this._stickyInputValue = suggestion;
     this.input.value = suggestion;
     this.input.setAttribute("selection-index", idx);
     this.input.setAttribute("selection-kind", "mouse");
     this._hideSuggestions();
@@ -295,16 +299,17 @@ SearchSuggestionUIController.prototype =
     }
   },
 
   _makeTableRow: function (type, suggestionStr, currentRow, searchWords) {
     let row = document.createElementNS(HTML_NS, "tr");
     row.classList.add("searchSuggestionRow");
     row.classList.add(type);
     row.setAttribute("role", "presentation");
+    row.addEventListener("mousemove", this);
     row.addEventListener("mousedown", this);
 
     let entry = document.createElementNS(HTML_NS, "td");
     entry.classList.add("searchSuggestionEntry");
     entry.setAttribute("role", "option");
     entry.id = this._idPrefix + SUGGESTION_ID_PREFIX + currentRow;
     entry.setAttribute("aria-selected", "false");
 
@@ -338,17 +343,17 @@ SearchSuggestionUIController.prototype =
   },
 
   _hideSuggestions: function () {
     this.input.setAttribute("aria-expanded", "false");
     this._table.hidden = true;
     while (this._table.firstElementChild) {
       this._table.firstElementChild.remove();
     }
-    this.selectedIndex = -1;
+    this.selectAndUpdateInput(-1);
   },
 
   _indexOfTableRowOrDescendent: function (row) {
     while (row && row.localName != "tr") {
       row = row.parentNode;
     }
     if (!row) {
       throw new Error("Element is not a row");
--- a/browser/base/content/test/general/browser_mixedcontent_securityflags.js
+++ b/browser/base/content/test/general/browser_mixedcontent_securityflags.js
@@ -38,24 +38,37 @@ function blockMixedContentTest()
 function overrideMCB()
 {
   // test mixed content flags on load (reload)
   gTestBrowser.addEventListener("load", mixedContentOverrideTest, true);
   var notification = PopupNotifications.getNotification("bad-content", gTestBrowser);
   ok(notification, "Mixed Content Doorhanger should appear");
   notification.reshow();
   ok(PopupNotifications.panel.firstChild.isMixedContentBlocked, "OK: Mixed Content is being blocked");
+
+  // Make sure the notification has no mixedblockdisabled attribute
+  ok(!PopupNotifications.panel.firstChild.hasAttribute("mixedblockdisabled"),
+    "Doorhanger must have no mixedblockdisabled attribute");
   // Click on the doorhanger to allow mixed content (and reload page)
   PopupNotifications.panel.firstChild.disableMixedContentProtection();
   notification.remove();
 }
 
 function mixedContentOverrideTest()
 {
   gTestBrowser.removeEventListener("load", mixedContentOverrideTest, true);
 
   is(gTestBrowser.docShell.hasMixedDisplayContentLoaded, true, "hasMixedDisplayContentLoaded flag has not been set");
   is(gTestBrowser.docShell.hasMixedActiveContentLoaded, true, "hasMixedActiveContentLoaded flag has not been set");
   is(gTestBrowser.docShell.hasMixedDisplayContentBlocked, false, "second hasMixedDisplayContentBlocked flag has been set");
   is(gTestBrowser.docShell.hasMixedActiveContentBlocked, false, "second hasMixedActiveContentBlocked flag has been set");
+
+  let notification = PopupNotifications.getNotification("bad-content", gTestBrowser);
+  ok(notification, "Mixed Content Doorhanger should appear");
+  notification.reshow();
+
+  // Make sure the notification has the mixedblockdisabled attribute set to true
+  is(PopupNotifications.panel.firstChild.getAttribute("mixedblockdisabled"), "true",
+    "Doorhanger must have [mixedblockdisabled='true'] attribute");
+
   gBrowser.removeCurrentTab();
   finish();
 }
--- a/browser/base/content/test/general/browser_searchSuggestionUI.js
+++ b/browser/base/content/test/general/browser_searchSuggestionUI.js
@@ -97,16 +97,24 @@ add_task(rightArrowOrReturn("VK_RIGHT"))
 add_task(rightArrowOrReturn("VK_RETURN"));
 
 add_task(function* mouse() {
   yield setUp();
 
   let state = yield msg("key", { key: "x", waitForSuggestions: true });
   checkState(state, "x", ["xfoo", "xbar"], -1);
 
+  // Mouse over the first suggestion.
+  state = yield msg("mousemove", 0);
+  checkState(state, "x", ["xfoo", "xbar"], 0);
+
+  // Mouse over the second suggestion.
+  state = yield msg("mousemove", 1);
+  checkState(state, "x", ["xfoo", "xbar"], 1);
+
   // Click the second suggestion.  This should make it sticky.  To make sure it
   // sticks, trigger suggestions again and cycle through them by pressing Down
   // until nothing is selected again.
   state = yield msg("mousedown", 1);
   checkState(state, "xbar", [], -1);
 
   state = yield msg("key", { key: "VK_DOWN", waitForSuggestions: true });
   checkState(state, "xbar", ["xbarfoo", "xbarbar"], -1);
--- a/browser/base/content/test/general/browser_trackingUI.js
+++ b/browser/base/content/test/general/browser_trackingUI.js
@@ -63,29 +63,37 @@ function testTrackingPage(gTestBrowser)
   // Make sure the doorhanger appears
   var notification = PopupNotifications.getNotification("bad-content", gTestBrowser);
   isnot(notification, null, "Tracking Content Doorhanger did appear when protection was ON and tracking was present");
   notification.reshow();
   // Make sure the state of the doorhanger includes blocking tracking elements
   isnot(PopupNotifications.panel.firstChild.isTrackingContentBlocked, 0,
     "Tracking Content is being blocked");
 
+  // Make sure the notification has no trackingblockdisabled attribute
+  ok(!PopupNotifications.panel.firstChild.hasAttribute("trackingblockdisabled"),
+    "Doorhanger must have no trackingblockdisabled attribute");
+
   // Disable Tracking Content Protection for the page (which reloads the page)
   PopupNotifications.panel.firstChild.disableTrackingContentProtection();
 }
 
 function testTrackingPageWhitelisted(gTestBrowser)
 {
   // Make sure the doorhanger appears
   var notification = PopupNotifications.getNotification("bad-content", gTestBrowser);
   isnot(notification, null, "Tracking Content Doorhanger did appear when protection was ON and tracking was present but white-listed");
   notification.reshow();
   // Make sure the state of the doorhanger does NOT include blocking tracking elements
   is(PopupNotifications.panel.firstChild.isTrackingContentBlocked, 0,
     "Tracking Content is NOT being blocked");
+
+  // Make sure the notification has the trackingblockdisabled attribute set to true
+  is(PopupNotifications.panel.firstChild.getAttribute("trackingblockdisabled"), "true",
+    "Doorhanger must have [trackingblockdisabled='true'] attribute");
 }
 
 function testTrackingPageOFF(gTestBrowser)
 {
   // Make sure the doorhanger does NOT appear
   var notification = PopupNotifications.getNotification("bad-content", gTestBrowser);
   is(notification, null, "Tracking Content Doorhanger did NOT appear when protection was OFF and tracking was present");
 }
--- a/browser/base/content/test/general/searchSuggestionUI.js
+++ b/browser/base/content/test/general/searchSuggestionUI.js
@@ -32,16 +32,43 @@ let messageHandlers = {
     ack();
   },
 
   blur: function () {
     gController.input.blur();
     ack();
   },
 
+  mousemove: function (suggestionIdx) {
+    // Copied from widget/tests/test_panel_mouse_coords.xul and
+    // browser/base/content/test/newtab/head.js
+    let row = gController._table.children[suggestionIdx];
+    let rect = row.getBoundingClientRect();
+    let left = content.mozInnerScreenX + rect.left;
+    let x = left + rect.width / 2;
+    let y = content.mozInnerScreenY + rect.top + rect.height / 2;
+
+    let utils = content.SpecialPowers.getDOMWindowUtils(content);
+    let scale = utils.screenPixelsPerCSSPixel;
+
+    let widgetToolkit = content.SpecialPowers.
+                        Cc["@mozilla.org/xre/app-info;1"].
+                        getService(content.SpecialPowers.Ci.nsIXULRuntime).
+                        widgetToolkit;
+    let nativeMsg = widgetToolkit == "cocoa" ? 5 : // NSMouseMoved
+                    widgetToolkit == "windows" ? 1 : // MOUSEEVENTF_MOVE
+                    3; // GDK_MOTION_NOTIFY
+
+    row.addEventListener("mousemove", function onMove() {
+      row.removeEventListener("mousemove", onMove);
+      ack();
+    });
+    utils.sendNativeMouseEvent(x * scale, y * scale, nativeMsg, 0, null);
+  },
+
   mousedown: function (suggestionIdx) {
     gController.onClick = () => {
       gController.onClick = null;
       ack();
     };
     let row = gController._table.children[suggestionIdx];
     content.sendMouseEvent({ type: "mousedown" }, row);
   },
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -1623,17 +1623,17 @@
         </setter>
       </property>
     </implementation>
   </binding>
 
   <binding id="bad-content-notification" extends="chrome://global/content/bindings/notification.xml#popup-notification">
     <content>
       <xul:hbox align="start">
-        <xul:image class="popup-notification-icon" xbl:inherits="popupid"/>
+        <xul:image class="popup-notification-icon" xbl:inherits="popupid,mixedblockdisabled,trackingblockdisabled"/>
         <xul:vbox>
           <!-- header -->
           <xul:vbox>
             <xul:description anonid="badContentBlocked.title"
               class="popup-notification-item-title" xbl:inherits="popupid">
             </xul:description>
             <xul:description class="popup-notification-item-message"
               xbl:inherits="popupid">
--- a/browser/components/loop/MozLoopAPI.jsm
+++ b/browser/components/loop/MozLoopAPI.jsm
@@ -1,16 +1,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 
+Cu.import("resource://services-common/utils.js");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource:///modules/loop/MozLoopService.jsm");
 Cu.import("resource:///modules/loop/LoopContacts.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "hookWindowCloseForPanelClose",
                                         "resource://gre/modules/MozSocialAPI.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
@@ -18,16 +19,19 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 XPCOMUtils.defineLazyGetter(this, "appInfo", function() {
   return Cc["@mozilla.org/xre/app-info;1"]
            .getService(Ci.nsIXULAppInfo)
            .QueryInterface(Ci.nsIXULRuntime);
 });
 XPCOMUtils.defineLazyServiceGetter(this, "clipboardHelper",
                                          "@mozilla.org/widget/clipboardhelper;1",
                                          "nsIClipboardHelper");
+XPCOMUtils.defineLazyServiceGetter(this, "extProtocolSvc",
+                                         "@mozilla.org/uriloader/external-protocol-service;1",
+                                         "nsIExternalProtocolService");
 this.EXPORTED_SYMBOLS = ["injectLoopAPI"];
 
 /**
  * Trying to clone an Error object into a different container will yield an error.
  * We can work around this by copying the properties we care about onto a regular
  * object.
  *
  * @param {Error}        error        Error object to copy
@@ -450,16 +454,46 @@ function injectLoopAPI(targetWindow) {
             channel: defaults.getCharPref("app.update.channel"),
             version: appInfo.version,
             OS: appInfo.OS
           }, targetWindow);
         }
         return appVersionInfo;
       }
     },
+
+    /**
+     * Composes an email via the external protocol service.
+     *
+     * @param {String} subject Subject of the email to send
+     * @param {String} body    Body message of the email to send
+     */
+    composeEmail: {
+      enumerable: true,
+      writable: true,
+      value: function(subject, body) {
+        let mailtoURL = "mailto:?subject=" + encodeURIComponent(subject) + "&" +
+                        "body=" + encodeURIComponent(body);
+        extProtocolSvc.loadURI(CommonUtils.makeURI(mailtoURL));
+      }
+    },
+
+    /**
+     * Adds a value to a telemetry histogram.
+     *
+     * @param  {string}  histogramId Name of the telemetry histogram to update.
+     * @param  {integer} value       Value to add to the histogram.
+     */
+    telemetryAdd: {
+      enumerable: true,
+      writable: true,
+      value: function(histogramId, value) {
+        Services.telemetry.getHistogramById(histogramId).add(value);
+      }
+    },
   };
 
   function onStatusChanged(aSubject, aTopic, aData) {
     let event = new targetWindow.CustomEvent("LoopStatusChanged");
     targetWindow.dispatchEvent(event)
   };
 
   function onDOMWindowDestroyed(aSubject, aTopic, aData) {
--- a/browser/components/loop/content/js/client.js
+++ b/browser/components/loop/content/js/client.js
@@ -106,25 +106,32 @@ loop.Client = (function($) {
      *
      * @param  {string} nickname the nickname of the future caller
      * @param  {Function} cb Callback(err, callUrlData)
      */
     _requestCallUrlInternal: function(nickname, cb) {
       this.mozLoop.hawkRequest("/call-url/", "POST", {callerId: nickname},
                                function (error, responseText) {
         if (error) {
+          this._telemetryAdd("LOOP_CLIENT_CALL_URL_REQUESTS_SUCCESS", false);
           this._failureHandler(cb, error);
           return;
         }
 
         try {
           var urlData = JSON.parse(responseText);
 
-          cb(null, this._validate(urlData, expectedCallUrlProperties));
+          // This throws if the data is invalid, in which case only the failure
+          // telementry will be recorded.
+          var returnData = this._validate(urlData, expectedCallUrlProperties);
+
+          this._telemetryAdd("LOOP_CLIENT_CALL_URL_REQUESTS_SUCCESS", true);
+          cb(null, returnData);
         } catch (err) {
+          this._telemetryAdd("LOOP_CLIENT_CALL_URL_REQUESTS_SUCCESS", false);
           console.log("Error requesting call info", err);
           cb(err);
         }
       }.bind(this));
     },
 
     /**
      * Block call URL based on the token identifier
@@ -182,12 +189,26 @@ loop.Client = (function($) {
         if (err) {
           cb(err);
           return;
         }
 
         this._requestCallUrlInternal(nickname, cb);
       }.bind(this));
     },
+
+    /**
+     * Adds a value to a telemetry histogram, ignoring errors.
+     *
+     * @param  {string}  histogramId Name of the telemetry histogram to update.
+     * @param  {integer} value       Value to add to the histogram.
+     */
+    _telemetryAdd: function(histogramId, value) {
+      try {
+        this.mozLoop.telemetryAdd(histogramId, value);
+      } catch (err) {
+        console.error("Error recording telemetry", err);
+      }
+    },
   };
 
   return Client;
 })(jQuery);
--- a/browser/components/loop/content/js/panel.js
+++ b/browser/components/loop/content/js/panel.js
@@ -356,27 +356,21 @@ loop.panel = (function(_, mozL10n) {
         } catch(e) {
           console.log(e);
           this.props.notifications.errorL10n("unable_retrieve_url");
           this.setState(this.getInitialState());
         }
       }
     },
 
-    _generateMailTo: function() {
-      return encodeURI([
-        "mailto:?subject=" + __("share_email_subject3") + "&",
-        "body=" + __("share_email_body3", {callUrl: this.state.callUrl})
-      ].join(""));
-    },
-
     handleEmailButtonClick: function(event) {
       this.handleLinkExfiltration(event);
-      // Note: side effect
-      document.location = event.target.dataset.mailto;
+
+      navigator.mozLoop.composeEmail(__("share_email_subject3"),
+        __("share_email_body3", { callUrl: this.state.callUrl }));
     },
 
     handleCopyButtonClick: function(event) {
       this.handleLinkExfiltration(event);
       // XXX the mozLoop object should be passed as a prop, to ease testing and
       //     using a fake implementation in UI components showcase.
       navigator.mozLoop.copyString(this.state.callUrl);
       this.setState({copied: true});
@@ -404,18 +398,17 @@ loop.panel = (function(_, mozL10n) {
       return (
         PanelLayout({summary: __("share_link_header_text")}, 
           React.DOM.div({className: "invite"}, 
             React.DOM.input({type: "url", value: this.state.callUrl, readOnly: "true", 
                    onCopy: this.handleLinkExfiltration, 
                    className: inputCSSClass}), 
             React.DOM.p({className: "btn-group url-actions"}, 
               React.DOM.button({className: "btn btn-email", disabled: !this.state.callUrl, 
-                onClick: this.handleEmailButtonClick, 
-                'data-mailto': this._generateMailTo()}, 
+                onClick: this.handleEmailButtonClick}, 
                 __("share_button")
               ), 
               React.DOM.button({className: "btn btn-copy", disabled: !this.state.callUrl, 
                 onClick: this.handleCopyButtonClick}, 
                 this.state.copied ? __("copied_url_button") :
                                      __("copy_url_button")
               )
             )
@@ -525,25 +518,22 @@ loop.panel = (function(_, mozL10n) {
   /**
    * Panel initialisation.
    */
   function init() {
     // Do the initial L10n setup, we do this before anything
     // else to ensure the L10n environment is setup correctly.
     mozL10n.initialize(navigator.mozLoop);
 
-    var client = new loop.Client({
-      baseServerUrl: navigator.mozLoop.serverUrl
-    });
+    var client = new loop.Client();
     var notifications = new sharedModels.NotificationCollection()
 
     React.renderComponent(PanelView({
       client: client, 
-      notifications: notifications}
-    ), document.querySelector("#main"));
+      notifications: notifications}), document.querySelector("#main"));
 
     document.body.classList.add(loop.shared.utils.getTargetPlatform());
     document.body.setAttribute("dir", mozL10n.getDirection());
 
     // Notify the window that we've finished initalization and initial layout
     var evtObject = document.createEvent('Event');
     evtObject.initEvent('loopPanelInitialized', true, false);
     window.dispatchEvent(evtObject);
--- a/browser/components/loop/content/js/panel.jsx
+++ b/browser/components/loop/content/js/panel.jsx
@@ -356,27 +356,21 @@ loop.panel = (function(_, mozL10n) {
         } catch(e) {
           console.log(e);
           this.props.notifications.errorL10n("unable_retrieve_url");
           this.setState(this.getInitialState());
         }
       }
     },
 
-    _generateMailTo: function() {
-      return encodeURI([
-        "mailto:?subject=" + __("share_email_subject3") + "&",
-        "body=" + __("share_email_body3", {callUrl: this.state.callUrl})
-      ].join(""));
-    },
-
     handleEmailButtonClick: function(event) {
       this.handleLinkExfiltration(event);
-      // Note: side effect
-      document.location = event.target.dataset.mailto;
+
+      navigator.mozLoop.composeEmail(__("share_email_subject3"),
+        __("share_email_body3", { callUrl: this.state.callUrl }));
     },
 
     handleCopyButtonClick: function(event) {
       this.handleLinkExfiltration(event);
       // XXX the mozLoop object should be passed as a prop, to ease testing and
       //     using a fake implementation in UI components showcase.
       navigator.mozLoop.copyString(this.state.callUrl);
       this.setState({copied: true});
@@ -404,18 +398,17 @@ loop.panel = (function(_, mozL10n) {
       return (
         <PanelLayout summary={__("share_link_header_text")}>
           <div className="invite">
             <input type="url" value={this.state.callUrl} readOnly="true"
                    onCopy={this.handleLinkExfiltration}
                    className={inputCSSClass} />
             <p className="btn-group url-actions">
               <button className="btn btn-email" disabled={!this.state.callUrl}
-                onClick={this.handleEmailButtonClick}
-                data-mailto={this._generateMailTo()}>
+                onClick={this.handleEmailButtonClick}>
                 {__("share_button")}
               </button>
               <button className="btn btn-copy" disabled={!this.state.callUrl}
                 onClick={this.handleCopyButtonClick}>
                 {this.state.copied ? __("copied_url_button") :
                                      __("copy_url_button")}
               </button>
             </p>
@@ -525,25 +518,22 @@ loop.panel = (function(_, mozL10n) {
   /**
    * Panel initialisation.
    */
   function init() {
     // Do the initial L10n setup, we do this before anything
     // else to ensure the L10n environment is setup correctly.
     mozL10n.initialize(navigator.mozLoop);
 
-    var client = new loop.Client({
-      baseServerUrl: navigator.mozLoop.serverUrl
-    });
+    var client = new loop.Client();
     var notifications = new sharedModels.NotificationCollection()
 
     React.renderComponent(<PanelView
       client={client}
-      notifications={notifications}
-    />, document.querySelector("#main"));
+      notifications={notifications} />, document.querySelector("#main"));
 
     document.body.classList.add(loop.shared.utils.getTargetPlatform());
     document.body.setAttribute("dir", mozL10n.getDirection());
 
     // Notify the window that we've finished initalization and initial layout
     var evtObject = document.createEvent('Event');
     evtObject.initEvent('loopPanelInitialized', true, false);
     window.dispatchEvent(evtObject);
--- a/browser/components/loop/test/desktop-local/client_test.js
+++ b/browser/components/loop/test/desktop-local/client_test.js
@@ -29,17 +29,18 @@ describe("loop.Client", function() {
     fakeToken = "fakeTokenText";
     mozLoop = {
       getLoopCharPref: sandbox.stub()
         .returns(null)
         .withArgs("hawk-session-token")
         .returns(fakeToken),
       ensureRegistered: sinon.stub().callsArgWith(0, null),
       noteCallUrlExpiry: sinon.spy(),
-      hawkRequest: sinon.stub()
+      hawkRequest: sinon.stub(),
+      telemetryAdd: sinon.spy(),
     };
     // Alias for clearer tests.
     hawkRequestStub = mozLoop.hawkRequest;
     client = new loop.Client({
       mozLoop: mozLoop
     });
   });
 
@@ -151,16 +152,40 @@ describe("loop.Client", function() {
           hawkRequestStub.callsArgWith(3, null,
             JSON.stringify(callUrlData));
 
           client.requestCallUrl("foo", callback);
 
           sinon.assert.notCalled(mozLoop.noteCallUrlExpiry);
         });
 
+      it("should call mozLoop.telemetryAdd when the request succeeds",
+        function(done) {
+          var callUrlData = {
+            "callUrl": "fakeCallUrl",
+            "expiresAt": 60
+          };
+
+          // Sets up the hawkRequest stub to trigger the callback with no error
+          // and the url.
+          hawkRequestStub.callsArgWith(3, null,
+            JSON.stringify(callUrlData));
+
+          client.requestCallUrl("foo", function(err) {
+            expect(err).to.be.null;
+
+            sinon.assert.calledOnce(mozLoop.telemetryAdd);
+            sinon.assert.calledWith(mozLoop.telemetryAdd,
+                                    "LOOP_CLIENT_CALL_URL_REQUESTS_SUCCESS",
+                                    true);
+
+            done();
+          });
+        });
+
       it("should send an error when the request fails", function() {
         // Sets up the hawkRequest stub to trigger the callback with
         // an error
         hawkRequestStub.callsArgWith(3, fakeErrorRes);
 
         client.requestCallUrl("foo", callback);
 
         sinon.assert.calledOnce(callback);
@@ -176,11 +201,29 @@ describe("loop.Client", function() {
 
         client.requestCallUrl("foo", callback);
 
         sinon.assert.calledOnce(callback);
         sinon.assert.calledWithMatch(callback, sinon.match(function(err) {
           return /Invalid data received/.test(err.message);
         }));
       });
+
+      it("should call mozLoop.telemetryAdd when the request fails",
+        function(done) {
+          // Sets up the hawkRequest stub to trigger the callback with
+          // an error
+          hawkRequestStub.callsArgWith(3, fakeErrorRes);
+
+          client.requestCallUrl("foo", function(err) {
+            expect(err).not.to.be.null;
+
+            sinon.assert.calledOnce(mozLoop.telemetryAdd);
+            sinon.assert.calledWith(mozLoop.telemetryAdd,
+                                    "LOOP_CLIENT_CALL_URL_REQUESTS_SUCCESS",
+                                    false);
+
+            done();
+          });
+        });
     });
   });
 });
--- a/browser/components/loop/test/desktop-local/conversation_test.js
+++ b/browser/components/loop/test/desktop-local/conversation_test.js
@@ -15,19 +15,16 @@ describe("loop.conversation", function()
 
   beforeEach(function() {
     sandbox = sinon.sandbox.create();
     sandbox.useFakeTimers();
     notifications = new loop.shared.models.NotificationCollection();
 
     navigator.mozLoop = {
       doNotDisturb: true,
-      get serverUrl() {
-        return "http://example.com";
-      },
       getStrings: function() {
         return JSON.stringify({textContent: "fakeText"});
       },
       get locale() {
         return "en-US";
       },
       setLoopCharPref: sandbox.stub(),
       getLoopCharPref: sandbox.stub(),
--- a/browser/components/loop/test/desktop-local/panel_test.js
+++ b/browser/components/loop/test/desktop-local/panel_test.js
@@ -27,29 +27,27 @@ describe("loop.panel", function() {
     // https://github.com/cjohansen/Sinon.JS/issues/393
     fakeXHR.xhr.onCreate = function (xhr) {
       requests.push(xhr);
     };
     notifications = new loop.shared.models.NotificationCollection();
 
     navigator.mozLoop = {
       doNotDisturb: true,
-      get serverUrl() {
-        return "http://example.com";
-      },
       getStrings: function() {
         return JSON.stringify({textContent: "fakeText"});
       },
       get locale() {
         return "en-US";
       },
       setLoopCharPref: sandbox.stub(),
       getLoopCharPref: sandbox.stub().returns("unseen"),
       copyString: sandbox.stub(),
-      noteCallUrlExpiry: sinon.spy()
+      noteCallUrlExpiry: sinon.spy(),
+      composeEmail: sinon.spy()
     };
 
     document.mozL10n.initialize(navigator.mozLoop);
   });
 
   afterEach(function() {
     delete navigator.mozLoop;
     sandbox.restore();
@@ -338,26 +336,25 @@ describe("loop.panel", function() {
       });
 
       it("should reset all pending notifications", function() {
         sinon.assert.calledOnce(view.props.notifications.reset);
       });
 
       it("should display a share button for email", function() {
         fakeClient.requestCallUrl = sandbox.stub();
-        var mailto = 'mailto:?subject=email-subject&body=http://example.com';
         var view = TestUtils.renderIntoDocument(loop.panel.CallUrlResult({
           notifications: notifications,
           client: fakeClient
         }));
         view.setState({pending: false, callUrl: "http://example.com"});
 
         TestUtils.findRenderedDOMComponentWithClass(view, "btn-email");
-        expect(view.getDOMNode().querySelector(".btn-email").dataset.mailto)
-              .to.equal(encodeURI(mailto));
+        TestUtils.Simulate.click(view.getDOMNode().querySelector(".btn-email"));
+        sinon.assert.calledOnce(navigator.mozLoop.composeEmail);
       });
 
       it("should feature a copy button capable of copying the call url when clicked", function() {
         fakeClient.requestCallUrl = sandbox.stub();
         var view = TestUtils.renderIntoDocument(loop.panel.CallUrlResult({
           notifications: notifications,
           client: fakeClient
         }));
@@ -403,17 +400,16 @@ describe("loop.panel", function() {
           }));
           view.setState({
             pending: false,
             copied: false,
             callUrl: "http://example.com",
             callUrlExpiry: 6000
           });
 
-          view.getDOMNode().querySelector(".btn-email").dataset.mailto = "#";
           TestUtils.Simulate.click(view.getDOMNode().querySelector(".btn-email"));
 
           sinon.assert.calledOnce(navigator.mozLoop.noteCallUrlExpiry);
           sinon.assert.calledWithExactly(navigator.mozLoop.noteCallUrlExpiry,
             6000);
         });
 
       it("should note the call url expiry when the url is copied manually",
--- a/browser/components/loop/test/mochitest/browser.ini
+++ b/browser/components/loop/test/mochitest/browser.ini
@@ -11,8 +11,10 @@ skip-if = e10s
 [browser_LoopContacts.js]
 [browser_mozLoop_appVersionInfo.js]
 [browser_mozLoop_prefs.js]
 [browser_mozLoop_doNotDisturb.js]
 [browser_mozLoop_softStart.js]
 skip-if = buildapp == 'mulet'
 [browser_toolbarbutton.js]
 [browser_mozLoop_pluralStrings.js]
+[browser_mozLoop_telemetry.js]
+skip-if = e10s
new file mode 100644
--- /dev/null
+++ b/browser/components/loop/test/mochitest/browser_mozLoop_telemetry.js
@@ -0,0 +1,36 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/*
+ * This file contains tests for the mozLoop telemetry API.
+ */
+
+add_task(loadLoopPanel);
+
+/**
+ * Tests that boolean histograms exist and can be updated.
+ */
+add_task(function* test_mozLoop_telemetryAdd_boolean() {
+  for (let histogramId of [
+    "LOOP_CLIENT_CALL_URL_REQUESTS_SUCCESS",
+  ]) {
+    let snapshot = Services.telemetry.getHistogramById(histogramId).snapshot();
+
+    let initialFalseCount = snapshot.counts[0];
+    let initialTrueCount = snapshot.counts[1];
+
+    for (let value of [false, false, true]) {
+      gMozLoopAPI.telemetryAdd(histogramId, value);
+    }
+
+    // The telemetry service updates histograms asynchronously, so we need to
+    // poll for the final values and time out otherwise.
+    info("Waiting for update of " + histogramId);
+    do {
+      yield new Promise(resolve => setTimeout(resolve, 50));
+      snapshot = Services.telemetry.getHistogramById(histogramId).snapshot();
+    } while (snapshot.counts[0] == initialFalseCount + 2 &&
+             snapshot.counts[1] == initialTrueCount + 1);
+    ok(true, "Correctly updated " + histogramId);
+  }
+});
--- a/browser/components/loop/test/shared/models_test.js
+++ b/browser/components/loop/test/shared/models_test.js
@@ -51,31 +51,23 @@ describe("loop.shared.models", function(
       it("should require a sdk option", function() {
         expect(function() {
           new sharedModels.ConversationModel({}, {});
         }).to.Throw(Error, /missing required sdk/);
       });
     });
 
     describe("constructed", function() {
-      var conversation, fakeClient, fakeBaseServerUrl,
-          requestCallInfoStub, requestCallsInfoStub;
+      var conversation;
 
       beforeEach(function() {
         conversation = new sharedModels.ConversationModel({}, {
           sdk: fakeSDK
         });
         conversation.set("loopToken", "fakeToken");
-        fakeBaseServerUrl = "http://fakeBaseServerUrl";
-        fakeClient = {
-          requestCallInfo: sandbox.stub(),
-          requestCallsInfo: sandbox.stub()
-        };
-        requestCallInfoStub = fakeClient.requestCallInfo;
-        requestCallsInfoStub = fakeClient.requestCallsInfo;
       });
 
       describe("#incoming", function() {
         it("should trigger a `call:incoming` event", function(done) {
           conversation.once("call:incoming", function() {
             done();
           });
 
--- a/browser/components/loop/test/xpcshell/head.js
+++ b/browser/components/loop/test/xpcshell/head.js
@@ -21,16 +21,17 @@ const kServerPushUrl = "http://localhost
 const kEndPointUrl = "http://example.com/fake";
 const kUAID = "f47ac11b-58ca-4372-9567-0e02b2c3d479";
 
 // Fake loop server
 var loopServer;
 
 // Ensure loop is always enabled for tests
 Services.prefs.setBoolPref("loop.enabled", true);
+Services.prefs.setBoolPref("loop.throttled", false);
 
 function setupFakeLoopServer() {
   loopServer = new HttpServer();
   loopServer.start(-1);
 
   Services.prefs.setCharPref("services.push.serverURL", kServerPushUrl);
 
   Services.prefs.setCharPref("loop.server",
--- a/browser/components/loop/ui/ui-showcase.js
+++ b/browser/components/loop/ui/ui-showcase.js
@@ -123,31 +123,31 @@
               React.DOM.strong(null, "Note:"), " 332px wide."
             ), 
             Example({summary: "Call URL retrieved", dashed: "true", style: {width: "332px"}}, 
               PanelView({client: mockClient, notifications: notifications, 
                          callUrl: "http://invalid.example.url/"})
             ), 
             Example({summary: "Call URL retrieved - authenticated", dashed: "true", style: {width: "332px"}}, 
               PanelView({client: mockClient, notifications: notifications, 
-                         callUrl: "http://invalid.example.url/",
+                         callUrl: "http://invalid.example.url/", 
                          userProfile: {email: "test@example.com"}})
             ), 
             Example({summary: "Pending call url retrieval", dashed: "true", style: {width: "332px"}}, 
               PanelView({client: mockClient, notifications: notifications})
             ), 
             Example({summary: "Pending call url retrieval - authenticated", dashed: "true", style: {width: "332px"}}, 
-              PanelView({client: mockClient, notifications: notifications,
+              PanelView({client: mockClient, notifications: notifications, 
                          userProfile: {email: "test@example.com"}})
             ), 
             Example({summary: "Error Notification", dashed: "true", style: {width: "332px"}}, 
               PanelView({client: mockClient, notifications: errNotifications})
-            ),
+            ), 
             Example({summary: "Error Notification - authenticated", dashed: "true", style: {width: "332px"}}, 
-              PanelView({client: mockClient, notifications: errNotifications,
+              PanelView({client: mockClient, notifications: errNotifications, 
                          userProfile: {email: "test@example.com"}})
             )
           ), 
 
           Section({name: "IncomingCallView"}, 
             Example({summary: "Default / incoming video call", dashed: "true", style: {width: "280px"}}, 
               React.DOM.div({className: "fx-embedded"}, 
                 IncomingCallView({model: mockConversationModel, 
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -2282,16 +2282,17 @@ let E10SUINotification = {
     } else {
       let e10sPromptShownCount = 0;
       try {
         e10sPromptShownCount = Services.prefs.getIntPref("browser.displayedE10SPrompt");
       } catch(e) {}
 
       if (!Services.appinfo.inSafeMode &&
           !Services.appinfo.accessibilityEnabled &&
+          !Services.appinfo.keyboardMayHaveIME &&
           e10sPromptShownCount < 5) {
         Services.tm.mainThread.dispatch(() => {
           try {
             this._showE10SPrompt();
             Services.prefs.setIntPref("browser.displayedE10SPrompt", e10sPromptShownCount + 1);
           } catch (ex) {
             Cu.reportError("Failed to show e10s prompt: " + ex);
           }
--- a/browser/components/search/test/browser_amazon.js
+++ b/browser/components/search/test/browser_amazon.js
@@ -24,17 +24,17 @@ function test() {
   url = engine.getSubmission("foo", "application/x-suggestions+json").uri.spec;
   is(url, "https://completion.amazon.com/search/complete?q=foo&search-alias=aps&mkt=1", "Check search suggestion URL for 'foo'");
 
   // Check all other engine properties.
   const EXPECTED_ENGINE = {
     name: "Amazon.com",
     alias: null,
     description: "Amazon.com Search",
-    searchForm: "http://www.amazon.com/",
+    searchForm: "http://www.amazon.com/exec/obidos/external-search/?field-keywords=&mode=blended&tag=mozilla-20&sourceid=Mozilla-search",
     type: Ci.nsISearchEngine.TYPE_MOZSEARCH,
     hidden: false,
     wrappedJSObject: {
       queryCharset: "UTF-8",
       "_iconURL": "data:image/x-icon;base64,AAABAAIAEBAAAAAAAAC0AQAAJgAAACAgAAAAAAAA6QIAANoBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAF7SURBVDjLlZPLasJAFIaFRF+iVV+h6hO0GF+gVB9AaHwDt64qCG03tQgtdCFIuyhUelmGli66MXThSt24kNiFBUlAYi6ezjnNxSuawB/ITP7v/HNmJgQAEaZzpgHs/gwcTyTEXuXl2U6nA8ViEbK5HKler28CVRAwnB9ptVrAh8MrQuCaZ4iA8fzIqSgCxwzpTIaSuN/RWGwdYLwCUBQFZFkGSZLgqdmEE7YEN8VOAKyaSKUW4nNBAFmnYiKZpDRX1WqwBBzP089n5f/NEQsFL4WqqtsBWJlzDAJr5PwSMM1awEzzdxIbGI3Hvc6jCZeVFgRQRwpY7Qcw3ktgfpR8wLRxCPaot/X4GS95MppfF6DX9n2A3f+kAZycaT8bAZjU6r6B/duD6d3BYg9wQq/tkYzHY1blEiz5lmQyGc95mrO6r2CxgpjCBXgNsJVviolpXJiraeOIjJRE10juUa4sR8V+mO17VvmGqtuOcdNlwut8zTQJcJ0njifyB2bgTdKh6w4BAAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACsElEQVRYw71XQWsTURBe2LQgeNKLB+tVemt6txcteNSD/QGC6VEIGDx5s+eKPQqFgJhLNdFLBWMP7cU0oSAWjB70koC9WHbVQ5SO8+XtS14mr7svyaYDH9m87Jv55puZt1nPi4yIzjMeMj7T9OwjI88455nGC1cZX+nsDESumJmPFDwIAqrX6z00Gg1qt9vjkJgFgUeuO16Vy3RjeZkyMzM9+MY1fsM9I9h9zyV7ZAznZrA4FAoFVwJ1z+WuOysrg1lnMolkHJX4k0igzI5sARYWF7vEZEk0rvO6iyUSuJfLJUqM7zYSqRDIra4OOUZPmNZsNrsl8UVTpkJAjh1GzmaSpJ8mAWmYeZB5urHRhW5SNOfUCCDo47W1bvPZsp2qAhipy3Nz1kaLG8dUCEBqM5AvpgElqFar01NgIZsdco7Zb7VasU2YigIYL5tjqCL7Q5YkFQXKlcqQ7DbHthIALk/IWAKor82xPIhshxWABCYioDMz51sexcVi0XoG4DPLIyvJjkTArK3scDQnRvO0MdTrUHGiKZCP4tNgO6BAEI08EQH9Z2Qow0hyPypJGIa9p6JWKCn4SA8jSKmJIDgyRvPJkcRxjfUwNGr/i8+Mo32iHzWiThBD4NM60bet9P77/ubA728RlTjMiwiH6zEEfvIrwdZFtQmMJ7W/ofIDBZD5m3mVZGwJcOP2kmILIlCkE45HoPWurwCSg0+UQRD4ZyXxId+T7gQb9+4q9sioY5ltrOG3L5vqXiiJffDx/aUi83ZJ7jr2ohcEu8Hh6/m+I7OWGiVxbWKHsz+O3vSOakqFQdsFgQeJUiKD7Wv9YKXBgCeSUC3v2kM5EJhlHDh3NcgcPlG1BXZu98sDmTuBa4fsMnz9fniJUaGzs+eMC540XuR0aDO2L8Y3qPyMcdOM+R/8XcqRA3qp9gAAAABJRU5ErkJggg==",
       _urls : [
         {
           type: "application/x-suggestions+json",
--- a/browser/components/search/test/browser_bing.js
+++ b/browser/components/search/test/browser_bing.js
@@ -34,17 +34,17 @@ function test() {
   url = engine.getSubmission("foo", "application/x-suggestions+json").uri.spec;
   is(url, "http://api.bing.com/osjson.aspx?query=foo&form=OSDJAS&language=" + getLocale(), "Check search suggestion URL for 'foo'");
 
   // Check all other engine properties.
   const EXPECTED_ENGINE = {
     name: "Bing",
     alias: null,
     description: "Bing. Search by Microsoft.",
-    searchForm: "http://www.bing.com/search",
+    searchForm: "http://www.bing.com/search?q=&pc=MOZI",
     type: Ci.nsISearchEngine.TYPE_MOZSEARCH,
     hidden: false,
     wrappedJSObject: {
       queryCharset: "UTF-8",
       "_iconURL": "data:image/x-icon;base64,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",
       _urls : [
         {
           type: "application/x-suggestions+json",
--- a/browser/components/search/test/browser_google.js
+++ b/browser/components/search/test/browser_google.js
@@ -81,17 +81,18 @@ function test() {
   is(Services.search.parseSubmissionURL(alternateBase).terms, "foo",
      "Check alternate domain");
 
   // Check all other engine properties.
   const EXPECTED_ENGINE = {
     name: "Google",
     alias: null,
     description: "Google Search",
-    searchForm: "https://www.google.com/",
+    searchForm: "https://www.google.com/search?q=&ie=utf-8&oe=utf-8&aq=t&rls=" +
+                distributionID + ":" + getLocale() + ":" + MOZ_OFFICIAL + "&client=" + GOOGLE_CLIENT,
     type: Ci.nsISearchEngine.TYPE_MOZSEARCH,
     hidden: false,
     wrappedJSObject: {
       queryCharset: "UTF-8",
       "_iconURL": "data:image/x-icon;base64,AAABAAIAEBAAAAAAAAB9AQAAJgAAACAgAAAAAAAA8gIAAKMBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAFESURBVDjLpZNJSwNBEIXnt4lE4kHxovgT9BDwJHqPy0HEEOJBiAuCRg+KUdC4QS4KrpC4gCBGE3NQ48JsnZ6eZ3UOM6gjaePhQU93v6+qq2q0pqgeJj2S8EdJT1hr0OxBtKCD5iEd8QxDYpvhvOBAuMDKURX9C9aPu4GA1GEVkzvMg10UBfYveWAWgYAP00V01fa+R9M2bA51wJvhIn3qR+ybt3D3JNQBE5sMjCIOLFpoHzOwdsLRO22qA6R6kiZiWwxUvy/PUQZIhYZ1vFM9cvcOOsYNdcBgysISdSJBnZjJMlR0Fw8vAp0xoz5gao/h+NZBy4i/10XGwrPA+hmvDyhVRG2Avu/LwcrkFADZa16L1h330w1RNgc3DiJzCpPYRm1bpveXX11clQR28xwblHpk1vq1iP/5mcoS0CoXDZiL0vsJ+dzfl+3T/VYAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAK5SURBVFjDxVfrSxRRFJ9/Jta/oyWjF5XQm6D6EkHRgygIIgjUTcueVgqVWSRRkppEUQYWWB8ye1iGWilWlo/Ude489s7M6Zw7D9dlt53dmd29cFiWvXvO77x+51xpaaUsoSxBaUWZQ4ECy5xji2xKZDyCMlMEw6lCNiOSgwZKJK1SkcKeSealfP64t0mBjl4Ow39MkDUL0p2RSROOtqhZdeUEYM1pBl39XCg/fEeFtWcY7G9W4csvUxjlBkCsQ4Nt9QyWVfvT6RsAKXw3aoDGATZeYIt+W1kjw7cJG0RctWDTRebbKd8A6h5pwsDb70ba3w/eUr3wt/cmwgfw6Yft4TNMQaY7o1P2ncm4FT4ANQH/jQBJ2xv7kqIXEADDql8eS3+n8bku7oxNm+EDIM/dU92upb3T/NJGeaNbDx/AsbsLRUY5Xn92caWXY5d8RV6gWllxSg4fAEnTC90DQW13BLlgXR2D3dcUeDVkwOthA1bXspxILWcm3HdThcfvufB26LcJpkOEAz9NKI/lzqpSEC7feol5EWnpSeSlIxCALUkApmULdjUqxQVAQnl3D/X/yQda4QBEq2TYc12By091MQ17Bg3R88nHKlQbVmHvj89awNBLYrwT9zXY2aBAxTkGFdiSxP/Jp6FLDw+AS7GfsdJTJ2EqSO5khD43nGfBARy/ZxOQgZHe7GPM1jzUvChUtmnBAXQPcKGMJp3fdFGq6NByEhiAO4b/YptFfQJwNyQ/bZkVQGcf90Ja25ndIyrKBOa/f8wIpwi3X1G8UcxNu7ozUS7tiH0jBswwS3RIaF1w6LYKU/ML2+8sGnjygQswtKrVIy/Qd9qQP6LnO64q4fPAKpxyZIymHo1jWk6p1ag2BsdNwQMHcC+M5kHFJX+YlPxpVlbCx2mZ5DzPI04k4kUwHHdskU3pH76iftG8yWlkAAAAAElFTkSuQmCC",
       _urls : [
         {
           type: "application/x-suggestions+json",
@@ -170,19 +171,14 @@ function test() {
               "name": "client",
               "falseValue": "firefox",
               "trueValue": GOOGLE_CLIENT,
               "condition": "defaultEngine",
               "mozparam": true,
             },
           },
         },
-        {
-          type: "text/html",
-          method: "GET",
-          template: "https://www.google.com/",
-        },
       ],
     },
   };
 
   isSubObjectOf(EXPECTED_ENGINE, engine, "Google");
 }
--- a/browser/components/search/test/browser_yahoo.js
+++ b/browser/components/search/test/browser_yahoo.js
@@ -24,17 +24,17 @@ function test() {
   url = engine.getSubmission("foo", "application/x-suggestions+json").uri.spec;
   is(url, "https://search.yahoo.com/sugg/ff?output=fxjson&appid=ffd&command=foo", "Check search suggestion URL for 'foo'");
 
   // Check all other engine properties.
   const EXPECTED_ENGINE = {
     name: "Yahoo",
     alias: null,
     description: "Yahoo Search",
-    searchForm: "https://search.yahoo.com/",
+    searchForm: "https://search.yahoo.com/search?p=&ei=UTF-8&fr=moz35",
     type: Ci.nsISearchEngine.TYPE_MOZSEARCH,
     hidden: false,
     wrappedJSObject: {
       queryCharset: "UTF-8",
       "_iconURL": "data:image/x-icon;base64,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",
       _urls : [
         {
           type: "application/x-suggestions+json",
--- a/browser/devtools/debugger/test/browser.ini
+++ b/browser/devtools/debugger/test/browser.ini
@@ -262,16 +262,17 @@ skip-if = os == "linux" || e10s # Bug 88
 [browser_dbg_terminate-on-tab-close.js]
 [browser_dbg_tracing-01.js]
 [browser_dbg_tracing-02.js]
 [browser_dbg_tracing-03.js]
 [browser_dbg_tracing-04.js]
 [browser_dbg_tracing-05.js]
 [browser_dbg_tracing-06.js]
 [browser_dbg_tracing-07.js]
+[browser_dbg_tracing-08.js]
 [browser_dbg_variables-view-01.js]
 [browser_dbg_variables-view-02.js]
 [browser_dbg_variables-view-03.js]
 [browser_dbg_variables-view-04.js]
 [browser_dbg_variables-view-05.js]
 [browser_dbg_variables-view-accessibility.js]
 [browser_dbg_variables-view-data.js]
 [browser_dbg_variables-view-edit-cancel.js]
new file mode 100644
--- /dev/null
+++ b/browser/devtools/debugger/test/browser_dbg_tracing-08.js
@@ -0,0 +1,59 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/**
+ * Test that tracing about:config doesn't produce errors.
+ */
+
+const TAB_URL = "about:config";
+
+let gPanel, gDoneChecks;
+
+function test() {
+  gDoneChecks = promise.defer();
+  const tracerPref = promise.defer();
+  const configPref = promise.defer();
+  SpecialPowers.pushPrefEnv({'set': [["devtools.debugger.tracer", true]]}, tracerPref.resolve);
+  SpecialPowers.pushPrefEnv({'set': [["general.warnOnAboutConfig", false]]}, configPref.resolve);
+  promise.all([tracerPref.promise, configPref.promise]).then(() => {
+    initDebugger(TAB_URL).then(([,, aPanel]) => {
+      gPanel = aPanel;
+      gPanel.panelWin.gClient.addOneTimeListener("traces", testTraceLogs);
+    }).then(() => startTracing(gPanel))
+      .then(generateTrace)
+      .then(() => waitForClientEvents(gPanel, "traces"))
+      .then(() => gDoneChecks.promise)
+      .then(() => stopTracing(gPanel))
+      .then(resetPreferences)
+      .then(() => closeDebuggerAndFinish(gPanel))
+      .then(null, aError => {
+        ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
+      });
+  });
+}
+
+function testTraceLogs(name, packet) {
+  info("Traces: " + packet.traces.length);
+  ok(packet.traces.length > 0, "Got some traces.");
+  ok(packet.traces.every(t => t.type != "enteredFrame" || !!t.location),
+     "All enteredFrame traces contain location.");
+  gDoneChecks.resolve();
+}
+
+function generateTrace(name, packet) {
+  // Interact with the page to cause JS execution.
+  let search = content.document.getElementById("textbox");
+  info("Interacting with the page.");
+  search.value = "devtools";
+}
+
+function resetPreferences() {
+  const deferred = promise.defer();
+  SpecialPowers.popPrefEnv(() => SpecialPowers.popPrefEnv(deferred.resolve));
+  return deferred.promise;
+}
+
+registerCleanupFunction(function() {
+  gPanel = null;
+  gDoneChecks = null;
+});
--- a/browser/devtools/styleinspector/test/browser_ruleview_livepreview.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_livepreview.js
@@ -23,28 +23,28 @@ const TEST_DATA = [
 ];
 
 let test = asyncTest(function*() {
   yield addTab("data:text/html;charset=utf-8,test rule view live preview on user changes");
 
   let style = '#testid {display:block;}';
   let styleNode = addStyle(content.document, style);
   content.document.body.innerHTML = '<div id="testid">Styled Node</div><span>inline element</span>';
-  let testElement = getNode("#testid");
 
   let {toolbox, inspector, view} = yield openRuleView();
   yield selectNode("#testid", inspector);
 
   for (let data of TEST_DATA) {
-    yield testLivePreviewData(data, view, testElement);
+    yield testLivePreviewData(data, view, "#testid");
   }
 });
 
 
-function* testLivePreviewData(data, ruleView, testElement) {
+function* testLivePreviewData(data, ruleView, selector) {
+  let testElement = getNode(selector);
   let idRuleEditor = getRuleViewRuleEditor(ruleView, 1);
   let propEditor = idRuleEditor.rule.textProps[0].editor;
 
   info("Focusing the property value inplace-editor");
   let editor = yield focusEditableField(propEditor.valueSpan);
   is(inplaceEditor(propEditor.valueSpan), editor, "The focused editor is the value");
 
   info("Enter a value in the editor")
@@ -52,15 +52,18 @@ function* testLivePreviewData(data, rule
     EventUtils.sendChar(ch, ruleView.doc.defaultView);
   }
   if (data.escape) {
     EventUtils.synthesizeKey("VK_ESCAPE", {});
   } else {
     EventUtils.synthesizeKey("VK_RETURN", {});
   }
 
+  // This wait is an orange waiting to happen, but it might take a few event
+  // loop spins in either the client or parent process before we see the
+  // updated value.
   yield wait(1);
 
   // While the editor is still focused in, the display should have changed already
-  is(content.getComputedStyle(testElement).display,
+  is((yield getComputedStyleProperty(selector, null, "display")),
     data.expected,
     "Element should be previewed as " + data.expected);
 }
--- a/browser/devtools/styleinspector/test/browser_ruleview_pseudo-element.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_pseudo-element.js
@@ -16,21 +16,22 @@ let test = asyncTest(function*() {
   yield testTopRight(inspector, view);
   yield testBottomRight(inspector, view);
   yield testBottomLeft(inspector, view);
   yield testParagraph(inspector, view);
   yield testBody(inspector, view);
 });
 
 function* testTopLeft(inspector, view) {
+  let selector = "#topleft";
   let {
     rules,
     element,
     elementStyle
-  } = yield assertPseudoElementRulesNumbers("#topleft", inspector, view, {
+  } = yield assertPseudoElementRulesNumbers(selector, inspector, view, {
     elementRulesNb: 4,
     afterRulesNb: 1,
     beforeRulesNb: 2,
     firstLineRulesNb: 0,
     firstLetterRulesNb: 0,
     selectionRulesNb: 0
   });
 
@@ -82,45 +83,45 @@ function* testTopLeft(inspector, view) {
 
   is (firstProp, elementAfterRule.textProps[elementAfterRule.textProps.length - 2],
       "First added property is on back of array");
   is (secondProp, elementAfterRule.textProps[elementAfterRule.textProps.length - 1],
       "Second added property is on back of array");
 
   yield elementAfterRule._applyingModifications;
 
-  is(defaultView.getComputedStyle(element, ":after").getPropertyValue("background-color"),
+  is((yield getComputedStyleProperty(selector, ":after", "background-color")),
     "rgb(0, 255, 0)", "Added property should have been used.");
-  is(defaultView.getComputedStyle(element, ":after").getPropertyValue("padding-top"),
+  is((yield getComputedStyleProperty(selector, ":after", "padding-top")),
     "100px", "Added property should have been used.");
-  is(defaultView.getComputedStyle(element).getPropertyValue("padding-top"),
+  is((yield getComputedStyleProperty(selector, null, "padding-top")),
     "32px", "Added property should not apply to element");
 
   secondProp.setEnabled(false);
   yield elementAfterRule._applyingModifications;
 
-  is(defaultView.getComputedStyle(element, ":after").getPropertyValue("padding-top"), "0px",
+  is((yield getComputedStyleProperty(selector, ":after", "padding-top")), "0px",
     "Disabled property should have been used.");
-  is(defaultView.getComputedStyle(element).getPropertyValue("padding-top"), "32px",
+  is((yield getComputedStyleProperty(selector, null, "padding-top")), "32px",
     "Added property should not apply to element");
 
   secondProp.setEnabled(true);
   yield elementAfterRule._applyingModifications;
 
-  is(defaultView.getComputedStyle(element, ":after").getPropertyValue("padding-top"), "100px",
+  is((yield getComputedStyleProperty(selector, ":after", "padding-top")), "100px",
     "Enabled property should have been used.");
-  is(defaultView.getComputedStyle(element).getPropertyValue("padding-top"), "32px",
+  is((yield getComputedStyleProperty(selector, null, "padding-top")), "32px",
     "Added property should not apply to element");
 
   firstProp = elementRuleView.addProperty("background-color", "rgb(0, 0, 255)", "");
   yield elementRule._applyingModifications;
 
-  is(defaultView.getComputedStyle(element).getPropertyValue("background-color"), "rgb(0, 0, 255)",
+  is((yield getComputedStyleProperty(selector, null, "background-color")), "rgb(0, 0, 255)",
     "Added property should have been used.");
-  is(defaultView.getComputedStyle(element, ":after").getPropertyValue("background-color"), "rgb(0, 255, 0)",
+  is((yield getComputedStyleProperty(selector, ":after", "background-color")), "rgb(0, 255, 0)",
     "Added prop does not apply to pseudo");
 }
 
 function* testTopRight(inspector, view) {
   let {
     rules,
     element,
     elementStyle
--- a/browser/devtools/styleinspector/test/doc_frame_script.js
+++ b/browser/devtools/styleinspector/test/doc_frame_script.js
@@ -68,9 +68,24 @@ addMessageListener("Test:GetStyleSheetsI
       href: sheet.href,
       isContentSheet: CssLogic.isContentStylesheet(sheet)
     });
   }
 
   sendAsyncMessage("Test:GetStyleSheetsInfoForNode", sheets);
 });
 
+/**
+ * Get the property value from the computed style for an element.
+ * @param {Object} data Expects a data object with the following properties
+ * - {String} selector: The selector used to obtain the element.
+ * - {String} pseudo: pseudo id to query, or null.
+ * - {String} name: name of the property
+ * @return {String} The value, if found, null otherwise
+ */
+addMessageListener("Test:GetComputedStylePropertyValue", function(msg) {
+  let {selector, pseudo, name} = msg.data;
+  let element = content.document.querySelector(selector);
+  let value = content.document.defaultView.getComputedStyle(element, pseudo).getPropertyValue(name);
+  sendAsyncMessage("Test:GetComputedStylePropertyValue", value);
+});
+
 let dumpn = msg => dump(msg + "\n");
--- a/browser/devtools/styleinspector/test/head.js
+++ b/browser/devtools/styleinspector/test/head.js
@@ -381,16 +381,30 @@ function executeInContent(name, data={},
   if (expectResponse) {
     return waitForContentMessage(name);
   } else {
     return promise.resolve();
   }
 }
 
 /**
+ * Send an async message to the frame script and get back the requested
+ * computed style property.
+ * @param {String} selector: The selector used to obtain the element.
+ * @param {String} pseudo: pseudo id to query, or null.
+ * @param {String} name: name of the property.
+ */
+function* getComputedStyleProperty(selector, pseudo, propName) {
+ return yield executeInContent("Test:GetComputedStylePropertyValue",
+                               {selector: selector,
+                                pseudo: pseudo,
+                                name: propName});
+}
+
+/**
  * Given an inplace editable element, click to switch it to edit mode, wait for
  * focus
  * @return a promise that resolves to the inplace-editor element when ready
  */
 let focusEditableField = Task.async(function*(editable, xOffset=1, yOffset=1, options={}) {
   let onFocus = once(editable.parentNode, "focus", true);
 
   info("Clicking on editable field to turn to edit mode");
--- a/browser/locales/en-US/searchplugins/amazondotcom.xml
+++ b/browser/locales/en-US/searchplugins/amazondotcom.xml
@@ -5,16 +5,15 @@
 <SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
 <ShortName>Amazon.com</ShortName>
 <Description>Amazon.com Search</Description>
 <InputEncoding>UTF-8</InputEncoding>
 <Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAC0AQAAJgAAACAgAAAAAAAA6QIAANoBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAF7SURBVDjLlZPLasJAFIaFRF+iVV+h6hO0GF+gVB9AaHwDt64qCG03tQgtdCFIuyhUelmGli66MXThSt24kNiFBUlAYi6ezjnNxSuawB/ITP7v/HNmJgQAEaZzpgHs/gwcTyTEXuXl2U6nA8ViEbK5HKler28CVRAwnB9ptVrAh8MrQuCaZ4iA8fzIqSgCxwzpTIaSuN/RWGwdYLwCUBQFZFkGSZLgqdmEE7YEN8VOAKyaSKUW4nNBAFmnYiKZpDRX1WqwBBzP089n5f/NEQsFL4WqqtsBWJlzDAJr5PwSMM1awEzzdxIbGI3Hvc6jCZeVFgRQRwpY7Qcw3ktgfpR8wLRxCPaot/X4GS95MppfF6DX9n2A3f+kAZycaT8bAZjU6r6B/duD6d3BYg9wQq/tkYzHY1blEiz5lmQyGc95mrO6r2CxgpjCBXgNsJVviolpXJiraeOIjJRE10juUa4sR8V+mO17VvmGqtuOcdNlwut8zTQJcJ0njifyB2bgTdKh6w4BAAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACsElEQVRYw71XQWsTURBe2LQgeNKLB+tVemt6txcteNSD/QGC6VEIGDx5s+eKPQqFgJhLNdFLBWMP7cU0oSAWjB70koC9WHbVQ5SO8+XtS14mr7svyaYDH9m87Jv55puZt1nPi4yIzjMeMj7T9OwjI88455nGC1cZX+nsDESumJmPFDwIAqrX6z00Gg1qt9vjkJgFgUeuO16Vy3RjeZkyMzM9+MY1fsM9I9h9zyV7ZAznZrA4FAoFVwJ1z+WuOysrg1lnMolkHJX4k0igzI5sARYWF7vEZEk0rvO6iyUSuJfLJUqM7zYSqRDIra4OOUZPmNZsNrsl8UVTpkJAjh1GzmaSpJ8mAWmYeZB5urHRhW5SNOfUCCDo47W1bvPZsp2qAhipy3Nz1kaLG8dUCEBqM5AvpgElqFar01NgIZsdco7Zb7VasU2YigIYL5tjqCL7Q5YkFQXKlcqQ7DbHthIALk/IWAKor82xPIhshxWABCYioDMz51sexcVi0XoG4DPLIyvJjkTArK3scDQnRvO0MdTrUHGiKZCP4tNgO6BAEI08EQH9Z2Qow0hyPypJGIa9p6JWKCn4SA8jSKmJIDgyRvPJkcRxjfUwNGr/i8+Mo32iHzWiThBD4NM60bet9P77/ubA728RlTjMiwiH6zEEfvIrwdZFtQmMJ7W/ofIDBZD5m3mVZGwJcOP2kmILIlCkE45HoPWurwCSg0+UQRD4ZyXxId+T7gQb9+4q9sioY5ltrOG3L5vqXiiJffDx/aUi83ZJ7jr2ohcEu8Hh6/m+I7OWGiVxbWKHsz+O3vSOakqFQdsFgQeJUiKD7Wv9YKXBgCeSUC3v2kM5EJhlHDh3NcgcPlG1BXZu98sDmTuBa4fsMnz9fniJUaGzs+eMC540XuR0aDO2L8Y3qPyMcdOM+R/8XcqRA3qp9gAAAABJRU5ErkJggg==</Image>
 <Image width="65" height="26">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAAEEAAAAaCAYAAADovjFxAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyNpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NDkxMSwgMjAxMy8xMC8yOS0xMTo0NzoxNiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjk1RjU4MDYwQkU0RDExRTNBNkI0RTM0MDNENDQ0Q0QxIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjk1RjU4MDYxQkU0RDExRTNBNkI0RTM0MDNENDQ0Q0QxIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6OTVGNTgwNUVCRTREMTFFM0E2QjRFMzQwM0Q0NDRDRDEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6OTVGNTgwNUZCRTREMTFFM0E2QjRFMzQwM0Q0NDRDRDEiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4FxGXPAAAGU0lEQVR42uyYe2xU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</Image>
 <Image width="130" height="52">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAAIIAAAA0CAYAAABGkOCVAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyNpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NDkxMSwgMjAxMy8xMC8yOS0xMTo0NzoxNiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjk1RjU4MDVDQkU0RDExRTNBNkI0RTM0MDNENDQ0Q0QxIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjk1RjU4MDVEQkU0RDExRTNBNkI0RTM0MDNENDQ0Q0QxIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6OTVGNTgwNUFCRTREMTFFM0E2QjRFMzQwM0Q0NDRDRDEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6OTVGNTgwNUJCRTREMTFFM0E2QjRFMzQwM0Q0NDRDRDEiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz5AOR4OAAAOI0lEQVR42uxcC3BU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</Image>
 <Url type="application/x-suggestions+json" method="GET" template="https://completion.amazon.com/search/complete?q={searchTerms}&amp;search-alias=aps&amp;mkt=1"/>
-<Url type="text/html" method="GET" template="http://www.amazon.com/exec/obidos/external-search/">
+<Url type="text/html" method="GET" template="http://www.amazon.com/exec/obidos/external-search/" rel="searchform">
   <Param name="field-keywords" value="{searchTerms}"/>
   <Param name="mode" value="blended"/>
   <Param name="tag" value="mozilla-20"/>
   <Param name="sourceid" value="Mozilla-search"/>
 </Url>
-<SearchForm>http://www.amazon.com/</SearchForm>
 </SearchPlugin>
--- a/browser/locales/en-US/searchplugins/bing.xml
+++ b/browser/locales/en-US/searchplugins/bing.xml
@@ -9,19 +9,18 @@
     <Image width="16" height="16">data:image/x-icon;base64,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</Image>
     <Image width="65" height="26">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAAEEAAAAaCAYAAADovjFxAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyNpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NDkxMSwgMjAxMy8xMC8yOS0xMTo0NzoxNiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkVBOTQzNENBQzQxNDExRTM5RURBRUU5NUU4QkU3NjA4IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkVBOTQzNENCQzQxNDExRTM5RURBRUU5NUU4QkU3NjA4Ij4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NzU2RTRERkZDMzc1MTFFMzlFREFFRTk1RThCRTc2MDgiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NzU2RTRFMDBDMzc1MTFFMzlFREFFRTk1RThCRTc2MDgiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz76XOiPAAAD1ElEQVR42uyYeUgVQRzH9+nLNE07kMKIiqAkSaUIMgUpyu6eHdBhVBSBZQf1R4XkP0WHFUURWBlRmGGHdkI3nWIXVHZIaNkhFXmWYni+vhPfhWHZfbvvqVjZDz7Mzs6w8+Y3v2ue3eFwPFUU5R64CG6BRqWDiReIBCvBNfAeHAXjOpoSqqV+H7AQbO1oStCTz/+VoCjONlpvDdgPelqc3x8kgMD2UEJbSTRIAkMszhfB+jhIbU8lxIIZrbjeV7b1FudngefgansqoQ5kg3cgDUwBXVthXavutoXZ61x7KuEBOAkGgESap0ijGWAeCPZwXZv0bNf0PZFObuzX7klM2Kjp9wDzQSYVcgWsAqFubD4fjAIloAE0g0sgXDN/Li1xBPt+IAcks3+KViXc6xmYbrDuGBaETVzvFegHloKzVpRQBK4bjHUB48FeUADyQDcX32pmuxPkgkr6vahaJ9P/Q3Vi0mD2fbjRdeAln4VSboIIPkdp1lzA8RjuQ1h2CA9wH4i3mh2SLc4bCQJMYozCDDEbDOVpDwPLOHZGml/KtlpSongOArV0g5lgLFguxRFVxGaP0VrCQByYA7pT+b7ie1aV8ASMBhdM5jWY3D3UgLiLpizLAfCGP3agi2/4s43RvE+jucdKbpfEdjV4reNqVSLQu1Mn3AYOxoTcFgawHIPxbLZhJsHtg0Ga/cJxVdkTdKxLlnxFL1JKvqcn4oQWMai0RAk/DcarpFjjSmpN3E2uOOX6RCuNrpTQWdPvC9ZL5uVqk3YL7mBUJ4SwLTdZx2gNb4P1vA3c1McoRZaBxXwWAWgbM0SShZN+KJ2mnqgm3MtgXE1xL1qpDiowca8IReM/ClNUMH1OpKG3YIML91DlB1jL7FDjYp56Grt1xmbRzfJcmK9VUS0ik+0OnTmbWf3WeEkbPMQSdRqVkGrxtncYDAJ7LMwNlE6mhEXXRLAdnOZYgjTfTxNLbJrvaCVI009nPRDH+0c8mMrALIrAQuFaduZeUUAcAZeliGom92kl7mSKeqbRSSyYMqSxYiqgWHpXw/l1ko+LfoXB98s1dUoTrfMEFREnjQ1nbbHE5nA4vvOCFGlxI2UsntI9MNNARn7V3KNobd/AI535AaSSirAxnjTyd2glmK6g507hDPBCsXf47qN4J5SQyELDihykAir+gT+U/KmQIi9WasKn75qYfjRvkn+bAoINAud5Pqeo+baQ5WYK2KT5EySFwe9vFF+6Win/kxAn35sls3oLzbLrpI0b3PRjsMIk5f3pYmPsSuC1WZVPrH9+hwGb0+lUOrr8EmAAiqTecoRlgJMAAAAASUVORK5CYII=</Image>
     <Image width="130" height="52">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAAIIAAAA0CAYAAABGkOCVAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyNpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NDkxMSwgMjAxMy8xMC8yOS0xMTo0NzoxNiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjc1NkU0REZEQzM3NTExRTM5RURBRUU5NUU4QkU3NjA4IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjc1NkU0REZFQzM3NTExRTM5RURBRUU5NUU4QkU3NjA4Ij4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NzU2RTRERkJDMzc1MTFFMzlFREFFRTk1RThCRTc2MDgiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NzU2RTRERkNDMzc1MTFFMzlFREFFRTk1RThCRTc2MDgiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz5lzzn9AAAIPUlEQVR42uxdCWwV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</Image>
     <Url type="application/x-suggestions+json" template="http://api.bing.com/osjson.aspx">
         <Param name="query" value="{searchTerms}"/>
         <Param name="form" value="OSDJAS"/>
         <Param name="language" value="{moz:locale}"/>
     </Url>
-    <Url type="text/html" method="GET" template="http://www.bing.com/search">
+    <Url type="text/html" method="GET" template="http://www.bing.com/search" rel="searchform">
         <Param name="q" value="{searchTerms}"/>
         <Param name="pc" value="MOZI"/>
         <MozParam name="form" condition="purpose" purpose="contextmenu" value="MOZCON"/>
         <MozParam name="form" condition="purpose" purpose="searchbar" value="MOZSBR"/>
         <MozParam name="form" condition="purpose" purpose="homepage" value="MOZSPG"/>
         <MozParam name="form" condition="purpose" purpose="keyword" value="MOZLBR"/>
         <MozParam name="form" condition="purpose" purpose="newtab" value="MOZTSB"/>
     </Url>
-    <SearchForm>http://www.bing.com/search</SearchForm>
 </SearchPlugin>
--- a/browser/locales/en-US/searchplugins/google.xml
+++ b/browser/locales/en-US/searchplugins/google.xml
@@ -5,17 +5,17 @@
 <SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
 <ShortName>Google</ShortName>
 <Description>Google Search</Description>
 <InputEncoding>UTF-8</InputEncoding>
 <Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAB9AQAAJgAAACAgAAAAAAAA8gIAAKMBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAFESURBVDjLpZNJSwNBEIXnt4lE4kHxovgT9BDwJHqPy0HEEOJBiAuCRg+KUdC4QS4KrpC4gCBGE3NQ48JsnZ6eZ3UOM6gjaePhQU93v6+qq2q0pqgeJj2S8EdJT1hr0OxBtKCD5iEd8QxDYpvhvOBAuMDKURX9C9aPu4GA1GEVkzvMg10UBfYveWAWgYAP00V01fa+R9M2bA51wJvhIn3qR+ybt3D3JNQBE5sMjCIOLFpoHzOwdsLRO22qA6R6kiZiWwxUvy/PUQZIhYZ1vFM9cvcOOsYNdcBgysISdSJBnZjJMlR0Fw8vAp0xoz5gao/h+NZBy4i/10XGwrPA+hmvDyhVRG2Avu/LwcrkFADZa16L1h330w1RNgc3DiJzCpPYRm1bpveXX11clQR28xwblHpk1vq1iP/5mcoS0CoXDZiL0vsJ+dzfl+3T/VYAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAK5SURBVFjDxVfrSxRRFJ9/Jta/oyWjF5XQm6D6EkHRgygIIgjUTcueVgqVWSRRkppEUQYWWB8ye1iGWilWlo/Ude489s7M6Zw7D9dlt53dmd29cFiWvXvO77x+51xpaaUsoSxBaUWZQ4ECy5xji2xKZDyCMlMEw6lCNiOSgwZKJK1SkcKeSealfP64t0mBjl4Ow39MkDUL0p2RSROOtqhZdeUEYM1pBl39XCg/fEeFtWcY7G9W4csvUxjlBkCsQ4Nt9QyWVfvT6RsAKXw3aoDGATZeYIt+W1kjw7cJG0RctWDTRebbKd8A6h5pwsDb70ba3w/eUr3wt/cmwgfw6Yft4TNMQaY7o1P2ncm4FT4ANQH/jQBJ2xv7kqIXEADDql8eS3+n8bku7oxNm+EDIM/dU92upb3T/NJGeaNbDx/AsbsLRUY5Xn92caWXY5d8RV6gWllxSg4fAEnTC90DQW13BLlgXR2D3dcUeDVkwOthA1bXspxILWcm3HdThcfvufB26LcJpkOEAz9NKI/lzqpSEC7feol5EWnpSeSlIxCALUkApmULdjUqxQVAQnl3D/X/yQda4QBEq2TYc12By091MQ17Bg3R88nHKlQbVmHvj89awNBLYrwT9zXY2aBAxTkGFdiSxP/Jp6FLDw+AS7GfsdJTJ2EqSO5khD43nGfBARy/ZxOQgZHe7GPM1jzUvChUtmnBAXQPcKGMJp3fdFGq6NByEhiAO4b/YptFfQJwNyQ/bZkVQGcf90Ja25ndIyrKBOa/f8wIpwi3X1G8UcxNu7ozUS7tiH0jBswwS3RIaF1w6LYKU/ML2+8sGnjygQswtKrVIy/Qd9qQP6LnO64q4fPAKpxyZIymHo1jWk6p1ag2BsdNwQMHcC+M5kHFJX+YlPxpVlbCx2mZ5DzPI04k4kUwHHdskU3pH76iftG8yWlkAAAAAElFTkSuQmCC</Image>
 <Image width="65" height="26">data:image/png;base64,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</Image>
 <Image width="130" height="52">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIIAAAA0CAYAAABGkOCVAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyNpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NDkxMSwgMjAxMy8xMC8yOS0xMTo0NzoxNiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjMwQjQ3MEVGRjQxMTExRTM5RkNCRjhFNDM0QjY3OEQ1IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjMwQjQ3MEYwRjQxMTExRTM5RkNCRjhFNDM0QjY3OEQ1Ij4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MzBCNDcwRURGNDExMTFFMzlGQ0JGOEU0MzRCNjc4RDUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MzBCNDcwRUVGNDExMTFFMzlGQ0JGOEU0MzRCNjc4RDUiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz5U94CwAAArpElEQVR42ux9B5hU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</Image>
 <Url type="application/x-suggestions+json" method="GET" template="https://www.google.com/complete/search?client=firefox&amp;q={searchTerms}"/>
-<Url type="text/html" method="GET" template="https://www.google.com/search">
+<Url type="text/html" method="GET" template="https://www.google.com/search" rel="searchform">
   <Param name="q" value="{searchTerms}"/>
   <Param name="ie" value="utf-8"/>
   <Param name="oe" value="utf-8"/>
   <Param name="aq" value="t"/>
   <Param name="rls" value="{moz:distributionID}:{moz:locale}:{moz:official}"/>
 #if MOZ_UPDATE_CHANNEL == beta
   <MozParam name="client" condition="defaultEngine" trueValue="firefox-beta" falseValue="firefox"/>
 #elif MOZ_UPDATE_CHANNEL == aurora
@@ -27,10 +27,9 @@
 #endif
   <MozParam name="channel" condition="purpose" purpose="contextmenu" value="rcs"/>
   <MozParam name="channel" condition="purpose" purpose="keyword" value="fflb"/>
   <MozParam name="channel" condition="purpose" purpose="searchbar" value="sb"/>
   <MozParam name="channel" condition="purpose" purpose="homepage" value="np"/>
   <MozParam name="channel" condition="purpose" purpose="newtab" value="nts"/>
   <MozParam name="source" condition="purpose" purpose="homepage" value="hp"/>
 </Url>
-<Url type="text/html" method="GET" template="https://www.google.com/" rel="searchform"/>
 </SearchPlugin>
--- a/browser/locales/en-US/searchplugins/twitter.xml
+++ b/browser/locales/en-US/searchplugins/twitter.xml
@@ -4,15 +4,14 @@
 
 <SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
 <ShortName>Twitter</ShortName>
 <Description>Realtime Twitter Search</Description>
 <InputEncoding>UTF-8</InputEncoding>
 <Image width="16" height="16">data:image/x-icon;base64,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</Image>
 <Image width="65" height="26">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEEAAAAaCAYAAADovjFxAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyNpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NDkxMSwgMjAxMy8xMC8yOS0xMTo0NzoxNiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjQ0MDYxRTY0QjUyNTExRTNCNzdEOTU4N0NCMjI3MEFDIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjQ0MDYxRTY1QjUyNTExRTNCNzdEOTU4N0NCMjI3MEFDIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MDcyQzJENkJCNTI1MTFFM0I3N0Q5NTg3Q0IyMjcwQUMiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MDcyQzJENkNCNTI1MTFFM0I3N0Q5NTg3Q0IyMjcwQUMiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4/Os9TAAADvUlEQVR42uyYWWxNURSGz723OiotMbU1N25jKNImIhENfSAh8SDxQgQP7QPxQhAVU1DihYjxwRBCCAktaohZE6EkNIqUmtJWq0LV2On6V/OfZNnO6RXJfXJW8uXuffc9Z5/9r7XX2uf6QqGQ9b+bzxPBE8ETwRPBE+F3i8q+bwXxuRhcAmciJTbYBmaDXWA16AMKwGOw1+GaANgAosEK0BKxSMgqC73G5wD200B1BOYZCcqNBR4Ds9ifAEqNa5aBLWyvA2sjJYJfCSA2MELz1IPPbIsYsgcz1Phwh2v0dxmR3A4iQpPql0dQhCSQCzIpQkCNP3W45rtqv4poTjD6a8Bb7mGhDZSASi5gDjgMrqprZoJp3Otl6vuFIIv7ugqMAWPBG/Cc97Ytj2MBjp8yRJjIvCXjX8Ah0MyxrmAuyGb+qAHF4JbDehPAFNCf95J7nJScIGGa2IlQX8EwcIVh2Qh6chF9QS1/9wKksx1U3j0OFvA+Yh9AbwqZ4zLndD7obpfx62ASf3OXz2HaAc5r21RwkAlZW7X/L6IlgaHcyn40sbgY2+JUu59qy297qb54LsbwtGmDwoyn8LNECVABzoF37M8HK1VOKXEQQCzV3A5lzBE+9kNUVCbooSLDPlw0GxFj20/V/qEEtBjOZk6o4MP7uR33cGvaJiH+jOPfQD631wiO17H8vuTWPMI1SEXZBJYb67zJSG6XuaKMvJCrsrhleDOG7TYuzFxsi4sIfiWqLazPEEEWddvF2xbDuMAYX6TaySyx8RTZnq8LGKWqizhtslmO/cqrYuNcwq+dN7Q4kVMG7+YiQpQxh5+CaWEyHebU0TPapbLpw1i82m62Sb5oUFum1uE80vGAD8F49o+CreCTqhAVDJ8aLlSS6D6wHyxR90pjCF8G69X3ku3fq34sF1jB5Ca2mXmjjp6UcL7ICLEY4jLnA14rz3kBLFUleAZ4Qof5+Gk7IynciVEuPh0mOQ7l4aX4H8pwOhfXpLaTbK3BLL1OJiVwHj3nlPmreN9HPI2K3WNOa2GUtPI4XkknJPM0nOYkgsVElN/JQlaBjSxNOS7bxanS7GB9DxoHokR6XB+Nnd43gi4HKV2Z6jt5bkmUQyhIgJER+8dLSkpex5H8LPjIZBRHNZtJJcO7gQmqO70jW0neOwopYAyv9/EwVKgyfCM9IKVvJzjP70vp1RSW4lZGjIh+h2cKealLZUiHuJAicIL3LWJJtsft5/5O596g6JIct4Nr3qu093+CJ4IngieCJ0J4+yXAANopCw9hh0hVAAAAAElFTkSuQmCC</Image>
 <Image width="130" height="52">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIIAAAA0CAYAAABGkOCVAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyNpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NDkxMSwgMjAxMy8xMC8yOS0xMTo0NzoxNiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjg5QzlEREI0QjUyNjExRTNCNzdEOTU4N0NCMjI3MEFDIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjg5QzlEREI1QjUyNjExRTNCNzdEOTU4N0NCMjI3MEFDIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6ODlDOUREQjJCNTI2MTFFM0I3N0Q5NTg3Q0IyMjcwQUMiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6ODlDOUREQjNCNTI2MTFFM0I3N0Q5NTg3Q0IyMjcwQUMiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz5Ln/UEAAAHKElEQVR42uxca2wV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</Image>
-<SearchForm>https://twitter.com/search/</SearchForm>
-<Url type="text/html" method="GET" template="https://twitter.com/search">
+<Url type="text/html" method="GET" template="https://twitter.com/search" rel="searchform">
   <Param name="q" value="{searchTerms}"/>
   <Param name="partner" value="Firefox"/>
   <Param name="source" value="desktop-search"/>
 </Url>
 </SearchPlugin>
--- a/browser/locales/en-US/searchplugins/wikipedia.xml
+++ b/browser/locales/en-US/searchplugins/wikipedia.xml
@@ -8,14 +8,14 @@
 <InputEncoding>UTF-8</InputEncoding>
 <Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
 <Image width="65" height="26">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEEAAAAaCAYAAADovjFxAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyNpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NDkxMSwgMjAxMy8xMC8yOS0xMTo0NzoxNiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjA3MkMyRDY5QjUyNTExRTNCNzdEOTU4N0NCMjI3MEFDIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjA3MkMyRDZBQjUyNTExRTNCNzdEOTU4N0NCMjI3MEFDIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MDcyQzJENjdCNTI1MTFFM0I3N0Q5NTg3Q0IyMjcwQUMiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MDcyQzJENjhCNTI1MTFFM0I3N0Q5NTg3Q0IyMjcwQUMiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7lkNGzAAAELklEQVR42uyYa4hUZRjHn3Nm13X2Mu6urtqutrTeVjRUQikoKUoQLIy8hybiBcVMRdFASPwgQTczsCiMvFYGffBDeANFUDEydc31viheat2dyVndmdmdy57+7/I/+HCcKaX1Q3Re+LHnOe9z3sv/PM/znlnLcRz5vzdb/OaL4Ivgi3C/WV01UCAQkNraWqmpGSCVVVWSl5cnZaXl4jgZaWpugp0viURcwpGIJJMpSba1SY+yUlmy5B3ZuGGDXGlokJKSYkmn0pJOp6UDBbsl2iJFRYVi25bEYjFpwzOtra3S3t4umUxGuqqo53WVCGZR9fX1nZgWDAaxgWIJhUpASGyIFLBtSWKDhcFCScTjuE5JXV2dhMNhSaVS2Kwt0WgUYiU6hTCiRSLNGM2BnYF4yccWCWPB6yAC9oGzYC2Iga/pNx/kg/fBs2AcSICvQOMjT2pZD7xFE0kFBd0lHo89zsiv5d8L3o4nwW+dcotUMDo+p11Jn3YKY/qeY9900P0/lv5hUJ+rswc3Nlnd6wDvgmHgR3V/GfgyS0RZf1NrrEeoR/ZD1rDAPzzrHX8wuEYhcr68E6BV2W9RGJMiI9T9wxzwFfAd+AyUgeFgK/iG9ovgAMcpAIvB92AVNzCJ9hoKu4LjjwabmYrGdwtYyb45nPM98DbYyHW4bSr7Pwb9PPszqTwGnGdUZ22DuekX1L074JSy3wC7eV1C/53clFHXVLEz7Hc3UsG38gz9x7O/F+25oC+vPzI1FVwGN0FP8Dz4gmO4fvPYN5X2LI5ZSvsTT9F/iveEgkZyhc8lTrxd3TPhM1LZ08C3vL7HxRplM6AN/AqOgVGgjhts5sKugyi4qvKzhaKZ4voHGMKCe5oF2qHfIj7TyDGucSM/sH5tY7/p+x1cBGm17vmMgikUsxw8kSv/ZoBqqjiCm7zLsBQ+vMuTl/nKbuTJcdIjpmnduIBuKmfNmfcy570BlrMvzpSap+Z2GG2WZ869nr3Ynn7TngZ7wACKbIRdl+s74QgddlPphVzgh6A/c1g8xbND2b24qD/BLVDk8XWUv8MIKuTCTNinVFjfBh+oY82mv+OZs1SNJ1n6ZzLi1nvWsgksyFUbXuVAO5RQjppENxNynyq7AfzE6xsMyyDtfhxDF1mHkZCtSJ9T9mLWIPeZibzuyejb5hlztVr7ZaaBtzlu5GU7Zi7xW8BU0CaqZt7wfnBI+b0GhvIb4iBD7SWOuYfKr+Px+zN4k3loJj/KojYIFINfmALu6TCW0dGbp0gNj+nZLHI203YCOA6WqtNhEF/OWc45ki/kHOuWzW+cgYyyK//mw8MtLEU8AkMqbIMeP5OjfWj3oU9flUL63C5XZ7zZaJXq66+eGajmdJvrG2LkuHNUco1uLapWdarC8v+z5P+U9kXwRfBF8EXwRfBFyNH+EmAA/FQ613UCCjYAAAAASUVORK5CYII=</Image>
 <Image width="130" height="52">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIIAAAA0CAYAAABGkOCVAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyNpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NDkxMSwgMjAxMy8xMC8yOS0xMTo0NzoxNiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjg5QzlEREIwQjUyNjExRTNCNzdEOTU4N0NCMjI3MEFDIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjg5QzlEREIxQjUyNjExRTNCNzdEOTU4N0NCMjI3MEFDIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6ODlDOUREQUVCNTI2MTFFM0I3N0Q5NTg3Q0IyMjcwQUMiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6ODlDOUREQUZCNTI2MTFFM0I3N0Q5NTg3Q0IyMjcwQUMiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz41D9uwAAAJWElEQVR42uxcCWxU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</Image>
 <Url type="application/x-suggestions+json" method="GET" template="https://en.wikipedia.org/w/api.php">
   <Param name="action" value="opensearch"/>
   <Param name="search" value="{searchTerms}"/>
 </Url>
-<Url type="text/html" method="GET" template="https://en.wikipedia.org/wiki/Special:Search" resultdomain="wikipedia.org">
+<Url type="text/html" method="GET" template="https://en.wikipedia.org/wiki/Special:Search"
+     resultdomain="wikipedia.org" rel="searchform">
   <Param name="search" value="{searchTerms}"/>
   <Param name="sourceid" value="Mozilla-search"/>
 </Url>
-<SearchForm>https://en.wikipedia.org/wiki/Special:Search</SearchForm>
 </SearchPlugin>
--- a/browser/locales/en-US/searchplugins/yahoo.xml
+++ b/browser/locales/en-US/searchplugins/yahoo.xml
@@ -10,15 +10,15 @@
 <Image width="65" height="26">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEEAAAAaCAYAAADovjFxAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyNpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NDkxMSwgMjAxMy8xMC8yOS0xMTo0NzoxNiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjcwNUUyRjFGQjUyNTExRTNCNzdEOTU4N0NCMjI3MEFDIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjcwNUUyRjIwQjUyNTExRTNCNzdEOTU4N0NCMjI3MEFDIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NzA1RTJGMURCNTI1MTFFM0I3N0Q5NTg3Q0IyMjcwQUMiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NzA1RTJGMUVCNTI1MTFFM0I3N0Q5NTg3Q0IyMjcwQUMiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4qMBarAAAI8ElEQVR42uxZeVRTZxb/vSQQYgBhAEVgZFOpO56igsLUrZ6RujCDtepUa2faqdYZtWrHpcfagqdYOzoFrFp7aqW1VVGoa0UP1g1FsVCVKSIKBGRTCCGs2e98L5iYmLDU2vljxsf5knzfvd9yf+/e+7vvwRER/t8vAZ5eT0F4CsJTECxAyDpWQodTa4hUCOhM8dSBBjqxt4B0Op3j/4rxpbltVHVLQ6K7leWYu3AbNs3YWPr2oSDOnnL6yjaK3bwA6//xAqbMGaT5tQ93v1xH8nst6CGVwH+QI9eVfuN9XXZKYl54dUkjc20OBuihZ6zn4u6GWX8ajQGRsFmjSaGe+lJYFnwdncHxFDn3+bW0N1OFmqtb0DvMeoK2BkrPPh+49u2Xi/zbaQ9kBuHySTk6f+9eWLrHFrivk7Jp35E6xC0fjxHRzjbyq+fvUHzcNcx/Lgoz1/U2yz/fnEOn04rg4SGFk0QEjV6L2roW9AsMQdzmUWXwsPXW7QlnKPmdyxg13h8TpwcjZJgHhA5AWWkdzmWW4Lv9txH9/HQkpo6IgASXTfNk+a00blgGJvXvBfAgNDTWhgMz6A8+p4nvW7YVowpYITGKCm7dMMvyT7SwsdfJCXHUdJds5rz1yjYmX0Dnd7XayPh28vAVJo+hteMfrKnTC6eGJ5I3VtHu5HOkUNRPJdIJ1Xrl7MzMSxQatIT8kUTV56z3Wvfa12ydVyn1k1y7+/Att+Ai05lO0wLPE2nJ1TR+82ITeeEr2rXmxkPlHQn8grMoc6PGvODNdL6SiqZFC9ZbbbJ4SBYNlr5DfbGUkueU2xzgn++msnmrKD9DZ/dwVy/xwL5J2xeVGuXzIpNYfyFVFzR1YIw6wNNjMgVjF6nukYwfO3Y4k82ZQp8uLO4QAFPLzjll1E2c0mDWzU5XMBC2UtaRImvlgV6vkA8TmPojxJtIhNGk0jUHmMYUdw0kRjxdOFxIH676gvywxeYQiRvSiMNaKvxeb/eA1/OKmHwJZSap6WZ5jhKIpaTY0k6NOXnyBDNkHKUsagcq1Gce9cZm0jfQe12BwLfIgX+hnviE6m+3e9PBTWX0DD4mhbx+thVFfrbvr6jCd/jiTTkdSSiiH9U78emOlRALpTKTzq5lBSz5tCByegg3a+nI6xW4gQs7tNa1N78xSy0+gfYZ2Lef8xyOaQiEAhzYf9oV8Mdz8zolJ0RFRfm4wxNnM36CrLys9FpVPWL8JkHQE+91J9lOjh0KJXKR862hnRkK7sFP7AC337jvE1kqjp0whpszfjgt2b6T5dcaDO8/HH9+Y6ZVYktOO4NZowONvwP6DA4dJHGmTWsyELVwmllHJBKhB1th66p/wz1ASw6OAmYwy9p6go5xS1V1DVzhhua2BlTdaYEz/ODi3bkREom0eoCbLxTyBlw6o2SIOcF/YO9uM46vrw/7zEOljDke3FFeUoXgkVL7xdKmlMXXnblCtKEQ21NWW8kykmpJxsYTMiaas+xHBybgWMMx3M2B2Rs4TsA6BihVVaxVQNFShfqmKuO3UlUJpbqCyXW8JqMnARzYH6HrBzknjqczLbT6VtZzhiPn2m0QRJyYfYpBnNbYr6+XY1CUZ7vMYDBwAoHAfAK/3/qGhvj3oCDZDEREhFl5wZ74XHaHxTiV3BJOdJ2dm0O90o1JVNgfV4yVx4LbaVWrYSA6Yl3iZEgDbDla0SwP35oan93DSQqvAAc0MADUtZ2XAxqNRlKnMMDfnxD2O3/GTAJOfkvUbRAaKvnyxgG9goTtEStSYciYPg89gQeCb6YJBmaAmJGy5XXnvJYO1J3Dy7F9Ud94H/LGKsjZ3XVwAn7/rDf+dfwgVLUw5g4+H/AlS0Wpwe6BKm4rsnkd/u5EvziU6VeiKLVzI4qvyFt/wj0MHi/B4H4jBIEeGhwv+4FVPd3LCXmH6iBlOSUi1lVvNFyswTPP9jlqFOr1es7UzJnUdzlFYg+jahKaxpYN47l9PqmoVmbDxXkXjbyf8rrcmHk/Wref9VczitTazfi5lwuZfAl99vd2eo0aupg8kUlUSR0yREzQPnJgNUGF7H4h39/55Q62xhuUsZS6pMjKa0qj7rLwdKPu9awymj9uI/G1iPF9CnsWEPLNEoSxvVfTWHxDujYyUuO1481M8zWaP3mDeUNLfb4NcXuVBUccGdichHd3G4uprN0quwfMPPoDk7/EiqV8o7y28Y4yOORvNBTpdOEbNkf/EPySXB3NCuPrjrl09lCO1Xovxqxg48mU+2XHQDSWEKPxeAp2X0FNiuYJ7eMa12bt/b38bx0r1ETsh5DjOJ7Q+dBgrqJzFWhcmDP3YGECbxZBstwLxRgR4YjFG6JhCh/TtymfrE+aifjEEyjOaykdEhqAqMhyiD1ajcno0cvFxYXJ+6Pf2Pa+p0twzzuF78veXpPun/hxOo6neemcPQgtqhaUltUBPnIUl7zXGBTYv6flvqnffhC48K3NpdPnJ2Hm3tEU/cf+CB7qCoFIj8qyBpw5WYSUz88icKQGR4+s3eLsJv1eo1VLrqZBGTjAC5JQ/Vxj8Gq1WkcLatPwLhIkWKlrhS9KaldelnpyETpqCxBxEtmD8BHaizmhUGiMtbY2dR+JRFzdnhu0rmQQNtk8upoTsV7IpyPrMeXeG/k1s5vqNHCQcAgZ3uv9npJe5ri3zF2mOT/eukIHt1WitdwBYpEju4EaqPQtIKkaE2f7IeaFieY5ZXdLCwP6JoSEYQyu0ssMVFGjFQhsUa1OZ3A6eehKq1qrR/S08FAnZ9ENS/boCgT+4YqtpLd3aFsQbOWWMsur633b99ajaQ+7t4w3pPFMapbxrwB4j9dqdW57vjpU5+3hheiYcQI+AjhGPbzwQaHHprPfvEcYN2ZeYdBByHXxMPsgnIxh9d98H2ARykLTTbQE8dF3H7x9DDSzjskBjCB0YeBjH/JJgPOoob9gnY4Lqa4OaW9yd4ExHfwJGCB8EsZ2tLaoq03sAfRzNvolnvS4hv1cIE0gOLDDah/nLphA6sijfq1/7pjOZbn/Y6xhtPs/AgwA60Nh9SzP0OoAAAAASUVORK5CYII=</Image>
 <Image width="130" height="52">data:image/png;base64,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</Image>
 <Url type="application/x-suggestions+json" method="GET"
      template="https://search.yahoo.com/sugg/ff">
   <Param name="output"  value="fxjson" />
   <Param name="appid"   value="ffd" />
   <Param name="command" value="{searchTerms}" />
 </Url>
-<Url type="text/html" method="GET" template="https://search.yahoo.com/search" resultdomain="yahoo.com">
+<Url type="text/html" method="GET" template="https://search.yahoo.com/search"
+     resultdomain="yahoo.com" rel="searchform">
   <Param name="p" value="{searchTerms}"/>
   <Param name="ei" value="UTF-8"/>
   <MozParam name="fr" condition="pref" pref="yahoo-fr" />
 </Url>
-<SearchForm>https://search.yahoo.com/</SearchForm>
 </SearchPlugin>
--- a/browser/modules/ContentSearch.jsm
+++ b/browser/modules/ContentSearch.jsm
@@ -247,17 +247,17 @@ this.ContentSearch = {
     }
 
     let browserData = this._suggestionDataForBrowser(msg.target, true);
     let { controller } = browserData;
     let ok = SearchSuggestionController.engineOffersSuggestions(engine);
     controller.maxLocalResults = ok ? 2 : 6;
     controller.maxRemoteResults = ok ? 6 : 0;
     controller.remoteTimeout = data.remoteTimeout || undefined;
-    let priv = PrivateBrowsingUtils.isWindowPrivate(msg.target.contentWindow);
+    let priv = PrivateBrowsingUtils.isBrowserPrivate(msg.target);
     // fetch() rejects its promise if there's a pending request, but since we
     // process our event queue serially, there's never a pending request.
     let suggestions = yield controller.fetch(data.searchString, priv, engine);
 
     // Keep the form history result so RemoveFormHistoryEntry can remove entries
     // from it.  Keeping only one result isn't foolproof because the client may
     // try to remove an entry from one set of suggestions after it has requested
     // more but before it's received them.  In that case, the entry may not
--- a/browser/modules/UITour.jsm
+++ b/browser/modules/UITour.jsm
@@ -1129,16 +1129,23 @@ this.UITour = {
       case "availableTargets":
         this.getAvailableTargets(aContentDocument, aCallbackID);
         break;
       case "sync":
         this.sendPageCallback(aContentDocument, aCallbackID, {
           setup: Services.prefs.prefHasUserValue("services.sync.username"),
         });
         break;
+      case "appinfo":
+        let props = ["defaultUpdateChannel", "distributionID", "isOfficialBranding",
+                     "isReleaseBuild", "name", "vendor", "version"];
+        let appinfo = {};
+        props.forEach(property => appinfo[property] = Services.appinfo[property]);
+        this.sendPageCallback(aContentDocument, aCallbackID, appinfo);
+        break;
       default:
         Cu.reportError("getConfiguration: Unknown configuration requested: " + aConfiguration);
         break;
     }
   },
 
   getAvailableTargets: function(aContentDocument, aCallbackID) {
     let window = this.getChromeWindow(aContentDocument);
--- a/browser/modules/test/browser_UITour.js
+++ b/browser/modules/test/browser_UITour.js
@@ -260,15 +260,28 @@ let tests = [
         is(desc.textContent, "search text", "Popup should have correct description text");
 
         done();
       });
     });
 
     gContentAPI.showInfo("urlbar", "urlbar title", "urlbar text");
   },
+  function test_getConfigurationVersion(done) {
+    function callback(result) {
+      let props = ["defaultUpdateChannel", "distributionID", "isOfficialBranding",
+                   "isReleaseBuild", "name", "vendor", "version"];
+      for (let property of props) {
+        ok(typeof(result[property]) !== undefined, "Check " + property + " isn't undefined.");
+        is(result[property], Services.appinfo[property], "Should have the same " + property + " property.");
+      }
+      done();
+    }
+
+    gContentAPI.getConfiguration("appinfo", callback);
+  },
 
   // Make sure this test is last in the file so the appMenu gets left open and done will confirm it got tore down.
   function cleanupMenus(done) {
     gContentAPI.showMenu("appMenu");
     done();
   },
 ];
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..54eb9f365f75d3870858cd7d7ac3544c176a642e
GIT binary patch
literal 3209
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
--- a/browser/themes/linux/browser.css
+++ b/browser/themes/linux/browser.css
@@ -1179,16 +1179,21 @@ toolbarbutton[sdk-button="true"][cui-are
 .popup-notification-icon[popupid="webapps-install"] {
   list-style-image: url(chrome://global/skin/icons/webapps-64.png);
 }
 
 .popup-notification-icon[popupid="bad-content"] {
   list-style-image: url(chrome://browser/skin/bad-content-blocked-64.png);
 }
 
+.popup-notification-icon[popupid="bad-content"][mixedblockdisabled],
+.popup-notification-icon[popupid="bad-content"][trackingblockdisabled] {
+  list-style-image: url(chrome://browser/skin/bad-content-unblocked-64.png);
+}
+
 .popup-notification-icon[popupid="webRTC-sharingDevices"],
 .popup-notification-icon[popupid="webRTC-shareDevices"] {
   list-style-image: url(chrome://browser/skin/webRTC-shareDevice-64.png);
 }
 
 .popup-notification-icon[popupid="webRTC-sharingMicrophone"],
 .popup-notification-icon[popupid="webRTC-shareMicrophone"] {
   list-style-image: url(chrome://browser/skin/webRTC-shareMicrophone-64.png);
--- a/browser/themes/linux/jar.mn
+++ b/browser/themes/linux/jar.mn
@@ -41,16 +41,17 @@ browser.jar:
   skin/classic/browser/menuPanel.png
   skin/classic/browser/menuPanel-customize.png
   skin/classic/browser/menuPanel-exit.png
   skin/classic/browser/menuPanel-help.png
   skin/classic/browser/menuPanel-small.png
   skin/classic/browser/bad-content-blocked-16.png
   skin/classic/browser/bad-content-blocked-64.png
   skin/classic/browser/bad-content-unblocked-16.png
+  skin/classic/browser/bad-content-unblocked-64.png
   skin/classic/browser/monitor.png
   skin/classic/browser/monitor_16-10.png
   skin/classic/browser/notification-16.png
   skin/classic/browser/notification-64.png
 * skin/classic/browser/pageInfo.css
   skin/classic/browser/pageInfo.png
   skin/classic/browser/page-livemarks.png
   skin/classic/browser/pluginInstall-16.png
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..54eb9f365f75d3870858cd7d7ac3544c176a642e
GIT binary patch
literal 3209
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
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..e147189c4b3df0ecb0d3cb7914e1f69b17f16050
GIT binary patch
literal 7488
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
KMNUMnLSTZrcN47u
--- a/browser/themes/osx/browser.css
+++ b/browser/themes/osx/browser.css
@@ -40,16 +40,20 @@
 
 #main-window {
   -moz-appearance: none;
   background-color: #eeeeee;
 }
 
 /** Begin titlebar **/
 
+#titlebar {
+  -moz-window-dragging: drag;
+}
+
 #titlebar-buttonbox > .titlebar-button {
   display: none;
 }
 
 /* NB: these would be -moz-margin-start/end if it wasn't for the fact that OS X
  * doesn't reverse the order of the items in the titlebar in RTL mode. */
 .titlebar-placeholder[type="caption-buttons"],
 #titlebar-buttonbox {
@@ -4035,16 +4039,27 @@ menulist.translate-infobar-element > .me
   list-style-image: url(chrome://browser/skin/bad-content-blocked-64.png);
 }
 @media (min-resolution: 2dppx) {
   .popup-notification-icon[popupid="bad-content"] {
     list-style-image: url(chrome://browser/skin/bad-content-blocked-64@2x.png);
   }
 }
 
+.popup-notification-icon[popupid="bad-content"][mixedblockdisabled],
+.popup-notification-icon[popupid="bad-content"][trackingblockdisabled] {
+  list-style-image: url(chrome://browser/skin/bad-content-unblocked-64.png);
+}
+@media (min-resolution: 2dppx) {
+  .popup-notification-icon[popupid="bad-content"][mixedblockdisabled],
+  .popup-notification-icon[popupid="bad-content"][trackingblockdisabled] {
+    list-style-image: url(chrome://browser/skin/bad-content-unblocked-64@2x.png);
+  }
+}
+
 .popup-notification-icon[popupid="pointerLock"] {
   list-style-image: url(chrome://browser/skin/pointerLock-64.png);
 }
 @media (min-resolution: 2dppx) {
   .popup-notification-icon[popupid="pointerLock"] {
     list-style-image: url(chrome://browser/skin/pointerLock-64@2x.png);
   }
 }
--- a/browser/themes/osx/jar.mn
+++ b/browser/themes/osx/jar.mn
@@ -67,16 +67,18 @@ browser.jar:
   skin/classic/browser/menuPanel-small.png
   skin/classic/browser/menuPanel-small@2x.png
   skin/classic/browser/bad-content-blocked-16.png
   skin/classic/browser/bad-content-blocked-16@2x.png
   skin/classic/browser/bad-content-blocked-64.png
   skin/classic/browser/bad-content-blocked-64@2x.png
   skin/classic/browser/bad-content-unblocked-16.png
   skin/classic/browser/bad-content-unblocked-16@2x.png
+  skin/classic/browser/bad-content-unblocked-64.png
+  skin/classic/browser/bad-content-unblocked-64@2x.png
   skin/classic/browser/panel-expander-closed.png
   skin/classic/browser/panel-expander-closed@2x.png
   skin/classic/browser/panel-expander-open.png
   skin/classic/browser/panel-expander-open@2x.png
   skin/classic/browser/panel-plus-sign.png
   skin/classic/browser/page-livemarks.png
   skin/classic/browser/page-livemarks@2x.png
   skin/classic/browser/pageInfo.css
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..54eb9f365f75d3870858cd7d7ac3544c176a642e
GIT binary patch
literal 3209
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
--- a/browser/themes/windows/browser.css
+++ b/browser/themes/windows/browser.css
@@ -2197,16 +2197,21 @@ toolbarbutton.bookmark-item[dragover="tr
 .popup-notification-icon[popupid="webapps-install"] {
   list-style-image: url(chrome://global/skin/icons/webapps-64.png);
 }
 
 .popup-notification-icon[popupid="bad-content"] {
   list-style-image: url(chrome://browser/skin/bad-content-blocked-64.png);
 }
 
+.popup-notification-icon[popupid="bad-content"][mixedblockdisabled],
+.popup-notification-icon[popupid="bad-content"][trackingblockdisabled] {
+  list-style-image: url(chrome://browser/skin/bad-content-unblocked-64.png);
+}
+
 .popup-notification-icon[popupid="webRTC-sharingDevices"],
 .popup-notification-icon[popupid="webRTC-shareDevices"] {
   list-style-image: url(chrome://browser/skin/webRTC-shareDevice-64.png);
 }
 
 .popup-notification-icon[popupid="webRTC-sharingMicrophone"],
 .popup-notification-icon[popupid="webRTC-shareMicrophone"] {
   list-style-image: url(chrome://browser/skin/webRTC-shareMicrophone-64.png);
--- a/browser/themes/windows/jar.mn
+++ b/browser/themes/windows/jar.mn
@@ -51,16 +51,17 @@ browser.jar:
         skin/classic/browser/menuPanel-help.png
         skin/classic/browser/menuPanel-small.png
         skin/classic/browser/Metro_Glyph.png                        (Metro_Glyph-aero.png)
         skin/classic/browser/Metro_Glyph-inverted.png
         skin/classic/browser/Metro_Glyph-menuPanel.png
         skin/classic/browser/bad-content-blocked-16.png
         skin/classic/browser/bad-content-blocked-64.png
         skin/classic/browser/bad-content-unblocked-16.png
+        skin/classic/browser/bad-content-unblocked-64.png
         skin/classic/browser/monitor.png
         skin/classic/browser/monitor_16-10.png
         skin/classic/browser/notification-16.png
         skin/classic/browser/notification-64.png
         skin/classic/browser/pageInfo.css
         skin/classic/browser/pageInfo.png
         skin/classic/browser/page-livemarks.png                      (feeds/feedIcon16.png)
         skin/classic/browser/pluginInstall-16.png
@@ -473,16 +474,17 @@ browser.jar:
         skin/classic/aero/browser/menuPanel-small.png
         skin/classic/aero/browser/menuPanel-small-aero.png
         skin/classic/aero/browser/Metro_Glyph.png                    (Metro_Glyph-aero.png)
         skin/classic/aero/browser/Metro_Glyph-inverted.png
         skin/classic/aero/browser/Metro_Glyph-menuPanel.png
         skin/classic/aero/browser/bad-content-blocked-16.png
         skin/classic/aero/browser/bad-content-blocked-64.png
         skin/classic/aero/browser/bad-content-unblocked-16.png
+        skin/classic/aero/browser/bad-content-unblocked-64.png
         skin/classic/aero/browser/monitor.png
         skin/classic/aero/browser/monitor_16-10.png
         skin/classic/aero/browser/notification-16.png
         skin/classic/aero/browser/notification-64.png
         skin/classic/aero/browser/pageInfo.css
         skin/classic/aero/browser/pageInfo.png                       (pageInfo-aero.png)
         skin/classic/aero/browser/page-livemarks.png                 (feeds/feedIcon16-aero.png)
         skin/classic/aero/browser/pluginInstall-16.png
--- a/chrome/nsChromeRegistryChrome.cpp
+++ b/chrome/nsChromeRegistryChrome.cpp
@@ -676,28 +676,36 @@ nsChromeRegistryChrome::OverlayListHash:
   return &entry->mArray;
 }
 
 #ifdef MOZ_XUL
 NS_IMETHODIMP
 nsChromeRegistryChrome::GetStyleOverlays(nsIURI *aChromeURL,
                                          nsISimpleEnumerator **aResult)
 {
-  const nsCOMArray<nsIURI>* parray = mStyleHash.GetArray(aChromeURL);
+  nsCOMPtr<nsIURI> chromeURLWithoutHash;
+  if (aChromeURL) {
+    aChromeURL->CloneIgnoringRef(getter_AddRefs(chromeURLWithoutHash));
+  }
+  const nsCOMArray<nsIURI>* parray = mStyleHash.GetArray(chromeURLWithoutHash);
   if (!parray)
     return NS_NewEmptyEnumerator(aResult);
 
   return NS_NewArrayEnumerator(aResult, *parray);
 }
 
 NS_IMETHODIMP
 nsChromeRegistryChrome::GetXULOverlays(nsIURI *aChromeURL,
                                        nsISimpleEnumerator **aResult)
 {
-  const nsCOMArray<nsIURI>* parray = mOverlayHash.GetArray(aChromeURL);
+  nsCOMPtr<nsIURI> chromeURLWithoutHash;
+  if (aChromeURL) {
+    aChromeURL->CloneIgnoringRef(getter_AddRefs(chromeURLWithoutHash));
+  }
+  const nsCOMArray<nsIURI>* parray = mOverlayHash.GetArray(chromeURLWithoutHash);
   if (!parray)
     return NS_NewEmptyEnumerator(aResult);
 
   return NS_NewArrayEnumerator(aResult, *parray);
 }
 #endif // MOZ_XUL
 
 nsIURI*
@@ -890,17 +898,20 @@ nsChromeRegistryChrome::ManifestOverlay(
   }
 
   if (!CanLoadResource(overlayuri)) {
     LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
                           "Cannot register non-local URI '%s' as an overlay.", overlay);
     return;
   }
 
-  mOverlayHash.Add(baseuri, overlayuri);
+  nsCOMPtr<nsIURI> baseuriWithoutHash;
+  baseuri->CloneIgnoringRef(getter_AddRefs(baseuriWithoutHash));
+
+  mOverlayHash.Add(baseuriWithoutHash, overlayuri);
 }
 
 void
 nsChromeRegistryChrome::ManifestStyle(ManifestProcessingContext& cx, int lineno,
                                       char *const * argv, bool platform,
                                       bool contentaccessible)
 {
   char* base = argv[0];
@@ -915,17 +926,20 @@ nsChromeRegistryChrome::ManifestStyle(Ma
   }
 
   if (!CanLoadResource(overlayuri)) {
     LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
                           "Cannot register non-local URI '%s' as a style overlay.", overlay);
     return;
   }
 
-  mStyleHash.Add(baseuri, overlayuri);
+  nsCOMPtr<nsIURI> baseuriWithoutHash;
+  baseuri->CloneIgnoringRef(getter_AddRefs(baseuriWithoutHash));
+
+  mStyleHash.Add(baseuriWithoutHash, overlayuri);
 }
 
 void
 nsChromeRegistryChrome::ManifestOverride(ManifestProcessingContext& cx, int lineno,
                                          char *const * argv, bool platform,
                                          bool contentaccessible)
 {
   char* chrome = argv[0];
--- a/config/check_spidermonkey_style.py
+++ b/config/check_spidermonkey_style.py
@@ -231,27 +231,28 @@ def get_all_filenames():
 
 
 def check_style():
     # We deal with two kinds of name.
     # - A "filename" is a full path to a file from the repository root.
     # - An "inclname" is how a file is referred to in a #include statement.
     #
     # Examples (filename -> inclname)
-    # - "mfbt/Attributes.h"  -> "mozilla/Attributes.h"
-    # - "js/public/Vector.h" -> "js/Vector.h"
-    # - "js/src/vm/String.h" -> "vm/String.h"
+    # - "mfbt/Attributes.h"     -> "mozilla/Attributes.h"
+    # - "mfbt/decimal/Decimal.h -> "mozilla/Decimal.h"
+    # - "js/public/Vector.h"    -> "js/Vector.h"
+    # - "js/src/vm/String.h"    -> "vm/String.h"
 
     mfbt_inclnames = set()      # type: set(inclname)
     js_names = dict()           # type: dict(filename, inclname)
 
     # Select the appropriate files.
     for filename in get_all_filenames():
         if filename.startswith('mfbt/') and filename.endswith('.h'):
-            inclname = 'mozilla/' + filename[len('mfbt/'):]
+            inclname = 'mozilla/' + filename.split('/')[-1]
             mfbt_inclnames.add(inclname)
 
         if filename.startswith('js/public/') and filename.endswith('.h'):
             inclname = 'js/' + filename[len('js/public/'):]
             js_names[filename] = inclname
 
         if filename.startswith('js/src/') and \
            not filename.startswith(tuple(ignored_js_src_dirs)) and \
@@ -449,17 +450,17 @@ def do_file(filename, inclname, file_kin
 
         else:
             if include.inclname not in included_inclnames_to_ignore:
                 included_kind = FileKind.get(include.inclname)
 
                 # Check the #include path has the correct form.
                 if include.inclname not in all_inclnames:
                     error(filename, include.linenum,
-                          include.quote() + ' is included ' + 'using the wrong path;',
+                          include.quote() + ' is included using the wrong path;',
                           'did you forget a prefix, or is the file not yet committed?')
 
                 # Record inclusions of .h files for cycle detection later.
                 # (Exclude .tbl and .msg files.)
                 elif included_kind == FileKind.H or included_kind == FileKind.INL_H:
                     included_h_inclnames.add(include.inclname)
 
                 # Check a H file doesn't #include an INL_H file.
--- a/content/media/CubebUtils.cpp
+++ b/content/media/CubebUtils.cpp
@@ -2,36 +2,56 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include <stdint.h>
 #include <algorithm>
 #include "mozilla/Preferences.h"
+#include "mozilla/StaticMutex.h"
 #include "CubebUtils.h"
+#include "nsAutoRef.h"
 #include "prdtoa.h"
 
 #define PREF_VOLUME_SCALE "media.volume_scale"
 #define PREF_CUBEB_LATENCY "media.cubeb_latency_ms"
 
 namespace mozilla {
 
+namespace {
+
+// This mutex protects the variables below.
+StaticMutex sMutex;
+cubeb* sCubebContext;
+double sVolumeScale;
+uint32_t sCubebLatency;
+bool sCubebLatencyPrefSet;
+
+// Prefered samplerate, in Hz (characteristic of the hardware, mixer, platform,
+// and API used).
+//
+// sMutex protects *initialization* of this, which must be performed from each
+// thread before fetching, after which it is safe to fetch without holding the
+// mutex because it is only written once per process execution (by the first
+// initialization to complete).  Since the init must have been called on a
+// given thread before fetching the value, it's guaranteed (via the mutex) that
+// sufficient memory barriers have occurred to ensure the correct value is
+// visible on the querying thread/CPU.
+uint32_t sPreferredSampleRate;
+
+} // anonymous namespace
+
 extern PRLogModuleInfo* gAudioStreamLog;
 
 static const uint32_t CUBEB_NORMAL_LATENCY_MS = 100;
 
-StaticMutex CubebUtils::sMutex;
-cubeb* CubebUtils::sCubebContext;
-uint32_t CubebUtils::sPreferredSampleRate;
-double CubebUtils::sVolumeScale;
-uint32_t CubebUtils::sCubebLatency;
-bool CubebUtils::sCubebLatencyPrefSet;
+namespace CubebUtils {
 
-/*static*/ void CubebUtils::PrefChanged(const char* aPref, void* aClosure)
+void PrefChanged(const char* aPref, void* aClosure)
 {
   if (strcmp(aPref, PREF_VOLUME_SCALE) == 0) {
     nsAdoptingString value = Preferences::GetString(aPref);
     StaticMutexAutoLock lock(sMutex);
     if (value.IsEmpty()) {
       sVolumeScale = 1.0;
     } else {
       NS_ConvertUTF16toUTF8 utf8(value);
@@ -43,116 +63,117 @@ bool CubebUtils::sCubebLatencyPrefSet;
     // audible.
     sCubebLatencyPrefSet = Preferences::HasUserValue(aPref);
     uint32_t value = Preferences::GetUint(aPref, CUBEB_NORMAL_LATENCY_MS);
     StaticMutexAutoLock lock(sMutex);
     sCubebLatency = std::min<uint32_t>(std::max<uint32_t>(value, 1), 1000);
   }
 }
 
-/*static*/ bool CubebUtils::GetFirstStream()
+bool GetFirstStream()
 {
   static bool sFirstStream = true;
 
   StaticMutexAutoLock lock(sMutex);
   bool result = sFirstStream;
   sFirstStream = false;
   return result;
 }
 
-/*static*/ double CubebUtils::GetVolumeScale()
+double GetVolumeScale()
 {
   StaticMutexAutoLock lock(sMutex);
   return sVolumeScale;
 }
 
-/*static*/ cubeb* CubebUtils::GetCubebContext()
+cubeb* GetCubebContext()
 {
   StaticMutexAutoLock lock(sMutex);
   return GetCubebContextUnlocked();
 }
 
-/*static*/ void CubebUtils::InitPreferredSampleRate()
+void InitPreferredSampleRate()
 {
   StaticMutexAutoLock lock(sMutex);
   if (sPreferredSampleRate == 0 &&
       cubeb_get_preferred_sample_rate(GetCubebContextUnlocked(),
                                       &sPreferredSampleRate) != CUBEB_OK) {
+    // Query failed, use a sensible default.
     sPreferredSampleRate = 44100;
   }
 }
 
-/*static*/ cubeb* CubebUtils::GetCubebContextUnlocked()
+cubeb* GetCubebContextUnlocked()
 {
   sMutex.AssertCurrentThreadOwns();
   if (sCubebContext ||
       cubeb_init(&sCubebContext, "CubebUtils") == CUBEB_OK) {
     return sCubebContext;
   }
   NS_WARNING("cubeb_init failed");
   return nullptr;
 }
 
-/*static*/ uint32_t CubebUtils::GetCubebLatency()
+uint32_t GetCubebLatency()
 {
   StaticMutexAutoLock lock(sMutex);
   return sCubebLatency;
 }
 
-/*static*/ bool CubebUtils::CubebLatencyPrefSet()
+bool CubebLatencyPrefSet()
 {
   StaticMutexAutoLock lock(sMutex);
   return sCubebLatencyPrefSet;
 }
 
-/*static*/ void CubebUtils::InitLibrary()
+void InitLibrary()
 {
 #ifdef PR_LOGGING
   gAudioStreamLog = PR_NewLogModule("AudioStream");
 #endif
   PrefChanged(PREF_VOLUME_SCALE, nullptr);
   Preferences::RegisterCallback(PrefChanged, PREF_VOLUME_SCALE);
   PrefChanged(PREF_CUBEB_LATENCY, nullptr);
   Preferences::RegisterCallback(PrefChanged, PREF_CUBEB_LATENCY);
 }
 
-/*static*/ void CubebUtils::ShutdownLibrary()
+void ShutdownLibrary()
 {
   Preferences::UnregisterCallback(PrefChanged, PREF_VOLUME_SCALE);
   Preferences::UnregisterCallback(PrefChanged, PREF_CUBEB_LATENCY);
 
   StaticMutexAutoLock lock(sMutex);
   if (sCubebContext) {
     cubeb_destroy(sCubebContext);
     sCubebContext = nullptr;
   }
 }
 
-/*static*/ int CubebUtils::MaxNumberOfChannels()
+uint32_t MaxNumberOfChannels()
 {
-  cubeb* cubebContext = CubebUtils::GetCubebContext();
+  cubeb* cubebContext = GetCubebContext();
   uint32_t maxNumberOfChannels;
   if (cubebContext &&
       cubeb_get_max_channel_count(cubebContext,
                                   &maxNumberOfChannels) == CUBEB_OK) {
-    return static_cast<int>(maxNumberOfChannels);
+    return maxNumberOfChannels;
   }
 
   return 0;
 }
 
-/*static*/ int CubebUtils::PreferredSampleRate()
+uint32_t PreferredSampleRate()
 {
   MOZ_ASSERT(sPreferredSampleRate,
              "sPreferredSampleRate has not been initialized!");
   return sPreferredSampleRate;
 }
 
 #if defined(__ANDROID__) && defined(MOZ_B2G)
-/*static*/ cubeb_stream_type CubebUtils::ConvertChannelToCubebType(dom::AudioChannel aChannel)
+cubeb_stream_type ConvertChannelToCubebType(dom::AudioChannel aChannel)
 {
   switch(aChannel) {
     case dom::AudioChannel::Normal:
       return CUBEB_STREAM_TYPE_SYSTEM;
     case dom::AudioChannel::Content:
       return CUBEB_STREAM_TYPE_MUSIC;
     case dom::AudioChannel::Notification:
       return CUBEB_STREAM_TYPE_NOTIFICATION;
@@ -166,9 +187,10 @@ bool CubebUtils::sCubebLatencyPrefSet;
       return CUBEB_STREAM_TYPE_SYSTEM_ENFORCED;
     default:
       NS_ERROR("The value of AudioChannel is invalid");
       return CUBEB_STREAM_TYPE_MAX;
   }
 }
 #endif
 
-}
+} // namespace CubebUtils
+} // namespace mozilla
--- a/content/media/CubebUtils.h
+++ b/content/media/CubebUtils.h
@@ -3,70 +3,47 @@
 /* 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/. */
 
 #if !defined(CubebUtils_h_)
 #define CubebUtils_h_
 
 #include "cubeb/cubeb.h"
-#include "nsAutoRef.h"
-#include "mozilla/StaticMutex.h"
 #include "mozilla/dom/AudioChannelBinding.h"
 
-template <>
-class nsAutoRefTraits<cubeb_stream> : public nsPointerRefTraits<cubeb_stream>
-{
-public:
-  static void Release(cubeb_stream* aStream) { cubeb_stream_destroy(aStream); }
-};
-
 namespace mozilla {
+namespace CubebUtils {
 
-class CubebUtils {
-public:
-  // Initialize Audio Library. Some Audio backends require initializing the
-  // library before using it.
-  static void InitLibrary();
+// Initialize Audio Library. Some Audio backends require initializing the
+// library before using it.
+void InitLibrary();
 
-  // Shutdown Audio Library. Some Audio backends require shutting down the
-  // library after using it.
-  static void ShutdownLibrary();
+// Shutdown Audio Library. Some Audio backends require shutting down the
+// library after using it.
+void ShutdownLibrary();
 
-  // Returns the maximum number of channels supported by the audio hardware.
-  static int MaxNumberOfChannels();
+// Returns the maximum number of channels supported by the audio hardware.
+uint32_t MaxNumberOfChannels();
 
-  // Queries the samplerate the hardware/mixer runs at, and stores it.
-  // Can be called on any thread. When this returns, it is safe to call
-  // PreferredSampleRate without locking.
-  static void InitPreferredSampleRate();
-  // Get the aformentionned sample rate. Does not lock.
-  static int PreferredSampleRate();
+// Queries the samplerate the hardware/mixer runs at, and stores it.
+// Can be called on any thread. When this returns, it is safe to call
+// PreferredSampleRate.
+void InitPreferredSampleRate();
+
+// Get the aforementioned sample rate. Thread safe.
+uint32_t PreferredSampleRate();
 
-  static void PrefChanged(const char* aPref, void* aClosure);
-  static double GetVolumeScale();
-  static bool GetFirstStream();
-  static cubeb* GetCubebContext();
-  static cubeb* GetCubebContextUnlocked();
-  static uint32_t GetCubebLatency();
-  static bool CubebLatencyPrefSet();
+void PrefChanged(const char* aPref, void* aClosure);
+double GetVolumeScale();
+bool GetFirstStream();
+cubeb* GetCubebContext();
+cubeb* GetCubebContextUnlocked();
+uint32_t GetCubebLatency();
+bool CubebLatencyPrefSet();
 #if defined(__ANDROID__) && defined(MOZ_B2G)
-  static cubeb_stream_type ConvertChannelToCubebType(dom::AudioChannel aChannel);
+cubeb_stream_type ConvertChannelToCubebType(dom::AudioChannel aChannel);
 #endif
 
-private:
-  // This mutex protects the static members below.
-  static StaticMutex sMutex;
-  static cubeb* sCubebContext;
-
-  // Prefered samplerate, in Hz (characteristic of the
-  // hardware/mixer/platform/API used).
-  static uint32_t sPreferredSampleRate;
-
-  static double sVolumeScale;
-  static uint32_t sCubebLatency;
-  static bool sCubebLatencyPrefSet;
-};
-}
-
-
+} // namespace CubebUtils
+} // namespace mozilla
 
 #endif // CubebUtils_h_
--- a/content/media/GraphDriver.h
+++ b/content/media/GraphDriver.h
@@ -9,19 +9,25 @@
 #include "nsAutoPtr.h"
 #include "nsAutoRef.h"
 #include "AudioBufferUtils.h"
 #include "AudioMixer.h"
 #include "AudioSegment.h"
 
 struct cubeb_stream;
 
+template <>
+class nsAutoRefTraits<cubeb_stream> : public nsPointerRefTraits<cubeb_stream>
+{
+public:
+  static void Release(cubeb_stream* aStream) { cubeb_stream_destroy(aStream); }
+};
+
 namespace mozilla {
 
-
 /**
  * Assume we can run an iteration of the MediaStreamGraph loop in this much time
  * or less.
  * We try to run the control loop at this rate.
  */
 static const int MEDIA_GRAPH_TARGET_PERIOD_MS = 10;
 
 /**
--- a/content/media/MediaDecoder.cpp
+++ b/content/media/MediaDecoder.cpp
@@ -1433,20 +1433,16 @@ void MediaDecoder::UpdatePlaybackOffset(
 
 bool MediaDecoder::OnStateMachineThread() const
 {
   return mDecoderStateMachine->OnStateMachineThread();
 }
 
 void MediaDecoder::SetPlaybackRate(double aPlaybackRate)
 {
-  if (aPlaybackRate == mInitialPlaybackRate) {
-    return;
-  }
-
   if (aPlaybackRate == 0.0) {
     mPausedForPlaybackRateNull = true;
     mInitialPlaybackRate = aPlaybackRate;
     Pause();
     return;
   } else if (mPausedForPlaybackRateNull) {
     // Play() uses mPausedForPlaybackRateNull value, so must reset it first
     mPausedForPlaybackRateNull = false;
--- a/content/media/fmp4/MP4Decoder.cpp
+++ b/content/media/fmp4/MP4Decoder.cpp
@@ -16,18 +16,17 @@
 
 #ifdef XP_WIN
 #include "mozilla/WindowsVersion.h"
 #endif
 #ifdef MOZ_FFMPEG
 #include "FFmpegRuntimeLinker.h"
 #endif
 #ifdef MOZ_APPLEMEDIA
-#include "apple/AppleCMLinker.h"
-#include "apple/AppleVTLinker.h"
+#include "apple/AppleDecoderModule.h"
 #endif
 
 namespace mozilla {
 
 MediaDecoderStateMachine* MP4Decoder::CreateStateMachine()
 {
   return new MediaDecoderStateMachine(this, new MP4Reader(this));
 }
@@ -146,27 +145,17 @@ IsAppleAvailable()
 #ifndef MOZ_APPLEMEDIA
   // Not the right platform.
   return false;
 #else
   if (!Preferences::GetBool("media.apple.mp4.enabled", false)) {
     // Disabled by preference.
     return false;
   }
-  // Attempt to load the required frameworks.
-  bool haveCoreMedia = AppleCMLinker::Link();
-  if (!haveCoreMedia) {
-    return false;
-  }
-  bool haveVideoToolbox = AppleVTLinker::Link();
-  if (!haveVideoToolbox) {
-    return false;
-  }
-  // All hurdles cleared!
-  return true;
+  return NS_SUCCEEDED(AppleDecoderModule::CanDecode());
 #endif
 }
 
 static bool
 IsGonkMP4DecoderAvailable()
 {
   return Preferences::GetBool("media.fragmented-mp4.gonk.enabled", false);
 }
--- a/content/media/fmp4/apple/AppleCMFunctions.h
+++ b/content/media/fmp4/apple/AppleCMFunctions.h
@@ -1,12 +1,12 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* 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/. */
 
 // Construct references to each of the CoreMedia symbols we use.
 
-LINK_FUNC(CMVideoFormatDescriptionCreate)
-LINK_FUNC(CMBlockBufferCreateWithMemoryBlock)
-LINK_FUNC(CMSampleBufferCreate)
-LINK_FUNC(CMTimeMake)
+LINK_FUNC(VideoFormatDescriptionCreate)
+LINK_FUNC(BlockBufferCreateWithMemoryBlock)
+LINK_FUNC(SampleBufferCreate)
+LINK_FUNC(TimeMake)
--- a/content/media/fmp4/apple/AppleCMLinker.cpp
+++ b/content/media/fmp4/apple/AppleCMLinker.cpp
@@ -3,65 +3,106 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include <dlfcn.h>
 
 #include "AppleCMLinker.h"
 #include "MainThreadUtils.h"
+#include "mozilla/ArrayUtils.h"
+#include "nsCocoaFeatures.h"
 #include "nsDebug.h"
 
 #ifdef PR_LOGGING
 PRLogModuleInfo* GetAppleMediaLog();
 #define LOG(...) PR_LOG(GetAppleMediaLog(), PR_LOG_DEBUG, (__VA_ARGS__))
 #else
 #define LOG(...)
 #endif
 
 namespace mozilla {
 
 AppleCMLinker::LinkStatus
 AppleCMLinker::sLinkStatus = LinkStatus_INIT;
 
 void* AppleCMLinker::sLink = nullptr;
 nsrefcnt AppleCMLinker::sRefCount = 0;
+CFStringRef AppleCMLinker::skPropExtensionAtoms = nullptr;
+CFStringRef AppleCMLinker::skPropFullRangeVideo = nullptr;
 
-#define LINK_FUNC(func) typeof(func) func;
+#define LINK_FUNC(func) typeof(CM ## func) CM ## func;
 #include "AppleCMFunctions.h"
 #undef LINK_FUNC
 
 /* static */ bool
 AppleCMLinker::Link()
 {
   // Bump our reference count every time we're called.
   // Add a lock or change the thread assertion if
   // you need to call this off the main thread.
   MOZ_ASSERT(NS_IsMainThread());
   ++sRefCount;
 
   if (sLinkStatus) {
     return sLinkStatus == LinkStatus_SUCCEEDED;
   }
 
-  const char* dlname =
-    "/System/Library/Frameworks/CoreMedia.framework/CoreMedia";
-  if (!(sLink = dlopen(dlname, RTLD_NOW | RTLD_LOCAL))) {
+  const char* dlnames[] =
+    { "/System/Library/Frameworks/CoreMedia.framework/CoreMedia",
+      "/System/Library/PrivateFrameworks/CoreMedia.framework/CoreMedia" };
+  bool dlfound = false;
+  for (size_t i = 0; i < ArrayLength(dlnames); i++) {
+    if ((sLink = dlopen(dlnames[i], RTLD_NOW | RTLD_LOCAL))) {
+      dlfound = true;
+      break;
+    }
+  }
+  if (!dlfound) {
     NS_WARNING("Couldn't load CoreMedia framework");
     goto fail;
   }
 
-#define LINK_FUNC(func)                                        \
+  if (nsCocoaFeatures::OnLionOrLater()) {
+#define LINK_FUNC2(func)                                       \
   func = (typeof(func))dlsym(sLink, #func);                    \
   if (!func) {                                                 \
-    NS_WARNING("Couldn't load CoreMedia function " #func ); \
+    NS_WARNING("Couldn't load CoreMedia function " #func );    \
     goto fail;                                                 \
   }
+#define LINK_FUNC(func) LINK_FUNC2(CM ## func)
 #include "AppleCMFunctions.h"
 #undef LINK_FUNC
+#undef LINK_FUNC2
+
+    skPropExtensionAtoms =
+      GetIOConst("kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms");
+
+    skPropFullRangeVideo =
+      GetIOConst("kCMFormatDescriptionExtension_FullRangeVideo");
+
+  } else {
+#define LINK_FUNC2(cm, fig)                                    \
+  cm = (typeof(cm))dlsym(sLink, #fig);                         \
+  if (!cm) {                                                   \
+    NS_WARNING("Couldn't load CoreMedia function " #fig );     \
+    goto fail;                                                 \
+  }
+#define LINK_FUNC(func) LINK_FUNC2(CM ## func, Fig ## func)
+#include "AppleCMFunctions.h"
+#undef LINK_FUNC
+#undef LINK_FUNC2
+
+    skPropExtensionAtoms =
+      GetIOConst("kFigFormatDescriptionExtension_SampleDescriptionExtensionAtoms");
+  }
+
+  if (!skPropExtensionAtoms) {
+    goto fail;
+  }
 
   LOG("Loaded CoreMedia framework.");
   sLinkStatus = LinkStatus_SUCCEEDED;
   return true;
 
 fail:
   Unlink();
 
@@ -74,12 +115,24 @@ AppleCMLinker::Unlink()
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(sRefCount > 0, "Unbalanced Unlink()");
   --sRefCount;
   if (sLink && sRefCount < 1) {
     LOG("Unlinking CoreMedia framework.");
     dlclose(sLink);
     sLink = nullptr;
+    sLinkStatus = LinkStatus_INIT;
   }
 }
 
+/* static */ CFStringRef
+AppleCMLinker::GetIOConst(const char* symbol)
+{
+  CFStringRef* address = (CFStringRef*)dlsym(sLink, symbol);
+  if (!address) {
+    return nullptr;
+  }
+
+  return *address;
+}
+
 } // namespace mozilla
--- a/content/media/fmp4/apple/AppleCMLinker.h
+++ b/content/media/fmp4/apple/AppleCMLinker.h
@@ -17,27 +17,31 @@ extern "C" {
 
 namespace mozilla {
 
 class AppleCMLinker
 {
 public:
   static bool Link();
   static void Unlink();
+  static CFStringRef skPropExtensionAtoms;
+  static CFStringRef skPropFullRangeVideo;
 
 private:
   static void* sLink;
   static nsrefcnt sRefCount;
 
   static enum LinkStatus {
     LinkStatus_INIT = 0,
     LinkStatus_FAILED,
     LinkStatus_SUCCEEDED
   } sLinkStatus;
+
+  static CFStringRef GetIOConst(const char* symbol);
 };
 
-#define LINK_FUNC(func) extern typeof(func)* func;
+#define LINK_FUNC(func) extern typeof(CM ## func)* CM ## func;
 #include "AppleCMFunctions.h"
 #undef LINK_FUNC
 
 } // namespace mozilla
 
 #endif // AppleCMLinker_h
--- a/content/media/fmp4/apple/AppleDecoderModule.cpp
+++ b/content/media/fmp4/apple/AppleDecoderModule.cpp
@@ -2,71 +2,140 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "AppleATDecoder.h"
 #include "AppleCMLinker.h"
 #include "AppleDecoderModule.h"
+#include "AppleVDADecoder.h"
+#include "AppleVDALinker.h"
 #include "AppleVTDecoder.h"
 #include "AppleVTLinker.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/DebugOnly.h"
 
 namespace mozilla {
 
-bool AppleDecoderModule::sIsEnabled = false;
+bool AppleDecoderModule::sInitialized = false;
+bool AppleDecoderModule::sIsVTAvailable = false;
+bool AppleDecoderModule::sIsVTHWAvailable = false;
+bool AppleDecoderModule::sIsVDAAvailable = false;
+bool AppleDecoderModule::sForceVDA = false;
 
 AppleDecoderModule::AppleDecoderModule()
 {
 }
 
 AppleDecoderModule::~AppleDecoderModule()
 {
 }
 
 /* static */
 void
 AppleDecoderModule::Init()
 {
   MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread.");
-  sIsEnabled = Preferences::GetBool("media.apple.mp4.enabled", false);
-  if (!sIsEnabled) {
+
+  sForceVDA = Preferences::GetBool("media.apple.forcevda", false);
+
+  if (sInitialized) {
     return;
   }
 
+  // dlopen VideoDecodeAcceleration.framework if it's available.
+  sIsVDAAvailable = AppleVDALinker::Link();
+
   // dlopen CoreMedia.framework if it's available.
-  sIsEnabled = AppleCMLinker::Link();
-  if (!sIsEnabled) {
-    return;
+  bool haveCoreMedia = AppleCMLinker::Link();
+  // dlopen VideoToolbox.framework if it's available.
+  // We must link both CM and VideoToolbox framework to allow for proper
+  // paired Link/Unlink calls
+  bool haveVideoToolbox = AppleVTLinker::Link();
+  sIsVTAvailable = haveCoreMedia && haveVideoToolbox;
+
+  sIsVTHWAvailable = AppleVTLinker::skPropHWAccel != nullptr;
+
+  if (sIsVDAAvailable) {
+    AppleVDALinker::Unlink();
+  }
+  if (sIsVTAvailable) {
+    AppleVTLinker::Unlink();
+    AppleCMLinker::Unlink();
+  }
+  sInitialized = true;
+}
+
+class InitTask : public nsRunnable {
+public:
+  NS_IMETHOD Run() MOZ_OVERRIDE {
+    MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread.");
+    AppleDecoderModule::Init();
+    return NS_OK;
+  }
+};
+
+/* static */
+nsresult
+AppleDecoderModule::CanDecode()
+{
+  if (!sInitialized) {
+    if (NS_IsMainThread()) {
+      Init();
+    } else {
+      nsRefPtr<nsIRunnable> task(new InitTask());
+      NS_DispatchToMainThread(task, NS_DISPATCH_SYNC);
+    }
   }
 
-  // dlopen VideoToolbox.framework if it's available.
-  sIsEnabled = AppleVTLinker::Link();
+  return (sIsVDAAvailable || sIsVTAvailable) ? NS_OK : NS_ERROR_NO_INTERFACE;
 }
 
+class LinkTask : public nsRunnable {
+public:
+  NS_IMETHOD Run() MOZ_OVERRIDE {
+    MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread.");
+    MOZ_ASSERT(AppleDecoderModule::sInitialized);
+    if (AppleDecoderModule::sIsVDAAvailable) {
+      AppleVDALinker::Link();
+    }
+    if (AppleDecoderModule::sIsVTAvailable) {
+      AppleVTLinker::Link();
+      AppleCMLinker::Link();
+    }
+    return NS_OK;
+  }
+};
+
 nsresult
 AppleDecoderModule::Startup()
 {
-  // We don't have any per-instance initialization to do.
-  // Check whether ::Init() above succeeded to know if
-  // we're functional.
-  if (!sIsEnabled) {
+  if (!sIsVDAAvailable && !sIsVTAvailable) {
     return NS_ERROR_FAILURE;
   }
+
+  nsRefPtr<nsIRunnable> task(new LinkTask());
+  NS_DispatchToMainThread(task, NS_DISPATCH_SYNC);
+
   return NS_OK;
 }
 
 class UnlinkTask : public nsRunnable {
 public:
   NS_IMETHOD Run() MOZ_OVERRIDE {
     MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread.");
-    AppleVTLinker::Unlink();
-    AppleCMLinker::Unlink();
+    MOZ_ASSERT(AppleDecoderModule::sInitialized);
+    if (AppleDecoderModule::sIsVDAAvailable) {
+      AppleVDALinker::Unlink();
+    }
+    if (AppleDecoderModule::sIsVTAvailable) {
+      AppleVTLinker::Unlink();
+      AppleCMLinker::Unlink();
+    }
     return NS_OK;
   }
 };
 
 nsresult
 AppleDecoderModule::Shutdown()
 {
   nsRefPtr<nsIRunnable> task(new UnlinkTask());
@@ -76,18 +145,34 @@ AppleDecoderModule::Shutdown()
 
 already_AddRefed<MediaDataDecoder>
 AppleDecoderModule::CreateH264Decoder(const mp4_demuxer::VideoDecoderConfig& aConfig,
                                       layers::LayersBackend aLayersBackend,
                                       layers::ImageContainer* aImageContainer,
                                       MediaTaskQueue* aVideoTaskQueue,
                                       MediaDataDecoderCallback* aCallback)
 {
-  nsRefPtr<MediaDataDecoder> decoder =
-    new AppleVTDecoder(aConfig, aVideoTaskQueue, aCallback, aImageContainer);
+  nsRefPtr<MediaDataDecoder> decoder;
+
+  if (sIsVDAAvailable && (!sIsVTHWAvailable || sForceVDA)) {
+    decoder =
+      AppleVDADecoder::CreateVDADecoder(aConfig,
+                                        aVideoTaskQueue,
+                                        aCallback,
+                                        aImageContainer);
+    if (decoder) {
+      return decoder.forget();
+    }
+  }
+  // We fallback here if VDA isn't available, or is available but isn't
+  // supported by the current platform.
+  if (sIsVTAvailable) {
+    decoder =
+      new AppleVTDecoder(aConfig, aVideoTaskQueue, aCallback, aImageContainer);
+  }
   return decoder.forget();
 }
 
 already_AddRefed<MediaDataDecoder>
 AppleDecoderModule::CreateAudioDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig,
                                        MediaTaskQueue* aAudioTaskQueue,
                                        MediaDataDecoderCallback* aCallback)
 {
--- a/content/media/fmp4/apple/AppleDecoderModule.h
+++ b/content/media/fmp4/apple/AppleDecoderModule.h
@@ -36,15 +36,25 @@ public:
   virtual already_AddRefed<MediaDataDecoder>
   CreateAudioDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig,
                      MediaTaskQueue* aAudioTaskQueue,
                      MediaDataDecoderCallback* aCallback) MOZ_OVERRIDE;
 
   virtual bool SupportsAudioMimeType(const char* aMimeType) MOZ_OVERRIDE;
 
   static void Init();
+  static nsresult CanDecode();
+
 private:
-  static bool sIsEnabled;
+  friend class InitTask;
+  friend class LinkTask;
+  friend class UnlinkTask;
+
+  static bool sInitialized;
+  static bool sIsVTAvailable;
+  static bool sIsVTHWAvailable;
+  static bool sIsVDAAvailable;
+  static bool sForceVDA;
 };
 
 } // namespace mozilla
 
 #endif // mozilla_AppleDecoderModule_h
copy from content/media/fmp4/apple/AppleVTDecoder.cpp
copy to content/media/fmp4/apple/AppleVDADecoder.cpp
--- a/content/media/fmp4/apple/AppleVTDecoder.cpp
+++ b/content/media/fmp4/apple/AppleVDADecoder.cpp
@@ -1,252 +1,243 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include <CoreFoundation/CFString.h>
 
-#include "AppleCMLinker.h"
 #include "AppleUtils.h"
-#include "AppleVTDecoder.h"
-#include "AppleVTLinker.h"
+#include "AppleVDADecoder.h"
+#include "AppleVDALinker.h"
 #include "mp4_demuxer/DecoderData.h"
-#include "MP4Reader.h"
 #include "MP4Decoder.h"
 #include "MediaData.h"
 #include "MacIOSurfaceImage.h"
 #include "mozilla/ArrayUtils.h"
 #include "nsAutoPtr.h"
+#include "nsCocoaFeatures.h"
 #include "nsThreadUtils.h"
 #include "prlog.h"
 #include "VideoUtils.h"
 
 #ifdef PR_LOGGING
 PRLogModuleInfo* GetAppleMediaLog();
 #define LOG(...) PR_LOG(GetAppleMediaLog(), PR_LOG_DEBUG, (__VA_ARGS__))
 //#define LOG_MEDIA_SHA1
 #else
 #define LOG(...)
 #endif
 
-#ifdef LOG_MEDIA_SHA1
-#include "mozilla/SHA1.h"
-#endif
-
 namespace mozilla {
 
-AppleVTDecoder::AppleVTDecoder(const mp4_demuxer::VideoDecoderConfig& aConfig,
+AppleVDADecoder::AppleVDADecoder(const mp4_demuxer::VideoDecoderConfig& aConfig,
                                MediaTaskQueue* aVideoTaskQueue,
                                MediaDataDecoderCallback* aCallback,
                                layers::ImageContainer* aImageContainer)
   : mConfig(aConfig)
   , mTaskQueue(aVideoTaskQueue)
   , mCallback(aCallback)
   , mImageContainer(aImageContainer)
-  , mFormat(nullptr)
-  , mSession(nullptr)
+  , mDecoder(nullptr)
+  , mIs106(!nsCocoaFeatures::OnLionOrLater())
 {
-  MOZ_COUNT_CTOR(AppleVTDecoder);
+  MOZ_COUNT_CTOR(AppleVDADecoder);
   // TODO: Verify aConfig.mime_type.
-  LOG("Creating AppleVTDecoder for %dx%d h.264 video",
+  LOG("Creating AppleVDADecoder for %dx%d h.264 video",
       mConfig.display_width,
       mConfig.display_height
      );
 }
 
-AppleVTDecoder::~AppleVTDecoder()
+AppleVDADecoder::~AppleVDADecoder()
 {
-  MOZ_COUNT_DTOR(AppleVTDecoder);
+  MOZ_COUNT_DTOR(AppleVDADecoder);
 }
 
 nsresult
-AppleVTDecoder::Init()
+AppleVDADecoder::Init()
 {
+  if (mDecoder) {
+    return NS_OK;
+  }
   nsresult rv = InitializeSession();
   return rv;
 }
 
 nsresult
-AppleVTDecoder::Shutdown()
+AppleVDADecoder::Shutdown()
 {
-  if (mSession) {
-    LOG("%s: cleaning up session %p", __func__, mSession);
-    VTDecompressionSessionInvalidate(mSession);
-    CFRelease(mSession);
-    mSession = nullptr;
-  }
-  if (mFormat) {
-    LOG("%s: releasing format %p", __func__, mFormat);
-    CFRelease(mFormat);
-    mFormat = nullptr;
+  if (mDecoder) {
+    LOG("%s: cleaning up decoder %p", __func__, mDecoder);
+    VDADecoderDestroy(mDecoder);
+    mDecoder = nullptr;
   }
   return NS_OK;
 }
 
 nsresult
-AppleVTDecoder::Input(mp4_demuxer::MP4Sample* aSample)
+AppleVDADecoder::Input(mp4_demuxer::MP4Sample* aSample)
 {
   LOG("mp4 input sample %p pts %lld duration %lld us%s %d bytes",
       aSample,
       aSample->composition_timestamp,
       aSample->duration,
       aSample->is_sync_point ? " keyframe" : "",
       aSample->size);
 
-#ifdef LOG_MEDIA_SHA1
-  SHA1Sum hash;
-  hash.update(aSample->data, aSample->size);
-  uint8_t digest_buf[SHA1Sum::kHashSize];
-  hash.finish(digest_buf);
-  nsAutoCString digest;
-  for (size_t i = 0; i < sizeof(digest_buf); i++) {
-    digest.AppendPrintf("%02x", digest_buf[i]);
-  }
-  LOG("    sha1 %s", digest.get());
-#endif // LOG_MEDIA_SHA1
-
   mTaskQueue->Dispatch(
       NS_NewRunnableMethodWithArg<nsAutoPtr<mp4_demuxer::MP4Sample>>(
           this,
-          &AppleVTDecoder::SubmitFrame,
+          &AppleVDADecoder::SubmitFrame,
           nsAutoPtr<mp4_demuxer::MP4Sample>(aSample)));
   return NS_OK;
 }
 
 nsresult
-AppleVTDecoder::Flush()
+AppleVDADecoder::Flush()
 {
   mTaskQueue->Flush();
-  nsresult rv = WaitForAsynchronousFrames();
-  if (NS_FAILED(rv)) {
-    LOG("AppleVTDecoder::Drain failed waiting for platform decoder.");
+  OSStatus rv = VDADecoderFlush(mDecoder, 0 /*dont emit*/);
+  if (rv != noErr) {
+    LOG("AppleVDADecoder::Flush failed waiting for platform decoder "
+        "with error:%d.", rv);
   }
   ClearReorderedFrames();
 
-  return rv;
+  return NS_OK;
 }
 
 nsresult
-AppleVTDecoder::Drain()
+AppleVDADecoder::Drain()
 {
   mTaskQueue->AwaitIdle();
-  nsresult rv = WaitForAsynchronousFrames();
-  if (NS_FAILED(rv)) {
-    LOG("AppleVTDecoder::Drain failed waiting for platform decoder.");
-    return rv;
+  OSStatus rv = VDADecoderFlush(mDecoder, kVDADecoderFlush_EmitFrames);
+  if (rv != noErr) {
+    LOG("AppleVDADecoder::Drain failed waiting for platform decoder "
+        "with error:%d.", rv);
   }
   DrainReorderedFrames();
   mCallback->DrainComplete();
   return NS_OK;
 }
 
 //
 // Implementation details.
 //
 
-// Context object to hold a copy of sample metadata.
-class FrameRef {
-public:
-  Microseconds decode_timestamp;
-  Microseconds composition_timestamp;
-  Microseconds duration;
-  int64_t byte_offset;
-  bool is_sync_point;
-
-  explicit FrameRef(mp4_demuxer::MP4Sample* aSample)
-  {
-    MOZ_ASSERT(aSample);
-    decode_timestamp = aSample->decode_timestamp;
-    composition_timestamp = aSample->composition_timestamp;
-    duration = aSample->duration;
-    byte_offset = aSample->byte_offset;
-    is_sync_point = aSample->is_sync_point;
-  }
-};
-
 // Callback passed to the VideoToolbox decoder for returning data.
 // This needs to be static because the API takes a C-style pair of
 // function and userdata pointers. This validates parameters and
 // forwards the decoded image back to an object method.
 static void
 PlatformCallback(void* decompressionOutputRefCon,
-                 void* sourceFrameRefCon,
+                 CFDictionaryRef frameInfo,
                  OSStatus status,
-                 VTDecodeInfoFlags flags,
-                 CVImageBufferRef image,
-                 CMTime presentationTimeStamp,
-                 CMTime presentationDuration)
+                 VDADecodeInfoFlags infoFlags,
+                 CVImageBufferRef image)
 {
-  LOG("AppleVideoDecoder %s status %d flags %d", __func__, status, flags);
-
-  AppleVTDecoder* decoder =
-    static_cast<AppleVTDecoder*>(decompressionOutputRefCon);
-  nsAutoPtr<FrameRef> frameRef =
-    nsAutoPtr<FrameRef>(static_cast<FrameRef*>(sourceFrameRefCon));
-
-  LOG("mp4 output frame %lld dts %lld pts %lld duration %lld us%s",
-    frameRef->byte_offset,
-    frameRef->decode_timestamp,
-    frameRef->composition_timestamp,
-    frameRef->duration,
-    frameRef->is_sync_point ? " keyframe" : ""
-  );
+  LOG("AppleVDADecoder[%s] status %d flags %d retainCount %ld",
+      __func__, status, infoFlags, CFGetRetainCount(frameInfo));
 
   // Validate our arguments.
+  // According to Apple's TN2267
+  // The output callback is still called for all flushed frames,
+  // but no image buffers will be returned.
+  // FIXME: Distinguish between errors and empty flushed frames.
   if (status != noErr || !image) {
-    NS_WARNING("VideoToolbox decoder returned no data");
+    NS_WARNING("AppleVDADecoder decoder returned no data");
+    return;
+  }
+  MOZ_ASSERT(CFGetTypeID(image) == CVPixelBufferGetTypeID(),
+             "AppleVDADecoder returned an unexpected image type");
+
+  if (infoFlags & kVDADecodeInfo_FrameDropped)
+  {
+    NS_WARNING("  ...frame dropped...");
     return;
   }
-  if (flags & kVTDecodeInfo_FrameDropped) {
-    NS_WARNING("  ...frame dropped...");
-  }
-  MOZ_ASSERT(CFGetTypeID(image) == CVPixelBufferGetTypeID(),
-    "VideoToolbox returned an unexpected image type");
+
+  AppleVDADecoder* decoder =
+    static_cast<AppleVDADecoder*>(decompressionOutputRefCon);
+
+  AutoCFRelease<CFNumberRef> ptsref =
+    (CFNumberRef)CFDictionaryGetValue(frameInfo, CFSTR("FRAME_PTS"));
+  AutoCFRelease<CFNumberRef> dtsref =
+    (CFNumberRef)CFDictionaryGetValue(frameInfo, CFSTR("FRAME_DTS"));
+  AutoCFRelease<CFNumberRef> durref =
+    (CFNumberRef)CFDictionaryGetValue(frameInfo, CFSTR("FRAME_DURATION"));
+  AutoCFRelease<CFNumberRef> boref =
+    (CFNumberRef)CFDictionaryGetValue(frameInfo, CFSTR("FRAME_OFFSET"));
+  AutoCFRelease<CFNumberRef> kfref =
+    (CFNumberRef)CFDictionaryGetValue(frameInfo, CFSTR("FRAME_KEYFRAME"));
+
+  Microseconds dts;
+  Microseconds pts;
+  Microseconds duration;
+  int64_t byte_offset;
+  char is_sync_point;
+
+  CFNumberGetValue(ptsref, kCFNumberSInt64Type, &pts);
+  CFNumberGetValue(dtsref, kCFNumberSInt64Type, &dts);
+  CFNumberGetValue(durref, kCFNumberSInt64Type, &duration);
+  CFNumberGetValue(boref, kCFNumberSInt64Type, &byte_offset);
+  CFNumberGetValue(kfref, kCFNumberSInt8Type, &is_sync_point);
+
+  nsAutoPtr<AppleVDADecoder::AppleFrameRef> frameRef(
+    new AppleVDADecoder::AppleFrameRef(dts,
+    pts,
+    duration,
+    byte_offset,
+    is_sync_point == 1));
 
   // Forward the data back to an object method which can access
   // the correct MP4Reader callback.
   decoder->OutputFrame(image, frameRef);
 }
 
-nsresult
-AppleVTDecoder::WaitForAsynchronousFrames()
+AppleVDADecoder::AppleFrameRef*
+AppleVDADecoder::CreateAppleFrameRef(const mp4_demuxer::MP4Sample* aSample)
 {
-  OSStatus rv = VTDecompressionSessionWaitForAsynchronousFrames(mSession);
-  if (rv != noErr) {
-    LOG("AppleVTDecoder: Error %d waiting for asynchronous frames", rv);
-    return NS_ERROR_FAILURE;
-  }
-  return NS_OK;
+  MOZ_ASSERT(aSample);
+  return new AppleFrameRef(*aSample);
 }
 
 void
-AppleVTDecoder::DrainReorderedFrames()
+AppleVDADecoder::DrainReorderedFrames()
 {
   while (!mReorderQueue.IsEmpty()) {
     mCallback->Output(mReorderQueue.Pop());
   }
 }
 
 void
-AppleVTDecoder::ClearReorderedFrames()
+AppleVDADecoder::ClearReorderedFrames()
 {
   while (!mReorderQueue.IsEmpty()) {
     delete mReorderQueue.Pop();
   }
 }
 
 // Copy and return a decoded frame.
 nsresult
-AppleVTDecoder::OutputFrame(CVPixelBufferRef aImage,
-                            nsAutoPtr<FrameRef> aFrameRef)
+AppleVDADecoder::OutputFrame(CVPixelBufferRef aImage,
+                             nsAutoPtr<AppleVDADecoder::AppleFrameRef> aFrameRef)
 {
   IOSurfacePtr surface = MacIOSurfaceLib::CVPixelBufferGetIOSurface(aImage);
-  MOZ_ASSERT(surface, "VideoToolbox didn't return an IOSurface backed buffer");
+  MOZ_ASSERT(surface, "Decoder didn't return an IOSurface backed buffer");
+
+  LOG("mp4 output frame %lld dts %lld pts %lld duration %lld us%s",
+    aFrameRef->byte_offset,
+    aFrameRef->decode_timestamp,
+    aFrameRef->composition_timestamp,
+    aFrameRef->duration,
+    aFrameRef->is_sync_point ? " keyframe" : ""
+  );
 
   nsRefPtr<MacIOSurface> macSurface = new MacIOSurface(surface);
   // Bounds.
   VideoInfo info;
   info.mDisplay = nsIntSize(macSurface->GetWidth(), macSurface->GetHeight());
   info.mHasVideo = true;
   gfx::IntRect visible = gfx::IntRect(0,
                                       0,
@@ -292,174 +283,223 @@ AppleVTDecoder::OutputFrame(CVPixelBuffe
     }
   }
   LOG("%llu decoded frames queued",
       static_cast<unsigned long long>(mReorderQueue.Length()));
 
   return NS_OK;
 }
 
-// Helper to fill in a timestamp structure.
-static CMSampleTimingInfo
-TimingInfoFromSample(mp4_demuxer::MP4Sample* aSample)
+nsresult
+AppleVDADecoder::SubmitFrame(mp4_demuxer::MP4Sample* aSample)
 {
-  CMSampleTimingInfo timestamp;
-
-  timestamp.duration = CMTimeMake(aSample->duration, USECS_PER_S);
-  timestamp.presentationTimeStamp =
-    CMTimeMake(aSample->composition_timestamp, USECS_PER_S);
-  timestamp.decodeTimeStamp =
-    CMTimeMake(aSample->decode_timestamp, USECS_PER_S);
+  AutoCFRelease<CFDataRef> block =
+    CFDataCreate(kCFAllocatorDefault, aSample->data, aSample->size);
+  if (!block) {
+    NS_ERROR("Couldn't create CFData");
+    return NS_ERROR_FAILURE;
+  }
 
-  return timestamp;
-}
-
-nsresult
-AppleVTDecoder::SubmitFrame(mp4_demuxer::MP4Sample* aSample)
-{
-  // For some reason this gives me a double-free error with stagefright.
-  AutoCFRelease<CMBlockBufferRef> block = nullptr;
-  AutoCFRelease<CMSampleBufferRef> sample = nullptr;
-  VTDecodeInfoFlags flags;
-  OSStatus rv;
+  AutoCFRelease<CFNumberRef> pts =
+    CFNumberCreate(kCFAllocatorDefault,
+                   kCFNumberSInt64Type,
+                   &aSample->composition_timestamp);
+  AutoCFRelease<CFNumberRef> dts =
+    CFNumberCreate(kCFAllocatorDefault,
+                   kCFNumberSInt64Type,
+                   &aSample->decode_timestamp);
+  AutoCFRelease<CFNumberRef> duration =
+    CFNumberCreate(kCFAllocatorDefault,
+                   kCFNumberSInt64Type,
+                   &aSample->duration);
+  AutoCFRelease<CFNumberRef> byte_offset =
+    CFNumberCreate(kCFAllocatorDefault,
+                   kCFNumberSInt64Type,
+                   &aSample->byte_offset);
+  char keyframe = aSample->is_sync_point ? 1 : 0;
+  AutoCFRelease<CFNumberRef> cfkeyframe =
+    CFNumberCreate(kCFAllocatorDefault,
+                   kCFNumberSInt8Type,
+                   &keyframe);
 
-  // FIXME: This copies the sample data. I think we can provide
-  // a custom block source which reuses the aSample buffer.
-  // But note that there may be a problem keeping the samples
-  // alive over multiple frames.
-  rv = CMBlockBufferCreateWithMemoryBlock(NULL // Struct allocator.
-                                         ,aSample->data
-                                         ,aSample->size
-                                         ,kCFAllocatorNull // Block allocator.
-                                         ,NULL // Block source.
-                                         ,0    // Data offset.
-                                         ,aSample->size
-                                         ,false
-                                         ,block.receive());
-  NS_ASSERTION(rv == noErr, "Couldn't create CMBlockBuffer");
-  CMSampleTimingInfo timestamp = TimingInfoFromSample(aSample);
-  rv = CMSampleBufferCreate(NULL, block, true, 0, 0, mFormat, 1, 1, &timestamp, 0, NULL, sample.receive());
-  NS_ASSERTION(rv == noErr, "Couldn't create CMSampleBuffer");
-  rv = VTDecompressionSessionDecodeFrame(mSession,
-                                         sample,
-                                         0,
-                                         new FrameRef(aSample),
-                                         &flags);
-  NS_ASSERTION(rv == noErr, "Couldn't pass frame to decoder");
+  const void* keys[] = { CFSTR("FRAME_PTS"),
+                         CFSTR("FRAME_DTS"),
+                         CFSTR("FRAME_DURATION"),
+                         CFSTR("FRAME_OFFSET"),
+                         CFSTR("FRAME_KEYFRAME") };
+  const void* values[] = { pts,
+                           dts,
+                           duration,
+                           byte_offset,
+                           cfkeyframe };
+  static_assert(ArrayLength(keys) == ArrayLength(values),
+                "Non matching keys/values array size");
+
+  AutoCFRelease<CFDictionaryRef> frameInfo =
+    CFDictionaryCreate(kCFAllocatorDefault,
+                       keys,
+                       values,
+                       ArrayLength(keys),
+                       &kCFTypeDictionaryKeyCallBacks,
+                       &kCFTypeDictionaryValueCallBacks);
+
+  OSStatus rv = VDADecoderDecode(mDecoder,
+                                 0,
+                                 block,
+                                 frameInfo);
+
+  LOG("[%s]: FrameInfo retain count = %ld",
+      __func__, CFGetRetainCount(frameInfo));
+  MOZ_ASSERT(CFGetRetainCount(frameInfo) >= 2, "Bad retain count");
+
+  if (rv != noErr) {
+    NS_ERROR("AppleVDADecoder: Couldn't pass frame to decoder");
+    return NS_ERROR_FAILURE;
+  }
+
+  if (mIs106) {
+    // TN2267:
+    // frameInfo: A CFDictionaryRef containing information to be returned in
+    // the output callback for this frame.
+    // This dictionary can contain client provided information associated with
+    // the frame being decoded, for example presentation time.
+    // The CFDictionaryRef will be retained by the framework.
+    // In 10.6, it is released one too many. So retain it.
+    CFRetain(frameInfo);
+  }
 
   // Ask for more data.
   if (mTaskQueue->IsEmpty()) {
-    LOG("AppleVTDecoder task queue empty; requesting more data");
+    LOG("AppleVDADecoder task queue empty; requesting more data");
     mCallback->InputExhausted();
   }
 
   return NS_OK;
 }
 
 nsresult
-AppleVTDecoder::InitializeSession()
+AppleVDADecoder::InitializeSession()
 {
   OSStatus rv;
-  AutoCFRelease<CFMutableDictionaryRef> extensions =
-    CFDictionaryCreateMutable(NULL, 0,
-                              &kCFTypeDictionaryKeyCallBacks,
-                              &kCFTypeDictionaryValueCallBacks);
-  AppleUtils::SetCFDict(extensions, "CVImageBufferChromaLocationBottomField", "left");
-  AppleUtils::SetCFDict(extensions, "CVImageBufferChromaLocationTopField", "left");
-  AppleUtils::SetCFDict(extensions, "FullRangeVideo", true);
 
-  AutoCFRelease<CFMutableDictionaryRef> atoms =
-    CFDictionaryCreateMutable(NULL, 0,
-                              &kCFTypeDictionaryKeyCallBacks,
-                              &kCFTypeDictionaryValueCallBacks);
-  AutoCFRelease<CFDataRef> avc_data = CFDataCreate(NULL,
-      mConfig.extra_data.begin(), mConfig.extra_data.length());
+  AutoCFRelease<CFDictionaryRef> decoderConfig =
+    CreateDecoderSpecification();
+
+  AutoCFRelease<CFDictionaryRef> outputConfiguration =
+    CreateOutputConfiguration();
 
-#ifdef LOG_MEDIA_SHA1
-  SHA1Sum avc_hash;
-  avc_hash.update(mConfig.extra_data.begin(), mConfig.extra_data.length());
-  uint8_t digest_buf[SHA1Sum::kHashSize];
-  avc_hash.finish(digest_buf);
-  nsAutoCString avc_digest;
-  for (size_t i = 0; i < sizeof(digest_buf); i++) {
-    avc_digest.AppendPrintf("%02x", digest_buf[i]);
-  }
-  LOG("AVCDecoderConfig %ld bytes sha1 %s",
-      mConfig.extra_data.length(), avc_digest.get());
-#endif // LOG_MEDIA_SHA1
+  rv =
+    VDADecoderCreate(decoderConfig,
+                     outputConfiguration,
+                     (VDADecoderOutputCallback*)PlatformCallback,
+                     this,
+                     &mDecoder);
 
-  CFDictionarySetValue(atoms, CFSTR("avcC"), avc_data);
-  CFDictionarySetValue(extensions, CFSTR("SampleDescriptionExtensionAtoms"), atoms);
-  rv = CMVideoFormatDescriptionCreate(NULL, // Use default allocator.
-                                      kCMVideoCodecType_H264,
-                                      mConfig.display_width,
-                                      mConfig.display_height,
-                                      extensions,
-                                      &mFormat);
   if (rv != noErr) {
-    NS_ERROR("Couldn't create format description!");
+    NS_ERROR("AppleVDADecoder: Couldn't create decoder!");
     return NS_ERROR_FAILURE;
   }
 
-  // Contruct video decoder selection spec.
-  AutoCFRelease<CFDictionaryRef> spec = CreateDecoderSpecification();
+  return NS_OK;
+}
+
+CFDictionaryRef
+AppleVDADecoder::CreateDecoderSpecification()
+{
+  const uint8_t* extradata = mConfig.extra_data.begin();
+  int extrasize = mConfig.extra_data.length();
+
+  OSType format = 'avc1';
+  AutoCFRelease<CFNumberRef> avc_width  =
+    CFNumberCreate(kCFAllocatorDefault,
+                   kCFNumberSInt32Type,
+                   &mConfig.display_width);
+  AutoCFRelease<CFNumberRef> avc_height =
+    CFNumberCreate(kCFAllocatorDefault,
+                   kCFNumberSInt32Type,
+                   &mConfig.display_height);
+  AutoCFRelease<CFNumberRef> avc_format =
+    CFNumberCreate(kCFAllocatorDefault,
+                   kCFNumberSInt32Type,
+                   &format);
+  AutoCFRelease<CFDataRef> avc_data =
+    CFDataCreate(kCFAllocatorDefault,
+                 extradata,
+                 extrasize);
+
+  const void* decoderKeys[] = { AppleVDALinker::skPropWidth,
+                                AppleVDALinker::skPropHeight,
+                                AppleVDALinker::skPropSourceFormat,
+                                AppleVDALinker::skPropAVCCData };
+  const void* decoderValue[] = { avc_width,
+                                 avc_height,
+                                 avc_format,
+                                 avc_data };
+  static_assert(ArrayLength(decoderKeys) == ArrayLength(decoderValue),
+                "Non matching keys/values array size");
+
+  return CFDictionaryCreate(kCFAllocatorDefault,
+                            decoderKeys,
+                            decoderValue,
+                            ArrayLength(decoderKeys),
+                            &kCFTypeDictionaryKeyCallBacks,
+                            &kCFTypeDictionaryValueCallBacks);
+}
+
+CFDictionaryRef
+AppleVDADecoder::CreateOutputConfiguration()
+{
+  // Construct IOSurface Properties
+  const void* IOSurfaceKeys[] = { MacIOSurfaceLib::kPropIsGlobal };
+  const void* IOSurfaceValues[] = { kCFBooleanTrue };
+  static_assert(ArrayLength(IOSurfaceKeys) == ArrayLength(IOSurfaceValues),
+                "Non matching keys/values array size");
 
   // Contruct output configuration.
   AutoCFRelease<CFDictionaryRef> IOSurfaceProperties =
-    CFDictionaryCreate(NULL,
-                       NULL,
-                       NULL,
-                       0,
+    CFDictionaryCreate(kCFAllocatorDefault,
+                       IOSurfaceKeys,
+                       IOSurfaceValues,
+                       ArrayLength(IOSurfaceKeys),
                        &kCFTypeDictionaryKeyCallBacks,
                        &kCFTypeDictionaryValueCallBacks);
 
   SInt32 PixelFormatTypeValue = kCVPixelFormatType_32BGRA;
   AutoCFRelease<CFNumberRef> PixelFormatTypeNumber =
-    CFNumberCreate(NULL, kCFNumberSInt32Type, &PixelFormatTypeValue);
+    CFNumberCreate(kCFAllocatorDefault,
+                   kCFNumberSInt32Type,
+                   &PixelFormatTypeValue);
 
   const void* outputKeys[] = { kCVPixelBufferIOSurfacePropertiesKey,
                                kCVPixelBufferPixelFormatTypeKey,
                                kCVPixelBufferOpenGLCompatibilityKey };
   const void* outputValues[] = { IOSurfaceProperties,
                                  PixelFormatTypeNumber,
                                  kCFBooleanTrue };
-  AutoCFRelease<CFDictionaryRef> outputConfiguration =
-    CFDictionaryCreate(NULL,
-                       outputKeys,
-                       outputValues,
-                       ArrayLength(outputKeys),
-                       &kCFTypeDictionaryKeyCallBacks,
-                       &kCFTypeDictionaryValueCallBacks);
-
-  VTDecompressionOutputCallbackRecord cb = { PlatformCallback, this };
-  rv = VTDecompressionSessionCreate(NULL, // Allocator.
-                                    mFormat,
-                                    spec, // Video decoder selection.
-                                    outputConfiguration, // Output video format.
-                                    &cb,
-                                    &mSession);
+  static_assert(ArrayLength(outputKeys) == ArrayLength(outputValues),
+                "Non matching keys/values array size");
 
-  if (rv != noErr) {
-    NS_ERROR("Couldn't create decompression session!");
-    return NS_ERROR_FAILURE;
-  }
-
-  return NS_OK;
-}
-
-CFDictionaryRef
-AppleVTDecoder::CreateDecoderSpecification()
-{
-  if (!AppleVTLinker::GetPropHWAccel()) {
-    return nullptr;
-  }
-
-  const void* specKeys[] = { AppleVTLinker::GetPropHWAccel() };
-  const void* specValues[] = { kCFBooleanTrue };
-  return CFDictionaryCreate(NULL,
-                            specKeys,
-                            specValues,
-                            ArrayLength(specKeys),
+  return CFDictionaryCreate(kCFAllocatorDefault,
+                            outputKeys,
+                            outputValues,
+                            ArrayLength(outputKeys),
                             &kCFTypeDictionaryKeyCallBacks,
                             &kCFTypeDictionaryValueCallBacks);
 }
 
+/* static */
+already_AddRefed<AppleVDADecoder>
+AppleVDADecoder::CreateVDADecoder(
+  const mp4_demuxer::VideoDecoderConfig& aConfig,
+  MediaTaskQueue* aVideoTaskQueue,
+  MediaDataDecoderCallback* aCallback,
+  layers::ImageContainer* aImageContainer)
+{
+  nsRefPtr<AppleVDADecoder> decoder =
+    new AppleVDADecoder(aConfig, aVideoTaskQueue, aCallback, aImageContainer);
+  if (NS_FAILED(decoder->Init())) {
+    NS_ERROR("AppleVDADecoder an error occurred");
+    return nullptr;
+  }
+  return decoder.forget();
+}
+
 } // namespace mozilla
copy from content/media/fmp4/apple/AppleVTDecoder.h
copy to content/media/fmp4/apple/AppleVDADecoder.h
--- a/content/media/fmp4/apple/AppleVTDecoder.h
+++ b/content/media/fmp4/apple/AppleVDADecoder.h
@@ -1,64 +1,108 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#ifndef mozilla_AppleVTDecoder_h
-#define mozilla_AppleVTDecoder_h
+#ifndef mozilla_AppleVDADecoder_h
+#define mozilla_AppleVDADecoder_h
 
 #include "PlatformDecoderModule.h"
 #include "mozilla/RefPtr.h"
 #include "mozilla/ReentrantMonitor.h"
+#include "MP4Reader.h"
+#include "MP4Decoder.h"
 #include "nsIThread.h"
 #include "ReorderQueue.h"
 
-#include "VideoToolbox/VideoToolbox.h"
+#include "VideoDecodeAcceleration/VDADecoder.h"
 
 namespace mozilla {
 
 class MediaTaskQueue;
 class MediaDataDecoderCallback;
 namespace layers {
   class ImageContainer;
 }
-class FrameRef;
 
-class AppleVTDecoder : public MediaDataDecoder {
+class AppleVDADecoder : public MediaDataDecoder {
 public:
-  AppleVTDecoder(const mp4_demuxer::VideoDecoderConfig& aConfig,
-                 MediaTaskQueue* aVideoTaskQueue,
-                 MediaDataDecoderCallback* aCallback,
-                 layers::ImageContainer* aImageContainer);
-  ~AppleVTDecoder();
+  class AppleFrameRef {
+  public:
+    Microseconds decode_timestamp;
+    Microseconds composition_timestamp;
+    Microseconds duration;
+    int64_t byte_offset;
+    bool is_sync_point;
+
+    explicit AppleFrameRef(const mp4_demuxer::MP4Sample& aSample)
+    : decode_timestamp(aSample.decode_timestamp)
+    , composition_timestamp(aSample.composition_timestamp)
+    , duration(aSample.duration)
+    , byte_offset(aSample.byte_offset)
+    , is_sync_point(aSample.is_sync_point)
+    {
+    }
+
+    AppleFrameRef(Microseconds aDts,
+                  Microseconds aPts,
+                  Microseconds aDuration,
+                  int64_t aByte_offset,
+                  bool aIs_sync_point)
+    : decode_timestamp(aDts)
+    , composition_timestamp(aPts)
+    , duration(aDuration)
+    , byte_offset(aByte_offset)
+    , is_sync_point(aIs_sync_point)
+    {
+    }
+  };
+
+  // Return a new created AppleVDADecoder or nullptr if media or hardware is
+  // not supported by current configuration.
+  static already_AddRefed<AppleVDADecoder> CreateVDADecoder(
+    const mp4_demuxer::VideoDecoderConfig& aConfig,
+    MediaTaskQueue* aVideoTaskQueue,
+    MediaDataDecoderCallback* aCallback,
+    layers::ImageContainer* aImageContainer);
+
+  AppleVDADecoder(const mp4_demuxer::VideoDecoderConfig& aConfig,
+                  MediaTaskQueue* aVideoTaskQueue,
+                  MediaDataDecoderCallback* aCallback,
+                  layers::ImageContainer* aImageContainer);
+  ~AppleVDADecoder();
   virtual nsresult Init() MOZ_OVERRIDE;
   virtual nsresult Input(mp4_demuxer::MP4Sample* aSample) MOZ_OVERRIDE;
   virtual nsresult Flush() MOZ_OVERRIDE;
   virtual nsresult Drain() MOZ_OVERRIDE;
   virtual nsresult Shutdown() MOZ_OVERRIDE;
-  // Return hook for VideoToolbox callback.
+
   nsresult OutputFrame(CVPixelBufferRef aImage,
-                       nsAutoPtr<FrameRef> frameRef);
-private:
+                       nsAutoPtr<AppleFrameRef> aFrameRef);
+
+ protected:
+  AppleFrameRef* CreateAppleFrameRef(const mp4_demuxer::MP4Sample* aSample);
+  void DrainReorderedFrames();
+  void ClearReorderedFrames();
+  CFDictionaryRef CreateOutputConfiguration();
+
   const mp4_demuxer::VideoDecoderConfig& mConfig;
   RefPtr<MediaTaskQueue> mTaskQueue;
   MediaDataDecoderCallback* mCallback;
   layers::ImageContainer* mImageContainer;
-  CMVideoFormatDescriptionRef mFormat;
-  VTDecompressionSessionRef mSession;
   ReorderQueue mReorderQueue;
 
+private:
+  VDADecoder mDecoder;
+  bool mIs106;
+
   // Method to pass a frame to VideoToolbox for decoding.
   nsresult SubmitFrame(mp4_demuxer::MP4Sample* aSample);
   // Method to set up the decompression session.
   nsresult InitializeSession();
-  nsresult WaitForAsynchronousFrames();
-  void DrainReorderedFrames();
-  void ClearReorderedFrames();
-
   CFDictionaryRef CreateDecoderSpecification();
 };
 
 } // namespace mozilla
 
-#endif // mozilla_AppleVTDecoder_h
+#endif // mozilla_AppleVDADecoder_h
copy from content/media/fmp4/apple/AppleVTFunctions.h
copy to content/media/fmp4/apple/AppleVDAFunctions.h
--- a/content/media/fmp4/apple/AppleVTFunctions.h
+++ b/content/media/fmp4/apple/AppleVDAFunctions.h
@@ -1,12 +1,12 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* 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/. */
 
-// Construct references to each of the VideoToolbox symbols we use.
+// Construct references to each of the VDA symbols we use.
 
-LINK_FUNC(VTDecompressionSessionCreate)
-LINK_FUNC(VTDecompressionSessionDecodeFrame)
-LINK_FUNC(VTDecompressionSessionInvalidate)
-LINK_FUNC(VTDecompressionSessionWaitForAsynchronousFrames)
+LINK_FUNC(VDADecoderCreate)
+LINK_FUNC(VDADecoderDecode)
+LINK_FUNC(VDADecoderFlush)
+LINK_FUNC(VDADecoderDestroy)
copy from content/media/fmp4/apple/AppleVTLinker.cpp
copy to content/media/fmp4/apple/AppleVDALinker.cpp
--- a/content/media/fmp4/apple/AppleVTLinker.cpp
+++ b/content/media/fmp4/apple/AppleVDALinker.cpp
@@ -1,112 +1,119 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include <dlfcn.h>
 
-#include "AppleVTLinker.h"
+#include "AppleVDALinker.h"
 #include "MainThreadUtils.h"
 #include "nsDebug.h"
 
 #ifdef PR_LOGGING
 PRLogModuleInfo* GetAppleMediaLog();
 #define LOG(...) PR_LOG(GetAppleMediaLog(), PR_LOG_DEBUG, (__VA_ARGS__))
 #else
 #define LOG(...)
 #endif
 
 namespace mozilla {
 
-AppleVTLinker::LinkStatus
-AppleVTLinker::sLinkStatus = LinkStatus_INIT;
+AppleVDALinker::LinkStatus
+AppleVDALinker::sLinkStatus = LinkStatus_INIT;
 
-void* AppleVTLinker::sLink = nullptr;
-nsrefcnt AppleVTLinker::sRefCount = 0;
-CFStringRef AppleVTLinker::skPropHWAccel = nullptr;
+void* AppleVDALinker::sLink = nullptr;
+nsrefcnt AppleVDALinker::sRefCount = 0;
+CFStringRef AppleVDALinker::skPropWidth = nullptr;
+CFStringRef AppleVDALinker::skPropHeight = nullptr;
+CFStringRef AppleVDALinker::skPropSourceFormat = nullptr;
+CFStringRef AppleVDALinker::skPropAVCCData = nullptr;
 
 #define LINK_FUNC(func) typeof(func) func;
-#include "AppleVTFunctions.h"
+#include "AppleVDAFunctions.h"
 #undef LINK_FUNC
 
 /* static */ bool
-AppleVTLinker::Link()
+AppleVDALinker::Link()
 {
   // Bump our reference count every time we're called.
   // Add a lock or change the thread assertion if
   // you need to call this off the main thread.
   MOZ_ASSERT(NS_IsMainThread());
   ++sRefCount;
 
   if (sLinkStatus) {
     return sLinkStatus == LinkStatus_SUCCEEDED;
   }
 
   const char* dlname =
-    "/System/Library/Frameworks/VideoToolbox.framework/VideoToolbox";
+    "/System/Library/Frameworks/VideoDecodeAcceleration.framework/VideoDecodeAcceleration";
+
   if (!(sLink = dlopen(dlname, RTLD_NOW | RTLD_LOCAL))) {
-    NS_WARNING("Couldn't load VideoToolbox framework");
+    NS_WARNING("Couldn't load VideoDecodeAcceleration framework");
     goto fail;
   }
 
-#define LINK_FUNC(func)                                        \
-  func = (typeof(func))dlsym(sLink, #func);                    \
-  if (!func) {                                                 \
-    NS_WARNING("Couldn't load VideoToolbox function " #func ); \
-    goto fail;                                                 \
+#define LINK_FUNC(func)                                                   \
+  func = (typeof(func))dlsym(sLink, #func);                               \
+  if (!func) {                                                            \
+    NS_WARNING("Couldn't load VideoDecodeAcceleration function " #func ); \
+    goto fail;                                                            \
   }
-#include "AppleVTFunctions.h"
+#include "AppleVDAFunctions.h"
 #undef LINK_FUNC
 
-  // Will only resolve in 10.9 and later.
-  skPropHWAccel =
-    GetIOConst("kVTVideoDecoderSpecification_EnableHardwareAcceleratedVideoDecoder");
+  skPropWidth = GetIOConst("kVDADecoderConfiguration_Width");
+  skPropHeight = GetIOConst("kVDADecoderConfiguration_Height");
+  skPropSourceFormat = GetIOConst("kVDADecoderConfiguration_SourceFormat");
+  skPropAVCCData = GetIOConst("kVDADecoderConfiguration_avcCData");
 
-  LOG("Loaded VideoToolbox framework.");
+  if (!skPropWidth || !skPropHeight || !skPropSourceFormat || !skPropAVCCData) {
+    goto fail;
+  }
+
+  LOG("Loaded VideoDecodeAcceleration framework.");
   sLinkStatus = LinkStatus_SUCCEEDED;
   return true;
 
 fail:
   Unlink();
 
   sLinkStatus = LinkStatus_FAILED;
   return false;
 }
 
 /* static */ void
-AppleVTLinker::Unlink()
+AppleVDALinker::Unlink()
 {
   // We'll be called by multiple Decoders, one intantiated for
   // each media element. Therefore we receive must maintain a
   // reference count to avoidunloading our symbols when other
   // instances still need them.
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(sRefCount > 0, "Unbalanced Unlink()");
   --sRefCount;
   if (sLink && sRefCount < 1) {
     LOG("Unlinking VideoToolbox framework.");
     dlclose(sLink);
     sLink = nullptr;
-    skPropHWAccel = nullptr;
+    skPropWidth = nullptr;
+    skPropHeight = nullptr;
+    skPropSourceFormat = nullptr;
+    skPropAVCCData = nullptr;
+    sLinkStatus = LinkStatus_INIT;
   }
 }
 
 /* static */ CFStringRef
-AppleVTLinker::GetIOConst(const char* symbol)
+AppleVDALinker::GetIOConst(const char* symbol)
 {
   CFStringRef* address = (CFStringRef*)dlsym(sLink, symbol);
   if (!address) {
     return nullptr;
   }
 
   return *address;
 }
 
-/* static */ CFStringRef
-AppleVTLinker::GetPropHWAccel()
-{
-  return skPropHWAccel;
-}
-
 } // namespace mozilla
copy from content/media/fmp4/apple/AppleVTLinker.h
copy to content/media/fmp4/apple/AppleVDALinker.h
--- a/content/media/fmp4/apple/AppleVTLinker.h
+++ b/content/media/fmp4/apple/AppleVDALinker.h
@@ -1,47 +1,49 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#ifndef AppleVTLinker_h
-#define AppleVTLinker_h
+#ifndef AppleVDALinker_h
+#define AppleVDALinker_h
 
 extern "C" {
 #pragma GCC visibility push(default)
-#include "VideoToolbox/VideoToolbox.h"
+#include "VideoDecodeAcceleration/VDADecoder.h"
 #pragma GCC visibility pop
 }
 
 #include "nscore.h"
 
 namespace mozilla {
 
-class AppleVTLinker
+class AppleVDALinker
 {
 public:
   static bool Link();
   static void Unlink();
-  static CFStringRef GetPropHWAccel();
+  static CFStringRef skPropWidth;
+  static CFStringRef skPropHeight;
+  static CFStringRef skPropSourceFormat;
+  static CFStringRef skPropAVCCData;
 
 private:
   static void* sLink;
   static nsrefcnt sRefCount;
-  static CFStringRef skPropHWAccel;
 
   static enum LinkStatus {
     LinkStatus_INIT = 0,
     LinkStatus_FAILED,
     LinkStatus_SUCCEEDED
   } sLinkStatus;
 
   static CFStringRef GetIOConst(const char* symbol);
 };
 
 #define LINK_FUNC(func) extern typeof(func)* func;
-#include "AppleVTFunctions.h"
+#include "AppleVDAFunctions.h"
 #undef LINK_FUNC
 
 } // namespace mozilla
 
-#endif // AppleVTLinker_h
+#endif // AppleVDALinker_h
--- a/content/media/fmp4/apple/AppleVTDecoder.cpp
+++ b/content/media/fmp4/apple/AppleVTDecoder.cpp
@@ -6,18 +6,16 @@
 
 #include <CoreFoundation/CFString.h>
 
 #include "AppleCMLinker.h"
 #include "AppleUtils.h"
 #include "AppleVTDecoder.h"
 #include "AppleVTLinker.h"
 #include "mp4_demuxer/DecoderData.h"
-#include "MP4Reader.h"
-#include "MP4Decoder.h"
 #include "MediaData.h"
 #include "MacIOSurfaceImage.h"
 #include "mozilla/ArrayUtils.h"
 #include "nsAutoPtr.h"
 #include "nsThreadUtils.h"
 #include "prlog.h"
 #include "VideoUtils.h"
 
@@ -34,20 +32,17 @@ PRLogModuleInfo* GetAppleMediaLog();
 #endif
 
 namespace mozilla {
 
 AppleVTDecoder::AppleVTDecoder(const mp4_demuxer::VideoDecoderConfig& aConfig,
                                MediaTaskQueue* aVideoTaskQueue,
                                MediaDataDecoderCallback* aCallback,
                                layers::ImageContainer* aImageContainer)
-  : mConfig(aConfig)
-  , mTaskQueue(aVideoTaskQueue)
-  , mCallback(aCallback)
-  , mImageContainer(aImageContainer)
+  : AppleVDADecoder(aConfig, aVideoTaskQueue, aCallback, aImageContainer)
   , mFormat(nullptr)
   , mSession(nullptr)
 {
   MOZ_COUNT_CTOR(AppleVTDecoder);
   // TODO: Verify aConfig.mime_type.
   LOG("Creating AppleVTDecoder for %dx%d h.264 video",
       mConfig.display_width,
       mConfig.display_height
@@ -114,61 +109,42 @@ AppleVTDecoder::Input(mp4_demuxer::MP4Sa
 }
 
 nsresult
 AppleVTDecoder::Flush()
 {
   mTaskQueue->Flush();
   nsresult rv = WaitForAsynchronousFrames();
   if (NS_FAILED(rv)) {
-    LOG("AppleVTDecoder::Drain failed waiting for platform decoder.");
+    LOG("AppleVTDecoder::Flush failed waiting for platform decoder "
+        "with error:%d.", rv);
   }
   ClearReorderedFrames();
 
   return rv;
 }
 
 nsresult
 AppleVTDecoder::Drain()
 {
   mTaskQueue->AwaitIdle();
   nsresult rv = WaitForAsynchronousFrames();
   if (NS_FAILED(rv)) {
-    LOG("AppleVTDecoder::Drain failed waiting for platform decoder.");
-    return rv;
+    LOG("AppleVTDecoder::Drain failed waiting for platform decoder "
+        "with error:%d.", rv);
   }
   DrainReorderedFrames();
   mCallback->DrainComplete();
   return NS_OK;
 }
 
 //
 // Implementation details.
 //
 
-// Context object to hold a copy of sample metadata.
-class FrameRef {
-public:
-  Microseconds decode_timestamp;
-  Microseconds composition_timestamp;
-  Microseconds duration;
-  int64_t byte_offset;
-  bool is_sync_point;
-
-  explicit FrameRef(mp4_demuxer::MP4Sample* aSample)
-  {
-    MOZ_ASSERT(aSample);
-    decode_timestamp = aSample->decode_timestamp;
-    composition_timestamp = aSample->composition_timestamp;
-    duration = aSample->duration;
-    byte_offset = aSample->byte_offset;
-    is_sync_point = aSample->is_sync_point;
-  }
-};
-
 // Callback passed to the VideoToolbox decoder for returning data.
 // This needs to be static because the API takes a C-style pair of
 // function and userdata pointers. This validates parameters and
 // forwards the decoded image back to an object method.
 static void
 PlatformCallback(void* decompressionOutputRefCon,
                  void* sourceFrameRefCon,
                  OSStatus status,
@@ -176,26 +152,18 @@ PlatformCallback(void* decompressionOutp
                  CVImageBufferRef image,
                  CMTime presentationTimeStamp,
                  CMTime presentationDuration)
 {
   LOG("AppleVideoDecoder %s status %d flags %d", __func__, status, flags);
 
   AppleVTDecoder* decoder =
     static_cast<AppleVTDecoder*>(decompressionOutputRefCon);
-  nsAutoPtr<FrameRef> frameRef =
-    nsAutoPtr<FrameRef>(static_cast<FrameRef*>(sourceFrameRefCon));
-
-  LOG("mp4 output frame %lld dts %lld pts %lld duration %lld us%s",
-    frameRef->byte_offset,
-    frameRef->decode_timestamp,
-    frameRef->composition_timestamp,
-    frameRef->duration,
-    frameRef->is_sync_point ? " keyframe" : ""
-  );
+  nsAutoPtr<AppleVTDecoder::AppleFrameRef> frameRef(
+    static_cast<AppleVTDecoder::AppleFrameRef*>(sourceFrameRefCon));
 
   // Validate our arguments.
   if (status != noErr || !image) {
     NS_WARNING("VideoToolbox decoder returned no data");
     return;
   }
   if (flags & kVTDecodeInfo_FrameDropped) {
     NS_WARNING("  ...frame dropped...");
@@ -214,94 +182,16 @@ AppleVTDecoder::WaitForAsynchronousFrame
   OSStatus rv = VTDecompressionSessionWaitForAsynchronousFrames(mSession);
   if (rv != noErr) {
     LOG("AppleVTDecoder: Error %d waiting for asynchronous frames", rv);
     return NS_ERROR_FAILURE;
   }
   return NS_OK;
 }
 
-void
-AppleVTDecoder::DrainReorderedFrames()
-{
-  while (!mReorderQueue.IsEmpty()) {
-    mCallback->Output(mReorderQueue.Pop());
-  }
-}
-
-void
-AppleVTDecoder::ClearReorderedFrames()
-{
-  while (!mReorderQueue.IsEmpty()) {
-    delete mReorderQueue.Pop();
-  }
-}
-
-// Copy and return a decoded frame.
-nsresult
-AppleVTDecoder::OutputFrame(CVPixelBufferRef aImage,
-                            nsAutoPtr<FrameRef> aFrameRef)
-{
-  IOSurfacePtr surface = MacIOSurfaceLib::CVPixelBufferGetIOSurface(aImage);
-  MOZ_ASSERT(surface, "VideoToolbox didn't return an IOSurface backed buffer");
-
-  nsRefPtr<MacIOSurface> macSurface = new MacIOSurface(surface);
-  // Bounds.
-  VideoInfo info;
-  info.mDisplay = nsIntSize(macSurface->GetWidth(), macSurface->GetHeight());
-  info.mHasVideo = true;
-  gfx::IntRect visible = gfx::IntRect(0,
-                                      0,
-                                      mConfig.display_width,
-                                      mConfig.display_height);
-
-  nsRefPtr<layers::Image> image =
-    mImageContainer->CreateImage(ImageFormat::MAC_IOSURFACE);
-  layers::MacIOSurfaceImage* videoImage =
-    static_cast<layers::MacIOSurfaceImage*>(image.get());
-  videoImage->SetSurface(macSurface);
-
-  nsAutoPtr<VideoData> data;
-  data = VideoData::CreateFromImage(info,
-                                    mImageContainer,
-                                    aFrameRef->byte_offset,
-                                    aFrameRef->composition_timestamp,
-                                    aFrameRef->duration, image.forget(),
-                                    aFrameRef->is_sync_point,
-                                    aFrameRef->decode_timestamp,
-                                    visible);
-
-  if (!data) {
-    NS_ERROR("Couldn't create VideoData for frame");
-    mCallback->Error();
-    return NS_ERROR_FAILURE;
-  }
-
-  // Frames come out in DTS order but we need to output them
-  // in composition order.
-  mReorderQueue.Push(data.forget());
-  // Assume a frame with a PTS <= current DTS is ready.
-  while (mReorderQueue.Length() > 0) {
-    VideoData* readyData = mReorderQueue.Pop();
-    if (readyData->mTime <= aFrameRef->decode_timestamp) {
-      LOG("returning queued frame with pts %lld", readyData->mTime);
-      mCallback->Output(readyData);
-    } else {
-      LOG("requeued frame with pts %lld > %lld",
-          readyData->mTime, aFrameRef->decode_timestamp);
-      mReorderQueue.Push(readyData);
-      break;
-    }
-  }
-  LOG("%llu decoded frames queued",
-      static_cast<unsigned long long>(mReorderQueue.Length()));
-
-  return NS_OK;
-}
-
 // Helper to fill in a timestamp structure.
 static CMSampleTimingInfo
 TimingInfoFromSample(mp4_demuxer::MP4Sample* aSample)
 {
   CMSampleTimingInfo timestamp;
 
   timestamp.duration = CMTimeMake(aSample->duration, USECS_PER_S);
   timestamp.presentationTimeStamp =
@@ -320,146 +210,166 @@ AppleVTDecoder::SubmitFrame(mp4_demuxer:
   AutoCFRelease<CMSampleBufferRef> sample = nullptr;
   VTDecodeInfoFlags flags;
   OSStatus rv;
 
   // FIXME: This copies the sample data. I think we can provide
   // a custom block source which reuses the aSample buffer.
   // But note that there may be a problem keeping the samples
   // alive over multiple frames.
-  rv = CMBlockBufferCreateWithMemoryBlock(NULL // Struct allocator.
+  rv = CMBlockBufferCreateWithMemoryBlock(kCFAllocatorDefault // Struct allocator.
                                          ,aSample->data
                                          ,aSample->size
                                          ,kCFAllocatorNull // Block allocator.
                                          ,NULL // Block source.
                                          ,0    // Data offset.
                                          ,aSample->size
                                          ,false
                                          ,block.receive());
-  NS_ASSERTION(rv == noErr, "Couldn't create CMBlockBuffer");
+  if (rv != noErr) {
+    NS_ERROR("Couldn't create CMBlockBuffer");
+    return NS_ERROR_FAILURE;
+  }
   CMSampleTimingInfo timestamp = TimingInfoFromSample(aSample);
-  rv = CMSampleBufferCreate(NULL, block, true, 0, 0, mFormat, 1, 1, &timestamp, 0, NULL, sample.receive());
-  NS_ASSERTION(rv == noErr, "Couldn't create CMSampleBuffer");
+  rv = CMSampleBufferCreate(kCFAllocatorDefault, block, true, 0, 0, mFormat, 1, 1, &timestamp, 0, NULL, sample.receive());
+  if (rv != noErr) {
+    NS_ERROR("Couldn't create CMSampleBuffer");
+    return NS_ERROR_FAILURE;
+  }
   rv = VTDecompressionSessionDecodeFrame(mSession,
                                          sample,
                                          0,
-                                         new FrameRef(aSample),
+                                         CreateAppleFrameRef(aSample),
                                          &flags);
-  NS_ASSERTION(rv == noErr, "Couldn't pass frame to decoder");
+  if (rv != noErr) {
+    NS_ERROR("Couldn't pass frame to decoder");
+    return NS_ERROR_FAILURE;
+  }
 
   // Ask for more data.
   if (mTaskQueue->IsEmpty()) {
     LOG("AppleVTDecoder task queue empty; requesting more data");
     mCallback->InputExhausted();
   }
 
   return NS_OK;
 }
 
 nsresult
 AppleVTDecoder::InitializeSession()
 {
   OSStatus rv;
-  AutoCFRelease<CFMutableDictionaryRef> extensions =
-    CFDictionaryCreateMutable(NULL, 0,
-                              &kCFTypeDictionaryKeyCallBacks,
-                              &kCFTypeDictionaryValueCallBacks);
-  AppleUtils::SetCFDict(extensions, "CVImageBufferChromaLocationBottomField", "left");
-  AppleUtils::SetCFDict(extensions, "CVImageBufferChromaLocationTopField", "left");
-  AppleUtils::SetCFDict(extensions, "FullRangeVideo", true);
-
-  AutoCFRelease<CFMutableDictionaryRef> atoms =
-    CFDictionaryCreateMutable(NULL, 0,
-                              &kCFTypeDictionaryKeyCallBacks,
-                              &kCFTypeDictionaryValueCallBacks);
-  AutoCFRelease<CFDataRef> avc_data = CFDataCreate(NULL,
-      mConfig.extra_data.begin(), mConfig.extra_data.length());
 
 #ifdef LOG_MEDIA_SHA1
   SHA1Sum avc_hash;
   avc_hash.update(mConfig.extra_data.begin(), mConfig.extra_data.length());
   uint8_t digest_buf[SHA1Sum::kHashSize];
   avc_hash.finish(digest_buf);
   nsAutoCString avc_digest;
   for (size_t i = 0; i < sizeof(digest_buf); i++) {
     avc_digest.AppendPrintf("%02x", digest_buf[i]);
   }
   LOG("AVCDecoderConfig %ld bytes sha1 %s",
       mConfig.extra_data.length(), avc_digest.get());
 #endif // LOG_MEDIA_SHA1
 
-  CFDictionarySetValue(atoms, CFSTR("avcC"), avc_data);
-  CFDictionarySetValue(extensions, CFSTR("SampleDescriptionExtensionAtoms"), atoms);
-  rv = CMVideoFormatDescriptionCreate(NULL, // Use default allocator.
+  AutoCFRelease<CFDictionaryRef> extensions = CreateDecoderExtensions();
+
+  rv = CMVideoFormatDescriptionCreate(kCFAllocatorDefault,
                                       kCMVideoCodecType_H264,
                                       mConfig.display_width,
                                       mConfig.display_height,
                                       extensions,
                                       &mFormat);
   if (rv != noErr) {
     NS_ERROR("Couldn't create format description!");
     return NS_ERROR_FAILURE;
   }
 
   // Contruct video decoder selection spec.
   AutoCFRelease<CFDictionaryRef> spec = CreateDecoderSpecification();
 
   // Contruct output configuration.
-  AutoCFRelease<CFDictionaryRef> IOSurfaceProperties =
-    CFDictionaryCreate(NULL,
-                       NULL,
-                       NULL,
-                       0,
-                       &kCFTypeDictionaryKeyCallBacks,
-                       &kCFTypeDictionaryValueCallBacks);
-
-  SInt32 PixelFormatTypeValue = kCVPixelFormatType_32BGRA;
-  AutoCFRelease<CFNumberRef> PixelFormatTypeNumber =
-    CFNumberCreate(NULL, kCFNumberSInt32Type, &PixelFormatTypeValue);
-
-  const void* outputKeys[] = { kCVPixelBufferIOSurfacePropertiesKey,
-                               kCVPixelBufferPixelFormatTypeKey,
-                               kCVPixelBufferOpenGLCompatibilityKey };
-  const void* outputValues[] = { IOSurfaceProperties,
-                                 PixelFormatTypeNumber,
-                                 kCFBooleanTrue };
   AutoCFRelease<CFDictionaryRef> outputConfiguration =
-    CFDictionaryCreate(NULL,
-                       outputKeys,
-                       outputValues,
-                       ArrayLength(outputKeys),
-                       &kCFTypeDictionaryKeyCallBacks,
-                       &kCFTypeDictionaryValueCallBacks);
+    CreateOutputConfiguration();
 
   VTDecompressionOutputCallbackRecord cb = { PlatformCallback, this };
-  rv = VTDecompressionSessionCreate(NULL, // Allocator.
+  rv = VTDecompressionSessionCreate(kCFAllocatorDefault,
                                     mFormat,
                                     spec, // Video decoder selection.
                                     outputConfiguration, // Output video format.
                                     &cb,
                                     &mSession);
 
   if (rv != noErr) {
     NS_ERROR("Couldn't create decompression session!");
     return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
 }
 
 CFDictionaryRef
+AppleVTDecoder::CreateDecoderExtensions()
+{
+  AutoCFRelease<CFDataRef> avc_data =
+    CFDataCreate(kCFAllocatorDefault,
+                 mConfig.extra_data.begin(),
+                 mConfig.extra_data.length());
+
+  const void* atomsKey[] = { CFSTR("avcC") };
+  const void* atomsValue[] = { avc_data };
+  static_assert(ArrayLength(atomsKey) == ArrayLength(atomsValue),
+                "Non matching keys/values array size");
+
+  AutoCFRelease<CFDictionaryRef> atoms =
+    CFDictionaryCreate(kCFAllocatorDefault,
+                       atomsKey,
+                       atomsValue,
+                       ArrayLength(atomsKey),
+                       &kCFTypeDictionaryKeyCallBacks,
+                       &kCFTypeDictionaryValueCallBacks);
+
+  const void* extensionKeys[] =
+    { kCVImageBufferChromaLocationBottomFieldKey,
+      kCVImageBufferChromaLocationTopFieldKey,
+      AppleCMLinker::skPropExtensionAtoms,
+      AppleCMLinker::skPropFullRangeVideo /* Not defined in 10.6 */ };
+
+  const void* extensionValues[] =
+    { kCVImageBufferChromaLocation_Left,
+      kCVImageBufferChromaLocation_Left,
+      atoms,
+      kCFBooleanTrue };
+  static_assert(ArrayLength(extensionKeys) == ArrayLength(extensionValues),
+                "Non matching keys/values array size");
+
+  return CFDictionaryCreate(kCFAllocatorDefault,
+                            extensionKeys,
+                            extensionValues,
+                            AppleCMLinker::skPropFullRangeVideo ?
+                              ArrayLength(extensionKeys) :
+                              ArrayLength(extensionKeys) - 1,
+                            &kCFTypeDictionaryKeyCallBacks,
+                            &kCFTypeDictionaryValueCallBacks);
+}
+
+CFDictionaryRef
 AppleVTDecoder::CreateDecoderSpecification()
 {
-  if (!AppleVTLinker::GetPropHWAccel()) {
+  if (!AppleVTLinker::skPropHWAccel) {
     return nullptr;
   }
 
-  const void* specKeys[] = { AppleVTLinker::GetPropHWAccel() };
+  const void* specKeys[] = { AppleVTLinker::skPropHWAccel };
   const void* specValues[] = { kCFBooleanTrue };
-  return CFDictionaryCreate(NULL,
+  static_assert(ArrayLength(specKeys) == ArrayLength(specValues),
+                "Non matching keys/values array size");
+
+  return CFDictionaryCreate(kCFAllocatorDefault,
                             specKeys,
                             specValues,
                             ArrayLength(specKeys),
                             &kCFTypeDictionaryKeyCallBacks,
                             &kCFTypeDictionaryValueCallBacks);
 }
 
 } // namespace mozilla
--- a/content/media/fmp4/apple/AppleVTDecoder.h
+++ b/content/media/fmp4/apple/AppleVTDecoder.h
@@ -2,63 +2,43 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_AppleVTDecoder_h
 #define mozilla_AppleVTDecoder_h
 
-#include "PlatformDecoderModule.h"
-#include "mozilla/RefPtr.h"
-#include "mozilla/ReentrantMonitor.h"
-#include "nsIThread.h"
-#include "ReorderQueue.h"
+#include "AppleVDADecoder.h"
 
 #include "VideoToolbox/VideoToolbox.h"
 
 namespace mozilla {
 
-class MediaTaskQueue;
-class MediaDataDecoderCallback;
-namespace layers {
-  class ImageContainer;
-}
-class FrameRef;
-
-class AppleVTDecoder : public MediaDataDecoder {
+class AppleVTDecoder : public AppleVDADecoder {
 public:
   AppleVTDecoder(const mp4_demuxer::VideoDecoderConfig& aConfig,
                  MediaTaskQueue* aVideoTaskQueue,
                  MediaDataDecoderCallback* aCallback,
                  layers::ImageContainer* aImageContainer);
   ~AppleVTDecoder();
   virtual nsresult Init() MOZ_OVERRIDE;
   virtual nsresult Input(mp4_demuxer::MP4Sample* aSample) MOZ_OVERRIDE;
   virtual nsresult Flush() MOZ_OVERRIDE;
   virtual nsresult Drain() MOZ_OVERRIDE;
   virtual nsresult Shutdown() MOZ_OVERRIDE;
-  // Return hook for VideoToolbox callback.
-  nsresult OutputFrame(CVPixelBufferRef aImage,
-                       nsAutoPtr<FrameRef> frameRef);
+
 private:
-  const mp4_demuxer::VideoDecoderConfig& mConfig;
-  RefPtr<MediaTaskQueue> mTaskQueue;
-  MediaDataDecoderCallback* mCallback;
-  layers::ImageContainer* mImageContainer;
   CMVideoFormatDescriptionRef mFormat;
   VTDecompressionSessionRef mSession;
-  ReorderQueue mReorderQueue;
 
   // Method to pass a frame to VideoToolbox for decoding.
   nsresult SubmitFrame(mp4_demuxer::MP4Sample* aSample);
   // Method to set up the decompression session.
   nsresult InitializeSession();
   nsresult WaitForAsynchronousFrames();
-  void DrainReorderedFrames();
-  void ClearReorderedFrames();
-
   CFDictionaryRef CreateDecoderSpecification();
+  CFDictionaryRef CreateDecoderExtensions();
 };
 
 } // namespace mozilla
 
 #endif // mozilla_AppleVTDecoder_h
--- a/content/media/fmp4/apple/AppleVTLinker.cpp
+++ b/content/media/fmp4/apple/AppleVTLinker.cpp
@@ -3,16 +3,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include <dlfcn.h>
 
 #include "AppleVTLinker.h"
 #include "MainThreadUtils.h"
+#include "mozilla/ArrayUtils.h"
 #include "nsDebug.h"
 
 #ifdef PR_LOGGING
 PRLogModuleInfo* GetAppleMediaLog();
 #define LOG(...) PR_LOG(GetAppleMediaLog(), PR_LOG_DEBUG, (__VA_ARGS__))
 #else
 #define LOG(...)
 #endif
@@ -38,19 +39,27 @@ AppleVTLinker::Link()
   // you need to call this off the main thread.
   MOZ_ASSERT(NS_IsMainThread());
   ++sRefCount;
 
   if (sLinkStatus) {
     return sLinkStatus == LinkStatus_SUCCEEDED;
   }
 
-  const char* dlname =
-    "/System/Library/Frameworks/VideoToolbox.framework/VideoToolbox";
-  if (!(sLink = dlopen(dlname, RTLD_NOW | RTLD_LOCAL))) {
+  const char* dlnames[] =
+    { "/System/Library/Frameworks/VideoToolbox.framework/VideoToolbox",
+      "/System/Library/PrivateFrameworks/VideoToolbox.framework/VideoToolbox" };
+  bool dlfound = false;
+  for (size_t i = 0; i < ArrayLength(dlnames); i++) {
+    if ((sLink = dlopen(dlnames[i], RTLD_NOW | RTLD_LOCAL))) {
+      dlfound = true;
+      break;
+    }
+  }
+  if (!dlfound) {
     NS_WARNING("Couldn't load VideoToolbox framework");
     goto fail;
   }
 
 #define LINK_FUNC(func)                                        \
   func = (typeof(func))dlsym(sLink, #func);                    \
   if (!func) {                                                 \
     NS_WARNING("Couldn't load VideoToolbox function " #func ); \
@@ -84,29 +93,24 @@ AppleVTLinker::Unlink()
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(sRefCount > 0, "Unbalanced Unlink()");
   --sRefCount;
   if (sLink && sRefCount < 1) {
     LOG("Unlinking VideoToolbox framework.");
     dlclose(sLink);
     sLink = nullptr;
     skPropHWAccel = nullptr;
+    sLinkStatus = LinkStatus_INIT;
   }
 }
 
 /* static */ CFStringRef
 AppleVTLinker::GetIOConst(const char* symbol)
 {
   CFStringRef* address = (CFStringRef*)dlsym(sLink, symbol);
   if (!address) {
     return nullptr;
   }
 
   return *address;
 }
 
-/* static */ CFStringRef
-AppleVTLinker::GetPropHWAccel()
-{
-  return skPropHWAccel;
-}
-
 } // namespace mozilla
--- a/content/media/fmp4/apple/AppleVTLinker.h
+++ b/content/media/fmp4/apple/AppleVTLinker.h
@@ -17,22 +17,21 @@ extern "C" {
 
 namespace mozilla {
 
 class AppleVTLinker
 {
 public:
   static bool Link();
   static void Unlink();
-  static CFStringRef GetPropHWAccel();
+  static CFStringRef skPropHWAccel;
 
 private:
   static void* sLink;
   static nsrefcnt sRefCount;
-  static CFStringRef skPropHWAccel;
 
   static enum LinkStatus {
     LinkStatus_INIT = 0,
     LinkStatus_FAILED,
     LinkStatus_SUCCEEDED
   } sLinkStatus;
 
   static CFStringRef GetIOConst(const char* symbol);
new file mode 100644
--- /dev/null
+++ b/content/media/fmp4/apple/VideoDecodeAcceleration/VDADecoder.h
@@ -0,0 +1,63 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* 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/. */
+
+// Stub header for VideoDecodeAcceleration framework API.
+// This is a private Framework on 10.6 see:
+// https://developer.apple.com/library/mac/technotes/tn2267/_index.html
+// We include our own copy so we can build on MacOS versions
+// where it's not available.
+
+#ifndef mozilla_VideoDecodeAcceleration_VDADecoder_h
+#define mozilla_VideoDecodeAcceleration_VDADecoder_h
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <CoreVideo/CoreVideo.h>
+
+typedef uint32_t VDADecodeFrameFlags;
+typedef uint32_t VDADecodeInfoFlags;
+
+enum {
+  kVDADecodeInfo_Asynchronous = 1UL << 0,
+  kVDADecodeInfo_FrameDropped = 1UL << 1
+};
+
+enum {
+  kVDADecoderFlush_EmitFrames = 1 << 0
+};
+
+typedef struct OpaqueVDADecoder* VDADecoder;
+
+typedef void (*VDADecoderOutputCallback)
+  (void* decompressionOutputRefCon,
+   CFDictionaryRef frameInfo,
+   OSStatus status,
+   uint32_t infoFlags,
+   CVImageBufferRef imageBuffer);
+
+OSStatus
+VDADecoderCreate(
+  CFDictionaryRef decoderConfiguration,
+  CFDictionaryRef destinationImageBufferAttributes, /* can be NULL */
+  VDADecoderOutputCallback* outputCallback,
+  void* decoderOutputCallbackRefcon,
+  VDADecoder* decoderOut);
+
+OSStatus
+VDADecoderDecode(
+  VDADecoder decoder,
+  uint32_t decodeFlags,
+  CFTypeRef compressedBuffer,
+  CFDictionaryRef frameInfo); /* can be NULL */
+
+OSStatus
+VDADecoderFlush(
+  VDADecoder decoder,
+  uint32_t flushFlags);
+
+OSStatus
+VDADecoderDestroy(VDADecoder decoder);
+
+#endif // mozilla_VideoDecodeAcceleration_VDADecoder_h
--- a/content/media/fmp4/apple/VideoToolbox/VideoToolbox.h
+++ b/content/media/fmp4/apple/VideoToolbox/VideoToolbox.h
@@ -10,22 +10,19 @@
 
 #ifndef mozilla_VideoToolbox_VideoToolbox_h
 #define mozilla_VideoToolbox_VideoToolbox_h
 
 // CoreMedia is available starting in OS X 10.7,
 // so we need to dlopen it as well to run on 10.6,
 // but we can depend on the real framework headers at build time.
 
-#include <CoreMedia/CMBase.h>
 #include <CoreFoundation/CoreFoundation.h>
+#include <CoreMedia/CoreMedia.h>
 #include <CoreVideo/CVPixelBuffer.h>
-#include <CoreMedia/CMSampleBuffer.h>
-#include <CoreMedia/CMFormatDescription.h>
-#include <CoreMedia/CMTime.h>
 
 typedef uint32_t VTDecodeFrameFlags;
 typedef uint32_t VTDecodeInfoFlags;
 enum {
   kVTDecodeInfo_Asynchronous = 1UL << 0,
   kVTDecodeInfo_FrameDropped = 1UL << 1,
 };
 
--- a/content/media/fmp4/moz.build
+++ b/content/media/fmp4/moz.build
@@ -47,16 +47,18 @@ if CONFIG['MOZ_APPLEMEDIA']:
   EXPORTS += [
       'apple/AppleDecoderModule.h',
   ]
   UNIFIED_SOURCES += [
       'apple/AppleATDecoder.cpp',
       'apple/AppleCMLinker.cpp',
       'apple/AppleDecoderModule.cpp',
       'apple/AppleUtils.cpp',
+      'apple/AppleVDADecoder.cpp',
+      'apple/AppleVDALinker.cpp',
       'apple/AppleVTDecoder.cpp',
       'apple/AppleVTLinker.cpp',
   ]
   OS_LIBS += [
       '-framework AudioToolbox',
   ]
 
 if CONFIG['ANDROID_VERSION'] >= '18'and CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
--- a/content/media/mediasource/MediaSource.cpp
+++ b/content/media/mediasource/MediaSource.cpp
@@ -16,17 +16,16 @@
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/BindingDeclarations.h"
 #include "mozilla/dom/HTMLMediaElement.h"
 #include "mozilla/dom/TimeRanges.h"
 #include "mozilla/mozalloc.h"
 #include "nsContentTypeParser.h"
 #include "nsDebug.h"
 #include "nsError.h"
-#include "nsIEventTarget.h"
 #include "nsIRunnable.h"
 #include "nsPIDOMWindow.h"
 #include "nsString.h"
 #include "nsThreadUtils.h"
 #include "prlog.h"
 
 struct JSContext;
 class JSObject;
--- a/content/media/mediasource/MediaSourceReader.cpp
+++ b/content/media/mediasource/MediaSourceReader.cpp
@@ -5,17 +5,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #include "MediaSourceReader.h"
 
 #include "prlog.h"
 #include "mozilla/dom/TimeRanges.h"
 #include "DecoderTraits.h"
 #include "MediaDataDecodedListener.h"
 #include "MediaDecoderOwner.h"
-#include "MediaSource.h"
 #include "MediaSourceDecoder.h"
 #include "MediaSourceUtils.h"
 #include "SourceBufferDecoder.h"
 #include "TrackBuffer.h"
 
 #ifdef MOZ_FMP4
 #include "MP4Decoder.h"
 #include "MP4Reader.h"
--- a/content/media/mediasource/SourceBuffer.cpp
+++ b/content/media/mediasource/SourceBuffer.cpp
@@ -4,17 +4,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "SourceBuffer.h"
 
 #include "AsyncEventRunner.h"
 #include "MediaSourceUtils.h"
 #include "TrackBuffer.h"
-#include "VideoUtils.h"
 #include "WebMBufferedParser.h"
 #include "mozilla/Endian.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/FloatingPoint.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/MediaSourceBinding.h"
 #include "mozilla/dom/TimeRanges.h"
 #include "mp4_demuxer/BufferStream.h"
@@ -578,25 +577,19 @@ SourceBuffer::AbortUpdating()
   QueueAsyncSimpleEvent("abort");
   QueueAsyncSimpleEvent("updateend");
 }
 
 void
 SourceBuffer::AppendData(const uint8_t* aData, uint32_t aLength, ErrorResult& aRv)
 {
   MSE_DEBUG("SourceBuffer(%p)::AppendData(aLength=%u)", this, aLength);
-  if (!IsAttached() || mUpdating) {
-    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+  if (!PrepareAppend(aRv)) {
     return;
   }
-  if (mMediaSource->ReadyState() == MediaSourceReadyState::Ended) {
-    mMediaSource->SetReadyState(MediaSourceReadyState::Open);
-  }
-  // TODO: Run coded frame eviction algorithm.
-  // TODO: Test buffer full flag.
   StartUpdating();
   // TODO: Run more of the buffer append algorithm asynchronously.
   if (mParser->IsInitSegmentPresent(aData, aLength)) {
     MSE_DEBUG("SourceBuffer(%p)::AppendData: New initialization segment.", this);
     mMediaSource->QueueInitializationEvent();
     mTrackBuffer->DiscardDecoder();
     if (!mTrackBuffer->NewDecoder()) {
       aRv.Throw(NS_ERROR_FAILURE); // XXX: Review error handling.
@@ -642,16 +635,38 @@ SourceBuffer::AppendData(const uint8_t* 
   if (!mTrackBuffer->AppendData(aData, aLength)) {
     Optional<MediaSourceEndOfStreamError> decodeError(MediaSourceEndOfStreamError::Decode);
     ErrorResult dummy;
     mMediaSource->EndOfStream(decodeError, dummy);
     aRv.Throw(NS_ERROR_FAILURE);
     return;
   }
 
+  // Schedule the state machine thread to ensure playback starts
+  // if required when data is appended.
+  mMediaSource->GetDecoder()->ScheduleStateMachineThread();
+
+  // Run the final step of the buffer append algorithm asynchronously to
+  // ensure the SourceBuffer's updating flag transition behaves as required
+  // by the spec.
+  nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(this, &SourceBuffer::StopUpdating);
+  NS_DispatchToMainThread(event);
+}
+
+bool
+SourceBuffer::PrepareAppend(ErrorResult& aRv)
+{
+  if (!IsAttached() || mUpdating) {
+    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+    return false;
+  }
+  if (mMediaSource->ReadyState() == MediaSourceReadyState::Ended) {
+    mMediaSource->SetReadyState(MediaSourceReadyState::Open);
+  }
+
   // Eviction uses a byte threshold. If the buffer is greater than the
   // number of bytes then data is evicted. The time range for this
   // eviction is reported back to the media source. It will then
   // evict data before that range across all SourceBuffers it knows
   // about.
   // TODO: Make the eviction threshold smaller for audio-only streams.
   // TODO: Drive evictions off memory pressure notifications.
   // TODO: Consider a global eviction threshold  rather than per TrackBuffer.
@@ -660,25 +675,18 @@ SourceBuffer::AppendData(const uint8_t* 
     MSE_DEBUG("SourceBuffer(%p)::AppendData Evict; current buffered start=%f",
               this, GetBufferedStart());
 
     // We notify that we've evicted from the time range 0 through to
     // the current start point.
     mMediaSource->NotifyEvicted(0.0, GetBufferedStart());
   }
 
-  // Run the final step of the buffer append algorithm asynchronously to
-  // ensure the SourceBuffer's updating flag transition behaves as required
-  // by the spec.
-  nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(this, &SourceBuffer::StopUpdating);
-  NS_DispatchToMainThread(event);
-
-  // Schedule the state machine thread to ensure playback starts
-  // if required when data is appended.
-  mMediaSource->GetDecoder()->ScheduleStateMachineThread();
+  // TODO: Test buffer full flag.
+  return true;
 }
 
 double
 SourceBuffer::GetBufferedStart()
 {
   MOZ_ASSERT(NS_IsMainThread());
   ErrorResult dummy;
   nsRefPtr<TimeRanges> ranges = GetBuffered(dummy);
--- a/content/media/mediasource/SourceBuffer.h
+++ b/content/media/mediasource/SourceBuffer.h
@@ -130,16 +130,20 @@ private:
   // Update mUpdating and fire the appropriate events.
   void StartUpdating();
   void StopUpdating();
   void AbortUpdating();
 
   // Shared implementation of AppendBuffer overloads.
   void AppendData(const uint8_t* aData, uint32_t aLength, ErrorResult& aRv);
 
+  // Implements the "Prepare Append Algorithm".  Returns true if the append
+  // may continue, or false (with aRv set) on error.
+  bool PrepareAppend(ErrorResult& aRv);
+
   nsRefPtr<MediaSource> mMediaSource;
 
   const nsCString mType;
 
   uint32_t mEvictionThreshold;
 
   nsAutoPtr<ContainerParser> mParser;
 
--- a/content/media/mediasource/SourceBufferDecoder.cpp
+++ b/content/media/mediasource/SourceBufferDecoder.cpp
@@ -3,17 +3,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "SourceBufferDecoder.h"
 #include "prlog.h"
 #include "AbstractMediaDecoder.h"
 #include "MediaDecoderReader.h"
-#include "mozilla/dom/TimeRanges.h"
 
 #ifdef PR_LOGGING
 extern PRLogModuleInfo* GetMediaSourceLog();
 extern PRLogModuleInfo* GetMediaSourceAPILog();
 
 #define MSE_DEBUG(...) PR_LOG(GetMediaSourceLog(), PR_LOG_DEBUG, (__VA_ARGS__))
 #define MSE_API(...) PR_LOG(GetMediaSourceAPILog(), PR_LOG_DEBUG, (__VA_ARGS__))
 #else
--- a/content/media/mediasource/SourceBufferList.cpp
+++ b/content/media/mediasource/SourceBufferList.cpp
@@ -6,17 +6,16 @@
 
 #include "SourceBufferList.h"
 
 #include "AsyncEventRunner.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/dom/SourceBufferListBinding.h"
 #include "mozilla/mozalloc.h"
 #include "nsCOMPtr.h"
-#include "nsIEventTarget.h"
 #include "nsIRunnable.h"
 #include "nsString.h"
 #include "nsThreadUtils.h"
 #include "prlog.h"
 
 struct JSContext;
 class JSObject;
 
--- a/content/media/mediasource/SourceBufferResource.cpp
+++ b/content/media/mediasource/SourceBufferResource.cpp
@@ -1,21 +1,20 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "SourceBufferResource.h"
 
-#include <string.h>
 #include <algorithm>
 
 #include "nsISeekableStream.h"
-#include "nsISupportsImpl.h"
+#include "nsISupports.h"
 #include "prlog.h"
 
 #ifdef PR_LOGGING
 PRLogModuleInfo* GetSourceBufferResourceLog()
 {
   static PRLogModuleInfo* sLogModule;
   if (!sLogModule) {
     sLogModule = PR_NewLogModule("SourceBufferResource");
@@ -27,22 +26,16 @@ PRLogModuleInfo* GetSourceBufferResource
 #define SBR_DEBUGV(...) PR_LOG(GetSourceBufferResourceLog(), PR_LOG_DEBUG+1, (__VA_ARGS__))
 #else
 #define SBR_DEBUG(...)
 #define SBR_DEBUGV(...)
 #endif
 
 namespace mozilla {
 
-namespace dom {
-
-class SourceBuffer;
-
-}  // namespace dom
-
 nsresult
 SourceBufferResource::Close()
 {
   ReentrantMonitorAutoEnter mon(mMonitor);
   SBR_DEBUG("SourceBufferResource(%p)::Close", this);
   //MOZ_ASSERT(!mClosed);
   mClosed = true;
   mon.NotifyAll();
--- a/content/media/mediasource/TrackBuffer.cpp
+++ b/content/media/mediasource/TrackBuffer.cpp
@@ -8,17 +8,16 @@
 
 #include "MediaSourceDecoder.h"
 #include "SharedThreadPool.h"
 #include "MediaTaskQueue.h"
 #include "SourceBufferDecoder.h"
 #include "SourceBufferResource.h"
 #include "VideoUtils.h"
 #include "mozilla/FloatingPoint.h"
-#include "mozilla/dom/MediaSourceBinding.h"
 #include "mozilla/dom/TimeRanges.h"
 #include "nsError.h"
 #include "nsIRunnable.h"
 #include "nsThreadUtils.h"
 #include "prlog.h"
 
 #if defined(DEBUG)
 #include <sys/stat.h>
--- a/content/media/test/test_can_play_type_mpeg.html
+++ b/content/media/test/test_can_play_type_mpeg.html
@@ -94,25 +94,25 @@ function check_mp3(v, enabled) {
 }
 
 function IsWindowsVistaOrLater() {
   var re = /Windows NT (\d+\.\d)/;
   var winver = navigator.userAgent.match(re);
   return winver && winver.length == 2 && parseFloat(winver[1]) >= 6.0;
 }
 
-function IsMacOSLionOrLater() {
+function IsMacOSSnowLeopardOrLater() {
   var re = /Mac OS X (\d+)\.(\d+)/;
   var ver = navigator.userAgent.match(re);
   if (!ver || ver.length != 3) {
     return false;
   }
   var major = ver[1] | 0;
   var minor = ver[2] | 0;
-  return major == 10 && minor >= 7;
+  return major == 10 && minor >= 6;
 }
 
 function getPref(name) {
   var pref = false;
   try {
     pref = SpecialPowers.getBoolPref(name);
   } catch(ex) { }
   return pref;
@@ -122,17 +122,17 @@ function IsLinuxGStreamer() {
   return /Linux/.test(navigator.userAgent) &&
          getPref("media.gstreamer.enabled");
 }
 
 // Check whether we should expect the new MP4Reader-based support to work.
 function IsMP4ReaderAvailable() {
   var prefs = getPref("media.fragmented-mp4.enabled") &&
               getPref("media.fragmented-mp4.exposed");
-  return prefs && (IsWindowsVistaOrLater() || IsMacOSLionOrLater());
+  return prefs && (IsWindowsVistaOrLater() || IsMacOSSnowLeopardOrLater());
 }
 
 var haveMp4 = (getPref("media.windows-media-foundation.enabled") && IsWindowsVistaOrLater()) ||
                getPref("media.omx.enabled") ||
                getPref("media.gstreamer.enabled") ||
                IsMP4ReaderAvailable();
 // TODO:  Add "getPref("media.plugins.enabled")" once MP4 works on Gingerbread.
              
--- a/content/svg/content/src/SVGForeignObjectElement.cpp
+++ b/content/svg/content/src/SVGForeignObjectElement.cpp
@@ -111,25 +111,26 @@ SVGForeignObjectElement::BindToTree(nsID
                                     nsIContent* aBindingParent,
                                     bool aCompileEventHandlers)
 {
   nsresult rv = SVGGraphicsElement::BindToTree(aDocument, aParent,
                                                aBindingParent,
                                                aCompileEventHandlers);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  if (aDocument && aDocument->IsSVG()) {
+  nsIDocument* doc = GetComposedDoc();
+  if (doc && doc->IsSVG()) {
     // We assume that we're going to have HTML content, so we ensure that the
     // UA style sheets that nsDocumentViewer::CreateStyleSet skipped when
     // it saw the document was an SVG document are loaded.
     //
     // We setup these style sheets during binding, not element construction,
     // because elements can be moved from the document that creates them to
     // another document.
-    aDocument->AsSVGDocument()->EnsureNonSVGUserAgentStyleSheetsLoaded();
+    doc->AsSVGDocument()->EnsureNonSVGUserAgentStyleSheetsLoaded();
   }
 
   return rv;
 }
 
 NS_IMETHODIMP_(bool)
 SVGForeignObjectElement::IsAttributeMapped(const nsIAtom* name) const
 {
--- a/content/svg/content/src/SVGSVGElement.cpp
+++ b/content/svg/content/src/SVGSVGElement.cpp
@@ -751,22 +751,22 @@ SVGSVGElement::BindToTree(nsIDocument* a
     }
   }
 
   nsresult rv = SVGSVGElementBase::BindToTree(aDocument, aParent,
                                               aBindingParent,
                                               aCompileEventHandlers);
   NS_ENSURE_SUCCESS(rv,rv);
 
-  if (aDocument) {
+  nsIDocument* doc = GetComposedDoc();
+  if (doc) {
     // Setup the style sheet during binding, not element construction,
     // because we could move the root SVG element from the document
     // that created it to another document.
-    aDocument->
-      EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::SVGSheet());
+    doc->EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::SVGSheet());
   }
 
   if (mTimedDocumentRoot && smilController) {
     rv = mTimedDocumentRoot->SetParent(smilController);
     if (mStartAnimationOnBindToTree) {
       mTimedDocumentRoot->Begin();
       mStartAnimationOnBindToTree = false;
     }
--- a/content/xul/content/src/nsXULElement.cpp
+++ b/content/xul/content/src/nsXULElement.cpp
@@ -834,32 +834,33 @@ nsXULElement::BindToTree(nsIDocument* aD
     nsContentUtils::AddScriptRunner(new XULInContentErrorReporter(aDocument));
   }
 
   nsresult rv = nsStyledElement::BindToTree(aDocument, aParent,
                                             aBindingParent,
                                             aCompileEventHandlers);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  if (aDocument &&
-      !aDocument->LoadsFullXULStyleSheetUpFront() &&
-      !aDocument->IsUnstyledDocument()) {
+  nsIDocument* doc = GetComposedDoc();
+  if (doc &&
+      !doc->LoadsFullXULStyleSheetUpFront() &&
+      !doc->IsUnstyledDocument()) {
 
     // To save CPU cycles and memory, non-XUL documents only load the user
     // agent style sheet rules for a minimal set of XUL elements such as
     // 'scrollbar' that may be created implicitly for their content (those
     // rules being in minimal-xul.css).  This is where we make sure that all
     // the other XUL UA style sheet rules (xul.css) have been loaded if the
     // minimal set is not sufficient.
     //
     // We do this during binding, not element construction, because elements
     // can be moved from the document that creates them to another document.
 
     if (!XULElementsRulesInMinimalXULSheet(Tag())) {
-      aDocument->EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::XULSheet());
+      doc->EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::XULSheet());
       // To keep memory usage down it is important that we try and avoid
       // pulling xul.css into non-XUL documents. That should be very rare, and
       // for HTML we currently should only pull it in if the document contains
       // an <audio> or <video> element. This assertion is here to make sure
       // that we don't fail to notice if a change to bindings causes us to
       // start pulling in xul.css much more frequently. If this assertion
       // fails then we need to figure out why, and how we can continue to avoid
       // pulling in xul.css.
--- a/content/xul/document/src/nsXULPrototypeCache.cpp
+++ b/content/xul/document/src/nsXULPrototypeCache.cpp
@@ -126,17 +126,23 @@ nsXULPrototypeCache::Observe(nsISupports
         NS_WARNING("Unexpected observer topic.");
     }
     return NS_OK;
 }
 
 nsXULPrototypeDocument*
 nsXULPrototypeCache::GetPrototype(nsIURI* aURI)
 {
-    nsXULPrototypeDocument* protoDoc = mPrototypeTable.GetWeak(aURI);
+    if (!aURI)
+        return nullptr;
+
+    nsCOMPtr<nsIURI> uriWithoutRef;
+    aURI->CloneIgnoringRef(getter_AddRefs(uriWithoutRef));
+
+    nsXULPrototypeDocument* protoDoc = mPrototypeTable.GetWeak(uriWithoutRef);
     if (protoDoc)
         return protoDoc;
 
     nsresult rv = BeginCaching(aURI);
     if (NS_FAILED(rv))
         return nullptr;
 
     // No prototype in XUL memory cache. Spin up the cache Service.
@@ -159,17 +165,23 @@ nsXULPrototypeCache::GetPrototype(nsIURI
     
     mInputStreamTable.Remove(aURI);
     return newProto;
 }
 
 nsresult
 nsXULPrototypeCache::PutPrototype(nsXULPrototypeDocument* aDocument)
 {
-    nsCOMPtr<nsIURI> uri = aDocument->GetURI();
+    if (!aDocument->GetURI()) {
+        return NS_ERROR_FAILURE;
+    }
+
+    nsCOMPtr<nsIURI> uri;
+    aDocument->GetURI()->CloneIgnoringRef(getter_AddRefs(uri));
+
     // Put() releases any old value and addrefs the new one
     mPrototypeTable.Put(uri, aDocument);
 
     return NS_OK;
 }
 
 nsresult
 nsXULPrototypeCache::PutStyleSheet(CSSStyleSheet* aStyleSheet)
--- a/docshell/test/browser/browser.ini
+++ b/docshell/test/browser/browser.ini
@@ -97,8 +97,9 @@ skip-if = e10s
 [browser_loadURI.js]
 skip-if = e10s # Bug ?????? - event handler checks event.target is the content document and test e10s-utils doesn't do that.
 [browser_onbeforeunload_navigation.js]
 skip-if = e10s
 [browser_search_notification.js]
 skip-if = e10s
 [browser_timelineMarkers-01.js]
 [browser_timelineMarkers-02.js]
+skip-if = e10s
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -1350,37 +1350,52 @@ DOMInterfaces = {
 
 'WebGLRenderingContext': {
     'nativeType': 'mozilla::WebGLContext',
     'headerFile': 'WebGLContext.h',
     'implicitJSContext': [ 'getSupportedExtensions' ],
 },
 
 'WebGL2RenderingContext': {
-    'nativeType': 'mozilla::WebGLContext',
-    'headerFile': 'WebGLContext.h',
+    'nativeType': 'mozilla::WebGL2Context',
+    'headerFile': 'WebGL2Context.h',
     'implicitJSContext': [ 'getSupportedExtensions' ],
 },
 
+'WebGLSampler': {
+    'nativeType': 'mozilla::WebGLSampler',
+    'headerFile': 'WebGLSampler.h'
+},
+
 'WebGLShader': {
     'nativeType': 'mozilla::WebGLShader',
     'headerFile': 'WebGLShader.h'
 },
 
 'WebGLShaderPrecisionFormat': {
     'nativeType': 'mozilla::WebGLShaderPrecisionFormat',
     'headerFile': 'WebGLShaderPrecisionFormat.h',
     'wrapperCache': False
 },
 
+'WebGLSync': {
+    'nativeType': 'mozilla::WebGLSync',
+    'headerFile': 'WebGLSync.h'
+},
+
 'WebGLTexture': {
     'nativeType': 'mozilla::WebGLTexture',
     'headerFile': 'WebGLTexture.h'
 },
 
+'WebGLTransformFeedback': {
+    'nativeType': 'mozilla::WebGLTransformFeedback',
+    'headerFile': 'WebGLTransformFeedback.h'
+},
+
 'WebGLUniformLocation': {
     'nativeType': 'mozilla::WebGLUniformLocation',
     'headerFile': 'WebGLUniformLocation.h',
     'wrapperCache': False
 },
 
 'WebGLVertexArray': {
     'nativeType': 'mozilla::WebGLVertexArray',
--- a/dom/canvas/WebGL2Context.h
+++ b/dom/canvas/WebGL2Context.h
@@ -5,59 +5,240 @@
 
 #ifndef WEBGL2CONTEXT_H_
 #define WEBGL2CONTEXT_H_
 
 #include "WebGLContext.h"
 
 namespace mozilla {
 
+class WebGLSampler;
+class WebGLSync;
+class WebGLTransformFeedback;
+class WebGLVertexArrayObject;
+
 class WebGL2Context
     : public WebGLContext
 {
-// -----------------------------------------------------------------------------
-// PUBLIC
 public:
 
-    // -------------------------------------------------------------------------
-    // DESTRUCTOR
-
     virtual ~WebGL2Context();
 
-
-    // -------------------------------------------------------------------------
-    // STATIC FUNCTIONS
-
     static bool IsSupported();
-
     static WebGL2Context* Create();
 
-
-    // -------------------------------------------------------------------------
-    // IMPLEMENT WebGLContext
-
     virtual bool IsWebGL2() const MOZ_OVERRIDE
     {
         return true;
     }
 
-
     // -------------------------------------------------------------------------
     // IMPLEMENT nsWrapperCache
 
     virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
 
 
-// -----------------------------------------------------------------------------
-// PRIVATE
-private:
+    // -------------------------------------------------------------------------
+    // Buffer objects - WebGL2ContextBuffers.cpp
+
+    void CopyBufferSubData(GLenum readTarget, GLenum writeTarget,
+                           GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+    void GetBufferSubData(GLenum target, GLintptr offset, const dom::ArrayBuffer& returnedData);
+    void GetBufferSubData(GLenum target, GLintptr offset, const dom::ArrayBufferView& returnedData);
+
+    // -------------------------------------------------------------------------
+    // Framebuffer objects - WebGL2ContextFramebuffers.cpp
+
+    void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+                         GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+                         GLbitfield mask, GLenum filter);
+    void FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+    void GetInternalformatParameter(JSContext*, GLenum target, GLenum internalformat, GLenum pname, JS::MutableHandleValue retval);
+    void InvalidateFramebuffer(GLenum target, const dom::Sequence<GLenum>& attachments);
+    void InvalidateSubFramebuffer (GLenum target, const dom::Sequence<GLenum>& attachments, GLint x, GLint y,
+                                   GLsizei width, GLsizei height);
+    void ReadBuffer(GLenum mode);
+    void RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat,
+                                        GLsizei width, GLsizei height);
+
+
+    // -------------------------------------------------------------------------
+    // Texture objects - WebGL2ContextTextures.cpp
+
+    void TexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+    void TexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height,
+                      GLsizei depth);
+
+    void TexSubImage3D(GLenum target, GLint level,
+                       GLint xoffset, GLint yoffset, GLint zoffset,
+                       GLsizei width, GLsizei height, GLsizei depth,
+                       GLenum format, GLenum type, const Nullable<dom::ArrayBufferView>& pixels,
+                       ErrorResult& rv);
+    void TexSubImage3D(GLenum target, GLint level,
+                       GLint xoffset, GLint yoffset, GLint zoffset,
+                       GLenum format, GLenum type, dom::ImageData* data,
+                       ErrorResult& rv);
+    template<class ElementType>
+    void TexSubImage3D(GLenum target, GLint level,
+                       GLint xoffset, GLint yoffset, GLint zoffset,
+                       GLenum format, GLenum type, ElementType& elt, ErrorResult& rv)
+    {}
+
+    void CopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+                           GLint x, GLint y, GLsizei width, GLsizei height);
+    void CompressedTexImage3D(GLenum target, GLint level, GLenum internalformat,
+                              GLsizei width, GLsizei height, GLsizei depth,
+                              GLint border, GLsizei imageSize, const dom::ArrayBufferView& data);
+    void CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+                                 GLsizei width, GLsizei height, GLsizei depth,
+                                 GLenum format, GLsizei imageSize, const dom::ArrayBufferView& data);
+
+
+    // -------------------------------------------------------------------------
+    // Programs and shaders - WebGL2ContextPrograms.cpp
+    GLint GetFragDataLocation(WebGLProgram* program, const nsAString& name);
+
+
+    // -------------------------------------------------------------------------
+    // Uniforms and attributes - WebGL2ContextUniforms.cpp
+    void VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset);
+
+    void Uniform1ui(WebGLUniformLocation* location, GLuint v0);
+    void Uniform2ui(WebGLUniformLocation* location, GLuint v0, GLuint v1);
+    void Uniform3ui(WebGLUniformLocation* location, GLuint v0, GLuint v1, GLuint v2);
+    void Uniform4ui(WebGLUniformLocation* location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+    void Uniform1uiv(WebGLUniformLocation* location, const dom::Sequence<GLuint>& value);
+    void Uniform2uiv(WebGLUniformLocation* location, const dom::Sequence<GLuint>& value);
+    void Uniform3uiv(WebGLUniformLocation* location, const dom::Sequence<GLuint>& value);
+    void Uniform4uiv(WebGLUniformLocation* location, const dom::Sequence<GLuint>& value);
+    void UniformMatrix2x3fv(WebGLUniformLocation* location, bool transpose, const dom::Float32Array& value);
+    void UniformMatrix2x3fv(WebGLUniformLocation* location, bool transpose, const dom::Sequence<GLfloat>& value);
+    void UniformMatrix3x2fv(WebGLUniformLocation* location, bool transpose, const dom::Float32Array& value);
+    void UniformMatrix3x2fv(WebGLUniformLocation* location, bool transpose, const dom::Sequence<GLfloat>& value);
+    void UniformMatrix2x4fv(WebGLUniformLocation* location, bool transpose, const dom::Float32Array& value);
+    void UniformMatrix2x4fv(WebGLUniformLocation* location, bool transpose, const dom::Sequence<GLfloat>& value);
+    void UniformMatrix4x2fv(WebGLUniformLocation* location, bool transpose, const dom::Float32Array& value);
+    void UniformMatrix4x2fv(WebGLUniformLocation* location, bool transpose, const dom::Sequence<GLfloat>& value);
+    void UniformMatrix3x4fv(WebGLUniformLocation* location, bool transpose, const dom::Float32Array& value);
+    void UniformMatrix3x4fv(WebGLUniformLocation* location, bool transpose, const dom::Sequence<GLfloat>& value);
+    void UniformMatrix4x3fv(WebGLUniformLocation* location, bool transpose, const dom::Float32Array& value);
+    void UniformMatrix4x3fv(WebGLUniformLocation* location, bool transpose, const dom::Sequence<GLfloat>& value);
+
+    void VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w);
+    void VertexAttribI4iv(GLuint index, const dom::Sequence<GLint>& v);
+    void VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+    void VertexAttribI4uiv(GLuint index, const dom::Sequence<GLuint>& v);
+
 
     // -------------------------------------------------------------------------
-    // CONSTRUCTOR
+    // Writing to the drawing buffer
+    // TODO(djg): Implemented in WebGLContext
+/*
+    void VertexAttribDivisor(GLuint index, GLuint divisor);
+    void DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount);
+    void DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, GLintptr offset, GLsizei instanceCount);
+*/
+    void DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, GLintptr offset);
+
+
+    // ------------------------------------------------------------------------
+    // Multiple Render Targets - WebGL2ContextMRTs.cpp
+    // TODO(djg): Implemented in WebGLContext
+/*
+    void DrawBuffers(const dom::Sequence<GLenum>& buffers);
+*/
+    void ClearBufferiv(GLenum buffer, GLint drawbuffer, const dom::Int32Array& value);
+    void ClearBufferiv(GLenum buffer, GLint drawbuffer, const dom::Sequence<GLint>& value);
+    void ClearBufferuiv(GLenum buffer, GLint drawbuffer, const dom::Uint32Array& value);
+    void ClearBufferuiv(GLenum buffer, GLint drawbuffer, const dom::Sequence<GLuint>& value);
+    void ClearBufferfv(GLenum buffer, GLint drawbuffer, const dom::Float32Array& value);
+    void ClearBufferfv(GLenum buffer, GLint drawbuffer, const dom::Sequence<GLfloat>& value);
+    void ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+
+
+    // -------------------------------------------------------------------------
+    // Query Objects - WebGL2ContextQueries.cpp
+    // TODO(djg): Implemented in WebGLContext
+    /* already_AddRefed<WebGLQuery> CreateQuery();
+    void DeleteQuery(WebGLQuery* query);
+    bool IsQuery(WebGLQuery* query);
+    void BeginQuery(GLenum target, WebGLQuery* query);
+    void EndQuery(GLenum target);
+    JS::Value GetQuery(JSContext*, GLenum target, GLenum pname); */
+    void GetQueryParameter(JSContext*, WebGLQuery* query, GLenum pname, JS::MutableHandleValue retval);
+
+    // -------------------------------------------------------------------------
+    // Sampler Objects - WebGL2ContextSamplers.cpp
+
+    already_AddRefed<WebGLSampler> CreateSampler();
+    void DeleteSampler(WebGLSampler* sampler);
+    bool IsSampler(WebGLSampler* sampler);
+    void BindSampler(GLuint unit, WebGLSampler* sampler);
+    void SamplerParameteri(WebGLSampler* sampler, GLenum pname, GLint param);
+    void SamplerParameteriv(WebGLSampler* sampler, GLenum pname, const dom::Int32Array& param);
+    void SamplerParameteriv(WebGLSampler* sampler, GLenum pname, const dom::Sequence<GLint>& param);
+    void SamplerParameterf(WebGLSampler* sampler, GLenum pname, GLfloat param);
+    void SamplerParameterfv(WebGLSampler* sampler, GLenum pname, const dom::Float32Array& param);
+    void SamplerParameterfv(WebGLSampler* sampler, GLenum pname, const dom::Sequence<GLfloat>& param);
+    void GetSamplerParameter(JSContext*, WebGLSampler* sampler, GLenum pname, JS::MutableHandleValue retval);
+
+
+    // -------------------------------------------------------------------------
+    // Sync objects - WebGL2ContextSync.cpp
+
+    already_AddRefed<WebGLSync> FenceSync(GLenum condition, GLbitfield flags);
+    bool IsSync(WebGLSync* sync);
+    void DeleteSync(WebGLSync* sync);
+    GLenum ClientWaitSync(WebGLSync* sync, GLbitfield flags, GLuint64 timeout);
+    void WaitSync(WebGLSync* sync, GLbitfield flags, GLuint64 timeout);
+    void GetSyncParameter(JSContext*, WebGLSync* sync, GLenum pname, JS::MutableHandleValue retval);
+
+
+    // -------------------------------------------------------------------------
+    // Transform Feedback - WebGL2ContextTransformFeedback.cpp
+    already_AddRefed<WebGLTransformFeedback> CreateTransformFeedback();
+    void DeleteTransformFeedback(WebGLTransformFeedback* tf);
+    bool IsTransformFeedback(WebGLTransformFeedback* tf);
+    void BindTransformFeedback(GLenum target, GLuint id);
+    void BeginTransformFeedback(GLenum primitiveMode);
+    void EndTransformFeedback();
+    void TransformFeedbackVaryings(WebGLProgram* program, GLsizei count,
+                                   const dom::Sequence<nsString>& varyings, GLenum bufferMode);
+    already_AddRefed<WebGLActiveInfo> GetTransformFeedbackVarying(WebGLProgram* program, GLuint index);
+    void PauseTransformFeedback();
+    void ResumeTransformFeedback();
+
+
+    // -------------------------------------------------------------------------
+    // Uniform Buffer Objects and Transform Feedback Buffers - WebGL2ContextUniforms.cpp
+    // TODO(djg): Implemented in WebGLContext
+/*
+    void BindBufferBase(GLenum target, GLuint index, WebGLBuffer* buffer);
+    void BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer, GLintptr offset, GLsizeiptr size);
+*/
+    void GetIndexedParameter(JSContext*, GLenum target, GLuint index, JS::MutableHandleValue retval);
+    void GetUniformIndices(WebGLProgram* program, const dom::Sequence<nsString>& uniformNames, dom::Nullable< nsTArray<GLuint> >& retval);
+    void GetActiveUniforms(WebGLProgram* program, const dom::Sequence<GLuint>& uniformIndices, GLenum pname,
+                           dom::Nullable< nsTArray<GLint> >& retval);
+    GLuint GetUniformBlockIndex(WebGLProgram* program, const nsAString& uniformBlockName);
+    void GetActiveUniformBlockParameter(JSContext*, WebGLProgram* program, GLuint uniformBlockIndex, GLenum pname, JS::MutableHandleValue retval);
+    void GetActiveUniformBlockName(WebGLProgram* program, GLuint uniformBlockIndex, dom::DOMString& retval);
+    void UniformBlockBinding(WebGLProgram* program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+
+
+    // -------------------------------------------------------------------------
+    // Vertex Array Object - WebGL2ContextVAOs.cpp
+    // TODO(djg): Implemented in WebGLContext
+/*
+    already_AddRefed<WebGLVertexArrayObject> CreateVertexArray();
+    void DeleteVertexArray(WebGLVertexArrayObject* vertexArray);
+    bool IsVertexArray(WebGLVertexArrayObject* vertexArray);
+    void BindVertexArray(WebGLVertexArrayObject* vertexArray);
+*/
+
+private:
 
     WebGL2Context();
-
-
 };
 
 } // namespace mozilla
 
 #endif
new file mode 100644
--- /dev/null
+++ b/dom/canvas/WebGL2ContextBuffers.cpp
@@ -0,0 +1,32 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "WebGL2Context.h"
+#include "GLContext.h"
+
+using namespace mozilla;
+using namespace mozilla::dom;
+
+// -------------------------------------------------------------------------
+// Buffer objects
+
+void
+WebGL2Context::CopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset,
+                                 GLintptr writeOffset, GLsizeiptr size)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::GetBufferSubData(GLenum target, GLintptr offset, const dom::ArrayBuffer& returnedData)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::GetBufferSubData(GLenum target, GLintptr offset, const dom::ArrayBufferView& returnedData)
+{
+    MOZ_CRASH("Not Implemented.");
+}
new file mode 100644
--- /dev/null
+++ b/dom/canvas/WebGL2ContextDraw.cpp
@@ -0,0 +1,19 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "WebGL2Context.h"
+#include "GLContext.h"
+
+using namespace mozilla;
+using namespace mozilla::dom;
+
+// -------------------------------------------------------------------------
+// Writing to the drawing buffer
+
+void
+WebGL2Context::DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, GLintptr offset)
+{
+    MOZ_CRASH("Not Implemented.");
+}
new file mode 100644
--- /dev/null
+++ b/dom/canvas/WebGL2ContextFramebuffers.cpp
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "WebGL2Context.h"
+#include "GLContext.h"
+
+using namespace mozilla;
+using namespace mozilla::dom;
+
+// -------------------------------------------------------------------------
+// Framebuffer objects
+
+void
+WebGL2Context::BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+                               GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+                               GLbitfield mask, GLenum filter)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::GetInternalformatParameter(JSContext*, GLenum target, GLenum internalformat, GLenum pname, JS::MutableHandleValue retval)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::InvalidateFramebuffer(GLenum target, const dom::Sequence<GLenum>& attachments)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::InvalidateSubFramebuffer (GLenum target, const dom::Sequence<GLenum>& attachments,
+                                         GLint x, GLint y, GLsizei width, GLsizei height)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::ReadBuffer(GLenum mode)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat,
+                                              GLsizei width, GLsizei height)
+{
+    MOZ_CRASH("Not Implemented.");
+}
new file mode 100644
--- /dev/null
+++ b/dom/canvas/WebGL2ContextMRTs.cpp
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "WebGL2Context.h"
+#include "GLContext.h"
+
+using namespace mozilla;
+using namespace mozilla::dom;
+
+void
+WebGL2Context::ClearBufferiv(GLenum buffer, GLint drawbuffer, const dom::Int32Array& value)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::ClearBufferiv(GLenum buffer, GLint drawbuffer, const dom::Sequence<GLint>& value)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::ClearBufferuiv(GLenum buffer, GLint drawbuffer, const dom::Uint32Array& value)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::ClearBufferuiv(GLenum buffer, GLint drawbuffer, const dom::Sequence<GLuint>& value)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::ClearBufferfv(GLenum buffer, GLint drawbuffer, const dom::Float32Array& value)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::ClearBufferfv(GLenum buffer, GLint drawbuffer, const dom::Sequence<GLfloat>& value)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
+{
+    MOZ_CRASH("Not Implemented.");
+}
new file mode 100644
--- /dev/null
+++ b/dom/canvas/WebGL2ContextPrograms.cpp
@@ -0,0 +1,19 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "WebGL2Context.h"
+#include "GLContext.h"
+
+using namespace mozilla;
+using namespace mozilla::dom;
+
+// -------------------------------------------------------------------------
+// Programs and shaders
+GLint
+WebGL2Context::GetFragDataLocation(WebGLProgram* program, const nsAString& name)
+{
+    MOZ_CRASH("Not Implemented.");
+    return 0;
+}
new file mode 100644
--- /dev/null
+++ b/dom/canvas/WebGL2ContextQueries.cpp
@@ -0,0 +1,28 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "WebGL2Context.h"
+#include "GLContext.h"
+
+using namespace mozilla;
+using namespace mozilla::dom;
+
+// -------------------------------------------------------------------------
+// Query Objects
+// TODO(djg): Implemented in WebGLContext
+
+/*
+    already_AddRefed<WebGLQuery> CreateQuery();
+    void DeleteQuery(WebGLQuery* query);
+    bool IsQuery(WebGLQuery* query);
+    void BeginQuery(GLenum target, WebGLQuery* query);
+    void EndQuery(GLenum target);
+    JS::Value GetQuery(JSContext*, GLenum target, GLenum pname);
+*/
+void
+WebGL2Context::GetQueryParameter(JSContext*, WebGLQuery* query, GLenum pname, JS::MutableHandleValue retval)
+{
+    MOZ_CRASH("Not Implemented");
+}
new file mode 100644
--- /dev/null
+++ b/dom/canvas/WebGL2ContextSamplers.cpp
@@ -0,0 +1,78 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "WebGL2Context.h"
+#include "GLContext.h"
+
+using namespace mozilla;
+using namespace mozilla::dom;
+
+already_AddRefed<WebGLSampler>
+WebGL2Context::CreateSampler()
+{
+    MOZ_CRASH("Not Implemented.");
+    return nullptr;
+}
+
+void
+WebGL2Context::DeleteSampler(WebGLSampler* sampler)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+bool
+WebGL2Context::IsSampler(WebGLSampler* sampler)
+{
+    MOZ_CRASH("Not Implemented.");
+    return false;
+}
+
+void
+WebGL2Context::BindSampler(GLuint unit, WebGLSampler* sampler)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::SamplerParameteri(WebGLSampler* sampler, GLenum pname, GLint param)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::SamplerParameteriv(WebGLSampler* sampler, GLenum pname, const dom::Int32Array& param)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::SamplerParameteriv(WebGLSampler* sampler, GLenum pname, const dom::Sequence<GLint>& param)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::SamplerParameterf(WebGLSampler* sampler, GLenum pname, GLfloat param)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::SamplerParameterfv(WebGLSampler* sampler, GLenum pname, const dom::Float32Array& param)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::SamplerParameterfv(WebGLSampler* sampler, GLenum pname, const dom::Sequence<GLfloat>& param)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::GetSamplerParameter(JSContext*, WebGLSampler* sampler, GLenum pname, JS::MutableHandleValue retval)
+{
+    MOZ_CRASH("Not Implemented.");
+}
new file mode 100644
--- /dev/null
+++ b/dom/canvas/WebGL2ContextSync.cpp
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "WebGL2Context.h"
+#include "GLContext.h"
+
+using namespace mozilla;
+using namespace mozilla::dom;
+
+// -------------------------------------------------------------------------
+// Sync objects
+
+already_AddRefed<WebGLSync>
+WebGL2Context::FenceSync(GLenum condition, GLbitfield flags)
+{
+    MOZ_CRASH("Not Implemented.");
+    return nullptr;
+}
+
+bool
+WebGL2Context::IsSync(WebGLSync* sync)
+{
+    MOZ_CRASH("Not Implemented.");
+    return false;
+}
+
+void
+WebGL2Context::DeleteSync(WebGLSync* sync)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+GLenum
+WebGL2Context::ClientWaitSync(WebGLSync* sync, GLbitfield flags, GLuint64 timeout)
+{
+    MOZ_CRASH("Not Implemented.");
+    return LOCAL_GL_FALSE;
+}
+
+void
+WebGL2Context::WaitSync(WebGLSync* sync, GLbitfield flags, GLuint64 timeout)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::GetSyncParameter(JSContext*, WebGLSync* sync, GLenum pname, JS::MutableHandleValue retval)
+{
+    MOZ_CRASH("Not Implemented.");
+}
new file mode 100644
--- /dev/null
+++ b/dom/canvas/WebGL2ContextTextures.cpp
@@ -0,0 +1,69 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "WebGL2Context.h"
+#include "GLContext.h"
+
+using namespace mozilla;
+using namespace mozilla::dom;
+
+// -------------------------------------------------------------------------
+// Texture objects
+
+void
+WebGL2Context::TexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::TexStorage3D(GLenum target, GLsizei levels, GLenum internalformat,
+                            GLsizei width, GLsizei height, GLsizei depth)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::TexSubImage3D(GLenum target, GLint level,
+                             GLint xoffset, GLint yoffset, GLint zoffset,
+                             GLsizei width, GLsizei height, GLsizei depth,
+                             GLenum format, GLenum type, const Nullable<dom::ArrayBufferView>& pixels,
+                             ErrorResult& rv)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::TexSubImage3D(GLenum target, GLint level,
+                             GLint xoffset, GLint yoffset, GLint zoffset,
+                             GLenum format, GLenum type, dom::ImageData* data,
+                             ErrorResult& rv)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::CopyTexSubImage3D(GLenum target, GLint level,
+                                 GLint xoffset, GLint yoffset, GLint zoffset,
+                                 GLint x, GLint y, GLsizei width, GLsizei height)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::CompressedTexImage3D(GLenum target, GLint level, GLenum internalformat,
+                                    GLsizei width, GLsizei height, GLsizei depth,
+                                    GLint border, GLsizei imageSize, const dom::ArrayBufferView& data)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+                                       GLsizei width, GLsizei height, GLsizei depth,
+                                       GLenum format, GLsizei imageSize, const dom::ArrayBufferView& data)
+{
+    MOZ_CRASH("Not Implemented.");
+}
new file mode 100644
--- /dev/null
+++ b/dom/canvas/WebGL2ContextTransformFeedback.cpp
@@ -0,0 +1,78 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "WebGL2Context.h"
+#include "GLContext.h"
+
+using namespace mozilla;
+using namespace mozilla::dom;
+
+// -------------------------------------------------------------------------
+// Transform Feedback
+
+already_AddRefed<WebGLTransformFeedback>
+WebGL2Context::CreateTransformFeedback()
+{
+    MOZ_CRASH("Not Implemented.");
+    return nullptr;
+}
+
+void
+WebGL2Context::DeleteTransformFeedback(WebGLTransformFeedback* tf)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+bool
+WebGL2Context::IsTransformFeedback(WebGLTransformFeedback* tf)
+{
+    MOZ_CRASH("Not Implemented.");
+    return false;
+}
+
+void
+WebGL2Context::BindTransformFeedback(GLenum target, GLuint id)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::BeginTransformFeedback(GLenum primitiveMode)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::EndTransformFeedback()
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::TransformFeedbackVaryings(WebGLProgram* program, GLsizei count,
+                                         const dom::Sequence<nsString>& varyings, GLenum bufferMode)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+
+already_AddRefed<WebGLActiveInfo>
+WebGL2Context::GetTransformFeedbackVarying(WebGLProgram* program, GLuint index)
+{
+    MOZ_CRASH("Not Implemented.");
+    return nullptr;
+}
+
+void
+WebGL2Context::PauseTransformFeedback()
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::ResumeTransformFeedback()
+{
+    MOZ_CRASH("Not Implemented.");
+}
new file mode 100644
--- /dev/null
+++ b/dom/canvas/WebGL2ContextUniforms.cpp
@@ -0,0 +1,221 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "WebGL2Context.h"
+#include "GLContext.h"
+
+using namespace mozilla;
+using namespace mozilla::dom;
+
+// -------------------------------------------------------------------------
+// Uniforms and attributes
+
+void
+WebGL2Context::VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::Uniform1ui(WebGLUniformLocation* location, GLuint v0)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::Uniform2ui(WebGLUniformLocation* location, GLuint v0, GLuint v1)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::Uniform3ui(WebGLUniformLocation* location, GLuint v0, GLuint v1, GLuint v2)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::Uniform4ui(WebGLUniformLocation* location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::Uniform1uiv(WebGLUniformLocation* location, const dom::Sequence<GLuint>& value)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::Uniform2uiv(WebGLUniformLocation* location, const dom::Sequence<GLuint>& value)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::Uniform3uiv(WebGLUniformLocation* location, const dom::Sequence<GLuint>& value)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::Uniform4uiv(WebGLUniformLocation* location, const dom::Sequence<GLuint>& value)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::UniformMatrix2x3fv(WebGLUniformLocation* location, bool transpose, const dom::Float32Array& value)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::UniformMatrix2x3fv(WebGLUniformLocation* location, bool transpose, const dom::Sequence<GLfloat>& value)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::UniformMatrix3x2fv(WebGLUniformLocation* location, bool transpose, const dom::Float32Array& value)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::UniformMatrix3x2fv(WebGLUniformLocation* location, bool transpose, const dom::Sequence<GLfloat>& value)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::UniformMatrix2x4fv(WebGLUniformLocation* location, bool transpose, const dom::Float32Array& value)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::UniformMatrix2x4fv(WebGLUniformLocation* location, bool transpose, const dom::Sequence<GLfloat>& value)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::UniformMatrix4x2fv(WebGLUniformLocation* location, bool transpose, const dom::Float32Array& value)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::UniformMatrix4x2fv(WebGLUniformLocation* location, bool transpose, const dom::Sequence<GLfloat>& value)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::UniformMatrix3x4fv(WebGLUniformLocation* location, bool transpose, const dom::Float32Array& value)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::UniformMatrix3x4fv(WebGLUniformLocation* location, bool transpose, const dom::Sequence<GLfloat>& value)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::UniformMatrix4x3fv(WebGLUniformLocation* location, bool transpose, const dom::Float32Array& value)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::UniformMatrix4x3fv(WebGLUniformLocation* location, bool transpose, const dom::Sequence<GLfloat>& value)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::VertexAttribI4iv(GLuint index, const dom::Sequence<GLint>& v)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::VertexAttribI4uiv(GLuint index, const dom::Sequence<GLuint>& v)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+// -------------------------------------------------------------------------
+// Uniform Buffer Objects and Transform Feedback Buffers
+// TODO(djg): Implemented in WebGLContext
+/*
+    void BindBufferBase(GLenum target, GLuint index, WebGLBuffer* buffer);
+    void BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer, GLintptr offset, GLsizeiptr size);
+*/
+
+void
+WebGL2Context::GetIndexedParameter(JSContext*, GLenum target, GLuint index, JS::MutableHandleValue retval)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::GetUniformIndices(WebGLProgram* program,
+                                 const dom::Sequence<nsString>& uniformNames,
+                                 dom::Nullable< nsTArray<GLuint> >& retval)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::GetActiveUniforms(WebGLProgram* program,
+                                 const dom::Sequence<GLuint>& uniformIndices,
+                                 GLenum pname,
+                                 dom::Nullable< nsTArray<GLint> >& retval)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+GLuint
+WebGL2Context::GetUniformBlockIndex(WebGLProgram* program, const nsAString& uniformBlockName)
+{
+    MOZ_CRASH("Not Implemented.");
+    return 0;
+}
+
+void
+WebGL2Context::GetActiveUniformBlockParameter(JSContext*, WebGLProgram* program,
+                                              GLuint uniformBlockIndex, GLenum pname,
+                                              JS::MutableHandleValue retval)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::GetActiveUniformBlockName(WebGLProgram* program, GLuint uniformBlockIndex, dom::DOMString& retval)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+void
+WebGL2Context::UniformBlockBinding(WebGLProgram* program, GLuint uniformBlockIndex, GLuint uniformBlockBinding)
+{
+    MOZ_CRASH("Not Implemented.");
+}
new file mode 100644
--- /dev/null
+++ b/dom/canvas/WebGL2ContextVAOs.cpp
@@ -0,0 +1,20 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "WebGL2Context.h"
+#include "GLContext.h"
+
+using namespace mozilla;
+using namespace mozilla::dom;
+
+// -------------------------------------------------------------------------
+// Vertex Array Object
+// TODO(djg): Implemented in WebGLContext
+/*
+    already_AddRefed<WebGLVertexArrayObject> CreateVertexArray();
+    void DeleteVertexArray(WebGLVertexArrayObject* vertexArray);
+    bool IsVertexArray(WebGLVertexArrayObject* vertexArray);
+    void BindVertexArray(WebGLVertexArrayObject* vertexArray);
+*/
new file mode 100644
--- /dev/null
+++ b/dom/canvas/WebGLSampler.cpp
@@ -0,0 +1,49 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "WebGLContext.h"
+#include "WebGLSampler.h"
+
+#include "GLContext.h"
+
+#include "mozilla/dom/WebGL2RenderingContextBinding.h"
+
+using namespace mozilla;
+
+WebGLSampler::WebGLSampler(WebGLContext* context)
+    : WebGLBindableName()
+    , WebGLContextBoundObject(context)
+{
+    SetIsDOMBinding();
+    MOZ_CRASH("Not Implemented.");
+}
+
+WebGLSampler::~WebGLSampler()
+{}
+
+void
+WebGLSampler::Delete()
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+WebGLContext*
+WebGLSampler::GetParentObject() const
+{
+    MOZ_CRASH("Not Implemented.");
+    return nullptr;
+}
+
+JSObject*
+WebGLSampler::WrapObject(JSContext* cx)
+{
+    MOZ_CRASH("Not Implemented.");
+    return dom::WebGLSamplerBinding::Wrap(cx, this);
+}
+
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLSampler)
+NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLSampler, AddRef)
+NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLSampler, Release)
new file mode 100644
--- /dev/null
+++ b/dom/canvas/WebGLSampler.h
@@ -0,0 +1,46 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef WEBGL2SAMPLER_H_
+#define WEBGL2SAMPLER_H_
+
+#include "WebGLBindableName.h"
+#include "WebGLObjectModel.h"
+
+#include "nsWrapperCache.h"
+
+#include "mozilla/LinkedList.h"
+
+namespace mozilla {
+
+class WebGLSampler MOZ_FINAL
+    : public WebGLBindableName
+    , public nsWrapperCache
+    , public WebGLRefCountedObject<WebGLSampler>
+    , public LinkedListElement<WebGLSampler>
+    , public WebGLContextBoundObject
+{
+    friend class WebGLContext2;
+
+public:
+
+    WebGLSampler(WebGLContext* context);
+
+    void Delete();
+    WebGLContext* GetParentObject() const;
+
+    virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
+
+    NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLSampler)
+    NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLSampler)
+
+private:
+
+    ~WebGLSampler();
+};
+
+} // namespace mozilla
+
+#endif // !WEBGL2SAMPLER_H_
new file mode 100644
--- /dev/null
+++ b/dom/canvas/WebGLSync.cpp
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "WebGLSync.h"
+
+#include "mozilla/dom/WebGL2RenderingContextBinding.h"
+
+using namespace mozilla;
+
+WebGLSync::WebGLSync(WebGLContext* context) :
+    WebGLContextBoundObject(context)
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+WebGLSync::~WebGLSync()
+{}
+
+void
+WebGLSync::Delete()
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+WebGLContext*
+WebGLSync::GetParentObject() const
+{
+    MOZ_CRASH("Not Implemented.");
+    return nullptr;
+}
+
+// -------------------------------------------------------------------------
+// IMPLEMENT NS
+JSObject*
+WebGLSync::WrapObject(JSContext *cx)
+{
+    return dom::WebGLSyncBinding::Wrap(cx, this);
+}
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLSync)
+NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLSync, AddRef)
+NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLSync, Release);
new file mode 100644
--- /dev/null
+++ b/dom/canvas/WebGLSync.h
@@ -0,0 +1,46 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef WEBGLSYNC_H_
+#define WEBGLSYNC_H_
+
+#include "WebGLObjectModel.h"
+
+#include "nsWrapperCache.h"
+
+#include "mozilla/LinkedList.h"
+
+namespace mozilla {
+
+class WebGLSync MOZ_FINAL
+    : public nsWrapperCache
+    , public WebGLRefCountedObject<WebGLSync>
+    , public LinkedListElement<WebGLSync>
+    , public WebGLContextBoundObject
+{
+    friend class WebGL2Context;
+
+public:
+
+    WebGLSync(WebGLContext* context);
+
+    void Delete();
+    WebGLContext* GetParentObject() const;
+
+    // -------------------------------------------------------------------------
+    // IMPLEMENT NS
+    virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
+
+    NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLSync)
+    NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLSync)
+
+private:
+
+    ~WebGLSync();
+};
+
+} // namespace mozilla
+
+#endif // !WEBGLSYNC_H_
new file mode 100644
--- /dev/null
+++ b/dom/canvas/WebGLTransformFeedback.cpp
@@ -0,0 +1,48 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "WebGL2Context.h"
+#include "WebGLTransformFeedback.h"
+
+#include "GLContext.h"
+
+#include "mozilla/dom/WebGL2RenderingContextBinding.h"
+
+using namespace mozilla;
+
+WebGLTransformFeedback::WebGLTransformFeedback(WebGLContext* context)
+    : WebGLBindableName()
+    , WebGLContextBoundObject(context)
+{
+    SetIsDOMBinding();
+    MOZ_CRASH("Not Implemented.");
+}
+
+WebGLTransformFeedback::~WebGLTransformFeedback()
+{}
+
+void
+WebGLTransformFeedback::Delete()
+{
+    MOZ_CRASH("Not Implemented.");
+}
+
+WebGLContext*
+WebGLTransformFeedback::GetParentObject() const
+{
+    MOZ_CRASH("Not Implemented.");
+    return nullptr;
+}
+
+JSObject*
+WebGLTransformFeedback::WrapObject(JSContext* cx)
+{
+    return dom::WebGLTransformFeedbackBinding::Wrap(cx, this);
+}
+
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLTransformFeedback)
+NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLTransformFeedback, AddRef)
+NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLTransformFeedback, Release)
new file mode 100644
--- /dev/null
+++ b/dom/canvas/WebGLTransformFeedback.h
@@ -0,0 +1,48 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef WEBGLTRANSFORMFEEDBACK_H_
+#define WEBGLTRANSFORMFEEDBACK_H_
+
+#include "WebGLBindableName.h"
+#include "WebGLObjectModel.h"
+
+#include "nsWrapperCache.h"
+
+#include "mozilla/LinkedList.h"
+
+namespace mozilla {
+
+class WebGLTransformFeedback MOZ_FINAL
+    : public WebGLBindableName
+    , public nsWrapperCache
+    , public WebGLRefCountedObject<WebGLTransformFeedback>
+    , public LinkedListElement<WebGLTransformFeedback>
+    , public WebGLContextBoundObject
+{
+    friend class WebGLContext;
+
+public:
+
+    WebGLTransformFeedback(WebGLContext* context);
+
+    void Delete();
+    WebGLContext* GetParentObject() const;
+
+    // -------------------------------------------------------------------------
+    // IMPLEMENT NS
+    virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
+
+    NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLTransformFeedback)
+    NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLTransformFeedback)
+
+private:
+
+    ~WebGLTransformFeedback();
+};
+
+}
+
+#endif // !WEBGLTRANSFORMFEEDBACK_H_
--- a/dom/canvas/moz.build
+++ b/dom/canvas/moz.build
@@ -35,16 +35,28 @@ UNIFIED_SOURCES += [
     'ImageData.cpp',
 ]
 
 # WebGL Sources
 UNIFIED_SOURCES += [
     'MurmurHash3.cpp',
     'WebGL1Context.cpp',
     'WebGL2Context.cpp',
+    'WebGL2ContextBuffers.cpp',
+    'WebGL2ContextDraw.cpp',
+    'WebGL2ContextFramebuffers.cpp',
+    'WebGL2ContextMRTs.cpp',
+    'WebGL2ContextPrograms.cpp',
+    'WebGL2ContextQueries.cpp',
+    'WebGL2ContextSamplers.cpp',
+    'WebGL2ContextSync.cpp',
+    'WebGL2ContextTextures.cpp',
+    'WebGL2ContextTransformFeedback.cpp',
+    'WebGL2ContextUniforms.cpp',
+    'WebGL2ContextVAOs.cpp',
     'WebGLActiveInfo.cpp',
     'WebGLBindableName.cpp',
     'WebGLBuffer.cpp',
     'WebGLContext.cpp',
     'WebGLContextAsyncQueries.cpp',
     'WebGLContextBuffers.cpp',
     'WebGLContextDraw.cpp',
     'WebGLContextExtensions.cpp',
@@ -84,20 +96,23 @@ UNIFIED_SOURCES += [
     'WebGLExtensionTextureHalfFloatLinear.cpp',
     'WebGLExtensionVertexArray.cpp',
     'WebGLFramebuffer.cpp',
     'WebGLFramebufferAttachable.cpp',
     'WebGLObjectModel.cpp',
     'WebGLProgram.cpp',
     'WebGLQuery.cpp',
     'WebGLRenderbuffer.cpp',
+    'WebGLSampler.cpp',
     'WebGLShader.cpp',
     'WebGLShaderPrecisionFormat.cpp',
+    'WebGLSync.cpp',
     'WebGLTexelConversions.cpp',
     'WebGLTexture.cpp',
+    'WebGLTransformFeedback.cpp',
     'WebGLUniformLocation.cpp',
     'WebGLVertexArray.cpp',
     'WebGLVertexArrayFake.cpp',
     'WebGLVertexArrayGL.cpp',
 ]
 LOCAL_INCLUDES += [
     '/js/xpconnect/wrappers',
 ]
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -493,27 +493,25 @@ private:
 
 NS_IMPL_ISUPPORTS(BackgroundChildPrimer, nsIIPCBackgroundChildCreateCallback)
 
 ContentChild* ContentChild::sSingleton;
 
 // Performs initialization that is not fork-safe, i.e. that must be done after
 // forking from the Nuwa process.
 static void
-InitOnContentProcessCreated(bool aAfterNuwaFork)
+InitOnContentProcessCreated()
 {
 #ifdef MOZ_NUWA_PROCESS
     // Wait until we are forked from Nuwa
-    if (!aAfterNuwaFork &&
-        Preferences::GetBool("dom.ipc.processPrelaunch.enabled", false)) {
+    if (IsNuwaProcess()) {
         return;
     }
-#else
-    unused << aAfterNuwaFork;
 #endif
+
     // This will register cross-process observer.
     mozilla::dom::time::InitializeDateCacheCleaner();
 }
 
 ContentChild::ContentChild()
  : mID(uint64_t(-1))
 #ifdef ANDROID
    ,mScreenSize(0, 0)
@@ -697,17 +695,17 @@ ContentChild::InitXPCOM()
     DebugOnly<FileUpdateDispatcher*> observer = FileUpdateDispatcher::GetSingleton();
     NS_ASSERTION(observer, "FileUpdateDispatcher is null");
 
     // This object is held alive by the observer service.
     nsRefPtr<SystemMessageHandledObserver> sysMsgObserver =
         new SystemMessageHandledObserver();
     sysMsgObserver->Init();
 
-    InitOnContentProcessCreated(/* aAfterNuwaFork = */false);
+    InitOnContentProcessCreated();
 }
 
 PMemoryReportRequestChild*
 ContentChild::AllocPMemoryReportRequestChild(const uint32_t& aGeneration,
                                              const bool &aAnonymize,
                                              const bool &aMinimizeMemoryUsage,
                                              const FileDescriptor& aDMDFile)
 {
@@ -2053,17 +2051,17 @@ public:
             transport = toplevel->GetTransport();
             fd = transport->GetFileDescriptor();
             transport->ResetFileDescriptor(fd);
 
             toplevel = toplevel->getNext();
         }
 
         // Perform other after-fork initializations.
-        InitOnContentProcessCreated(/* aAfterNuwaFork = */true);
+        InitOnContentProcessCreated();
 
         return NS_OK;
     }
 };
 
 static void
 DoNuwaFork()
 {
--- a/dom/mathml/nsMathMLElement.cpp
+++ b/dom/mathml/nsMathMLElement.cpp
@@ -97,29 +97,32 @@ nsMathMLElement::BindToTree(nsIDocument*
 
   nsresult rv = nsMathMLElementBase::BindToTree(aDocument, aParent,
                                                 aBindingParent,
                                                 aCompileEventHandlers);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (aDocument) {
     aDocument->RegisterPendingLinkUpdate(this);
-    
-    if (!aDocument->GetMathMLEnabled()) {
+  }
+
+  nsIDocument* doc = GetComposedDoc();
+  if (doc) {
+    if (!doc->GetMathMLEnabled()) {
       // Enable MathML and setup the style sheet during binding, not element
       // construction, because we could move a MathML element from the document
       // that created it to another document.
-      aDocument->SetMathMLEnabled();
-      aDocument->
+      doc->SetMathMLEnabled();
+      doc->
         EnsureOnDemandBuiltInUASheet(nsLayoutStylesheetCache::MathMLSheet());
 
       // Rebuild style data for the presshell, because style system
       // optimizations may have taken place assuming MathML was disabled.
       // (See nsRuleNode::CheckSpecifiedProperties.)
-      nsCOMPtr<nsIPresShell> shell = aDocument->GetShell();
+      nsCOMPtr<nsIPresShell> shell = doc->GetShell();
       if (shell) {
         shell->GetPresContext()->PostRebuildAllStyleDataEvent(nsChangeHint(0));
       }
     }
   }
 
   return rv;
 }
--- a/dom/webidl/WebGL2RenderingContext.webidl
+++ b/dom/webidl/WebGL2RenderingContext.webidl
@@ -1,131 +1,467 @@
 /* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* 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/.
  *
+ * The source for this IDL is found at https://www.khronos.org/registry/webgl/specs/latest/2.0
  * This IDL depends on WebGLRenderingContext.webidl
  */
 
+typedef long long GLint64; // Should this be int64?
+typedef unsigned long long GLuint64; // Should this be uint64?
+
 [Pref="webgl.enable-prototype-webgl2"]
 interface WebGLQuery {
 };
 
 [Pref="webgl.enable-prototype-webgl2"]
-interface WebGL2RenderingContext : WebGLRenderingContext {
+interface WebGLSampler {
+};
 
-    /* depth textures */
-    const GLenum UNSIGNED_INT_24_8                           = 0x84FA;
-
+[Pref="webgl.enable-prototype-webgl2"]
+interface WebGLSync {
+};
 
-    /* draw buffers */
-    const GLenum COLOR_ATTACHMENT1                           = 0x8CE1;
-    const GLenum COLOR_ATTACHMENT2                           = 0x8CE2;
-    const GLenum COLOR_ATTACHMENT3                           = 0x8CE3;
-    const GLenum COLOR_ATTACHMENT4                           = 0x8CE4;
-    const GLenum COLOR_ATTACHMENT5                           = 0x8CE5;
-    const GLenum COLOR_ATTACHMENT6                           = 0x8CE6;
-    const GLenum COLOR_ATTACHMENT7                           = 0x8CE7;
-    const GLenum COLOR_ATTACHMENT8                           = 0x8CE8;
-    const GLenum COLOR_ATTACHMENT9                           = 0x8CE9;
-    const GLenum COLOR_ATTACHMENT10                          = 0x8CEA;
-    const GLenum COLOR_ATTACHMENT11                          = 0x8CEB;
-    const GLenum COLOR_ATTACHMENT12                          = 0x8CEC;
-    const GLenum COLOR_ATTACHMENT13                          = 0x8CED;
-    const GLenum COLOR_ATTACHMENT14                          = 0x8CEE;
-    const GLenum COLOR_ATTACHMENT15                          = 0x8CEF;
+[Pref="webgl.enable-prototype-webgl2"]
+interface WebGLTransformFeedback {
+};
 
-    const GLenum DRAW_BUFFER0                                = 0x8825;
-    const GLenum DRAW_BUFFER1                                = 0x8826;
-    const GLenum DRAW_BUFFER2                                = 0x8827;
-    const GLenum DRAW_BUFFER3                                = 0x8828;
-    const GLenum DRAW_BUFFER4                                = 0x8829;
-    const GLenum DRAW_BUFFER5                                = 0x882A;
-    const GLenum DRAW_BUFFER6                                = 0x882B;
-    const GLenum DRAW_BUFFER7                                = 0x882C;
-    const GLenum DRAW_BUFFER8                                = 0x882D;
-    const GLenum DRAW_BUFFER9                                = 0x882E;
-    const GLenum DRAW_BUFFER10                               = 0x882F;
-    const GLenum DRAW_BUFFER11                               = 0x8830;
-    const GLenum DRAW_BUFFER12                               = 0x8831;
-    const GLenum DRAW_BUFFER13                               = 0x8832;
-    const GLenum DRAW_BUFFER14                               = 0x8833;
-    const GLenum DRAW_BUFFER15                               = 0x8834;
+/*
+[Pref="webgl.enable-prototype-webgl2"]
+interface WebGLVertexArrayObject {
+};
+*/
 
-    const GLenum MAX_COLOR_ATTACHMENTS                       = 0x8CDF;
-    const GLenum MAX_DRAW_BUFFERS                            = 0x8824;
-
-    void drawBuffers(sequence<GLenum> buffers);
-
-
-    /* draw instanced */
-    void drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount);
-    void drawElementsInstanced(GLenum mode, GLsizei count, GLenum type, GLintptr offset, GLsizei primcount);
-
-
-    /* instanced array */
-    const GLenum VERTEX_ATTRIB_ARRAY_DIVISOR                 = 0x88FE;
-
-    void vertexAttribDivisor(GLuint index, GLuint divisor);
-
+[Pref="webgl.enable-prototype-webgl2"]
+interface WebGL2RenderingContext : WebGLRenderingContext
+{
+    const GLenum READ_BUFFER                                   = 0x0C02;
+    const GLenum UNPACK_ROW_LENGTH                             = 0x0CF2;
+    const GLenum UNPACK_SKIP_ROWS                              = 0x0CF3;
+    const GLenum UNPACK_SKIP_PIXELS                            = 0x0CF4;
+    const GLenum PACK_ROW_LENGTH                               = 0x0D02;
+    const GLenum PACK_SKIP_ROWS                                = 0x0D03;
+    const GLenum PACK_SKIP_PIXELS                              = 0x0D04;
+    const GLenum COLOR                                         = 0x1800;
+    const GLenum DEPTH                                         = 0x1801;
+    const GLenum STENCIL                                       = 0x1802;
+    const GLenum RED                                           = 0x1903;
+    const GLenum RGB8                                          = 0x8051;
+    const GLenum RGBA8                                         = 0x8058;
+    const GLenum RGB10_A2                                      = 0x8059;
+    const GLenum TEXTURE_BINDING_3D                            = 0x806A;
+    const GLenum UNPACK_SKIP_IMAGES                            = 0x806D;
+    const GLenum UNPACK_IMAGE_HEIGHT                           = 0x806E;
+    const GLenum TEXTURE_3D                                    = 0x806F;
+    const GLenum TEXTURE_WRAP_R                                = 0x8072;
+    const GLenum MAX_3D_TEXTURE_SIZE                           = 0x8073;
+    const GLenum UNSIGNED_INT_2_10_10_10_REV                   = 0x8368;
+    const GLenum MAX_ELEMENTS_VERTICES                         = 0x80E8;
+    const GLenum MAX_ELEMENTS_INDICES                          = 0x80E9;
+    const GLenum TEXTURE_MIN_LOD                               = 0x813A;
+    const GLenum TEXTURE_MAX_LOD                               = 0x813B;
+    const GLenum TEXTURE_BASE_LEVEL                            = 0x813C;
+    const GLenum TEXTURE_MAX_LEVEL                             = 0x813D;
+    const GLenum MIN                                           = 0x8007;
+    const GLenum MAX                                           = 0x8008;
+    const GLenum DEPTH_COMPONENT24                             = 0x81A6;
+    const GLenum MAX_TEXTURE_LOD_BIAS                          = 0x84FD;
+    const GLenum TEXTURE_COMPARE_MODE                          = 0x884C;
+    const GLenum TEXTURE_COMPARE_FUNC                          = 0x884D;
+    const GLenum CURRENT_QUERY                                 = 0x8865;
+    const GLenum QUERY_RESULT                                  = 0x8866;
+    const GLenum QUERY_RESULT_AVAILABLE                        = 0x8867;
+    const GLenum STREAM_READ                                   = 0x88E1;
+    const GLenum STREAM_COPY                                   = 0x88E2;
+    const GLenum STATIC_READ                                   = 0x88E5;
+    const GLenum STATIC_COPY                                   = 0x88E6;
+    const GLenum DYNAMIC_READ                                  = 0x88E9;
+    const GLenum DYNAMIC_COPY                                  = 0x88EA;
+    const GLenum MAX_DRAW_BUFFERS                              = 0x8824;
+    const GLenum DRAW_BUFFER0                                  = 0x8825;
+    const GLenum DRAW_BUFFER1                                  = 0x8826;
+    const GLenum DRAW_BUFFER2                                  = 0x8827;
+    const GLenum DRAW_BUFFER3                                  = 0x8828;
+    const GLenum DRAW_BUFFER4                                  = 0x8829;
+    const GLenum DRAW_BUFFER5                                  = 0x882A;
+    const GLenum DRAW_BUFFER6                                  = 0x882B;
+    const GLenum DRAW_BUFFER7                                  = 0x882C;
+    const GLenum DRAW_BUFFER8                                  = 0x882D;
+    const GLenum DRAW_BUFFER9                                  = 0x882E;
+    const GLenum DRAW_BUFFER10                                 = 0x882F;
+    const GLenum DRAW_BUFFER11                                 = 0x8830;
+    const GLenum DRAW_BUFFER12                                 = 0x8831;
+    const GLenum DRAW_BUFFER13                                 = 0x8832;
+    const GLenum DRAW_BUFFER14                                 = 0x8833;
+    const GLenum DRAW_BUFFER15                                 = 0x8834;
+    const GLenum MAX_FRAGMENT_UNIFORM_COMPONENTS               = 0x8B49;
+    const GLenum MAX_VERTEX_UNIFORM_COMPONENTS                 = 0x8B4A;
+    const GLenum SAMPLER_3D                                    = 0x8B5F;
+    const GLenum SAMPLER_2D_SHADOW                             = 0x8B62;
+    const GLenum FRAGMENT_SHADER_DERIVATIVE_HINT               = 0x8B8B;
+    const GLenum PIXEL_PACK_BUFFER                             = 0x88EB;
+    const GLenum PIXEL_UNPACK_BUFFER                           = 0x88EC;
+    const GLenum PIXEL_PACK_BUFFER_BINDING                     = 0x88ED;
+    const GLenum PIXEL_UNPACK_BUFFER_BINDING                   = 0x88EF;
+    const GLenum FLOAT_MAT2x3                                  = 0x8B65;
+    const GLenum FLOAT_MAT2x4                                  = 0x8B66;
+    const GLenum FLOAT_MAT3x2                                  = 0x8B67;
+    const GLenum FLOAT_MAT3x4                                  = 0x8B68;
+    const GLenum FLOAT_MAT4x2                                  = 0x8B69;
+    const GLenum FLOAT_MAT4x3                                  = 0x8B6A;
+    const GLenum SRGB                                          = 0x8C40;
+    const GLenum SRGB8                                         = 0x8C41;
+    const GLenum SRGB8_ALPHA8                                  = 0x8C43;
+    const GLenum COMPARE_REF_TO_TEXTURE                        = 0x884E;
+    const GLenum RGBA32F                                       = 0x8814;
+    const GLenum RGB32F                                        = 0x8815;
+    const GLenum RGBA16F                                       = 0x881A;
+    const GLenum RGB16F                                        = 0x881B;
+    const GLenum VERTEX_ATTRIB_ARRAY_INTEGER                   = 0x88FD;
+    const GLenum MAX_ARRAY_TEXTURE_LAYERS                      = 0x88FF;
+    const GLenum MIN_PROGRAM_TEXEL_OFFSET                      = 0x8904;
+    const GLenum MAX_PROGRAM_TEXEL_OFFSET                      = 0x8905;
+    const GLenum MAX_VARYING_COMPONENTS                        = 0x8B4B;
+    const GLenum TEXTURE_2D_ARRAY                              = 0x8C1A;
+    const GLenum TEXTURE_BINDING_2D_ARRAY                      = 0x8C1D;
+    const GLenum R11F_G11F_B10F                                = 0x8C3A;
+    const GLenum UNSIGNED_INT_10F_11F_11F_REV                  = 0x8C3B;
+    const GLenum RGB9_E5                                       = 0x8C3D;
+    const GLenum UNSIGNED_INT_5_9_9_9_REV                      = 0x8C3E;
+    const GLenum TRANSFORM_FEEDBACK_BUFFER_MODE                = 0x8C7F;
+    const GLenum MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS    = 0x8C80;
+    const GLenum TRANSFORM_FEEDBACK_VARYINGS                   = 0x8C83;
+    const GLenum TRANSFORM_FEEDBACK_BUFFER_START               = 0x8C84;
+    const GLenum TRANSFORM_FEEDBACK_BUFFER_SIZE                = 0x8C85;
+    const GLenum TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN         = 0x8C88;
+    const GLenum RASTERIZER_DISCARD                            = 0x8C89;
+    const GLenum MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS = 0x8C8A;
+    const GLenum MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS       = 0x8C8B;
+    const GLenum INTERLEAVED_ATTRIBS                           = 0x8C8C;
+    const GLenum SEPARATE_ATTRIBS                              = 0x8C8D;
+    const GLenum TRANSFORM_FEEDBACK_BUFFER                     = 0x8C8E;
+    const GLenum TRANSFORM_FEEDBACK_BUFFER_BINDING             = 0x8C8F;
+    const GLenum RGBA32UI                                      = 0x8D70;
+    const GLenum RGB32UI                                       = 0x8D71;
+    const GLenum RGBA16UI                                      = 0x8D76;
+    const GLenum RGB16UI                                       = 0x8D77;
+    const GLenum RGBA8UI                                       = 0x8D7C;
+    const GLenum RGB8UI                                        = 0x8D7D;
+    const GLenum RGBA32I                                       = 0x8D82;
+    const GLenum RGB32I                                        = 0x8D83;
+    const GLenum RGBA16I                                       = 0x8D88;
+    const GLenum RGB16I                                        = 0x8D89;
+    const GLenum RGBA8I                                        = 0x8D8E;
+    const GLenum RGB8I                                         = 0x8D8F;
+    const GLenum RED_INTEGER                                   = 0x8D94;
+    const GLenum RGB_INTEGER                                   = 0x8D98;
+    const GLenum RGBA_INTEGER                                  = 0x8D99;
+    const GLenum SAMPLER_2D_ARRAY                              = 0x8DC1;
+    const GLenum SAMPLER_2D_ARRAY_SHADOW                       = 0x8DC4;
+    const GLenum SAMPLER_CUBE_SHADOW                           = 0x8DC5;
+    const GLenum UNSIGNED_INT_VEC2                             = 0x8DC6;
+    const GLenum UNSIGNED_INT_VEC3                             = 0x8DC7;
+    const GLenum UNSIGNED_INT_VEC4                             = 0x8DC8;
+    const GLenum INT_SAMPLER_2D                                = 0x8DCA;
+    const GLenum INT_SAMPLER_3D                                = 0x8DCB;
+    const GLenum INT_SAMPLER_CUBE                              = 0x8DCC;
+    const GLenum INT_SAMPLER_2D_ARRAY                          = 0x8DCF;
+    const GLenum UNSIGNED_INT_SAMPLER_2D                       = 0x8DD2;
+    const GLenum UNSIGNED_INT_SAMPLER_3D                       = 0x8DD3;
+    const GLenum UNSIGNED_INT_SAMPLER_CUBE                     = 0x8DD4;
+    const GLenum UNSIGNED_INT_SAMPLER_2D_ARRAY                 = 0x8DD7;
+    const GLenum DEPTH_COMPONENT32F                            = 0x8CAC;
+    const GLenum DEPTH32F_STENCIL8                             = 0x8CAD;
+    const GLenum FLOAT_32_UNSIGNED_INT_24_8_REV                = 0x8DAD;
+    const GLenum FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING         = 0x8210;
+    const GLenum FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE         = 0x8211;
+    const GLenum FRAMEBUFFER_ATTACHMENT_RED_SIZE               = 0x8212;
+    const GLenum FRAMEBUFFER_ATTACHMENT_GREEN_SIZE             = 0x8213;
+    const GLenum FRAMEBUFFER_ATTACHMENT_BLUE_SIZE              = 0x8214;
+    const GLenum FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE             = 0x8215;
+    const GLenum FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE             = 0x8216;
+    const GLenum FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE           = 0x8217;
+    const GLenum FRAMEBUFFER_DEFAULT                           = 0x8218;
+    const GLenum DEPTH_STENCIL_ATTACHMENT                      = 0x821A;
+    const GLenum DEPTH_STENCIL                                 = 0x84F9;
+    const GLenum UNSIGNED_INT_24_8                             = 0x84FA;
+    const GLenum DEPTH24_STENCIL8                              = 0x88F0;
+    const GLenum UNSIGNED_NORMALIZED                           = 0x8C17;
+    const GLenum DRAW_FRAMEBUFFER_BINDING                      = 0x8CA6; /* Same as FRAMEBUFFER_BINDING */
+    const GLenum READ_FRAMEBUFFER                              = 0x8CA8;
+    const GLenum DRAW_FRAMEBUFFER                              = 0x8CA9;
+    const GLenum READ_FRAMEBUFFER_BINDING                      = 0x8CAA;
+    const GLenum RENDERBUFFER_SAMPLES                          = 0x8CAB;
+    const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER          = 0x8CD4;
+    const GLenum MAX_COLOR_ATTACHMENTS                         = 0x8CDF;
+    const GLenum COLOR_ATTACHMENT1                             = 0x8CE1;
+    const GLenum COLOR_ATTACHMENT2                             = 0x8CE2;
+    const GLenum COLOR_ATTACHMENT3                             = 0x8CE3;
+    const GLenum COLOR_ATTACHMENT4                             = 0x8CE4;
+    const GLenum COLOR_ATTACHMENT5                             = 0x8CE5;
+    const GLenum COLOR_ATTACHMENT6                             = 0x8CE6;
+    const GLenum COLOR_ATTACHMENT7                             = 0x8CE7;
+    const GLenum COLOR_ATTACHMENT8                             = 0x8CE8;
+    const GLenum COLOR_ATTACHMENT9                             = 0x8CE9;
+    const GLenum COLOR_ATTACHMENT10                            = 0x8CEA;
+    const GLenum COLOR_ATTACHMENT11                            = 0x8CEB;
+    const GLenum COLOR_ATTACHMENT12                            = 0x8CEC;
+    const GLenum COLOR_ATTACHMENT13                            = 0x8CED;
+    const GLenum COLOR_ATTACHMENT14                            = 0x8CEE;
+    const GLenum COLOR_ATTACHMENT15                            = 0x8CEF;
+    const GLenum FRAMEBUFFER_INCOMPLETE_MULTISAMPLE            = 0x8D56;
+    const GLenum MAX_SAMPLES                                   = 0x8D57;
+    const GLenum HALF_FLOAT                                    = 0x140B;
+    const GLenum RG                                            = 0x8227;
+    const GLenum RG_INTEGER                                    = 0x8228;
+    const GLenum R8                                            = 0x8229;
+    const GLenum RG8                                           = 0x822B;
+    const GLenum R16F                                          = 0x822D;
+    const GLenum R32F                                          = 0x822E;
+    const GLenum RG16F                                         = 0x822F;
+    const GLenum RG32F                                         = 0x8230;
+    const GLenum R8I                                           = 0x8231;
+    const GLenum R8UI                                          = 0x8232;
+    const GLenum R16I                                          = 0x8233;
+    const GLenum R16UI                                         = 0x8234;
+    const GLenum R32I                                          = 0x8235;
+    const GLenum R32UI                                         = 0x8236;
+    const GLenum RG8I                                          = 0x8237;
+    const GLenum RG8UI                                         = 0x8238;
+    const GLenum RG16I                                         = 0x8239;
+    const GLenum RG16UI                                        = 0x823A;
+    const GLenum RG32I                                         = 0x823B;
+    const GLenum RG32UI                                        = 0x823C;
+    const GLenum VERTEX_ARRAY_BINDING                          = 0x85B5;
+    const GLenum R8_SNORM                                      = 0x8F94;
+    const GLenum RG8_SNORM                                     = 0x8F95;
+    const GLenum RGB8_SNORM                                    = 0x8F96;
+    const GLenum RGBA8_SNORM                                   = 0x8F97;
+    const GLenum SIGNED_NORMALIZED                             = 0x8F9C;
+    const GLenum PRIMITIVE_RESTART_FIXED_INDEX                 = 0x8D69;
+    const GLenum COPY_READ_BUFFER                              = 0x8F36;
+    const GLenum COPY_WRITE_BUFFER                             = 0x8F37;
+    const GLenum COPY_READ_BUFFER_BINDING                      = 0x8F36; /* Same as COPY_READ_BUFFER */
+    const GLenum COPY_WRITE_BUFFER_BINDING                     = 0x8F37; /* Same as COPY_WRITE_BUFFER */
+    const GLenum UNIFORM_BUFFER                                = 0x8A11;
+    const GLenum UNIFORM_BUFFER_BINDING                        = 0x8A28;
+    const GLenum UNIFORM_BUFFER_START                          = 0x8A29;
+    const GLenum UNIFORM_BUFFER_SIZE                           = 0x8A2A;
+    const GLenum MAX_VERTEX_UNIFORM_BLOCKS                     = 0x8A2B;
+    const GLenum MAX_FRAGMENT_UNIFORM_BLOCKS                   = 0x8A2D;
+    const GLenum MAX_COMBINED_UNIFORM_BLOCKS                   = 0x8A2E;
+    const GLenum MAX_UNIFORM_BUFFER_BINDINGS                   = 0x8A2F;
+    const GLenum MAX_UNIFORM_BLOCK_SIZE                        = 0x8A30;
+    const GLenum MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS        = 0x8A31;
+    const GLenum MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS      = 0x8A33;
+    const GLenum UNIFORM_BUFFER_OFFSET_ALIGNMENT               = 0x8A34;
+    const GLenum ACTIVE_UNIFORM_BLOCKS                         = 0x8A36;
+    const GLenum UNIFORM_TYPE                                  = 0x8A37;
+    const GLenum UNIFORM_SIZE                                  = 0x8A38;
+    const GLenum UNIFORM_BLOCK_INDEX                           = 0x8A3A;
+    const GLenum UNIFORM_OFFSET                                = 0x8A3B;
+    const GLenum UNIFORM_ARRAY_STRIDE                          = 0x8A3C;
+    const GLenum UNIFORM_MATRIX_STRIDE                         = 0x8A3D;
+    const GLenum UNIFORM_IS_ROW_MAJOR                          = 0x8A3E;
+    const GLenum UNIFORM_BLOCK_BINDING                         = 0x8A3F;
+    const GLenum UNIFORM_BLOCK_DATA_SIZE                       = 0x8A40;
+    const GLenum UNIFORM_BLOCK_ACTIVE_UNIFORMS                 = 0x8A42;
+    const GLenum UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES          = 0x8A43;
+    const GLenum UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER     = 0x8A44;
+    const GLenum UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER   = 0x8A46;
+    const GLenum INVALID_INDEX                                 = 0xFFFFFFFF;
+    const GLenum MAX_VERTEX_OUTPUT_COMPONENTS                  = 0x9122;
+    const GLenum MAX_FRAGMENT_INPUT_COMPONENTS                 = 0x9125;
+    const GLenum MAX_SERVER_WAIT_TIMEOUT                       = 0x9111;
+    const GLenum OBJECT_TYPE                                   = 0x9112;
+    const GLenum SYNC_CONDITION                                = 0x9113;
+    const GLenum SYNC_STATUS                                   = 0x9114;
+    const GLenum SYNC_FLAGS                                    = 0x9115;
+    const GLenum SYNC_FENCE                                    = 0x9116;
+    const GLenum SYNC_GPU_COMMANDS_COMPLETE                    = 0x9117;
+    const GLenum UNSIGNALED                                    = 0x9118;
+    const GLenum SIGNALED                                      = 0x9119;
+    const GLenum ALREADY_SIGNALED                              = 0x911A;
+    const GLenum TIMEOUT_EXPIRED                               = 0x911B;
+    const GLenum CONDITION_SATISFIED                           = 0x911C;
+    const GLenum WAIT_FAILED                                   = 0x911D;
+    const GLenum SYNC_FLUSH_COMMANDS_BIT                       = 0x00000001;
+    const GLenum VERTEX_ATTRIB_ARRAY_DIVISOR                   = 0x88FE;
+    const GLenum ANY_SAMPLES_PASSED                            = 0x8C2F;
+    const GLenum ANY_SAMPLES_PASSED_CONSERVATIVE               = 0x8D6A;
+    const GLenum SAMPLER_BINDING                               = 0x8919;
+    const GLenum RGB10_A2UI                                    = 0x906F;
+    const GLenum TEXTURE_SWIZZLE_R                             = 0x8E42;
+    const GLenum TEXTURE_SWIZZLE_G                             = 0x8E43;
+    const GLenum TEXTURE_SWIZZLE_B                             = 0x8E44;
+    const GLenum TEXTURE_SWIZZLE_A                             = 0x8E45;
+    const GLenum GREEN                                         = 0x1904;
+    const GLenum BLUE                                          = 0x1905;
+    const GLenum INT_2_10_10_10_REV                            = 0x8D9F;
+    const GLenum TRANSFORM_FEEDBACK                            = 0x8E22;
+    const GLenum TRANSFORM_FEEDBACK_PAUSED                     = 0x8E23;
+    const GLenum TRANSFORM_FEEDBACK_ACTIVE                     = 0x8E24;
+    const GLenum TRANSFORM_FEEDBACK_BINDING                    = 0x8E25;
+    const GLenum COMPRESSED_R11_EAC                            = 0x9270;
+    const GLenum COMPRESSED_SIGNED_R11_EAC                     = 0x9271;
+    const GLenum COMPRESSED_RG11_EAC                           = 0x9272;
+    const GLenum COMPRESSED_SIGNED_RG11_EAC                    = 0x9273;
+    const GLenum COMPRESSED_RGB8_ETC2                          = 0x9274;
+    const GLenum COMPRESSED_SRGB8_ETC2                         = 0x9275;
+    const GLenum COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2      = 0x9276;
+    const GLenum COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2     = 0x9277;
+    const GLenum COMPRESSED_RGBA8_ETC2_EAC                     = 0x9278;
+    const GLenum COMPRESSED_SRGB8_ALPHA8_ETC2_EAC              = 0x9279;
+    const GLenum TEXTURE_IMMUTABLE_FORMAT                      = 0x912F;
+    const GLenum MAX_ELEMENT_INDEX                             = 0x8D6B;
+    const GLenum NUM_SAMPLE_COUNTS                             = 0x9380;
+    const GLenum TEXTURE_IMMUTABLE_LEVELS                      = 0x82DF;
 
-    /* blend equations */
-    const GLenum MIN                                         = 0x8007;
-    const GLenum MAX                                         = 0x8008;
+    const GLint64 TIMEOUT_IGNORED                              = -1;
+
+    /* Buffer objects */
+    void copyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset,
+                           GLintptr writeOffset, GLsizeiptr size);
+    void getBufferSubData(GLenum target, GLintptr offset, ArrayBuffer returnedData);
+    void getBufferSubData(GLenum target, GLintptr offset, ArrayBufferView returnedData);
+
+    /* Framebuffer objects */
+    void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0,
+                         GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+    void framebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+    any getInternalformatParameter(GLenum target, GLenum internalformat, GLenum pname);
+    void invalidateFramebuffer(GLenum target, sequence<GLenum> attachments);
+    void invalidateSubFramebuffer (GLenum target, sequence<GLenum> attachments,
+                                   GLint x, GLint y, GLsizei width, GLsizei height);
+    void readBuffer(GLenum src);
+
+    /* Renderbuffer objects */
+    void renderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
 
+    /* Texture objects */
+    void texStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+    void texStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height,
+                      GLsizei depth);
+    [Throws] void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+                                GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type,
+                                ArrayBufferView? pixels);
+    [Throws] void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+                                GLenum format, GLenum type, ImageData? data);
+    [Throws] void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+                                GLenum format, GLenum type, HTMLImageElement image);
+    [Throws] void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+                                GLenum format, GLenum type, HTMLCanvasElement canvas);
+    [Throws] void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+                                GLenum format, GLenum type, HTMLVideoElement video);
+    void copyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+                           GLint x, GLint y, GLsizei width, GLsizei height);
+    void compressedTexImage3D(GLenum target, GLint level, GLenum internalformat,
+                              GLsizei width, GLsizei height, GLsizei depth,
+                              GLint border, GLsizei imageSize, ArrayBufferView data);
+    void compressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+                                 GLsizei width, GLsizei height, GLsizei depth,
+                                 GLenum format, GLsizei imageSize, ArrayBufferView data);
+
+    /* Programs and shaders */
+    [WebGLHandlesContextLoss] GLint getFragDataLocation(WebGLProgram? program, DOMString name);
 
-    /* transform feedback */
-    const GLenum RASTERIZER_DISCARD                          = 0x8C89;
-    const GLenum TRANSFORM_FEEDBACK_BUFFER                   = 0x8C8E;
-    const GLenum TRANSFORM_FEEDBACK_BUFFER_BINDING           = 0x8C8F;
-    const GLenum TRANSFORM_FEEDBACK_BUFFER_START             = 0x8C84;
-    const GLenum TRANSFORM_FEEDBACK_BUFFER_SIZE              = 0x8C85;
-    const GLenum MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS     = 0x8C8B;
-
+    /* Uniforms and attributes */
+    void uniform1ui(WebGLUniformLocation? location, GLuint v0);
+    void uniform2ui(WebGLUniformLocation? location, GLuint v0, GLuint v1);
+    void uniform3ui(WebGLUniformLocation? location, GLuint v0, GLuint v1, GLuint v2);
+    void uniform4ui(WebGLUniformLocation? location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+    void uniform1uiv(WebGLUniformLocation? location, sequence<GLuint> value);
+    void uniform2uiv(WebGLUniformLocation? location, sequence<GLuint> value);
+    void uniform3uiv(WebGLUniformLocation? location, sequence<GLuint> value);
+    void uniform4uiv(WebGLUniformLocation? location, sequence<GLuint> value);
+    void uniformMatrix2x3fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array value);
+    void uniformMatrix2x3fv(WebGLUniformLocation? location, GLboolean transpose, sequence<GLfloat> value);
+    void uniformMatrix3x2fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array value);
+    void uniformMatrix3x2fv(WebGLUniformLocation? location, GLboolean transpose, sequence<GLfloat> value);
+    void uniformMatrix2x4fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array value);
+    void uniformMatrix2x4fv(WebGLUniformLocation? location, GLboolean transpose, sequence<GLfloat> value);
+    void uniformMatrix4x2fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array value);
+    void uniformMatrix4x2fv(WebGLUniformLocation? location, GLboolean transpose, sequence<GLfloat> value);
+    void uniformMatrix3x4fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array value);
+    void uniformMatrix3x4fv(WebGLUniformLocation? location, GLboolean transpose, sequence<GLfloat> value);
+    void uniformMatrix4x3fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array value);
+    void uniformMatrix4x3fv(WebGLUniformLocation? location, GLboolean transpose, sequence<GLfloat> value);
+    void vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w);
+    void vertexAttribI4iv(GLuint index, sequence<GLint> v);
+    void vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+    void vertexAttribI4uiv(GLuint index, sequence<GLuint> v);
+    void vertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset);
 
-    /* query objects */
-    const GLenum CURRENT_QUERY                               = 0x8865;
-    const GLenum QUERY_RESULT                                = 0x8866;
-    const GLenum QUERY_RESULT_AVAILABLE                      = 0x8867;
+    /* Writing to the drawing buffer */
+    void vertexAttribDivisor(GLuint index, GLuint divisor);
+    void drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount);
+    void drawElementsInstanced(GLenum mode, GLsizei count, GLenum type, GLintptr offset, GLsizei instanceCount);
+    void drawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, GLintptr offset);
 
-    void beginQuery(GLenum target, WebGLQuery? queryObject);
+    /* Multiple Render Targets */
+    void drawBuffers(sequence<GLenum> buffers);
+    void clearBufferiv(GLenum buffer, GLint drawbuffer, Int32Array value);
+    void clearBufferiv(GLenum buffer, GLint drawbuffer, sequence<GLint> value);
+    void clearBufferuiv(GLenum buffer, GLint drawbuffer, Uint32Array value);
+    void clearBufferuiv(GLenum buffer, GLint drawbuffer, sequence<GLuint> value);
+    void clearBufferfv(GLenum buffer, GLint drawbuffer, Float32Array value);
+    void clearBufferfv(GLenum buffer, GLint drawbuffer, sequence<GLfloat> value);
+    void clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+
+    /* Query Objects */
     WebGLQuery? createQuery();
-    void deleteQuery(WebGLQuery? queryObject);
+    void deleteQuery(WebGLQuery? query);
+    [WebGLHandlesContextLoss] GLboolean isQuery(WebGLQuery? query);
+    void beginQuery(GLenum target, WebGLQuery? query);
     void endQuery(GLenum target);
     WebGLQuery? getQuery(GLenum target, GLenum pname);
-    any getQueryObject(WebGLQuery? queryObject, GLenum pname);
-    [WebGLHandlesContextLoss] GLboolean isQuery(WebGLQuery? queryObject);
-
-
-    /* occlusion queries */
-    const GLenum ANY_SAMPLES_PASSED                          = 0x8C2F;
-    const GLenum ANY_SAMPLES_PASSED_CONSERVATIVE             = 0x8D6A;
-
+    any getQueryParameter(WebGLQuery? query, GLenum pname);
 
-    /* transform feedback queries */
-    const GLenum TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN       = 0x8C88;
-
+    /* Sampler Objects */
+    WebGLSampler? createSampler();
+    void deleteSampler(WebGLSampler? sampler);
+    [WebGLHandlesContextLoss] GLboolean isSampler(WebGLSampler? sampler);
+    void bindSampler(GLuint unit, WebGLSampler? sampler);
+    void samplerParameteri(WebGLSampler? sampler, GLenum pname, GLint param);
+    void samplerParameterf(WebGLSampler? sampler, GLenum pname, GLfloat param);
+    any getSamplerParameter(WebGLSampler? sampler, GLenum pname);
 
-    /* buffer objects */
-    void bindBufferBase(GLenum target, GLuint index, WebGLBuffer? buffer);
-    void bindBufferRange(GLenum target, GLuint index, WebGLBuffer? buffer,
-                         GLintptr offset, GLsizeiptr size);
-
+    /* Sync objects */
+    WebGLSync? fenceSync(GLenum condition, GLbitfield flags);
+    [WebGLHandlesContextLoss] GLboolean isSync(WebGLSync? sync);
+    void deleteSync(WebGLSync? sync);
+    GLenum clientWaitSync(WebGLSync? sync, GLbitfield flags, GLint64 timeout);
+    void waitSync(WebGLSync? sync, GLbitfield flags, GLint64 timeout);
+    any getSyncParameter(WebGLSync? sync, GLenum pname);
 
-    /* standart derivatives */
-    const GLenum FRAGMENT_SHADER_DERIVATIVE_HINT             = 0x8B8B;
-
-
-    /* state requests */
-    any getParameterIndexed(GLenum pname, GLuint index);
-
+    /* Transform Feedback */
+    WebGLTransformFeedback? createTransformFeedback();
+    void deleteTransformFeedback(WebGLTransformFeedback? tf);
+    [WebGLHandlesContextLoss] GLboolean isTransformFeedback(WebGLTransformFeedback? tf);
+    void bindTransformFeedback(GLenum target, GLuint id);
+    void beginTransformFeedback(GLenum primitiveMode);
+    void endTransformFeedback();
+    void transformFeedbackVaryings(WebGLProgram? program, GLsizei count, sequence<DOMString> varyings, GLenum bufferMode);
+    [NewObject] WebGLActiveInfo? getTransformFeedbackVarying(WebGLProgram? program, GLuint index);
+    void pauseTransformFeedback();
+    void resumeTransformFeedback();
 
-    /* vertex array objects */
-    const GLenum VERTEX_ARRAY_BINDING                        = 0x85B5;
+    /* Uniform Buffer Objects and Transform Feedback Buffers */
+    void bindBufferBase(GLenum target, GLuint index, WebGLBuffer? buffer);
+    void bindBufferRange(GLenum target, GLuint index, WebGLBuffer? buffer, GLintptr offset, GLsizeiptr size);
+    any getIndexedParameter(GLenum target, GLuint index);
+    sequence<GLuint>? getUniformIndices(WebGLProgram? program, sequence<DOMString> uniformNames);
+    sequence<GLint>? getActiveUniforms(WebGLProgram? program, sequence<GLuint> uniformIndices, GLenum pname);
+    GLuint getUniformBlockIndex(WebGLProgram? program, DOMString uniformBlockName);
+    any getActiveUniformBlockParameter(WebGLProgram? program, GLuint uniformBlockIndex, GLenum pname);
+    DOMString? getActiveUniformBlockName(WebGLProgram? program, GLuint uniformBlockIndex);
+    void uniformBlockBinding(WebGLProgram? program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
 
-    void bindVertexArray(WebGLVertexArray? arrayObject);
-    WebGLVertexArray? createVertexArray();
-    void deleteVertexArray(WebGLVertexArray? arrayObject);
-    [WebGLHandlesContextLoss] GLboolean isVertexArray(WebGLVertexArray? arrayObject);
-
+    /* Vertex Array Objects */
+    /*
+    WebGLVertexArrayObject? createVertexArray();
+    void deleteVertexArray(WebGLVertexArrayObject? vertexArray);
+    [WebGLHandlesContextLoss] GLboolean isVertexArray(WebGLVertexArrayObject? vertexArray);
+    void bindVertexArray(WebGLVertexArrayObject? array);
+    */
 };
-
--- a/gfx/layers/composite/AsyncCompositionManager.cpp
+++ b/gfx/layers/composite/AsyncCompositionManager.cpp
@@ -27,16 +27,17 @@
 #include "nsDeviceContext.h"            // for nsDeviceContext
 #include "nsDisplayList.h"              // for nsDisplayTransform, etc
 #include "nsMathUtils.h"                // for NS_round
 #include "nsPoint.h"                    // for nsPoint
 #include "nsRect.h"                     // for nsIntRect
 #include "nsRegion.h"                   // for nsIntRegion
 #include "nsTArray.h"                   // for nsTArray, nsTArray_Impl, etc
 #include "nsTArrayForwardDeclare.h"     // for InfallibleTArray
+#include "UnitTransforms.h"             // for TransformTo
 #if defined(MOZ_WIDGET_ANDROID)
 # include <android/log.h>
 # include "AndroidBridge.h"
 #endif
 #include "GeckoProfiler.h"
 
 struct nsCSSValueSharedList;
 
@@ -132,16 +133,29 @@ static bool
 GetBaseTransform2D(Layer* aLayer, Matrix* aTransform)
 {
   // Start with the animated transform if there is one
   return (aLayer->AsLayerComposite()->GetShadowTransformSetByAnimation() ?
           aLayer->GetLocalTransform() : aLayer->GetTransform()).Is2D(aTransform);
 }
 
 static void
+TransformClipRect(Layer* aLayer,
+                  const Matrix4x4& aTransform)
+{
+  const nsIntRect* clipRect = aLayer->GetClipRect();
+  if (clipRect) {
+    LayerIntRect transformed = TransformTo<LayerPixel>(
+        aTransform, LayerIntRect::FromUntyped(*clipRect));
+    nsIntRect shadowClip = LayerIntRect::ToUntyped(transformed);
+    aLayer->AsLayerComposite()->SetShadowClipRect(&shadowClip);
+  }
+}
+
+static void
 TranslateShadowLayer2D(Layer* aLayer,
                        const gfxPoint& aTranslation,
                        bool aAdjustClipRect)
 {
   // This layer might also be a scrollable layer and have an async transform.
   // To make sure we don't clobber that, we start with the shadow transform.
   // Any adjustments to the shadow transform made in this function in previous
   // frames have been cleared in ClearAsyncTransforms(), so such adjustments
@@ -168,21 +182,18 @@ TranslateShadowLayer2D(Layer* aLayer,
     Matrix4x4().Scale(1.0f/aLayer->GetPostXScale(),
                       1.0f/aLayer->GetPostYScale(),
                       1);
 
   LayerComposite* layerComposite = aLayer->AsLayerComposite();
   layerComposite->SetShadowTransform(layerTransform3D);
   layerComposite->SetShadowTransformSetByAnimation(false);
 
-  const nsIntRect* clipRect = aLayer->GetClipRect();
-  if (aAdjustClipRect && clipRect) {
-    nsIntRect transformedClipRect(*clipRect);
-    transformedClipRect.MoveBy(aTranslation.x, aTranslation.y);
-    layerComposite->SetShadowClipRect(&transformedClipRect);
+  if (aAdjustClipRect) {
+    TransformClipRect(aLayer, Matrix4x4().Translate(aTranslation.x, aTranslation.y, 0));
   }
 }
 
 static bool
 AccumulateLayerTransforms2D(Layer* aLayer,
                             Layer* aAncestor,
                             Matrix& aMatrix)
 {
@@ -722,16 +733,24 @@ ApplyAsyncTransformToScrollbarForContent
   if (aScrollbarIsDescendant) {
     // If the scrollbar layer is a child of the content it is a scrollbar for, then we
     // need to do an extra untransform to cancel out the transient async transform on
     // the content. This is needed because otherwise that transient async transform is
     // part of the effective transform of this scrollbar, and the scrollbar will jitter
     // as the content scrolls.
     transientTransform.Invert();
     transform = transform * transientTransform;
+
+    // We also need to make a corresponding change on the clip rect of all the
+    // layers on the ancestor chain from the scrollbar layer up to but not
+    // including the layer with the async transform. Otherwise the scrollbar
+    // shifts but gets clipped and so appears to flicker.
+    for (Layer* ancestor = aScrollbar; ancestor != aContent.GetLayer(); ancestor = ancestor->GetParent()) {
+      TransformClipRect(ancestor, transientTransform);
+    }
   }
 
   // GetTransform already takes the pre- and post-scale into account.  Since we
   // will apply the pre- and post-scale again when computing the effective
   // transform, we must apply the inverses here.
   if (ContainerLayer* container = aScrollbar->AsContainerLayer()) {
     transform.Scale(1.0f/container->GetPreXScale(),
                     1.0f/container->GetPreYScale(),
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -528,17 +528,17 @@ ShadowLayerForwarder::EndTransaction(Inf
                                      bool aIsRepeatTransaction,
                                      const mozilla::TimeStamp& aTransactionStart,
                                      bool* aSent)
 {
   *aSent = false;
 
   MOZ_ASSERT(aId);
 
-  PROFILER_LABEL("ShadowLayerForwarder", "EndTranscation",
+  PROFILER_LABEL("ShadowLayerForwarder", "EndTransaction",
     js::ProfileEntry::Category::GRAPHICS);
 
   RenderTraceScope rendertrace("Foward Transaction", "000091");
   NS_ABORT_IF_FALSE(HasShadowManager(), "no manager to forward to");
   NS_ABORT_IF_FALSE(!mTxn->Finished(), "forgot BeginTransaction?");
 
   DiagnosticTypes diagnostics = gfxPlatform::GetPlatform()->GetLayerDiagnosticTypes();
   if (mDiagnosticTypes != diagnostics) {
--- a/gfx/src/nsRegion.h
+++ b/gfx/src/nsRegion.h
@@ -63,16 +63,20 @@ public:
   nsRegion (const nsRegion& aRegion) { pixman_region32_init(&mImpl); pixman_region32_copy(&mImpl,aRegion.Impl()); }
  ~nsRegion () { pixman_region32_fini(&mImpl); }
   nsRegion& operator = (const nsRect& aRect) { Copy (aRect); return *this; }
   nsRegion& operator = (const nsRegion& aRegion) { Copy (aRegion); return *this; }
   bool operator==(const nsRegion& aRgn) const
   {
     return IsEqual(aRgn);
   }
+  bool operator!=(const nsRegion& aRgn) const
+  {
+    return !(*this == aRgn);
+  }
 
   friend std::ostream& operator<<(std::ostream& stream, const nsRegion& m);
 
   void Swap(nsRegion* aOther)
   {
     pixman_region32_t tmp = mImpl;
     mImpl = aOther->mImpl;
     aOther->mImpl = tmp;
@@ -459,16 +463,20 @@ public:
   nsIntRegion (const nsIntRegion& aRegion) : mImpl (aRegion.mImpl) {}
   nsIntRegion& operator = (const nsIntRect& aRect) { mImpl = ToRect (aRect); return *this; }
   nsIntRegion& operator = (const nsIntRegion& aRegion) { mImpl = aRegion.mImpl; return *this; }
 
   bool operator==(const nsIntRegion& aRgn) const
   {
     return IsEqual(aRgn);
   }
+  bool operator!=(const nsIntRegion& aRgn) const
+  {
+    return !(*this == aRgn);
+  }
 
   friend std::ostream& operator<<(std::ostream& stream, const nsIntRegion& m) {
     return stream << m.mImpl;
   }
 
   void Swap(nsIntRegion* aOther)
   {
     mImpl.Swap(&aOther->mImpl);
--- a/gfx/thebes/gfxFontEntry.cpp
+++ b/gfx/thebes/gfxFontEntry.cpp
@@ -1298,17 +1298,17 @@ gfxFontFamily::CheckForSimpleFamily()
 bool
 gfxFontFamily::ContainsFace(gfxFontEntry* aFontEntry) {
     uint32_t i, numFonts = mAvailableFonts.Length();
     for (i = 0; i < numFonts; i++) {
         if (mAvailableFonts[i] == aFontEntry) {
             return true;
         }
         // userfonts contain the actual real font entry
-        if (mAvailableFonts[i]->mIsUserFontContainer) {
+        if (mAvailableFonts[i] && mAvailableFonts[i]->mIsUserFontContainer) {
             gfxUserFontEntry* ufe =
                 static_cast<gfxUserFontEntry*>(mAvailableFonts[i].get());
             if (ufe->GetPlatformFontEntry() == aFontEntry) {
                 return true;
             }
         }
     }
     return false;
--- a/image/src/imgFrame.cpp
+++ b/image/src/imgFrame.cpp
@@ -441,23 +441,24 @@ imgFrame::SurfaceForDrawing(bool        
     RefPtr<DrawTarget> target =
       gfxPlatform::GetPlatform()->
         CreateOffscreenContentDrawTarget(size, SurfaceFormat::B8G8R8A8);
     if (!target)
       return SurfaceWithFormat();
 
     // Fill 'available' with whatever we've got
     if (mSinglePixel) {
-      target->FillRect(ToRect(aRegion.Rect()), ColorPattern(mSinglePixelColor),
+      target->FillRect(ToRect(aRegion.Intersect(available).Rect()),
+                       ColorPattern(mSinglePixelColor),
                        DrawOptions(1.0f, CompositionOp::OP_SOURCE));
     } else {
       SurfacePattern pattern(aSurface,
                              ExtendMode::REPEAT,
                              ToMatrix(aContext->CurrentMatrix()));
-      target->FillRect(ToRect(aRegion.Rect()), pattern);
+      target->FillRect(ToRect(aRegion.Intersect(available).Rect()), pattern);
     }
 
     RefPtr<SourceSurface> newsurf = target->Snapshot();
     return SurfaceWithFormat(new gfxSurfaceDrawable(newsurf, ThebesIntSize(size)), target->GetFormat());
   }
 
   // Not tiling, and we have a surface, so we can account for
   // padding and/or a partial decode just by twiddling parameters.
@@ -498,17 +499,17 @@ bool imgFrame::Draw(gfxContext* aContext
                              CompositionOpForOp(aContext->CurrentOperator())));
     return true;
   }
 
   gfxRect imageRect(0, 0, mSize.width + aPadding.LeftRight(),
                     mSize.height + aPadding.TopBottom());
 
   RefPtr<SourceSurface> surf = GetSurface();
-  if (!surf) {
+  if (!surf && !mSinglePixel) {
     return false;
   }
 
   bool doTile = !imageRect.Contains(aRegion.Rect()) &&
                 !(aImageFlags & imgIContainer::FLAG_CLAMP);
   ImageRegion region(aRegion);
   SurfaceWithFormat surfaceResult =
     SurfaceForDrawing(doPadding, doPartialDecode, doTile, aContext,
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..14a59ff477a18e87d5d76cfd39452fdc3bb05f0f
GIT binary patch
literal 69
zc${<hbhEHb6krfwXkcVu_|NeF|9{1wER0+Xj0`#qKmd|qV3O(SUwL{h!{VAvm!$OB
Wq{?UKL~0Z*`Qdx+)HV-B25SI~qZLj7
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..e6d7c49322b6a0a4402d2ab9c7c1d64ce22d84f8
GIT binary patch
literal 49
zc${<hbhEHb6krfw_`t}(@SoxT|Nn|VSr|Y-hnazyfeQ#3m^fPcSDt>$pRCPb4FEkY
B3~&Gd
--- a/image/test/reftest/gif/reftest.list
+++ b/image/test/reftest/gif/reftest.list
@@ -14,16 +14,19 @@
 
 # a transparent gif that disposes previous frames with clear; we must properly
 # clear each frame to pass.
 random == delaytest.html?transparent-animation.gif transparent-animation-finalframe.gif # incorrect timing dependence (bug 558678)
 
 # test for bug 641198
 skip-if(B2G) random-if(Android) == test_bug641198.html animation2a-finalframe.gif # bug 773482
 
+# Bug 1062886: a gif with a single color and an offset
+== one-color-offset.gif one-color-offset-ref.gif
+
 # webcam-simulacrum.mgif is a hand-edited file containing red.gif and blue.gif,
 # concatenated together with the relevant headers for
 # multipart/x-mixed-replace. Specifically, with the headers in
 # webcam-simulacrum.mjpg^headers^, the web browser will get the following:
 #
 # HTTP 200 OK
 # Content-Type: multipart/x-mixed-replace;boundary=BOUNDARYOMG
 # 
--- a/intl/uconv/directory.txt
+++ b/intl/uconv/directory.txt
@@ -11,17 +11,17 @@ tools      - tools to build the tables u
 util       - utility functions used by the converters
 
 The following directories contain different charset converters:
 
 ucvcn    - Simplified Chinese charsets - GB2312, HZ, ISO-2022-CN, GBK, GB18030
 ucvja    - Japanese charsets - Shift-JIS, ISO-2022-JP, EUC-JP
 ucvko    - Korean charsets - ISO-2022-KR, EUC-KR, Johab
 ucvlatin - Latin charsets and others - ISO-8859-x, CP1250-1258
-                            CP866, 874, ISO-IR-111, KOI8,
+                            CP866, 874, KOI8,
                             Mac charsets, TIS620, UTF16
 ucvtw    - Traditional Chinese charsets Set 1 - Big5
 ucvtw2   - Traditional Chinese charsets Set 2 - EUC-TW
 
 Within the directories containing charset converters:
 
 *.ut - tables used to convert to Unicode from a charset
 *.uf - tables used to convert to a charset from Unicode
--- a/intl/uconv/moz.build
+++ b/intl/uconv/moz.build
@@ -56,17 +56,16 @@ UNIFIED_SOURCES += [
     'ucvcn/nsUnicodeToGBK.cpp',
     'ucvcn/nsUnicodeToHZ.cpp',
 ]
 
 UNIFIED_SOURCES += [
     'ucvja/nsJapaneseToUnicode.cpp',
     'ucvja/nsUnicodeToEUCJP.cpp',
     'ucvja/nsUnicodeToISO2022JP.cpp',
-    'ucvja/nsUnicodeToJISx0201.cpp',
     'ucvja/nsUnicodeToSJIS.cpp',
 ]
 
 UNIFIED_SOURCES += [
     'ucvko/nsCP949ToUnicode.cpp',
     'ucvko/nsUnicodeToCP949.cpp',
 ]
 
@@ -87,25 +86,21 @@ UNIFIED_SOURCES += [
     'ucvlatin/nsISO885913ToUnicode.cpp',
     'ucvlatin/nsISO885914ToUnicode.cpp',
     'ucvlatin/nsISO885915ToUnicode.cpp',
     'ucvlatin/nsISO885916ToUnicode.cpp',
     'ucvlatin/nsISO88592ToUnicode.cpp',
     'ucvlatin/nsISO88593ToUnicode.cpp',
     'ucvlatin/nsISO88594ToUnicode.cpp',
     'ucvlatin/nsISO88595ToUnicode.cpp',
-    'ucvlatin/nsISO88596EToUnicode.cpp',
-    'ucvlatin/nsISO88596IToUnicode.cpp',
     'ucvlatin/nsISO88596ToUnicode.cpp',
     'ucvlatin/nsISO88597ToUnicode.cpp',
-    'ucvlatin/nsISO88598EToUnicode.cpp',
     'ucvlatin/nsISO88598IToUnicode.cpp',
     'ucvlatin/nsISO88598ToUnicode.cpp',
     'ucvlatin/nsISO88599ToUnicode.cpp',
-    'ucvlatin/nsISOIR111ToUnicode.cpp',
     'ucvlatin/nsKOI8RToUnicode.cpp',
     'ucvlatin/nsKOI8UToUnicode.cpp',
     'ucvlatin/nsMacArabicToUnicode.cpp',
     'ucvlatin/nsMacCEToUnicode.cpp',
     'ucvlatin/nsMacCroatianToUnicode.cpp',
     'ucvlatin/nsMacCyrillicToUnicode.cpp',
     'ucvlatin/nsMacDevanagariToUnicode.cpp',
     'ucvlatin/nsMacFarsiToUnicode.cpp',
@@ -134,40 +129,35 @@ UNIFIED_SOURCES += [
     'ucvlatin/nsUnicodeToISO885914.cpp',
     'ucvlatin/nsUnicodeToISO885915.cpp',
     'ucvlatin/nsUnicodeToISO885916.cpp',
     'ucvlatin/nsUnicodeToISO88592.cpp',
     'ucvlatin/nsUnicodeToISO88593.cpp',
     'ucvlatin/nsUnicodeToISO88594.cpp',
     'ucvlatin/nsUnicodeToISO88595.cpp',
     'ucvlatin/nsUnicodeToISO88596.cpp',
-    'ucvlatin/nsUnicodeToISO88596E.cpp',
-    'ucvlatin/nsUnicodeToISO88596I.cpp',
     'ucvlatin/nsUnicodeToISO88597.cpp',
     'ucvlatin/nsUnicodeToISO88598.cpp',
-    'ucvlatin/nsUnicodeToISO88598E.cpp',
     'ucvlatin/nsUnicodeToISO88598I.cpp',
     'ucvlatin/nsUnicodeToISO88599.cpp',
-    'ucvlatin/nsUnicodeToISOIR111.cpp',
     'ucvlatin/nsUnicodeToKOI8R.cpp',
     'ucvlatin/nsUnicodeToKOI8U.cpp',
     'ucvlatin/nsUnicodeToMacCyrillic.cpp',
     'ucvlatin/nsUnicodeToTIS620.cpp',
     'ucvlatin/nsUnicodeToUserDefined.cpp',
     'ucvlatin/nsUnicodeToUTF16.cpp',
     'ucvlatin/nsUserDefinedToUnicode.cpp',
     'ucvlatin/nsUTF16ToUnicode.cpp',
 ]
 
 UNIFIED_SOURCES += [
     'ucvtw/nsBIG5HKSCSToUnicode.cpp',
     'ucvtw/nsBIG5ToUnicode.cpp',
     'ucvtw/nsUnicodeToBIG5.cpp',
     'ucvtw/nsUnicodeToBIG5HKSCS.cpp',
-    'ucvtw/nsUnicodeToHKSCS.cpp',
 ]
 
 UNIFIED_SOURCES += [
     'util/nsUCConstructors.cpp',
     'util/nsUCSupport.cpp',
     'util/nsUnicodeDecodeHelper.cpp',
     'util/nsUnicodeEncodeHelper.cpp',
     'util/ugen.c',
--- a/intl/uconv/nsUConvModule.cpp
+++ b/intl/uconv/nsUConvModule.cpp
@@ -29,29 +29,25 @@
 // ucvlatin
 #include "nsUCvLatinCID.h"
 #include "nsAsciiToUnicode.h"
 #include "nsISO88592ToUnicode.h"
 #include "nsISO88593ToUnicode.h"
 #include "nsISO88594ToUnicode.h"
 #include "nsISO88595ToUnicode.h"
 #include "nsISO88596ToUnicode.h"
-#include "nsISO88596EToUnicode.h"
-#include "nsISO88596IToUnicode.h"
 #include "nsISO88597ToUnicode.h"
 #include "nsISO88598ToUnicode.h"
-#include "nsISO88598EToUnicode.h"
 #include "nsISO88598IToUnicode.h"
 #include "nsISO88599ToUnicode.h"
 #include "nsISO885910ToUnicode.h"
 #include "nsISO885913ToUnicode.h"
 #include "nsISO885914ToUnicode.h"
 #include "nsISO885915ToUnicode.h"
 #include "nsISO885916ToUnicode.h"
-#include "nsISOIR111ToUnicode.h"
 #include "nsCP1250ToUnicode.h"
 #include "nsCP1251ToUnicode.h"
 #include "nsCP1253ToUnicode.h"
 #include "nsCP1254ToUnicode.h"
 #include "nsCP1255ToUnicode.h"
 #include "nsCP1256ToUnicode.h"
 #include "nsCP1257ToUnicode.h"
 #include "nsCP1258ToUnicode.h"
@@ -71,29 +67,25 @@
 #include "nsUTF16ToUnicode.h"
 #include "nsUserDefinedToUnicode.h"
 #include "nsUnicodeToAscii.h"
 #include "nsUnicodeToISO88592.h"
 #include "nsUnicodeToISO88593.h"
 #include "nsUnicodeToISO88594.h"
 #include "nsUnicodeToISO88595.h"
 #include "nsUnicodeToISO88596.h"
-#include "nsUnicodeToISO88596E.h"
-#include "nsUnicodeToISO88596I.h"
 #include "nsUnicodeToISO88597.h"
 #include "nsUnicodeToISO88598.h"
-#include "nsUnicodeToISO88598E.h"
 #include "nsUnicodeToISO88598I.h"
 #include "nsUnicodeToISO88599.h"
 #include "nsUnicodeToISO885910.h"
 #include "nsUnicodeToISO885913.h"
 #include "nsUnicodeToISO885914.h"
 #include "nsUnicodeToISO885915.h"
 #include "nsUnicodeToISO885916.h"
-#include "nsUnicodeToISOIR111.h"
 #include "nsUnicodeToCP1250.h"
 #include "nsUnicodeToCP1251.h"
 #include "nsUnicodeToCP1253.h"
 #include "nsUnicodeToCP1254.h"
 #include "nsUnicodeToCP1255.h"
 #include "nsUnicodeToCP1256.h"
 #include "nsUnicodeToCP1257.h"
 #include "nsUnicodeToCP1258.h"
@@ -116,26 +108,24 @@
 // ucvja
 #include "nsUCVJACID.h"
 #include "nsUCVJA2CID.h"
 #include "nsUCVJADll.h"
 #include "nsJapaneseToUnicode.h"
 #include "nsUnicodeToSJIS.h"
 #include "nsUnicodeToEUCJP.h"
 #include "nsUnicodeToISO2022JP.h"
-#include "nsUnicodeToJISx0201.h"
 
 // ucvtw
 #include "nsUCvTWCID.h"
 #include "nsUCvTWDll.h"
 #include "nsBIG5ToUnicode.h"
 #include "nsUnicodeToBIG5.h"
 #include "nsBIG5HKSCSToUnicode.h"
 #include "nsUnicodeToBIG5HKSCS.h"
-#include "nsUnicodeToHKSCS.h"
 
 // ucvko
 #include "nsUCvKOCID.h"
 #include "nsUCvKODll.h"
 #include "nsCP949ToUnicode.h"
 #include "nsUnicodeToCP949.h"
 
 // ucvcn
@@ -157,29 +147,25 @@ NS_UCONV_REG_UNREG("replacement", NS_REP
 
   // ucvlatin
 NS_UCONV_REG_UNREG("us-ascii", NS_ASCIITOUNICODE_CID, NS_UNICODETOASCII_CID)
 NS_UCONV_REG_UNREG("ISO-8859-2", NS_ISO88592TOUNICODE_CID, NS_UNICODETOISO88592_CID)
 NS_UCONV_REG_UNREG("ISO-8859-3", NS_ISO88593TOUNICODE_CID, NS_UNICODETOISO88593_CID)
 NS_UCONV_REG_UNREG("ISO-8859-4", NS_ISO88594TOUNICODE_CID, NS_UNICODETOISO88594_CID)
 NS_UCONV_REG_UNREG("ISO-8859-5", NS_ISO88595TOUNICODE_CID, NS_UNICODETOISO88595_CID)
 NS_UCONV_REG_UNREG("ISO-8859-6", NS_ISO88596TOUNICODE_CID, NS_UNICODETOISO88596_CID)
-NS_UCONV_REG_UNREG("ISO-8859-6-I", NS_ISO88596ITOUNICODE_CID, NS_UNICODETOISO88596I_CID)
-NS_UCONV_REG_UNREG("ISO-8859-6-E", NS_ISO88596ETOUNICODE_CID, NS_UNICODETOISO88596E_CID)
 NS_UCONV_REG_UNREG("ISO-8859-7", NS_ISO88597TOUNICODE_CID, NS_UNICODETOISO88597_CID)
 NS_UCONV_REG_UNREG("ISO-8859-8", NS_ISO88598TOUNICODE_CID, NS_UNICODETOISO88598_CID)
 NS_UCONV_REG_UNREG("ISO-8859-8-I", NS_ISO88598ITOUNICODE_CID, NS_UNICODETOISO88598I_CID)
-NS_UCONV_REG_UNREG("ISO-8859-8-E", NS_ISO88598ETOUNICODE_CID, NS_UNICODETOISO88598E_CID)
 NS_UCONV_REG_UNREG("ISO-8859-9", NS_ISO88599TOUNICODE_CID, NS_UNICODETOISO88599_CID)
 NS_UCONV_REG_UNREG("ISO-8859-10", NS_ISO885910TOUNICODE_CID, NS_UNICODETOISO885910_CID)
 NS_UCONV_REG_UNREG("ISO-8859-13", NS_ISO885913TOUNICODE_CID, NS_UNICODETOISO885913_CID)
 NS_UCONV_REG_UNREG("ISO-8859-14", NS_ISO885914TOUNICODE_CID, NS_UNICODETOISO885914_CID)
 NS_UCONV_REG_UNREG("ISO-8859-15", NS_ISO885915TOUNICODE_CID, NS_UNICODETOISO885915_CID)
 NS_UCONV_REG_UNREG("ISO-8859-16", NS_ISO885916TOUNICODE_CID, NS_UNICODETOISO885916_CID)
-NS_UCONV_REG_UNREG("ISO-IR-111", NS_ISOIR111TOUNICODE_CID, NS_UNICODETOISOIR111_CID)
 NS_UCONV_REG_UNREG("windows-1250", NS_CP1250TOUNICODE_CID, NS_UNICODETOCP1250_CID)
 NS_UCONV_REG_UNREG("windows-1251", NS_CP1251TOUNICODE_CID, NS_UNICODETOCP1251_CID)
 NS_UCONV_REG_UNREG("windows-1253", NS_CP1253TOUNICODE_CID, NS_UNICODETOCP1253_CID)
 NS_UCONV_REG_UNREG("windows-1254", NS_CP1254TOUNICODE_CID, NS_UNICODETOCP1254_CID)
 NS_UCONV_REG_UNREG("windows-1255", NS_CP1255TOUNICODE_CID, NS_UNICODETOCP1255_CID)
 NS_UCONV_REG_UNREG("windows-1256", NS_CP1256TOUNICODE_CID, NS_UNICODETOCP1256_CID)
 NS_UCONV_REG_UNREG("windows-1257", NS_CP1257TOUNICODE_CID, NS_UNICODETOCP1257_CID)
 NS_UCONV_REG_UNREG("windows-1258", NS_CP1258TOUNICODE_CID, NS_UNICODETOCP1258_CID)
@@ -206,24 +192,20 @@ NS_UCONV_REG_UNREG_DECODER("x-mac-farsi"
 NS_UCONV_REG_UNREG_DECODER("x-mac-gurmukhi" , NS_MACGURMUKHITOUNICODE_CID)
 NS_UCONV_REG_UNREG_DECODER("x-mac-gujarati" , NS_MACGUJARATITOUNICODE_CID)
 NS_UCONV_REG_UNREG_DECODER("x-mac-hebrew" , NS_MACHEBREWTOUNICODE_CID)
 
     // ucvja
 NS_UCONV_REG_UNREG("Shift_JIS", NS_SJISTOUNICODE_CID, NS_UNICODETOSJIS_CID)
 NS_UCONV_REG_UNREG("ISO-2022-JP", NS_ISO2022JPTOUNICODE_CID, NS_UNICODETOISO2022JP_CID)
 NS_UCONV_REG_UNREG("EUC-JP", NS_EUCJPTOUNICODE_CID, NS_UNICODETOEUCJP_CID)
-  
-NS_UCONV_REG_UNREG_ENCODER("jis_0201" , NS_UNICODETOJISX0201_CID)
 
     // ucvtw
 NS_UCONV_REG_UNREG("Big5", NS_BIG5TOUNICODE_CID, NS_UNICODETOBIG5_CID)
 NS_UCONV_REG_UNREG("Big5-HKSCS", NS_BIG5HKSCSTOUNICODE_CID, NS_UNICODETOBIG5HKSCS_CID)
-  
-NS_UCONV_REG_UNREG_ENCODER("hkscs-1" , NS_UNICODETOHKSCS_CID)
 
     // ucvko
 NS_UCONV_REG_UNREG("EUC-KR", NS_EUCKRTOUNICODE_CID, NS_UNICODETOEUCKR_CID)
 
 // ucvcn
 NS_UCONV_REG_UNREG("GB2312", NS_GB2312TOUNICODE_CID, NS_UNICODETOGB2312_CID)
 NS_UCONV_REG_UNREG("gbk", NS_GBKTOUNICODE_CID, NS_UNICODETOGBK_CID)
 NS_UCONV_REG_UNREG("HZ-GB-2312", NS_HZTOUNICODE_CID, NS_UNICODETOHZ_CID)
@@ -337,29 +319,25 @@ NS_DEFINE_NAMED_CID(NS_UNICODETOCP1252_C
 NS_DEFINE_NAMED_CID(NS_UNICODETOMACROMAN_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOUTF8_CID);
 NS_DEFINE_NAMED_CID(NS_ASCIITOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_ISO88592TOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_ISO88593TOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_ISO88594TOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_ISO88595TOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_ISO88596TOUNICODE_CID);
-NS_DEFINE_NAMED_CID(NS_ISO88596ITOUNICODE_CID);
-NS_DEFINE_NAMED_CID(NS_ISO88596ETOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_ISO88597TOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_ISO88598TOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_ISO88598ITOUNICODE_CID);
-NS_DEFINE_NAMED_CID(NS_ISO88598ETOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_ISO88599TOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_ISO885910TOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_ISO885913TOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_ISO885914TOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_ISO885915TOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_ISO885916TOUNICODE_CID);
-NS_DEFINE_NAMED_CID(NS_ISOIR111TOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_CP1250TOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_CP1251TOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_CP1253TOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_CP1254TOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_CP1255TOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_CP1256TOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_CP1257TOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_CP1258TOUNICODE_CID);
@@ -387,29 +365,25 @@ NS_DEFINE_NAMED_CID(NS_MACGURMUKHITOUNIC
 NS_DEFINE_NAMED_CID(NS_MACGUJARATITOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_MACHEBREWTOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOASCII_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOISO88592_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOISO88593_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOISO88594_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOISO88595_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOISO88596_CID);
-NS_DEFINE_NAMED_CID(NS_UNICODETOISO88596I_CID);
-NS_DEFINE_NAMED_CID(NS_UNICODETOISO88596E_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOISO88597_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOISO88598_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOISO88598I_CID);
-NS_DEFINE_NAMED_CID(NS_UNICODETOISO88598E_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOISO88599_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOISO885910_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOISO885913_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOISO885914_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOISO885915_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOISO885916_CID);
-NS_DEFINE_NAMED_CID(NS_UNICODETOISOIR111_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOCP1250_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOCP1251_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOCP1253_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOCP1254_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOCP1255_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOCP1256_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOCP1257_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOCP1258_CID);
@@ -425,21 +399,19 @@ NS_DEFINE_NAMED_CID(NS_UNICODETOUTF16LE_
 NS_DEFINE_NAMED_CID(NS_UNICODETOUTF16_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOUSERDEFINED_CID);
 NS_DEFINE_NAMED_CID(NS_SJISTOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_EUCJPTOUNICODE_CID);
 NS_DEFINE_NAMED_CID( NS_ISO2022JPTOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOSJIS_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOEUCJP_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOISO2022JP_CID);
-NS_DEFINE_NAMED_CID(NS_UNICODETOJISX0201_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOBIG5_CID);
 NS_DEFINE_NAMED_CID(NS_BIG5TOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOBIG5HKSCS_CID);
-NS_DEFINE_NAMED_CID(NS_UNICODETOHKSCS_CID);
 NS_DEFINE_NAMED_CID(NS_BIG5HKSCSTOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_EUCKRTOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOEUCKR_CID);
 NS_DEFINE_NAMED_CID(NS_GB2312TOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOGB2312_CID);
 NS_DEFINE_NAMED_CID(NS_GBKTOUNICODE_CID);
 NS_DEFINE_NAMED_CID(NS_UNICODETOGBK_CID);
 NS_DEFINE_NAMED_CID(NS_HZTOUNICODE_CID);
@@ -463,29 +435,25 @@ static const mozilla::Module::CIDEntry k
   { &kNS_UNICODETOMACROMAN_CID, false, nullptr, nsUnicodeToMacRomanConstructor },
   { &kNS_UNICODETOUTF8_CID, false, nullptr, nsUnicodeToUTF8Constructor },
   { &kNS_ASCIITOUNICODE_CID, false, nullptr, nsAsciiToUnicodeConstructor },
   { &kNS_ISO88592TOUNICODE_CID, false, nullptr, nsISO88592ToUnicodeConstructor },
   { &kNS_ISO88593TOUNICODE_CID, false, nullptr, nsISO88593ToUnicodeConstructor },
   { &kNS_ISO88594TOUNICODE_CID, false, nullptr, nsISO88594ToUnicodeConstructor },
   { &kNS_ISO88595TOUNICODE_CID, false, nullptr, nsISO88595ToUnicodeConstructor },
   { &kNS_ISO88596TOUNICODE_CID, false, nullptr, nsISO88596ToUnicodeConstructor },
-  { &kNS_ISO88596ITOUNICODE_CID, false, nullptr, nsISO88596IToUnicodeConstructor },
-  { &kNS_ISO88596ETOUNICODE_CID, false, nullptr, nsISO88596EToUnicodeConstructor },
   { &kNS_ISO88597TOUNICODE_CID, false, nullptr, nsISO88597ToUnicodeConstructor },
   { &kNS_ISO88598TOUNICODE_CID, false, nullptr, nsISO88598ToUnicodeConstructor },
   { &kNS_ISO88598ITOUNICODE_CID, false, nullptr, nsISO88598IToUnicodeConstructor },
-  { &kNS_ISO88598ETOUNICODE_CID, false, nullptr, nsISO88598EToUnicodeConstructor },
   { &kNS_ISO88599TOUNICODE_CID, false, nullptr, nsISO88599ToUnicodeConstructor },
   { &kNS_ISO885910TOUNICODE_CID, false, nullptr, nsISO885910ToUnicodeConstructor },
   { &kNS_ISO885913TOUNICODE_CID, false, nullptr, nsISO885913ToUnicodeConstructor },
   { &kNS_ISO885914TOUNICODE_CID, false, nullptr, nsISO885914ToUnicodeConstructor },
   { &kNS_ISO885915TOUNICODE_CID, false, nullptr, nsISO885915ToUnicodeConstructor },
   { &kNS_ISO885916TOUNICODE_CID, false, nullptr, nsISO885916ToUnicodeConstructor },
-  { &kNS_ISOIR111TOUNICODE_CID, false, nullptr, nsISOIR111ToUnicodeConstructor },
   { &kNS_CP1250TOUNICODE_CID, false, nullptr, nsCP1250ToUnicodeConstructor },
   { &kNS_CP1251TOUNICODE_CID, false, nullptr, nsCP1251ToUnicodeConstructor },
   { &kNS_CP1253TOUNICODE_CID, false, nullptr, nsCP1253ToUnicodeConstructor },
   { &kNS_CP1254TOUNICODE_CID, false, nullptr, nsCP1254ToUnicodeConstructor },
   { &kNS_CP1255TOUNICODE_CID, false, nullptr, nsCP1255ToUnicodeConstructor },
   { &kNS_CP1256TOUNICODE_CID, false, nullptr, nsCP1256ToUnicodeConstructor },
   { &kNS_CP1257TOUNICODE_CID, false, nullptr, nsCP1257ToUnicodeConstructor },
   { &kNS_CP1258TOUNICODE_CID, false, nullptr, nsCP1258ToUnicodeConstructor },
@@ -513,29 +481,25 @@ static const mozilla::Module::CIDEntry k
   { &kNS_MACGUJARATITOUNICODE_CID, false, nullptr, nsMacGujaratiToUnicodeConstructor },
   { &kNS_MACHEBREWTOUNICODE_CID, false, nullptr, nsMacHebrewToUnicodeConstructor },
   { &kNS_UNICODETOASCII_CID, false, nullptr, nsUnicodeToAsciiConstructor },
   { &kNS_UNICODETOISO88592_CID, false, nullptr, nsUnicodeToISO88592Constructor },
   { &kNS_UNICODETOISO88593_CID, false, nullptr, nsUnicodeToISO88593Constructor },
   { &kNS_UNICODETOISO88594_CID, false, nullptr, nsUnicodeToISO88594Constructor },
   { &kNS_UNICODETOISO88595_CID, false, nullptr, nsUnicodeToISO88595Constructor },
   { &kNS_UNICODETOISO88596_CID, false, nullptr, nsUnicodeToISO88596Constructor },
-  { &kNS_UNICODETOISO88596I_CID, false, nullptr, nsUnicodeToISO88596IConstructor },
-  { &kNS_UNICODETOISO88596E_CID, false, nullptr, nsUnicodeToISO88596EConstructor },
   { &kNS_UNICODETOISO88597_CID, false, nullptr, nsUnicodeToISO88597Constructor },
   { &kNS_UNICODETOISO88598_CID, false, nullptr, nsUnicodeToISO88598Constructor },
   { &kNS_UNICODETOISO88598I_CID, false, nullptr, nsUnicodeToISO88598IConstructor },
-  { &kNS_UNICODETOISO88598E_CID, false, nullptr, nsUnicodeToISO88598EConstructor },
   { &kNS_UNICODETOISO88599_CID, false, nullptr, nsUnicodeToISO88599Constructor },
   { &kNS_UNICODETOISO885910_CID, false, nullptr, nsUnicodeToISO885910Constructor },
   { &kNS_UNICODETOISO885913_CID, false, nullptr, nsUnicodeToISO885913Constructor },
   { &kNS_UNICODETOISO885914_CID, false, nullptr, nsUnicodeToISO885914Constructor },
   { &kNS_UNICODETOISO885915_CID, false, nullptr, nsUnicodeToISO885915Constructor },
   { &kNS_UNICODETOISO885916_CID, false, nullptr, nsUnicodeToISO885916Constructor },
-  { &kNS_UNICODETOISOIR111_CID, false, nullptr, nsUnicodeToISOIR111Constructor },
   { &kNS_UNICODETOCP1250_CID, false, nullptr, nsUnicodeToCP1250Constructor },
   { &kNS_UNICODETOCP1251_CID, false, nullptr, nsUnicodeToCP1251Constructor },
   { &kNS_UNICODETOCP1253_CID, false, nullptr, nsUnicodeToCP1253Constructor },
   { &kNS_UNICODETOCP1254_CID, false, nullptr, nsUnicodeToCP1254Constructor },
   { &kNS_UNICODETOCP1255_CID, false, nullptr, nsUnicodeToCP1255Constructor },
   { &kNS_UNICODETOCP1256_CID, false, nullptr, nsUnicodeToCP1256Constructor },
   { &kNS_UNICODETOCP1257_CID, false, nullptr, nsUnicodeToCP1257Constructor },
   { &kNS_UNICODETOCP1258_CID, false, nullptr, nsUnicodeToCP1258Constructor },
@@ -551,21 +515,19 @@ static const mozilla::Module::CIDEntry k
   { &kNS_UNICODETOUTF16_CID, false, nullptr, nsUnicodeToUTF16Constructor },
   { &kNS_UNICODETOUSERDEFINED_CID, false, nullptr, nsUnicodeToUserDefinedConstructor },
   { &kNS_SJISTOUNICODE_CID, false, nullptr, nsShiftJISToUnicodeConstructor },
   { &kNS_EUCJPTOUNICODE_CID, false, nullptr, nsEUCJPToUnicodeV2Constructor },
   { &kNS_ISO2022JPTOUNICODE_CID, false, nullptr, nsISO2022JPToUnicodeV2Constructor },
   { &kNS_UNICODETOSJIS_CID, false, nullptr, nsUnicodeToSJISConstructor },
   { &kNS_UNICODETOEUCJP_CID, false, nullptr, nsUnicodeToEUCJPConstructor },
   { &kNS_UNICODETOISO2022JP_CID, false, nullptr, nsUnicodeToISO2022JPConstructor },
-  { &kNS_UNICODETOJISX0201_CID, false, nullptr, nsUnicodeToJISx0201Constructor },
   { &kNS_UNICODETOBIG5_CID, false, nullptr, nsUnicodeToBIG5Constructor },
   { &kNS_BIG5TOUNICODE_CID, false, nullptr, nsBIG5ToUnicodeConstructor },
   { &kNS_UNICODETOBIG5HKSCS_CID, false, nullptr, nsUnicodeToBIG5HKSCSConstructor },
-  { &kNS_UNICODETOHKSCS_CID, false, nullptr, nsUnicodeToHKSCSConstructor },
   { &kNS_BIG5HKSCSTOUNICODE_CID, false, nullptr, nsBIG5HKSCSToUnicodeConstructor },
   { &kNS_EUCKRTOUNICODE_CID, false, nullptr, nsCP949ToUnicodeConstructor },
   { &kNS_UNICODETOEUCKR_CID, false, nullptr, nsUnicodeToCP949Constructor },
   { &kNS_GB2312TOUNICODE_CID, false, nullptr, nsGB18030ToUnicodeConstructor },
   { &kNS_UNICODETOGB2312_CID, false, nullptr, nsUnicodeToGB2312V2Constructor },
   { &kNS_GBKTOUNICODE_CID, false, nullptr, nsGB18030ToUnicodeConstructor },
   { &kNS_UNICODETOGBK_CID, false, nullptr, nsUnicodeToGBKConstructor },
   { &kNS_HZTOUNICODE_CID, false, nullptr, nsHZToUnicodeConstructor },
@@ -591,29 +553,25 @@ static const mozilla::Module::ContractID
   { NS_UNICODETOMACROMAN_CONTRACTID, &kNS_UNICODETOMACROMAN_CID },
   { NS_UNICODETOUTF8_CONTRACTID, &kNS_UNICODETOUTF8_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "us-ascii", &kNS_ASCIITOUNICODE_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "ISO-8859-2", &kNS_ISO88592TOUNICODE_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "ISO-8859-3", &kNS_ISO88593TOUNICODE_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "ISO-8859-4", &kNS_ISO88594TOUNICODE_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "ISO-8859-5", &kNS_ISO88595TOUNICODE_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "ISO-8859-6", &kNS_ISO88596TOUNICODE_CID },
-  { NS_UNICODEDECODER_CONTRACTID_BASE "ISO-8859-6-I", &kNS_ISO88596ITOUNICODE_CID },
-  { NS_UNICODEDECODER_CONTRACTID_BASE "ISO-8859-6-E", &kNS_ISO88596ETOUNICODE_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "ISO-8859-7", &kNS_ISO88597TOUNICODE_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "ISO-8859-8", &kNS_ISO88598TOUNICODE_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "ISO-8859-8-I", &kNS_ISO88598ITOUNICODE_CID },
-  { NS_UNICODEDECODER_CONTRACTID_BASE "ISO-8859-8-E", &kNS_ISO88598ETOUNICODE_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "ISO-8859-9", &kNS_ISO88599TOUNICODE_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "ISO-8859-10", &kNS_ISO885910TOUNICODE_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "ISO-8859-13", &kNS_ISO885913TOUNICODE_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "ISO-8859-14", &kNS_ISO885914TOUNICODE_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "ISO-8859-15", &kNS_ISO885915TOUNICODE_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "ISO-8859-16", &kNS_ISO885916TOUNICODE_CID },
-  { NS_UNICODEDECODER_CONTRACTID_BASE "ISO-IR-111", &kNS_ISOIR111TOUNICODE_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "windows-1250", &kNS_CP1250TOUNICODE_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "windows-1251", &kNS_CP1251TOUNICODE_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "windows-1253", &kNS_CP1253TOUNICODE_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "windows-1254", &kNS_CP1254TOUNICODE_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "windows-1255", &kNS_CP1255TOUNICODE_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "windows-1256", &kNS_CP1256TOUNICODE_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "windows-1257", &kNS_CP1257TOUNICODE_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "windows-1258", &kNS_CP1258TOUNICODE_CID },
@@ -641,29 +599,25 @@ static const mozilla::Module::ContractID
   { NS_UNICODEDECODER_CONTRACTID_BASE "x-mac-gujarati", &kNS_MACGUJARATITOUNICODE_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "x-mac-hebrew", &kNS_MACHEBREWTOUNICODE_CID },
   { NS_UNICODEENCODER_CONTRACTID_BASE "us-ascii", &kNS_UNICODETOASCII_CID },
   { NS_UNICODEENCODER_CONTRACTID_BASE "ISO-8859-2", &kNS_UNICODETOISO88592_CID },
   { NS_UNICODEENCODER_CONTRACTID_BASE "ISO-8859-3", &kNS_UNICODETOISO88593_CID },
   { NS_UNICODEENCODER_CONTRACTID_BASE "ISO-8859-4", &kNS_UNICODETOISO88594_CID },
   { NS_UNICODEENCODER_CONTRACTID_BASE "ISO-8859-5", &kNS_UNICODETOISO88595_CID },
   { NS_UNICODEENCODER_CONTRACTID_BASE "ISO-8859-6", &kNS_UNICODETOISO88596_CID },
-  { NS_UNICODEENCODER_CONTRACTID_BASE "ISO-8859-6-I", &kNS_UNICODETOISO88596I_CID },
-  { NS_UNICODEENCODER_CONTRACTID_BASE "ISO-8859-6-E", &kNS_UNICODETOISO88596E_CID },
   { NS_UNICODEENCODER_CONTRACTID_BASE "ISO-8859-7", &kNS_UNICODETOISO88597_CID },
   { NS_UNICODEENCODER_CONTRACTID_BASE "ISO-8859-8", &kNS_UNICODETOISO88598_CID },
   { NS_UNICODEENCODER_CONTRACTID_BASE "ISO-8859-8-I", &kNS_UNICODETOISO88598I_CID },
-  { NS_UNICODEENCODER_CONTRACTID_BASE "ISO-8859-8-E", &kNS_UNICODETOISO88598E_CID },
   { NS_UNICODEENCODER_CONTRACTID_BASE "ISO-8859-9", &kNS_UNICODETOISO88599_CID },
   { NS_UNICODEENCODER_CONTRACTID_BASE "ISO-8859-10", &kNS_UNICODETOISO885910_CID },
   { NS_UNICODEENCODER_CONTRACTID_BASE "ISO-8859-13", &kNS_UNICODETOISO885913_CID },
   { NS_UNICODEENCODER_CONTRACTID_BASE "ISO-8859-14", &kNS_UNICODETOISO885914_CID },
   { NS_UNICODEENCODER_CONTRACTID_BASE "ISO-8859-15", &kNS_UNICODETOISO885915_CID },
   { NS_UNICODEENCODER_CONTRACTID_BASE "ISO-8859-16", &kNS_UNICODETOISO885916_CID },
-  { NS_UNICODEENCODER_CONTRACTID_BASE "ISO-IR-111", &kNS_UNICODETOISOIR111_CID },
   { NS_UNICODEENCODER_CONTRACTID_BASE "windows-1250", &kNS_UNICODETOCP1250_CID },
   { NS_UNICODEENCODER_CONTRACTID_BASE "windows-1251", &kNS_UNICODETOCP1251_CID },
   { NS_UNICODEENCODER_CONTRACTID_BASE "windows-1253", &kNS_UNICODETOCP1253_CID },
   { NS_UNICODEENCODER_CONTRACTID_BASE "windows-1254", &kNS_UNICODETOCP1254_CID },
   { NS_UNICODEENCODER_CONTRACTID_BASE "windows-1255", &kNS_UNICODETOCP1255_CID },
   { NS_UNICODEENCODER_CONTRACTID_BASE "windows-1256", &kNS_UNICODETOCP1256_CID },
   { NS_UNICODEENCODER_CONTRACTID_BASE "windows-1257", &kNS_UNICODETOCP1257_CID },
   { NS_UNICODEENCODER_CONTRACTID_BASE "windows-1258", &kNS_UNICODETOCP1258_CID },
@@ -679,21 +633,19 @@ static const mozilla::Module::ContractID
   { NS_UNICODEENCODER_CONTRACTID_BASE "UTF-16", &kNS_UNICODETOUTF16_CID },
   { NS_UNICODEENCODER_CONTRACTID_BASE "x-user-defined", &kNS_UNICODETOUSERDEFINED_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "Shift_JIS", &kNS_SJISTOUNICODE_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "EUC-JP", &kNS_EUCJPTOUNICODE_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "ISO-2022-JP", &kNS_ISO2022JPTOUNICODE_CID },
   { NS_UNICODEENCODER_CONTRACTID_BASE "Shift_JIS", &kNS_UNICODETOSJIS_CID },
   { NS_UNICODEENCODER_CONTRACTID_BASE "EUC-JP", &kNS_UNICODETOEUCJP_CID },
   { NS_UNICODEENCODER_CONTRACTID_BASE "ISO-2022-JP", &kNS_UNICODETOISO2022JP_CID },
-  { NS_UNICODEENCODER_CONTRACTID_BASE "jis_0201", &kNS_UNICODETOJISX0201_CID },
   { NS_UNICODEENCODER_CONTRACTID_BASE "Big5", &kNS_UNICODETOBIG5_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "Big5", &kNS_BIG5TOUNICODE_CID },
   { NS_UNICODEENCODER_CONTRACTID_BASE "Big5-HKSCS", &kNS_UNICODETOBIG5HKSCS_CID },
-  { NS_UNICODEENCODER_CONTRACTID_BASE "hkscs-1", &kNS_UNICODETOHKSCS_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "Big5-HKSCS", &kNS_BIG5HKSCSTOUNICODE_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "EUC-KR", &kNS_EUCKRTOUNICODE_CID },
   { NS_UNICODEENCODER_CONTRACTID_BASE "EUC-KR", &kNS_UNICODETOEUCKR_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "GB2312", &kNS_GB2312TOUNICODE_CID },
   { NS_UNICODEENCODER_CONTRACTID_BASE "GB2312", &kNS_UNICODETOGB2312_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "gbk", &kNS_GBKTOUNICODE_CID },
   { NS_UNICODEENCODER_CONTRACTID_BASE "gbk", &kNS_UNICODETOGBK_CID },
   { NS_UNICODEDECODER_CONTRACTID_BASE "HZ-GB-2312", &kNS_HZTOUNICODE_CID },
--- a/intl/uconv/tools/jamap.pl
+++ b/intl/uconv/tools/jamap.pl
@@ -277,39 +277,34 @@ sub print_table {
       }
     }
   }
   print MAP "\n};\n";
 }
 
 
 my %cp932 = read_sjis_map('CP932.TXT', 0, 1);
-my %ibm = read_sjis_map('IBM943.TXT', 0, 1);
 my $jis0212 = read_0212_map('JIS0212.TXT', 0, 1);
 
 %printed = ();
 write_fromu_map('jis0201-uf-unify', 'jis',
   $cp932{jis0201},
-  $ibm{jis0201}
 );
 write_fromu_map('jis0208-uf-unify', 'jis',
   $cp932{jis0208},
-  $ibm{jis0208}
 );
 
 %printed = ();
 write_fromu_map('jis0208ext-uf-unify', 'jis',
   $cp932{jis0208undef},
-  $ibm{jis0208undef}
 );
 
 %printed = ();
 write_fromu_map('sjis-uf-unify', 'sjis',
   @cp932{'jis0201', 'jis0208', 'jis0208undef', 'sjis1undef', 'sjis2undef'},
-  @ibm{'jis0201', 'jis0208', 'jis0208undef', 'sjis1undef', 'sjis2undef'}
 );
 
 open MAP, ">japanese.map" or die $!;
 binmode MAP;
 
 while (<DATA>) {
   if ( /^!/ ) { last; }
   print MAP;
@@ -320,17 +315,16 @@ print MAP <<EOM;
 // 0x80 --> U+0080
 // 0xa0 --> U+F8F0
 // 0xfd --> U+F8F1
 // 0xfe --> U+F8F2
 // 0xff --> U+F8F3
 EOM
 
 print_table_index('CP932', @cp932{'jis0208', 'jis0208undef', 'sjis2undef'});
-print_table_index('IBM943', @ibm{'jis0208', 'jis0208undef', 'sjis2undef'});
 print_0212_table_index('JIS0212', $jis0212);
 print_table();
 
 close MAP or warn $!;
 
 __DATA__
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
--- a/intl/uconv/ucvja/japanese.map
+++ b/intl/uconv/ucvja/japanese.map
@@ -1,14 +1,14 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-/* generated by jamap.pl CP932.TXT IBM943.TXT JIS0212.TXT */
+/* generated by jamap.pl CP932.TXT JIS0212.TXT */
 
 // IE-compatible handling of undefined codepoints:
 // 0x80 --> U+0080
 // 0xa0 --> U+F8F0
 // 0xfd --> U+F8F1
 // 0xfe --> U+F8F2
 // 0xff --> U+F8F3
 static const uint16_t gCP932IndexShiftJis[] = {
@@ -46,71 +46,31 @@ static const uint16_t gCP932IndexJis0208
     6486,   6580,   6674,   6768,   6862,   6956,   7050,   7144,
     7238,   7332,   7426,   7520,   7614,      0,      0,      0,
        0,   7708,   7802,   7896,   7990,      0,      0, 0xFFFD,
 };
 static const uint16_t * const gCP932Index[] = {
   gCP932IndexShiftJis, gCP932IndexJis0208
 };
 
-static const uint16_t gIBM943IndexShiftJis[] = {
-  0xFFFD,   8648,    376,    564,    752,      0,      0,    940,
-    1128,   1316,   1504,   1692,   1880,   2068,   2256,   2444,
-    2632,   2820,   3008,   3196,   3384,   3572,   3760,   3948,
-    4136,   4324,   4512,   4700,   4888,   5076,   5264,   5452,
-  0xF8F0, 0xFF61, 0xFF62, 0xFF63, 0xFF64, 0xFF65, 0xFF66, 0xFF67,
-  0xFF68, 0xFF69, 0xFF6A, 0xFF6B, 0xFF6C, 0xFF6D, 0xFF6E, 0xFF6F,
-  0xFF70, 0xFF71, 0xFF72, 0xFF73, 0xFF74, 0xFF75, 0xFF76, 0xFF77,
-  0xFF78, 0xFF79, 0xFF7A, 0xFF7B, 0xFF7C, 0xFF7D, 0xFF7E, 0xFF7F,
-  0xFF80, 0xFF81, 0xFF82, 0xFF83, 0xFF84, 0xFF85, 0xFF86, 0xFF87,
-  0xFF88, 0xFF89, 0xFF8A, 0xFF8B, 0xFF8C, 0xFF8D, 0xFF8E, 0xFF8F,
-  0xFF90, 0xFF91, 0xFF92, 0xFF93, 0xFF94, 0xFF95, 0xFF96, 0xFF97,
-  0xFF98, 0xFF99, 0xFF9A, 0xFF9B, 0xFF9C, 0xFF9D, 0xFF9E, 0xFF9F,
-    5640,   5828,   6016,   6204,   6392,   6580,   6768,   6956,
-    7144,   7332,   7520,      0,      0,   7708,   8836,      0,
-  0xE000, 0xE0BC, 0xE178, 0xE234, 0xE2F0, 0xE3AC, 0xE468, 0xE524,
-  0xE5E0, 0xE69C,   9024,   8272,   8460, 0xF8F1, 0xF8F2, 0xF8F3,
-};
-static const uint16_t gIBM943IndexJis0208[] = {
-  0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
-  0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
-  0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
-  0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
-  0xFFFD,   8648,    282,    376,    470,    564,    658,    752,
-     846,      0,      0,      0,      0,    940,      0,      0,
-    1222,   1316,   1410,   1504,   1598,   1692,   1786,   1880,
-    1974,   2068,   2162,   2256,   2350,   2444,   2538,   2632,
-    2726,   2820,   2914,   3008,   3102,   3196,   3290,   3384,
-    3478,   3572,   3666,   3760,   3854,   3948,   4042,   4136,
-    4230,   4324,   4418,   4512,   4606,   4700,   4794,   4888,
-    4982,   5076,   5170,   5264,   5358,   5452,   5546,   5640,
-    5734,   5828,   5922,   6016,   6110,   6204,   6298,   6392,
-    6486,   6580,   6674,   6768,   6862,   6956,   7050,   7144,
-    7238,   7332,   7426,   7520,   7614,      0,      0,      0,
-       0,   7708,   7802,   7896,   8930,      0,      0, 0xFFFD,
-};
-static const uint16_t * const gIBM943Index[] = {
-  gIBM943IndexShiftJis, gIBM943IndexJis0208
-};
-
 static const uint16_t gJIS0212Index[] = {
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
-  0xFFFD,      0,   9212,      0,      0,      0,   9306,   9400,
-       0,   9494,   9588,   9682,      0,      0,      0,      0,
-    9776,   9870,   9964,  10058,  10152,  10246,  10340,  10434,
-   10528,  10622,  10716,  10810,  10904,  10998,  11092,  11186,
-   11280,  11374,  11468,  11562,  11656,  11750,  11844,  11938,
-   12032,  12126,  12220,  12314,  12408,  12502,  12596,  12690,
-   12784,  12878,  12972,  13066,  13160,  13254,  13348,  13442,
-   13536,  13630,  13724,  13818,  13912,  14006,  14100,  14194,
-   14288,  14382,  14476,  14570,  14664,  14758,  14852,  14946,
-   15040,  15134,  15228,  15322,  15416,  15510,      0,      0,
+  0xFFFD,      0,   8648,      0,      0,      0,   8742,   8836,
+       0,   8930,   9024,   9118,      0,      0,      0,      0,
+    9212,   9306,   9400,   9494,   9588,   9682,   9776,   9870,
+    9964,  10058,  10152,  10246,  10340,  10434,  10528,  10622,
+   10716,  10810,  10904,  10998,  11092,  11186,  11280,  11374,
+   11468,  11562,  11656,  11750,  11844,  11938,  12032,  12126,
+   12220,  12314,  12408,  12502,  12596,  12690,  12784,  12878,
+   12972,  13066,  13160,  13254,  13348,  13442,  13536,  13630,
+   13724,  13818,  13912,  14006,  14100,  14194,  14288,  14382,
+   14476,  14570,  14664,  14758,  14852,  14946,      0,      0,
        0,      0,      0,      0,      0,      0,      0,      0,
        0,      0,      0,      0,      0,      0,      0, 0xFFFD,
 };
 
 static const uint16_t gJapaneseMap[] = {
   /* index 0 */
           0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
@@ -1303,965 +1263,887 @@ static const uint16_t gJapaneseMap[] = {
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   /* index 8648 */
-          0x3000, 0x3001, 0x3002, 0xFF0C, 0xFF0E, 0x30FB, 0xFF1A,
-  0xFF1B, 0xFF1F, 0xFF01, 0x309B, 0x309C, 0x00B4, 0xFF40, 0x00A8,
-  0xFF3E, 0xFFE3, 0xFF3F, 0x30FD, 0x30FE, 0x309D, 0x309E, 0x3003,
-  0x4EDD, 0x3005, 0x3006, 0x3007, 0x30FC, 0x2014, 0x2010, 0xFF0F,
-  0xFF3C, 0x301C, 0x2016, 0xFF5C, 0x2026, 0x2025, 0x2018, 0x2019,
-  0x201C, 0x201D, 0xFF08, 0xFF09, 0x3014, 0x3015, 0xFF3B, 0xFF3D,
-  0xFF5B, 0xFF5D, 0x3008, 0x3009, 0x300A, 0x300B, 0x300C, 0x300D,
-  0x300E, 0x300F, 0x3010, 0x3011, 0xFF0B, 0x2212, 0x00B1, 0x00D7,
-  0x00F7, 0xFF1D, 0x2260, 0xFF1C, 0xFF1E, 0x2266, 0x2267, 0x221E,
-  0x2234, 0x2642, 0x2640, 0x00B0, 0x2032, 0x2033, 0x2103, 0xFFE5,
-  0xFF04, 0xFFE0, 0xFFE1, 0xFF05, 0xFF03, 0xFF06, 0xFF0A, 0xFF20,
-  0x00A7, 0x2606, 0x2605, 0x25CB, 0x25CF, 0x25CE, 0x25C7,
-  /* index 8742 */
-          0x25C6, 0x25A1, 0x25A0, 0x25B3, 0x25B2, 0x25BD, 0x25BC,
-  0x203B, 0x3012, 0x2192, 0x2190, 0x2191, 0x2193, 0x3013, 0xFFFD,
-  0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
-  0xFFFD, 0xFFFD, 0x2208, 0x220B, 0x2286, 0x2287, 0x2282, 0x2283,
-  0x222A, 0x2229, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
-  0xFFFD, 0xFFFD, 0x2227, 0x2228, 0xFFE2, 0x21D2, 0x21D4, 0x2200,
-  0x2203, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
-  0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x2220, 0x22A5, 0x2312, 0x2202,
-  0x2207, 0x2261, 0x2252, 0x226A, 0x226B, 0x221A, 0x223D, 0x221D,
-  0x2235, 0x222B, 0x222C, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
-  0xFFFD, 0xFFFD, 0x212B, 0x2030, 0x266F, 0x266D, 0x266A, 0x2020,
-  0x2021, 0x00B6, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x25EF,
-  /* index 8836 */
-          0x72BE, 0x7324, 0xFA16, 0x7377, 0x73BD, 0x73C9, 0x73D6,
-  0x73E3, 0x73D2, 0x7407, 0x73F5, 0x7426, 0x742A, 0x7429, 0x742E,
-  0x7462, 0x7489, 0x749F, 0x7501, 0x756F, 0x7682, 0x769C, 0x769E,
-  0x769B, 0x76A6, 0xFA17, 0x7746, 0x52AF, 0x7821, 0x784E, 0x7864,
-  0x787A, 0x7930, 0xFA18, 0xFA19, 0xFA1A, 0x7994, 0xFA1B, 0x799B,
-  0x7AD1, 0x7AE7, 0xFA1C, 0x7AEB, 0x7B9E, 0xFA1D, 0x7D48, 0x7D5C,
-  0x7DB7, 0x7DA0, 0x7DD6, 0x7E52, 0x7F47, 0x7FA1, 0xFA1E, 0x8301,
-  0x8362, 0x837F, 0x83C7, 0x83F6, 0x8448, 0x84B4, 0x8553, 0x8559,
-  0x856B, 0xFA1F, 0x85B0, 0xFA20, 0xFA21, 0x8807, 0x88F5, 0x8A12,
-  0x8A37, 0x8A79, 0x8AA7, 0x8ABE, 0x8ADF, 0xFA22, 0x8AF6, 0x8B53,
-  0x8B7F, 0x8CF0, 0x8CF4, 0x8D12, 0x8D76, 0xFA23, 0x8ECF, 0xFA24,
-  0xFA25, 0x9067, 0x90DE, 0xFA26, 0x9115, 0x9127, 0x91DA,
-  /* index 8930 */
-          0x91D7, 0x91DE, 0x91ED, 0x91EE, 0x91E4, 0x91E5, 0x9206,
-  0x9210, 0x920A, 0x923A, 0x9240, 0x923C, 0x924E, 0x9259, 0x9251,
-  0x9239, 0x9267, 0x92A7, 0x9277, 0x9278, 0x92E7, 0x92D7, 0x92D9,
-  0x92D0, 0xFA27, 0x92D5, 0x92E0, 0x92D3, 0x9325, 0x9321, 0x92FB,
-  0xFA28, 0x931E, 0x92FF, 0x931D, 0x9302, 0x9370, 0x9357, 0x93A4,
-  0x93C6, 0x93DE, 0x93F8, 0x9431, 0x9445, 0x9448, 0x9592, 0xF9DC,
-  0xFA29, 0x969D, 0x96AF, 0x9733, 0x973B, 0x9743, 0x974D, 0x974F,
-  0x9751, 0x9755, 0x9857, 0x9865, 0xFA2A, 0xFA2B, 0x9927, 0xFA2C,
-  0x999E, 0x9A4E, 0x9AD9, 0x9ADC, 0x9B75, 0x9B72, 0x9B8F, 0x9BB1,
-  0x9BBB, 0x9C00, 0x9D70, 0x9D6B, 0xFA2D, 0x9E19, 0x9ED1, 0xFFFD,
-  0xFFFD, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176,
-  0x2177, 0x2178, 0x2179, 0xFFE2, 0x00A6, 0xFF07, 0xFF02,
-  /* index 9024 */
-          0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176,
-  0x2177, 0x2178, 0x2179, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164,
-  0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0xFFE2, 0x00A6, 0xFF07,
-  0xFF02, 0x3231, 0x2116, 0x2121, 0x2235, 0x7E8A, 0x891C, 0x9348,
-  0x9288, 0x84DC, 0x4FC9, 0x70BB, 0x6631, 0x68C8, 0x92F9, 0x66FB,
-  0x5F45, 0x4E28, 0x4EE1, 0x4EFC, 0x4F00, 0x4F03, 0x4F39, 0x4F56,
-  0x4F92, 0x4F8A, 0x4F9A, 0x4F94, 0x4FCD, 0x5040, 0x5022, 0x4FFF,
-  0x501E, 0x5046, 0x5070, 0x5042, 0x5094, 0x50F4, 0x50D8, 0x514A,
-  0x5164, 0x519D, 0x51BE, 0x51EC, 0x5215, 0x529C, 0x52A6, 0x52C0,
-  0x52DB, 0x5300, 0x5307, 0x5324, 0x5372, 0x5393, 0x53B2, 0x53DD,
-  0xFA0E, 0x549C, 0x548A, 0x54A9, 0x54FF, 0x5586, 0x5759, 0x5765,
-  0x57AC, 0x57C8, 0x57C7, 0xFA0F, 0xFA10, 0x589E, 0x58B2,
-  /* index 9118 */
-          0x590B, 0x5953, 0x595B, 0x595D, 0x5963, 0x59A4, 0x59BA,
-  0x5B56, 0x5BC0, 0x752F, 0x5BD8, 0x5BEC, 0x5C1E, 0x5CA6, 0x5CBA,
-  0x5CF5, 0x5D27, 0x5D53, 0xFA11, 0x5D42, 0x5D6D, 0x5DB8, 0x5DB9,
-  0x5DD0, 0x5F21, 0x5F34, 0x5F67, 0x5FB7, 0x5FDE, 0x605D, 0x6085,
-  0x608A, 0x60DE, 0x60D5, 0x6120, 0x60F2, 0x6111, 0x6137, 0x6130,
-  0x6198, 0x6213, 0x62A6, 0x63F5, 0x6460, 0x649D, 0x64CE, 0x654E,
-  0x6600, 0x6615, 0x663B, 0x6609, 0x662E, 0x661E, 0x6624, 0x6665,
-  0x6657, 0x6659, 0xFA12, 0x6673, 0x6699, 0x66A0, 0x66B2, 0x66BF,
-  0x66FA, 0x670E, 0xF929, 0x6766, 0x67BB, 0x6852, 0x67C0, 0x6801,
-  0x6844, 0x68CF, 0xFA13, 0x6968, 0xFA14, 0x6998, 0x69E2, 0x6A30,
-  0x6A6B, 0x6A46, 0x6A73, 0x6A7E, 0x6AE2, 0x6AE4, 0x6BD6, 0x6C3F,
-  0x6C5C, 0x6C86, 0x6C6F, 0x6CDA, 0x6D04, 0x6D87, 0x6D6F,
-  /* index 9212 */
           0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x02D8,
   0x02C7, 0x00B8, 0x02D9, 0x02DD, 0x00AF, 0x02DB, 0x02DA, 0xFF5E,
   0x0384, 0x0385, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0x00A1, 0x00A6, 0x00BF, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0x00BA, 0x00AA, 0x00A9, 0x00AE, 0x2122,
   0x00A4, 0x2116, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
-  /* index 9306 */
+  /* index 8742 */
           0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0x0386, 0x0388, 0x0389, 0x038A, 0x03AA, 0xFFFD, 0x038C,
   0xFFFD, 0x038E, 0x03AB, 0xFFFD, 0x038F, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0x03AC, 0x03AD, 0x03AE, 0x03AF, 0x03CA, 0x0390, 0x03CC,
   0x03C2, 0x03CD, 0x03CB, 0x03B0, 0x03CE, 0xFFFD, 0xFFFD,
-  /* index 9400 */
+  /* index 8836 */
           0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407,
   0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x040E, 0x040F, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457,
   0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x045E, 0x045F,
-  /* index 9494 */
+  /* index 8930 */
           0x00C6, 0x0110, 0xFFFD, 0x0126, 0xFFFD, 0x0132, 0xFFFD,
   0x0141, 0x013F, 0xFFFD, 0x014A, 0x00D8, 0x0152, 0xFFFD, 0x0166,
   0x00DE, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0x00E6, 0x0111, 0x00F0, 0x0127, 0x0131, 0x0133, 0x0138,
   0x0142, 0x0140, 0x0149, 0x014B, 0x00F8, 0x0153, 0x00DF, 0x0167,
   0x00FE, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
-  /* index 9588 */
+  /* index 9024 */
           0x00C1, 0x00C0, 0x00C4, 0x00C2, 0x0102, 0x01CD, 0x0100,
   0x0104, 0x00C5, 0x00C3, 0x0106, 0x0108, 0x010C, 0x00C7, 0x010A,
   0x010E, 0x00C9, 0x00C8, 0x00CB, 0x00CA, 0x011A, 0x0116, 0x0112,
   0x0118, 0xFFFD, 0x011C, 0x011E, 0x0122, 0x0120, 0x0124, 0x00CD,
   0x00CC, 0x00CF, 0x00CE, 0x01CF, 0x0130, 0x012A, 0x012E, 0x0128,
   0x0134, 0x0136, 0x0139, 0x013D, 0x013B, 0x0143, 0x0147, 0x0145,
   0x00D1, 0x00D3, 0x00D2, 0x00D6, 0x00D4, 0x01D1, 0x0150, 0x014C,
   0x00D5, 0x0154, 0x0158, 0x0156, 0x015A, 0x015C, 0x0160, 0x015E,
   0x0164, 0x0162, 0x00DA, 0x00D9, 0x00DC, 0x00DB, 0x016C, 0x01D3,
   0x0170, 0x016A, 0x0172, 0x016E, 0x0168, 0x01D7, 0x01DB, 0x01D9,
   0x01D5, 0x0174, 0x00DD, 0x0178, 0x0176, 0x0179, 0x017D, 0x017B,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
-  /* index 9682 */
+  /* index 9118 */
           0x00E1, 0x00E0, 0x00E4, 0x00E2, 0x0103, 0x01CE, 0x0101,
   0x0105, 0x00E5, 0x00E3, 0x0107, 0x0109, 0x010D, 0x00E7, 0x010B,
   0x010F, 0x00E9, 0x00E8, 0x00EB, 0x00EA, 0x011B, 0x0117, 0x0113,
   0x0119, 0x01F5, 0x011D, 0x011F, 0xFFFD, 0x0121, 0x0125, 0x00ED,
   0x00EC, 0x00EF, 0x00EE, 0x01D0, 0xFFFD, 0x012B, 0x012F, 0x0129,
   0x0135, 0x0137, 0x013A, 0x013E, 0x013C, 0x0144, 0x0148, 0x0146,
   0x00F1, 0x00F3, 0x00F2, 0x00F6, 0x00F4, 0x01D2, 0x0151, 0x014D,
   0x00F5, 0x0155, 0x0159, 0x0157, 0x015B, 0x015D, 0x0161, 0x015F,
   0x0165, 0x0163, 0x00FA, 0x00F9, 0x00FC, 0x00FB, 0x016D, 0x01D4,
   0x0171, 0x016B, 0x0173, 0x016F, 0x0169, 0x01D8, 0x01DC, 0x01DA,
   0x01D6, 0x0175, 0x00FD, 0x00FF, 0x0177, 0x017A, 0x017E, 0x017C,
   0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
-  /* index 9776 */
+  /* index 9212 */
           0x4E02, 0x4E04, 0x4E05, 0x4E0C, 0x4E12, 0x4E1F, 0x4E23,
   0x4E24, 0x4E28, 0x4E2B, 0x4E2E, 0x4E2F, 0x4E30, 0x4E35, 0x4E40,
   0x4E41, 0x4E44, 0x4E47, 0x4E51, 0x4E5A, 0x4E5C, 0x4E63, 0x4E68,
   0x4E69, 0x4E74, 0x4E75, 0x4E79, 0x4E7F, 0x4E8D, 0x4E96, 0x4E97,
   0x4E9D, 0x4EAF, 0x4EB9, 0x4EC3, 0x4ED0, 0x4EDA, 0x4EDB, 0x4EE0,
   0x4EE1, 0x4EE2, 0x4EE8, 0x4EEF, 0x4EF1, 0x4EF3, 0x4EF5, 0x4EFD,
   0x4EFE, 0x4EFF, 0x4F00, 0x4F02, 0x4F03, 0x4F08, 0x4F0B, 0x4F0C,
   0x4F12, 0x4F15, 0x4F16, 0x4F17, 0x4F19, 0x4F2E, 0x4F31, 0x4F60,
   0x4F33, 0x4F35, 0x4F37, 0x4F39, 0x4F3B, 0x4F3E, 0x4F40, 0x4F42,
   0x4F48, 0x4F49, 0x4F4B, 0x4F4C, 0x4F52, 0x4F54, 0x4F56, 0x4F58,
   0x4F5F, 0x4F63, 0x4F6A, 0x4F6C, 0x4F6E, 0x4F71, 0x4F77, 0x4F78,
   0x4F79, 0x4F7A, 0x4F7D, 0x4F7E, 0x4F81, 0x4F82, 0x4F84,
-  /* index 9870 */
+  /* index 9306 */
           0x4F85, 0x4F89, 0x4F8A, 0x4F8C, 0x4F8E, 0x4F90, 0x4F92,
   0x4F93, 0x4F94, 0x4F97, 0x4F99, 0x4F9A, 0x4F9E, 0x4F9F, 0x4FB2,
   0x4FB7, 0x4FB9, 0x4FBB, 0x4FBC, 0x4FBD, 0x4FBE, 0x4FC0, 0x4FC1,
   0x4FC5, 0x4FC6, 0x4FC8, 0x4FC9, 0x4FCB, 0x4FCC, 0x4FCD, 0x4FCF,
   0x4FD2, 0x4FDC, 0x4FE0, 0x4FE2, 0x4FF0, 0x4FF2, 0x4FFC, 0x4FFD,
   0x4FFF, 0x5000, 0x5001, 0x5004, 0x5007, 0x500A, 0x500C, 0x500E,
   0x5010, 0x5013, 0x5017, 0x5018, 0x501B, 0x501C, 0x501D, 0x501E,
   0x5022, 0x5027, 0x502E, 0x5030, 0x5032, 0x5033, 0x5035, 0x5040,
   0x5041, 0x5042, 0x5045, 0x5046, 0x504A, 0x504C, 0x504E, 0x5051,
   0x5052, 0x5053, 0x5057, 0x5059, 0x505F, 0x5060, 0x5062, 0x5063,
   0x5066, 0x5067, 0x506A, 0x506D, 0x5070, 0x5071, 0x503B, 0x5081,
   0x5083, 0x5084, 0x5086, 0x508A, 0x508E, 0x508F, 0x5090,
-  /* index 9964 */
+  /* index 9400 */
           0x5092, 0x5093, 0x5094, 0x5096, 0x509B, 0x509C, 0x509E,
   0x509F, 0x50A0, 0x50A1, 0x50A2, 0x50AA, 0x50AF, 0x50B0, 0x50B9,
   0x50BA, 0x50BD, 0x50C0, 0x50C3, 0x50C4, 0x50C7, 0x50CC, 0x50CE,
   0x50D0, 0x50D3, 0x50D4, 0x50D8, 0x50DC, 0x50DD, 0x50DF, 0x50E2,
   0x50E4, 0x50E6, 0x50E8, 0x50E9, 0x50EF, 0x50F1, 0x50F6, 0x50FA,
   0x50FE, 0x5103, 0x5106, 0x5107, 0x5108, 0x510B, 0x510C, 0x510D,
   0x510E, 0x50F2, 0x5110, 0x5117, 0x5119, 0x511B, 0x511C, 0x511D,
   0x511E, 0x5123, 0x5127, 0x5128, 0x512C, 0x512D, 0x512F, 0x5131,
   0x5133, 0x5134, 0x5135, 0x5138, 0x5139, 0x5142, 0x514A, 0x514F,
   0x5153, 0x5155, 0x5157, 0x5158, 0x515F, 0x5164, 0x5166, 0x517E,
   0x5183, 0x5184, 0x518B, 0x518E, 0x5198, 0x519D, 0x51A1, 0x51A3,
   0x51AD, 0x51B8, 0x51BA, 0x51BC, 0x51BE, 0x51BF, 0x51C2,
-  /* index 10058 */
+  /* index 9494 */
           0x51C8, 0x51CF, 0x51D1, 0x51D2, 0x51D3, 0x51D5, 0x51D8,
   0x51DE, 0x51E2, 0x51E5, 0x51EE, 0x51F2, 0x51F3, 0x51F4, 0x51F7,
   0x5201, 0x5202, 0x5205, 0x5212, 0x5213, 0x5215, 0x5216, 0x5218,
   0x5222, 0x5228, 0x5231, 0x5232, 0x5235, 0x523C, 0x5245, 0x5249,
   0x5255, 0x5257, 0x5258, 0x525A, 0x525C, 0x525F, 0x5260, 0x5261,
   0x5266, 0x526E, 0x5277, 0x5278, 0x5279, 0x5280, 0x5282, 0x5285,
   0x528A, 0x528C, 0x5293, 0x5295, 0x5296, 0x5297, 0x5298, 0x529A,
   0x529C, 0x52A4, 0x52A5, 0x52A6, 0x52A7, 0x52AF, 0x52B0, 0x52B6,
   0x52B7, 0x52B8, 0x52BA, 0x52BB, 0x52BD, 0x52C0, 0x52C4, 0x52C6,
   0x52C8, 0x52CC, 0x52CF, 0x52D1, 0x52D4, 0x52D6, 0x52DB, 0x52DC,
   0x52E1, 0x52E5, 0x52E8, 0x52E9, 0x52EA, 0x52EC, 0x52F0, 0x52F1,
   0x52F4, 0x52F6, 0x52F7, 0x5300, 0x5303, 0x530A, 0x530B,
-  /* index 10152 */
+  /* index 9588 */
           0x530C, 0x5311, 0x5313, 0x5318, 0x531B, 0x531C, 0x531E,
   0x531F, 0x5325, 0x5327, 0x5328, 0x5329, 0x532B, 0x532C, 0x532D,
   0x5330, 0x5332, 0x5335, 0x533C, 0x533D, 0x533E, 0x5342, 0x534C,
   0x534B, 0x5359, 0x535B, 0x5361, 0x5363, 0x5365, 0x536C, 0x536D,
   0x5372, 0x5379, 0x537E, 0x5383, 0x5387, 0x5388, 0x538E, 0x5393,
   0x5394, 0x5399, 0x539D, 0x53A1, 0x53A4, 0x53AA, 0x53AB, 0x53AF,
   0x53B2, 0x53B4, 0x53B5, 0x53B7, 0x53B8, 0x53BA, 0x53BD, 0x53C0,
   0x53C5, 0x53CF, 0x53D2, 0x53D3, 0x53D5, 0x53DA, 0x53DD, 0x53DE,
   0x53E0, 0x53E6, 0x53E7, 0x53F5, 0x5402, 0x5413, 0x541A, 0x5421,
   0x5427, 0x5428, 0x542A, 0x542F, 0x5431, 0x5434, 0x5435, 0x5443,
   0x5444, 0x5447, 0x544D, 0x544F, 0x545E, 0x5462, 0x5464, 0x5466,
   0x5467, 0x5469, 0x546B, 0x546D, 0x546E, 0x5474, 0x547F,
-  /* index 10246 */
+  /* index 9682 */
           0x5481, 0x5483, 0x5485, 0x5488, 0x5489, 0x548D, 0x5491,
   0x5495, 0x5496, 0x549C, 0x549F, 0x54A1, 0x54A6, 0x54A7, 0x54A9,
   0x54AA, 0x54AD, 0x54AE, 0x54B1, 0x54B7, 0x54B9, 0x54BA, 0x54BB,
   0x54BF, 0x54C6, 0x54CA, 0x54CD, 0x54CE, 0x54E0, 0x54EA, 0x54EC,
   0x54EF, 0x54F6, 0x54FC, 0x54FE, 0x54FF, 0x5500, 0x5501, 0x5505,
   0x5508, 0x5509, 0x550C, 0x550D, 0x550E, 0x5515, 0x552A, 0x552B,
   0x5532, 0x5535, 0x5536, 0x553B, 0x553C, 0x553D, 0x5541, 0x5547,
   0x5549, 0x554A, 0x554D, 0x5550, 0x5551, 0x5558, 0x555A, 0x555B,
   0x555E, 0x5560, 0x5561, 0x5564, 0x5566, 0x557F, 0x5581, 0x5582,
   0x5586, 0x5588, 0x558E, 0x558F, 0x5591, 0x5592, 0x5593, 0x5594,
   0x5597, 0x55A3, 0x55A4, 0x55AD, 0x55B2, 0x55BF, 0x55C1, 0x55C3,
   0x55C6, 0x55C9, 0x55CB, 0x55CC, 0x55CE, 0x55D1, 0x55D2,
-  /* index 10340 */
+  /* index 9776 */
           0x55D3, 0x55D7, 0x55D8, 0x55DB, 0x55DE, 0x55E2, 0x55E9,
   0x55F6, 0x55FF, 0x5605, 0x5608, 0x560A, 0x560D, 0x560E, 0x560F,
   0x5610, 0x5611, 0x5612, 0x5619, 0x562C, 0x5630, 0x5633, 0x5635,
   0x5637, 0x5639, 0x563B, 0x563C, 0x563D, 0x563F, 0x5640, 0x5641,
   0x5643, 0x5644, 0x5646, 0x5649, 0x564B, 0x564D, 0x564F, 0x5654,
   0x565E, 0x5660, 0x5661, 0x5662, 0x5663, 0x5666, 0x5669, 0x566D,
   0x566F, 0x5671, 0x5672, 0x5675, 0x5684, 0x5685, 0x5688, 0x568B,
   0x568C, 0x5695, 0x5699, 0x569A, 0x569D, 0x569E, 0x569F, 0x56A6,
   0x56A7, 0x56A8, 0x56A9, 0x56AB, 0x56AC, 0x56AD, 0x56B1, 0x56B3,
   0x56B7, 0x56BE, 0x56C5, 0x56C9, 0x56CA, 0x56CB, 0x56CF, 0x56D0,
   0x56CC, 0x56CD, 0x56D9, 0x56DC, 0x56DD, 0x56DF, 0x56E1, 0x56E4,
   0x56E5, 0x56E6, 0x56E7, 0x56E8, 0x56F1, 0x56EB, 0x56ED,
-  /* index 10434 */
+  /* index 9870 */
           0x56F6, 0x56F7, 0x5701, 0x5702, 0x5707, 0x570A, 0x570C,
   0x5711, 0x5715, 0x571A, 0x571B, 0x571D, 0x5720, 0x5722, 0x5723,
   0x5724, 0x5725, 0x5729, 0x572A, 0x572C, 0x572E, 0x572F, 0x5733,
   0x5734, 0x573D, 0x573E, 0x573F, 0x5745, 0x5746, 0x574C, 0x574D,
   0x5752, 0x5762, 0x5765, 0x5767, 0x5768, 0x576B, 0x576D, 0x576E,
   0x576F, 0x5770, 0x5771, 0x5773, 0x5774, 0x5775, 0x5777, 0x5779,
   0x577A, 0x577B, 0x577C, 0x577E, 0x5781, 0x5783, 0x578C, 0x5794,
   0x5797, 0x5799, 0x579A, 0x579C, 0x579D, 0x579E, 0x579F, 0x57A1,
   0x5795, 0x57A7, 0x57A8, 0x57A9, 0x57AC, 0x57B8, 0x57BD, 0x57C7,
   0x57C8, 0x57CC, 0x57CF, 0x57D5, 0x57DD, 0x57DE, 0x57E4, 0x57E6,
   0x57E7, 0x57E9, 0x57ED, 0x57F0, 0x57F5, 0x57F6, 0x57F8, 0x57FD,
   0x57FE, 0x57FF, 0x5803, 0x5804, 0x5808, 0x5809, 0x57E1,
-  /* index 10528 */
+  /* index 9964 */
           0x580C, 0x580D, 0x581B, 0x581E, 0x581F, 0x5820, 0x5826,
   0x5827, 0x582D, 0x5832, 0x5839, 0x583F, 0x5849, 0x584C, 0x584D,
   0x584F, 0x5850, 0x5855, 0x585F, 0x5861, 0x5864, 0x5867, 0x5868,
   0x5878, 0x587C, 0x587F, 0x5880, 0x5881, 0x5887, 0x5888, 0x5889,
   0x588A, 0x588C, 0x588D, 0x588F, 0x5890, 0x5894, 0x5896, 0x589D,
   0x58A0, 0x58A1, 0x58A2, 0x58A6, 0x58A9, 0x58B1, 0x58B2, 0x58C4,
   0x58BC, 0x58C2, 0x58C8, 0x58CD, 0x58CE, 0x58D0, 0x58D2, 0x58D4,
   0x58D6, 0x58DA, 0x58DD, 0x58E1, 0x58E2, 0x58E9, 0x58F3, 0x5905,
   0x5906, 0x590B, 0x590C, 0x5912, 0x5913, 0x5914, 0x8641, 0x591D,
   0x5921, 0x5923, 0x5924, 0x5928, 0x592F, 0x5930, 0x5933, 0x5935,
   0x5936, 0x593F, 0x5943, 0x5946, 0x5952, 0x5953, 0x5959, 0x595B,
   0x595D, 0x595E, 0x595F, 0x5961, 0x5963, 0x596B, 0x596D,
-  /* index 10622 */
+  /* index 10058 */
           0x596F, 0x5972, 0x5975, 0x5976, 0x5979, 0x597B, 0x597C,
   0x598B, 0x598C, 0x598E, 0x5992, 0x5995, 0x5997, 0x599F, 0x59A4,
   0x59A7, 0x59AD, 0x59AE, 0x59AF, 0x59B0, 0x59B3, 0x59B7, 0x59BA,
   0x59BC, 0x59C1, 0x59C3, 0x59C4, 0x59C8, 0x59CA, 0x59CD, 0x59D2,
   0x59DD, 0x59DE, 0x59DF, 0x59E3, 0x59E4, 0x59E7, 0x59EE, 0x59EF,
   0x59F1, 0x59F2, 0x59F4, 0x59F7, 0x5A00, 0x5A04, 0x5A0C, 0x5A0D,
   0x5A0E, 0x5A12, 0x5A13, 0x5A1E, 0x5A23, 0x5A24, 0x5A27, 0x5A28,
   0x5A2A, 0x5A2D, 0x5A30, 0x5A44, 0x5A45, 0x5A47, 0x5A48, 0x5A4C,
   0x5A50, 0x5A55, 0x5A5E, 0x5A63, 0x5A65, 0x5A67, 0x5A6D, 0x5A77,
   0x5A7A, 0x5A7B, 0x5A7E, 0x5A8B, 0x5A90, 0x5A93, 0x5A96, 0x5A99,
   0x5A9C, 0x5A9E, 0x5A9F, 0x5AA0, 0x5AA2, 0x5AA7, 0x5AAC, 0x5AB1,
   0x5AB2, 0x5AB3, 0x5AB5, 0x5AB8, 0x5ABA, 0x5ABB, 0x5ABF,
-  /* index 10716 */
+  /* index 10152 */
           0x5AC4, 0x5AC6, 0x5AC8, 0x5ACF, 0x5ADA, 0x5ADC, 0x5AE0,
   0x5AE5, 0x5AEA, 0x5AEE, 0x5AF5, 0x5AF6, 0x5AFD, 0x5B00, 0x5B01,
   0x5B08, 0x5B17, 0x5B34, 0x5B19, 0x5B1B, 0x5B1D, 0x5B21, 0x5B25,
   0x5B2D, 0x5B38, 0x5B41, 0x5B4B, 0x5B4C, 0x5B52, 0x5B56, 0x5B5E,
   0x5B68, 0x5B6E, 0x5B6F, 0x5B7C, 0x5B7D, 0x5B7E, 0x5B7F, 0x5B81,
   0x5B84, 0x5B86, 0x5B8A, 0x5B8E, 0x5B90, 0x5B91, 0x5B93, 0x5B94,
   0x5B96, 0x5BA8, 0x5BA9, 0x5BAC, 0x5BAD, 0x5BAF, 0x5BB1, 0x5BB2,
   0x5BB7, 0x5BBA, 0x5BBC, 0x5BC0, 0x5BC1, 0x5BCD, 0x5BCF, 0x5BD6,
   0x5BD7, 0x5BD8, 0x5BD9, 0x5BDA, 0x5BE0, 0x5BEF, 0x5BF1, 0x5BF4,
   0x5BFD, 0x5C0C, 0x5C17, 0x5C1E, 0x5C1F, 0x5C23, 0x5C26, 0x5C29,
   0x5C2B, 0x5C2C, 0x5C2E, 0x5C30, 0x5C32, 0x5C35, 0x5C36, 0x5C59,
   0x5C5A, 0x5C5C, 0x5C62, 0x5C63, 0x5C67, 0x5C68, 0x5C69,
-  /* index 10810 */
+  /* index 10246 */
           0x5C6D, 0x5C70, 0x5C74, 0x5C75, 0x5C7A, 0x5C7B, 0x5C7C,
   0x5C7D, 0x5C87, 0x5C88, 0x5C8A, 0x5C8F, 0x5C92, 0x5C9D, 0x5C9F,
   0x5CA0, 0x5CA2, 0x5CA3, 0x5CA6, 0x5CAA, 0x5CB2, 0x5CB4, 0x5CB5,
   0x5CBA, 0x5CC9, 0x5CCB, 0x5CD2, 0x5CDD, 0x5CD7, 0x5CEE, 0x5CF1,
   0x5CF2, 0x5CF4, 0x5D01, 0x5D06, 0x5D0D, 0x5D12, 0x5D2B, 0x5D23,
   0x5D24, 0x5D26, 0x5D27, 0x5D31, 0x5D34, 0x5D39, 0x5D3D, 0x5D3F,
   0x5D42, 0x5D43, 0x5D46, 0x5D48, 0x5D55, 0x5D51, 0x5D59, 0x5D4A,
   0x5D5F, 0x5D60, 0x5D61, 0x5D62, 0x5D64, 0x5D6A, 0x5D6D, 0x5D70,
   0x5D79, 0x5D7A, 0x5D7E, 0x5D7F, 0x5D81, 0x5D83, 0x5D88, 0x5D8A,
   0x5D92, 0x5D93, 0x5D94, 0x5D95, 0x5D99, 0x5D9B, 0x5D9F, 0x5DA0,
   0x5DA7, 0x5DAB, 0x5DB0, 0x5DB4, 0x5DB8, 0x5DB9, 0x5DC3, 0x5DC7,
   0x5DCB, 0x5DD0, 0x5DCE, 0x5DD8, 0x5DD9, 0x5DE0, 0x5DE4,
-  /* index 10904 */
+  /* index 10340 */
           0x5DE9, 0x5DF8, 0x5DF9, 0x5E00, 0x5E07, 0x5E0D, 0x5E12,
   0x5E14, 0x5E15, 0x5E18, 0x5E1F, 0x5E20, 0x5E2E, 0x5E28, 0x5E32,
   0x5E35, 0x5E3E, 0x5E4B, 0x5E50, 0x5E49, 0x5E51, 0x5E56, 0x5E58,
   0x5E5B, 0x5E5C, 0x5E5E, 0x5E68, 0x5E6A, 0x5E6B, 0x5E6C, 0x5E6D,
   0x5E6E, 0x5E70, 0x5E80, 0x5E8B, 0x5E8E, 0x5EA2, 0x5EA4, 0x5EA5,
   0x5EA8, 0x5EAA, 0x5EAC, 0x5EB1, 0x5EB3, 0x5EBD, 0x5EBE, 0x5EBF,
   0x5EC6, 0x5ECC, 0x5ECB, 0x5ECE, 0x5ED1, 0x5ED2, 0x5ED4, 0x5ED5,
   0x5EDC, 0x5EDE, 0x5EE5, 0x5EEB, 0x5F02, 0x5F06, 0x5F07, 0x5F08,
   0x5F0E, 0x5F19, 0x5F1C, 0x5F1D, 0x5F21, 0x5F22, 0x5F23, 0x5F24,
   0x5F28, 0x5F2B, 0x5F2C, 0x5F2E, 0x5F30, 0x5F34, 0x5F36, 0x5F3B,
   0x5F3D, 0x5F3F, 0x5F40, 0x5F44, 0x5F45, 0x5F47, 0x5F4D, 0x5F50,
   0x5F54, 0x5F58, 0x5F5B, 0x5F60, 0x5F63, 0x5F64, 0x5F67,
-  /* index 10998 */
+  /* index 10434 */
           0x5F6F, 0x5F72, 0x5F74, 0x5F75, 0x5F78, 0x5F7A, 0x5F7D,
   0x5F7E, 0x5F89, 0x5F8D, 0x5F8F, 0x5F96, 0x5F9C, 0x5F9D, 0x5FA2,
   0x5FA7, 0x5FAB, 0x5FA4, 0x5FAC, 0x5FAF, 0x5FB0, 0x5FB1, 0x5FB8,
   0x5FC4, 0x5FC7, 0x5FC8, 0x5FC9, 0x5FCB, 0x5FD0, 0x5FD1, 0x5FD2,
   0x5FD3, 0x5FD4, 0x5FDE, 0x5FE1, 0x5FE2, 0x5FE8, 0x5FE9, 0x5FEA,
   0x5FEC, 0x5FED, 0x5FEE, 0x5FEF, 0x5FF2, 0x5FF3, 0x5FF6, 0x5FFA,
   0x5FFC, 0x6007, 0x600A, 0x600D, 0x6013, 0x6014, 0x6017, 0x6018,
   0x601A, 0x601F, 0x6024, 0x602D, 0x6033, 0x6035, 0x6040, 0x6047,
   0x6048, 0x6049, 0x604C, 0x6051, 0x6054, 0x6056, 0x6057, 0x605D,
   0x6061, 0x6067, 0x6071, 0x607E, 0x607F, 0x6082, 0x6086, 0x6088,
   0x608A, 0x608E, 0x6091, 0x6093, 0x6095, 0x6098, 0x609D, 0x609E,
   0x60A2, 0x60A4, 0x60A5, 0x60A8, 0x60B0, 0x60B1, 0x60B7,
-  /* index 11092 */
+  /* index 10528 */
           0x60BB, 0x60BE, 0x60C2, 0x60C4, 0x60C8, 0x60C9, 0x60CA,
   0x60CB, 0x60CE, 0x60CF, 0x60D4, 0x60D5, 0x60D9, 0x60DB, 0x60DD,
   0x60DE, 0x60E2, 0x60E5, 0x60F2, 0x60F5, 0x60F8, 0x60FC, 0x60FD,
   0x6102, 0x6107, 0x610A, 0x610C, 0x6110, 0x6111, 0x6112, 0x6113,
   0x6114, 0x6116, 0x6117, 0x6119, 0x611C, 0x611E, 0x6122, 0x612A,
   0x612B, 0x6130, 0x6131, 0x6135, 0x6136, 0x6137, 0x6139, 0x6141,
   0x6145, 0x6146, 0x6149, 0x615E, 0x6160, 0x616C, 0x6172, 0x6178,
   0x617B, 0x617C, 0x617F, 0x6180, 0x6181, 0x6183, 0x6184, 0x618B,
   0x618D, 0x6192, 0x6193, 0x6197, 0x6198, 0x619C, 0x619D, 0x619F,
   0x61A0, 0x61A5, 0x61A8, 0x61AA, 0x61AD, 0x61B8, 0x61B9, 0x61BC,
   0x61C0, 0x61C1, 0x61C2, 0x61CE, 0x61CF, 0x61D5, 0x61DC, 0x61DD,
   0x61DE, 0x61DF, 0x61E1, 0x61E2, 0x61E7, 0x61E9, 0x61E5,
-  /* index 11186 */
+  /* index 10622 */
           0x61EC, 0x61ED, 0x61EF, 0x6201, 0x6203, 0x6204, 0x6207,
   0x6213, 0x6215, 0x621C, 0x6220, 0x6222, 0x6223, 0x6227, 0x6229,
   0x622B, 0x6239, 0x623D, 0x6242, 0x6243, 0x6244, 0x6246, 0x624C,
   0x6250, 0x6251, 0x6252, 0x6254, 0x6256, 0x625A, 0x625C, 0x6264,
   0x626D, 0x626F, 0x6273, 0x627A, 0x627D, 0x628D, 0x628E, 0x628F,
   0x6290, 0x62A6, 0x62A8, 0x62B3, 0x62B6, 0x62B7, 0x62BA, 0x62BE,
   0x62BF, 0x62C4, 0x62CE, 0x62D5, 0x62D6, 0x62DA, 0x62EA, 0x62F2,
   0x62F4, 0x62FC, 0x62FD, 0x6303, 0x6304, 0x630A, 0x630B, 0x630D,
   0x6310, 0x6313, 0x6316, 0x6318, 0x6329, 0x632A, 0x632D, 0x6335,
   0x6336, 0x6339, 0x633C, 0x6341, 0x6342, 0x6343, 0x6344, 0x6346,