merge fx-team to m-c
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Thu, 05 Dec 2013 12:56:11 +0100
changeset 174539 632ee65fb67f1a0a5a137cb6732f45b93a2b6014
parent 174519 056164bcce96df11121687fd95fa2e149774773a (current diff)
parent 174538 9473d7b659e93b64eadd131541c2666c08b78920 (diff)
child 174540 2878c8b89da3b41c7b64bd1ace1afab614bfff80
child 174572 118234ab24ed153d6aa2ee0fc03493a9509b8d7d
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone28.0a1
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 fx-team to m-c
browser/devtools/framework/toolbox.css
browser/themes/linux/devtools/common.css
browser/themes/linux/devtools/toolbox.css
browser/themes/osx/devtools/common.css
browser/themes/osx/devtools/toolbox.css
browser/themes/shared/devtools/common.inc.css
browser/themes/windows/devtools/common.css
browser/themes/windows/devtools/toolbox.css
mobile/android/base/tests/testAwesomebarSwipes.java
mobile/android/base/tests/testTabHistory.java
rename from browser/devtools/framework/toolbox.css
rename to browser/devtools/framework/options-panel.css
--- a/browser/devtools/framework/toolbox.css
+++ b/browser/devtools/framework/options-panel.css
@@ -1,23 +1,12 @@
 /* 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/. */
 
-.devtools-tab {
-  -moz-binding: url("chrome://global/content/bindings/general.xml#control-item");
-  -moz-box-align: center;
-}
-
-#toolbox-controls > toolbarbutton > .toolbarbutton-text,
-#toolbox-dock-buttons > toolbarbutton > .toolbarbutton-text,
-.command-button > .toolbarbutton-text {
-  display: none;
-}
-
 #options-panel-container {
   overflow: auto;
 }
 
 #options-panel {
   overflow-y: auto;
   display: block;
 }
@@ -25,8 +14,46 @@
 .options-vertical-pane {
   display: inline;
   float: left;
 }
 
 .options-vertical-pane > label {
   display: block;
 }
+
+.options-vertical-pane {
+  margin: 5px;
+  width: calc(50% - 30px);
+  min-width: 400px;
+  -moz-padding-start: 5px;
+}
+
+.options-vertical-pane > label {
+  padding: 2px 0;
+  font-size: 1.4rem;
+}
+
+.options-groupbox {
+  -moz-margin-start: 15px;
+  padding: 2px;
+}
+
+.options-groupbox > * {
+  padding: 2px;
+}
+
+.options-citation-label {
+  font-size: 1rem !important;
+  /* !important is required otherwise font-size will still be 1.4rem */
+  font-style: italic;
+  padding: 4px 0 0; /* To align it with the checkbox */
+}
+
+.options-citation-label + label {
+  padding: 3px 0 0 !important; /* To align it with the checkbox */
+  font-style: italic;
+}
+
+.hidden-labels-box:not(.visible) > label,
+.hidden-labels-box.visible ~ .hidden-labels-box > label:last-child {
+  display: none;
+}
--- a/browser/devtools/framework/toolbox-options.xul
+++ b/browser/devtools/framework/toolbox-options.xul
@@ -2,18 +2,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/. -->
 <!DOCTYPE window [
 <!ENTITY % toolboxDTD SYSTEM "chrome://browser/locale/devtools/toolbox.dtd" >
  %toolboxDTD;
 ]>
 <?xml-stylesheet href="chrome://browser/skin/" type="text/css"?>
-<?xml-stylesheet rel="stylesheet" href="chrome://browser/content/devtools/framework/toolbox.css" type="text/css"?>
-<?xml-stylesheet rel="stylesheet" href="chrome://browser/skin/devtools/toolbox.css" type="text/css"?>
+<?xml-stylesheet rel="stylesheet" href="chrome://browser/content/devtools/framework/options-panel.css" type="text/css"?>
 
 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
   <script type="application/javascript;version=1.8"
           src="chrome://browser/content/devtools/theme-switching.js"/>
   <hbox id="options-panel-container" flex="1">
     <hbox id="options-panel" class="theme-body" flex="1">
       <vbox id="tools-box" class="options-vertical-pane" flex="1">
--- a/browser/devtools/framework/toolbox.xul
+++ b/browser/devtools/framework/toolbox.xul
@@ -2,19 +2,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/. -->
 <!DOCTYPE window [
 <!ENTITY % toolboxDTD SYSTEM "chrome://browser/locale/devtools/toolbox.dtd" >
  %toolboxDTD;
 ]>
 <?xml-stylesheet href="chrome://browser/skin/" type="text/css"?>
-<?xml-stylesheet href="chrome://browser/content/devtools/framework/toolbox.css" type="text/css"?>
 <?xml-stylesheet href="chrome://browser/skin/devtools/common.css" type="text/css"?>
-<?xml-stylesheet href="chrome://browser/skin/devtools/toolbox.css" type="text/css"?>
 <?xul-overlay href="chrome://global/content/editMenuOverlay.xul"?>
 
 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
   <script type="application/javascript;version=1.8"
           src="chrome://browser/content/devtools/theme-switching.js"/>
   <script type="application/javascript" src="chrome://global/content/globalOverlay.js"/>
 
--- a/browser/devtools/jar.mn
+++ b/browser/devtools/jar.mn
@@ -70,17 +70,17 @@ browser.jar:
     content/browser/devtools/profiler/cleopatra/images/treetwisty.svg  (profiler/cleopatra/images/treetwisty.svg)
     content/browser/devtools/commandline.css                           (commandline/commandline.css)
     content/browser/devtools/commandlineoutput.xhtml                   (commandline/commandlineoutput.xhtml)
     content/browser/devtools/commandlinetooltip.xhtml                  (commandline/commandlinetooltip.xhtml)
     content/browser/devtools/framework/toolbox-window.xul              (framework/toolbox-window.xul)
     content/browser/devtools/framework/toolbox-options.xul             (framework/toolbox-options.xul)
     content/browser/devtools/framework/toolbox-options.js              (framework/toolbox-options.js)
 *   content/browser/devtools/framework/toolbox.xul                     (framework/toolbox.xul)
-    content/browser/devtools/framework/toolbox.css                     (framework/toolbox.css)
+    content/browser/devtools/framework/options-panel.css               (framework/options-panel.css)
     content/browser/devtools/framework/toolbox-process-window.xul      (framework/toolbox-process-window.xul)
     content/browser/devtools/framework/toolbox-process-window.js       (framework/toolbox-process-window.js)
     content/browser/devtools/inspector/inspector.xul                   (inspector/inspector.xul)
     content/browser/devtools/inspector/inspector.css                   (inspector/inspector.css)
     content/browser/devtools/connect.xhtml                             (framework/connect/connect.xhtml)
     content/browser/devtools/connect.css                               (framework/connect/connect.css)
     content/browser/devtools/connect.js                                (framework/connect/connect.js)
     content/browser/devtools/app-manager/template.js                   (app-manager/content/template.js)
--- a/browser/devtools/responsivedesign/responsivedesign.jsm
+++ b/browser/devtools/responsivedesign/responsivedesign.jsm
@@ -198,17 +198,17 @@ function ResponsiveUI(aWindow, aTab)
     switchToFloatingScrollbars(this.tab);
 
   this.tab.__responsiveUI = this;
 
   this._telemetry.toolOpened("responsive");
 
   // Touch events support
   this.touchEnableBefore = false;
-  this.touchEventHandler = new TouchEventHandler(this.browser.contentWindow);
+  this.touchEventHandler = new TouchEventHandler(this.browser);
 
   this.browser.addEventListener("load", this.bound_onPageLoad, true);
   this.browser.addEventListener("unload", this.bound_onPageUnload, true);
 
   if (this.browser.contentWindow.document &&
       this.browser.contentWindow.document.readyState == "complete") {
     this.onPageLoad();
   }
@@ -227,17 +227,17 @@ ResponsiveUI.prototype = {
       this.stack.setAttribute("notransition", "true");
     }
   },
 
   /**
    * Window onload / onunload
    */
    onPageLoad: function() {
-     this.touchEventHandler = new TouchEventHandler(this.browser.contentWindow);
+     this.touchEventHandler = new TouchEventHandler(this.browser);
      if (this.touchEnableBefore) {
        this.enableTouch();
      }
    },
 
    onPageUnload: function() {
      if (this.closing)
        return;
--- a/browser/metro/base/content/browser.xul
+++ b/browser/metro/base/content/browser.xul
@@ -271,17 +271,17 @@ Desktop browser's sync prefs.
               <toolbarbutton id="pin-button" class="appbar-primary"
                              type="checkbox"
                              oncommand="Appbar.onPinButton()"/>
               <toolbarbutton id="menu-button" class="appbar-primary"
                              oncommand="Appbar.onMenuButton(event)"/>
             </hbox>
 
             <hbox id="toolbar-context-autocomplete" pack="end">
-              <toolbarbutton id="close-button" class="appbar-secondary"
+              <toolbarbutton id="close-button" class="appbar-primary"
                              oncommand="Appbar.onAutocompleteCloseButton()"/>
             </hbox>
           </stack>
         </toolbar>
       </vbox>
     </appbar>
 
     <vbox id="panel-container" class="window-width window-height meta"
@@ -357,29 +357,32 @@ Desktop browser's sync prefs.
 
       <toolbarbutton id="findbar-close-button" class="appbar-secondary"
                      command="cmd_findClose"/>
     </appbar>
 
     <!-- Context button bar -->
     <appbar id="contextappbar">
       <toolbar id="contextualactions-tray" labelled="true" flex="1">
-        <toolbarbutton id="pin-selected-button" class="appbar-secondary"
+        <toolbarbutton id="pin-selected-button" class="appbar-primary"
                        label-uses-set-name="true" hidden="true" fade="true"
                        oncommand="Appbar.dispatchContextualAction('pin')"/>
-        <toolbarbutton id="unpin-selected-button" class="appbar-secondary"
+        <toolbarbutton id="unpin-selected-button" class="appbar-primary"
                        label-uses-set-name="true" hidden="true" fade="true"
                        oncommand="Appbar.dispatchContextualAction('unpin')"/>
-        <toolbarbutton id="delete-selected-button" class="appbar-secondary"
+        <toolbarbutton id="hide-selected-button" class="appbar-primary"
+                       label-uses-set-name="true" hidden="true" fade="true"
+                       oncommand="Appbar.dispatchContextualAction('unpin')"/>
+        <toolbarbutton id="delete-selected-button" class="appbar-primary"
                        hidden="true" fade="true"
                        oncommand="Appbar.dispatchContextualAction('delete')"/>
-        <toolbarbutton id="restore-selected-button" class="appbar-secondary"
+        <toolbarbutton id="restore-selected-button" class="appbar-primary"
                        hidden="true" fade="true"
                        oncommand="Appbar.dispatchContextualAction('restore')"/>
-        <toolbarbutton id="clear-selected-button" class="appbar-secondary"
+        <toolbarbutton id="clear-selected-button" class="appbar-primary"
                        hidden="true" fade="true"
                        oncommand="Appbar.dispatchContextualAction('clear')"/>
       </toolbar>
     </appbar>
     <autoscroller class="autoscroller" id="autoscrollerid"/>
     <flyoutpanel id="about-flyoutpanel" class="flyout-narrow" headertext="&aboutHeader.title;">
       <label id="about-product-label" linewrap="true" value="&aboutHeader.product.label;"/>
       <label value="&aboutHeader.company.label;" linewrap="true"/>
--- a/browser/metro/base/content/startui/BookmarksView.js
+++ b/browser/metro/base/content/startui/BookmarksView.js
@@ -165,17 +165,17 @@ BookmarksView.prototype = Util.extend(Ob
     let item = this._set.insertItemAt(aPos || index, title, uri.spec, this._inBatch);
     item.setAttribute("anonid", aBookmarkId);
     this._setContextActions(item);
     this._updateFavicon(item, uri);
   },
 
   _setContextActions: function bv__setContextActions(aItem) {
     let itemId = this._getBookmarkIdForItem(aItem);
-    aItem.setAttribute("data-contextactions", "delete," + (this._pinHelper.isPinned(itemId) ? "unpin" : "pin"));
+    aItem.setAttribute("data-contextactions", "delete," + (this._pinHelper.isPinned(itemId) ? "hide" : "pin"));
     if (aItem.refresh) aItem.refresh();
   },
 
   _sendNeedsRefresh: function bv__sendNeedsRefresh(){
     // Event sent when all view instances need to refresh.
     let event = document.createEvent("Events");
     event.initEvent("BookmarksNeedsRefresh", true, false);
     window.dispatchEvent(event);
--- a/browser/metro/base/content/startui/HistoryView.js
+++ b/browser/metro/base/content/startui/HistoryView.js
@@ -102,17 +102,17 @@ HistoryView.prototype = Util.extend(Obje
   addItemToSet: function addItemToSet(aURI, aTitle, aIcon, aPos) {
     let item = this._set.insertItemAt(aPos || 0, aTitle, aURI, this._inBatch);
     this._setContextActions(item);
     this._updateFavicon(item, aURI);
   },
 
   _setContextActions: function bv__setContextActions(aItem) {
     let uri = aItem.getAttribute("value");
-    aItem.setAttribute("data-contextactions", "delete," + (this._pinHelper.isPinned(uri) ? "unpin" : "pin"));
+    aItem.setAttribute("data-contextactions", "delete," + (this._pinHelper.isPinned(uri) ? "hide" : "pin"));
     if ("refresh" in aItem) aItem.refresh();
   },
 
   _sendNeedsRefresh: function bv__sendNeedsRefresh(){
     // Event sent when all views need to refresh.
     let event = document.createEvent("Events");
     event.initEvent("HistoryNeedsRefresh", true, false);
     window.dispatchEvent(event);
--- a/browser/metro/base/tests/mochitest/browser_bookmarks.js
+++ b/browser/metro/base/tests/mochitest/browser_bookmarks.js
@@ -27,66 +27,66 @@ function setup() {
 }
 
 function tearDown() {
   PanelUI.hide();
   BookmarksTestHelper.restore();
 }
 
 gTests.push({
-  desc: "Test bookmarks StartUI unpin",
+  desc: "Test bookmarks StartUI hide",
   setUp: setup,
   tearDown: tearDown,
-  run: function testBookmarksStartUnpin() {
-    let unpinButton = document.getElementById("unpin-selected-button");
+  run: function testBookmarksStartHide() {
+    let hideButton = document.getElementById("hide-selected-button");
 
-    // --------- unpin item 2
+    // --------- hide item 2
 
     let item = gStartView._getItemForBookmarkId(2);
 
     let promise = waitForEvent(Elements.contextappbar, "transitionend", null, Elements.contextappbar);
     sendContextMenuClickToElement(window, item, 10, 10);
     yield promise;
 
-    ok(!unpinButton.hidden, "Unpin button is visible.");
+    ok(!hideButton.hidden, "Hide button is visible.");
 
     let promise = waitForEvent(Elements.contextappbar, "transitionend", null, Elements.contextappbar);
-    unpinButton.click();
+    hideButton.click();
     yield promise;
 
     item = gStartView._getItemForBookmarkId(2);
 
     ok(!item, "Item not in grid");
-    ok(!gStartView._pinHelper.isPinned(2), "Item unpinned");
+    ok(!gStartView._pinHelper.isPinned(2), "Item hidden");
     ok(gStartView._set.itemCount === gStartView._limit, "Grid repopulated");
 
-    // --------- unpin multiple items
+    // --------- hide multiple items
 
     let item1 = gStartView._getItemForBookmarkId(0);
     let item2 = gStartView._getItemForBookmarkId(5);
     let item3 = gStartView._getItemForBookmarkId(12);
 
     let promise = waitForEvent(Elements.contextappbar, "transitionend", null, Elements.contextappbar);
     sendContextMenuClickToElement(window, item1, 10, 10);
     sendContextMenuClickToElement(window, item2, 10, 10);
     sendContextMenuClickToElement(window, item3, 10, 10);
     yield promise;
 
-    ok(!unpinButton.hidden, "Unpin button is visible.");
+    ok(!hideButton.hidden, "Hide button is visible.");
 
     let promise = waitForEvent(Elements.contextappbar, "transitionend", null, Elements.contextappbar);
-    EventUtils.synthesizeMouse(unpinButton, 10, 10, {}, window);
+    EventUtils.synthesizeMouse(hideButton, 10, 10, {}, window);
     yield promise;
 
     item1 = gStartView._getItemForBookmarkId(0);
     item2 = gStartView._getItemForBookmarkId(5);
     item3 = gStartView._getItemForBookmarkId(12);
 
     ok(!item1 && !item2 && !item3, "Items are not in grid");
-    ok(!gStartView._pinHelper.isPinned(0) && !gStartView._pinHelper.isPinned(5) && !gStartView._pinHelper.isPinned(12) , "Items unpinned");
+    ok(!gStartView._pinHelper.isPinned(0) && !gStartView._pinHelper.isPinned(5) && !gStartView._pinHelper.isPinned(12) , "Items hidden");
     ok(gStartView._set.itemCount === gStartView._limit - 1, "Grid repopulated");
   }
 });
 
 gTests.push({
   desc: "Test bookmarks StartUI delete",
   setUp: setup,
   tearDown: tearDown,
--- a/browser/metro/base/tests/mochitest/browser_history.js
+++ b/browser/metro/base/tests/mochitest/browser_history.js
@@ -38,67 +38,67 @@ function tearDown() {
   HistoryTestHelper.restore();
 }
 
 function uriFromIndex(aIndex) {
   return "http://mock-history-" + aIndex + ".com.br/"
 }
 
 gTests.push({
-  desc: "Test history StartUI unpin",
+  desc: "Test history StartUI hide",
   setUp: setup,
   tearDown: tearDown,
-  run: function testHistoryStartUnpin() {
-    let unpinButton = document.getElementById("unpin-selected-button");
+  run: function testHistoryStartHide() {
+    let hideButton = document.getElementById("hide-selected-button");
 
-    // --------- unpin item 2
+    // --------- hide item 2
 
     let item = gStartView._set.getItemsByUrl(uriFromIndex(2))[0];
 
     let promise = waitForEvent(Elements.contextappbar, "transitionend", null, Elements.contextappbar);
     sendContextMenuClickToElement(window, item, 10, 10);
     yield promise;
 
-    ok(!unpinButton.hidden, "Unpin button is visible.");
+    ok(!hideButton.hidden, "Hide button is visible.");
 
     let promise = waitForEvent(Elements.contextappbar, "transitionend", null, Elements.contextappbar);
-    unpinButton.click();
+    hideButton.click();
     yield promise;
 
     item = gStartView._set.getItemsByUrl(uriFromIndex(2))[0];
 
     ok(!item, "Item not in grid");
-    ok(!gStartView._pinHelper.isPinned(uriFromIndex(2)), "Item unpinned");
+    ok(!gStartView._pinHelper.isPinned(uriFromIndex(2)), "Item hidden");
     is(gStartView._set.itemCount, gStartView._limit, "Grid repopulated");
 
-    // --------- unpin multiple items
+    // --------- hide multiple items
 
     let item1 = gStartView._set.getItemsByUrl(uriFromIndex(0))[0];
     let item2 = gStartView._set.getItemsByUrl(uriFromIndex(5))[0];
     let item3 = gStartView._set.getItemsByUrl(uriFromIndex(12))[0];
 
     scrollToEnd();
     let promise = waitForEvent(Elements.contextappbar, "transitionend", null, Elements.contextappbar);
     sendContextMenuClickToElement(window, item1, 10, 10);
     sendContextMenuClickToElement(window, item2, 10, 10);
     sendContextMenuClickToElement(window, item3, 10, 10);
     yield promise;
 
-    ok(!unpinButton.hidden, "Unpin button is visible.");
+    ok(!hideButton.hidden, "Hide button is visible.");
 
     let promise = waitForEvent(Elements.contextappbar, "transitionend", null, Elements.contextappbar);
-    EventUtils.synthesizeMouse(unpinButton, 10, 10, {}, window);
+    EventUtils.synthesizeMouse(hideButton, 10, 10, {}, window);
     yield promise;
 
     item1 = gStartView._set.getItemsByUrl(uriFromIndex(0))[0];
     item2 = gStartView._set.getItemsByUrl(uriFromIndex(5))[0];
     item3 = gStartView._set.getItemsByUrl(uriFromIndex(12))[0];
 
     ok(!item1 && !item2 && !item3, "Items are not in grid");
-    ok(!gStartView._pinHelper.isPinned(uriFromIndex(0)) && !gStartView._pinHelper.isPinned(uriFromIndex(5)) && !gStartView._pinHelper.isPinned(uriFromIndex(12)) , "Items unpinned");
+    ok(!gStartView._pinHelper.isPinned(uriFromIndex(0)) && !gStartView._pinHelper.isPinned(uriFromIndex(5)) && !gStartView._pinHelper.isPinned(uriFromIndex(12)) , "Items hidden");
     ok(gStartView._set.itemCount === gStartView._limit - 1, "Grid repopulated");
   }
 });
 
 gTests.push({
   desc: "Test history StartUI delete",
   setUp: setup,
   tearDown: tearDown,
--- a/browser/metro/locales/en-US/chrome/browser.properties
+++ b/browser/metro/locales/en-US/chrome/browser.properties
@@ -17,18 +17,18 @@ browser.search.contextTextSearchLabel2=S
 # Contextual Appbar - Button Labels
 
 contextAppbar2.pin.topSites=Pin to Top Sites
 contextAppbar2.pin.bookmarks=Pin to Bookmarks
 contextAppbar2.pin.recentHistory=Pin to Recent History
 contextAppbar2.pin.downloads=Pin to Downloads
 
 contextAppbar2.unpin.topSites=Unpin from Top Sites
-contextAppbar2.unpin.bookmarks=Unpin from Bookmarks
-contextAppbar2.unpin.recentHistory=Unpin from Recent History
+contextAppbar2.hide.bookmarks=Hide Bookmark
+contextAppbar2.hide.recentHistory=Hide
 contextAppbar2.unpin.downloads=Unpin from Downloads
 
 # LOCALIZATION NOTE (contextAppbar2.delete): Deletes selected pages.
 contextAppbar2.delete=Delete
 
 # LOCALIZATION NOTE (contextAppbar2.restore): Undoes a previous deletion.
 # Button with this label only appears immediately after a deletion.
 contextAppbar2.restore=Undo delete
--- a/browser/metro/theme/browser.css
+++ b/browser/metro/theme/browser.css
@@ -945,60 +945,89 @@ documenttab[selected] .documenttab-selec
   transition-timing-function: ease-in;
   transition-delay: 80ms;
 }
 #contextualactions-tray > toolbarbutton > .toolbarbutton-text {
   color: white;
 }
 
 #pin-selected-button {
-  -moz-image-region: rect(0px, 240px, 40px, 200px) !important;
-}
-#pin-selected-button:hover {
-  -moz-image-region: rect(40px, 240px, 80px, 200px) !important;
-}
-#pin-selected-button:active {
-  -moz-image-region: rect(80px, 240px, 120px, 200px) !important;
+  list-style-image: url(chrome://browser/skin/images/navbar-contextual-pin.png);
 }
+
 #unpin-selected-button {
-  -moz-image-region: rect(0px, 280px, 40px, 240px) !important;
-}
-#unpin-selected-button:hover {
-  -moz-image-region: rect(40px, 280px, 80px, 240px) !important;
-}
-#unpin-selected-button:active {
-  -moz-image-region: rect(80px, 280px, 120px, 240px) !important;
+  list-style-image: url(chrome://browser/skin/images/navbar-contextual-unpin.png);
 }
-#delete-selected-button {
-  -moz-image-region: rect(0px, 480px, 40px, 440px) !important;
-}
-#delete-selected-button:hover {
-  -moz-image-region: rect(40px, 480px, 80px, 440px) !important;
-}
-#delete-selected-button:active {
-  -moz-image-region: rect(80px, 480px, 120px, 440px) !important;
+
+#hide-selected-button {
+  list-style-image: url(chrome://browser/skin/images/navbar-contextual-hide.png);
 }
-#clear-selected-button {
-  -moz-image-region: rect(0px, 520px, 40px, 480px) !important;
+
+#delete-selected-button {
+  list-style-image: url(chrome://browser/skin/images/navbar-contextual-delete.png);
 }
-#clear-selected-button:hover {
-  -moz-image-region: rect(40px, 520px, 80px, 480px) !important;
-}
-#clear-selected-button:active {
-  -moz-image-region: rect(80px, 520px, 120px, 480px) !important;
+
+#clear-selected-button {
+  list-style-image: url(chrome://browser/skin/images/navbar-contextual-clear.png);
 }
 
 #restore-selected-button {
-  -moz-image-region: rect(0px, 560px, 40px, 520px) !important;
+  list-style-image: url(chrome://browser/skin/images/navbar-contextual-restore.png);
 }
-#restore-selected-button:hover {
-  -moz-image-region: rect(40px, 560px, 80px, 520px) !important;
+
+@media (min-resolution: @min_res_140pc@) {
+  #pin-selected-button {
+    list-style-image: url(chrome://browser/skin/images/navbar-contextual-pin@1.4x.png);
+  }
+
+  #unpin-selected-button {
+    list-style-image: url(chrome://browser/skin/images/navbar-contextual-unpin@1.4x.png);
+  }
+
+  #hide-selected-button {
+    list-style-image: url(chrome://browser/skin/images/navbar-contextual-hide@1.4x.png);
+  }
+
+  #delete-selected-button {
+    list-style-image: url(chrome://browser/skin/images/navbar-contextual-delete@1.4x.png);
+  }
+
+  #clear-selected-button {
+    list-style-image: url(chrome://browser/skin/images/navbar-contextual-clear@1.4x.png);
+  }
+
+  #restore-selected-button {
+    list-style-image: url(chrome://browser/skin/images/navbar-contextual-restore@1.4x.png);
+  }
 }
-#restore-selected-button:active {
-  -moz-image-region: rect(80px, 560px, 120px, 520px) !important;
+
+@media (min-resolution: @min_res_180pc@) {
+  #pin-selected-button {
+    list-style-image: url(chrome://browser/skin/images/navbar-contextual-pin@1.8x.png);
+  }
+
+  #unpin-selected-button {
+    list-style-image: url(chrome://browser/skin/images/navbar-contextual-unpin@1.8x.png);
+  }
+
+  #hide-selected-button {
+    list-style-image: url(chrome://browser/skin/images/navbar-contextual-hide@1.8x.png);
+  }
+
+  #delete-selected-button {
+    list-style-image: url(chrome://browser/skin/images/navbar-contextual-delete@1.8x.png);
+  }
+
+  #clear-selected-button {
+    list-style-image: url(chrome://browser/skin/images/navbar-contextual-clear@1.8x.png);
+  }
+
+  #restore-selected-button {
+    list-style-image: url(chrome://browser/skin/images/navbar-contextual-restore@1.8x.png);
+  }
 }
 
 /* Download notifications ======================================================= */
 
 .download-filename-text {
   font-weight: bold;
 }
 .download-host-text {
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..5ade4c8411e3c837bccf81378ea0f96a1fa14d18
GIT binary patch
literal 1578
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
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..6a3ba29b343720a283117c8df57b630cf7e10ed8
GIT binary patch
literal 2317
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
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..92f78792379e073c91e304017eb1b978193839a5
GIT binary patch
literal 3181
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
TelQQX00000NkvXXu0mjfupJpC
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0ec2a3458995a2d4a3c02b9f4147d80824815a59
GIT binary patch
literal 1254
zc$@*|1R48@P)<h;3K|Lk000e1NJLTq004LZ001Zm1^@s6HR?Vk000E7Nkl<Zc-rlp
zy-yrh6vZDT1-LZ0air9?TUb$Ko&R9m5NH5*w&ir#(!w7Q(m^CxJ9ZmIvX{<sfi3w%
z^18Lf7No?YW5JQ4NWpCE?B=X=imTC(H+N<pcVg|8erRTS_q{VZ%&_lkT(8&5!Z4Tw
zHLwY`!2viT2mEZ4WhR;9lnnIc)Td224}Ji9KpT6^J+EkQpiiYQyTRjN100J6-+}w!
zDwt%MQ8LcY7FcFi<Q=oFvkIYE^tHhg@Do@Bb6}dx@v}9S**DOq3WYwk!QX-Rto$F)
z0N;Wk#RU#Ar@=b<amczoxhj2K&;-li3W(Ccvdhfv2GLi1P+xX~zX0o^!sp;p0T+CU
zburKe+VbZ4^|iqFAj$*lXa&$0Ca6zq@F;l13O?|nUBTRB-TinB&M0!Fz7F^qL<Msf
zbn@v7A3lAFe|bXOdoTrDAg09Q>ru)(Me6$#+y+q~ZnF)&zS9rt^BcU*gadE^xWHUs
zTm4w~l$HAa;8P$9%uTkX&}SCwK7(gi@UPgN8=5J$*`o$WPSSTQ?%d$8tz(5g%a}RI
z;IraRx(?hab4@%sL>C}YUmZlJOkJVRFsLtXu(*Jyz!~vW80bh`-&+tF@z$fSEK!de
z{59yXk9tvUO!COgp0*yg{So|4O>uqQOkJVmJL@207wXfA`m%<sOV*h+s81Ta!e2ZD
z&X`|8kDB88UV+G%mx=mH71T$Ahs7OuIi(3rpp9nAx-W|-z;I08a!M0+fHrng*1epl
zPZw3-bRb6))Yng(6l2Rn0S$hw7}k8poQlxb23G<a{F`D}vz?$Xw87s1ZB+V+HJ;o9
zt|Z)}rkc>V1)`F$71LMNs5$&-@MJ+{f<Byr1?Dt_zBQEz`iK;)#q?zfry^T4oETW2
zD3QSv%xMXIizPC6QR*wP!7V4c5a%*A$aBxJ_JYnar!Dl&XEK=Qo@1@S^HN_<gXMXX
zh~r!axBH1lJQ*#K!6VE$68fe~Wbm}qSA@ZyV~{D1q`@NtgFiom2ao8Gk7#>?+p#ZM
z1_mp>WEmT*|B_{Ia7%WR<_!$ibdy$%4c2#)><w<j209E3Rt$6)8>}Dbus67tFjQ%4
zFg5IYhAPbrriOi~ufzsd;*$+k1A{e_4NJxb>n9uZ{ovQ~IJ3dj=b0`v8Oi#^GhJvs
zlJz1<UkOLDR`O2xH#IX!1{3}}nwcbn3IA%qnI!5<Ub6E9I3u=FEQxsoA|u}XFPH3)
zG0|ziX1wTbEaCTK){E{G`phD(FD`P{df6;BxD%K)UN-C3XCJe^h3^}N3*YN0%5PXK
zd{^nSi+Yx=E0uueRtng<ax0*@w?4bAE94A#EH<Cr2w?8@9GlOiz7Dt(=zne}kG?W)
zK9hV2?ubgB6}Wx$nW*<J+w$aj^=%ipeRMm3z5wCZmqzFe_+4xOe*mf(Hh@=|D>s18
zc=ELRx*QBy%CG@^iMib%`ic(f3;7C%U2q@FfeDrwA>;gP&hQlu`|Q)N{>LjERtK+e
zAml6XV~&@ItgsH3l7YUQ`trO6r~;P6Yk&^H2Xe^IHd&^^9H(TUFQ>kL0hbh0@+uo}
Q_5c6?07*qoM6N<$g4yn1H2?qr
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..6757eaf212c2ce2b434673ac95f54e4cb7623149
GIT binary patch
literal 1931
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
RpzZ(w002ovPDHLkV1oF|uF3!a
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..160fcc54ade4733c0635068d8db047d46f13ddb6
GIT binary patch
literal 2422
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
T1hu`w&kC@y!dcdu```NyWM_qi
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..a40af1cc70ef9ee334b09859a07ba99f79e2024e
GIT binary patch
literal 3185
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
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..a50c1d3c366013263fdba436d1fc3d8a8b7691aa
GIT binary patch
literal 4458
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
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..e9dcd36a8cf103a90676e48bcbe4d572562ae418
GIT binary patch
literal 5746
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
SbmH&7z$OM3`VY>!ME@5`+G3sn
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..4758188a7db0d8bfd87950de7f33afc0077680d0
GIT binary patch
literal 1727
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
VO-F9%0BryO002ovPDHLkV1mn9OpyQp
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..b9a73e233bbad025258bcac593417d65fea00a1a
GIT binary patch
literal 2552
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
O0000<MNUMnLSTXrN8957
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..3d5f886c9ba506bccd16c39a32c1727058863a2e
GIT binary patch
literal 3286
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
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0dca549403d696578eb01cbfdc4d47d66565a40a
GIT binary patch
literal 1798
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
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..ada02175a427aef226e6b39f607f8082dfa2748d
GIT binary patch
literal 2658
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
QPXGV_07*qoM6N<$f|)`sBLDyZ
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..1805719f677814dd6c31fa6bc3627f4baa64bb3d
GIT binary patch
literal 3563
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
LiMDuShQ0qk#cVk1
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..8207196cb49ce1077e012ca3b070081e138fb595
GIT binary patch
literal 1888
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
a-TM#QsoiAODp@}O0000<MNUMnLSTZLd9UjL
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..6645ca6e66355d001e75130789e1e79c19c86bd9
GIT binary patch
literal 2640
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
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..2d884199c1e8a6cf7f65ed9a6ab13ab940192b9e
GIT binary patch
literal 3588
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
--- a/browser/metro/theme/jar.mn
+++ b/browser/metro/theme/jar.mn
@@ -22,16 +22,34 @@ chrome.jar:
 % override chrome://global/skin/about.css chrome://browser/skin/about.css
 % override chrome://global/skin/media/videocontrols.css chrome://browser/skin/touchcontrols.css
 % override chrome://global/skin/netError.css chrome://browser/skin/netError.css
 
   skin/images/panel-dark.png                (images/panel-dark.png)
   skin/images/navbar-back.png               (images/navbar-back.png)
   skin/images/navbar-back@1.4x.png          (images/navbar-back@1.4x.png)
   skin/images/navbar-back@1.8x.png          (images/navbar-back@1.8x.png)
+  skin/images/navbar-contextual-clear.png (images/navbar-contextual-clear.png)
+  skin/images/navbar-contextual-clear@1.4x.png (images/navbar-contextual-clear@1.4x.png)
+  skin/images/navbar-contextual-clear@1.8x.png (images/navbar-contextual-clear@1.8x.png)
+  skin/images/navbar-contextual-delete.png (images/navbar-contextual-delete.png)
+  skin/images/navbar-contextual-delete@1.4x.png (images/navbar-contextual-delete@1.4x.png)
+  skin/images/navbar-contextual-delete@1.8x.png (images/navbar-contextual-delete@1.8x.png)
+  skin/images/navbar-contextual-hide.png (images/navbar-contextual-hide.png)
+  skin/images/navbar-contextual-hide@1.4x.png (images/navbar-contextual-hide@1.4x.png)
+  skin/images/navbar-contextual-hide@1.8x.png (images/navbar-contextual-hide@1.8x.png)
+  skin/images/navbar-contextual-pin.png (images/navbar-contextual-pin.png)
+  skin/images/navbar-contextual-pin@1.4x.png (images/navbar-contextual-pin@1.4x.png)
+  skin/images/navbar-contextual-pin@1.8x.png (images/navbar-contextual-pin@1.8x.png)
+  skin/images/navbar-contextual-restore.png (images/navbar-contextual-restore.png)
+  skin/images/navbar-contextual-restore@1.4x.png (images/navbar-contextual-restore@1.4x.png)
+  skin/images/navbar-contextual-restore@1.8x.png (images/navbar-contextual-restore@1.8x.png)
+  skin/images/navbar-contextual-unpin.png (images/navbar-contextual-unpin.png)
+  skin/images/navbar-contextual-unpin@1.4x.png (images/navbar-contextual-unpin@1.4x.png)
+  skin/images/navbar-contextual-unpin@1.8x.png (images/navbar-contextual-unpin@1.8x.png)
   skin/images/navbar-download.png           (images/navbar-download.png)
   skin/images/navbar-download@1.4x.png      (images/navbar-download@1.4x.png)
   skin/images/navbar-download@1.8x.png      (images/navbar-download@1.8x.png)
   skin/images/navbar-forward.png            (images/navbar-forward.png)
   skin/images/navbar-forward@1.4x.png       (images/navbar-forward@1.4x.png)
   skin/images/navbar-forward@1.8x.png       (images/navbar-forward@1.8x.png)
   skin/images/navbar-star.png               (images/navbar-star.png)
   skin/images/navbar-star@1.4x.png          (images/navbar-star@1.4x.png)
--- a/browser/metro/theme/platform.css
+++ b/browser/metro/theme/platform.css
@@ -631,16 +631,20 @@ tabmodalprompt:not([promptType="promptUs
     min-width: @touch_action_snapped_minwidth@;
   }
 }
 
 /*.meta -------------------------------------------------------------------- */
 
 .meta {
   background-color: @panel_light_color@;
+  background-image: url("chrome://browser/skin/images/firefox-watermark.png");
+  background-repeat: no-repeat;
+  background-position: center center;
+  background-attachment: fixed;
 }
 
 /* needs to observe the viewstate */
 .meta-section-container {
   padding: 45px 75px 0;
   -moz-box-orient: horizontal;
 }
 
deleted file mode 100644
--- a/browser/themes/linux/devtools/common.css
+++ /dev/null
@@ -1,351 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* Font for code */
-
-:root {
-  font: message-box;
-}
-
-.devtools-monospace {
-  font-family: monospace;
-  font-size: 80%;
-}
-
-/* Toolbar and Toolbar items */
-
-.devtools-toolbar {
-  -moz-appearance: none;
-  padding: 4px 3px;
-  border-bottom-width: 1px;
-  border-bottom-style: solid;
-}
-
-.devtools-menulist,
-.devtools-toolbarbutton {
-  -moz-appearance: none;
-  -moz-box-align: center;
-  min-width: 78px;
-  min-height: 22px;
-  text-shadow: 0 -1px 0 hsla(210,8%,5%,.45);
-  border: 1px solid hsla(210,8%,5%,.45);
-  border-radius: 3px;
-  background: linear-gradient(hsla(212,7%,57%,.35), hsla(212,7%,57%,.1)) padding-box;
-  box-shadow: 0 1px 0 hsla(210,16%,76%,.15) inset, 0 0 0 1px hsla(210,16%,76%,.15) inset, 0 1px 0 hsla(210,16%,76%,.15);
-  margin: 0 3px;
-  color: inherit;
-}
-
-.devtools-toolbarbutton > .toolbarbutton-menubutton-button {
-  -moz-box-orient: horizontal;
-}
-
-.devtools-menulist:-moz-focusring,
-.devtools-toolbarbutton:-moz-focusring {
-  outline: 1px dotted hsla(210,30%,85%,0.7);
-  outline-offset: -4px;
-}
-
-.devtools-toolbarbutton:not([label]) {
-  min-width: 32px;
-}
-
-.devtools-toolbarbutton:not([label]) > .toolbarbutton-text {
-  display: none;
-}
-
-.devtools-toolbarbutton:not([checked=true]):hover:active {
-  border-color: hsla(210,8%,5%,.6);
-  background: linear-gradient(hsla(220,6%,10%,.3), hsla(212,7%,57%,.15) 65%, hsla(212,7%,57%,.3));
-  box-shadow: 0 0 3px hsla(210,8%,5%,.25) inset, 0 1px 3px hsla(210,8%,5%,.25) inset, 0 1px 0 hsla(210,16%,76%,.15);
-}
-
-.devtools-menulist[open=true],
-.devtools-toolbarbutton[open=true],
-.devtools-toolbarbutton[checked=true] {
-  border-color: hsla(210,8%,5%,.6) !important;
-  background: linear-gradient(hsla(220,6%,10%,.6), hsla(210,11%,18%,.45) 75%, hsla(210,11%,30%,.4));
-  box-shadow: 0 1px 3px hsla(210,8%,5%,.25) inset, 0 1px 3px hsla(210,8%,5%,.25) inset, 0 1px 0 hsla(210,16%,76%,.15);
-}
-
-.devtools-toolbarbutton[checked=true] {
-  color: hsl(208,100%,60%) !important;
-}
-
-.devtools-toolbarbutton[checked=true]:hover {
-  background-color: transparent !important;
-}
-
-.devtools-toolbarbutton[checked=true]:hover:active {
-  background-color: hsla(210,8%,5%,.2) !important;
-}
-
-.devtools-option-toolbarbutton {
-  -moz-appearance: none;
-  list-style-image: url("chrome://browser/skin/devtools/option-icon.png");
-  -moz-image-region: rect(0px 16px 16px 0px);
-  background: none;
-  border: none;
-}
-
-.devtools-option-toolbarbutton[open=true] {
-  -moz-image-region: rect(0px 32px 16px 16px);
-}
-
-.devtools-menulist > .menulist-label-box {
-  text-align: center;
-}
-
-.devtools-menulist > .menulist-dropmarker {
-  -moz-appearance: none;
-  display: -moz-box;
-  list-style-image: url("chrome://browser/skin/devtools/dropmarker.png");
-  -moz-box-align: center;
-  min-width: 16px;
-}
-
-.devtools-toolbarbutton[type=menu-button] > .toolbarbutton-menubutton-button {
-  -moz-appearance: none;
-  color: inherit;
-  border-width: 0;
-  -moz-border-end: 1px solid hsla(210,8%,5%,.45);
-  box-shadow: -1px 0 0 hsla(210,16%,76%,.15) inset, 1px 0 0 hsla(210,16%,76%,.15);
-}
-
-.devtools-toolbarbutton[type=menu-button]:-moz-locale-dir(rtl) > .toolbarbutton-menubutton-button {
-  box-shadow: 1px 0 0 hsla(210,16%,76%,.15) inset, -1px 0 0 hsla(210,16%,76%,.15);
-}
-
-.devtools-toolbarbutton[type=menu-button] {
-  padding: 0 1px;
-  -moz-box-align: stretch;
-}
-
-.devtools-toolbarbutton[type=menu] > .toolbarbutton-menu-dropmarker,
-.devtools-toolbarbutton[type=menu-button] > .toolbarbutton-menubutton-dropmarker {
-  -moz-appearance: none !important;
-  list-style-image: url("chrome://browser/skin/devtools/dropmarker.png");
-  -moz-box-align: center;
-  padding: 0 3px;
-}
-
-/* Text input */
-
-.devtools-textinput,
-.devtools-searchinput {
-  -moz-appearance: none;
-  margin: 0 3px;
-  min-height: 22px;
-  border: 1px solid hsla(210,8%,5%,.6);
-  border-radius: 2px;
-  background-color: transparent;
-  background-image: linear-gradient(hsla(210,16%,76%,.15), hsla(210,16%,76%,.35));
-  padding: 3px;
-  box-shadow: 0 1px 1px hsla(210,8%,5%,.3) inset,
-              0 0 0 1px hsla(210,16%,76%,.1) inset,
-              0 1px 0 hsla(210,16%,76%,.15);
-  color: inherit;
-}
-
-.devtools-searchinput {
-  padding-top: 0;
-  padding-bottom: 0;
-  -moz-padding-start: 18px;
-  -moz-padding-end: 12px;
-  background-image: url(magnifying-glass.png), linear-gradient(hsla(210,16%,76%,.15), hsla(210,16%,76%,.35));
-  background-position: 4px center, top left, top left;
-  background-repeat: no-repeat;
-  font-size: inherit;
-}
-
-.devtools-searchinput:-moz-locale-dir(rtl) {
-  background-position: calc(100% - 4px) center, top left, top left;
-}
-
-.devtools-searchinput > .textbox-input-box > .textbox-search-icons {
-  display: none;
-}
-
-.devtools-searchinput > .textbox-input-box > .textbox-input::-moz-placeholder {
-  color: hsl(208,10%,66%);
-  opacity: 1.0;
-}
-
-.devtools-no-search-result {
-  box-shadow: inset 0 0 0 1px hsla(0,68%,6%,.35);
-  border-color: hsl(10,70%,40%) hsl(10,75%,37%) hsl(10,80%,35%) !important;
-  background-image: url(magnifying-glass.png), linear-gradient(hsla(1,16%,76%,.45), hsla(1,16%,76%,.75));
-}
-
-/* Close button */
-
-.devtools-closebutton {
-  list-style-image: url("chrome://browser/skin/devtools/close.png");
-  -moz-appearance: none;
-  border: none;
-  margin: 0 4px;
-  min-width: 16px;
-  width: 16px;
-  opacity: 0.6;
-}
-
-.devtools-closebutton > .toolbarbutton-icon {
-  /* XXX Buttons have padding in widget/ that we don't want here but can't override with good CSS, so we must
-     use evil CSS to give the impression of smaller content */
-  margin: -4px;
-}
-
-.devtools-closebutton > .toolbarbutton-text {
-  display: none;
-}
-
-.devtools-closebutton:hover {
-  opacity: 0.8;
-}
-
-.devtools-closebutton:hover:active {
-  opacity: 1;
-}
-
-/* Splitters */
-
-.devtools-horizontal-splitter {
-  -moz-appearance: none;
-  border-top: 1px solid black;
-  border-bottom-width: 0;
-  min-height: 3px;
-  height: 3px;
-  margin-bottom: -3px;
-  position: relative;
-}
-
-.devtools-side-splitter {
-  -moz-appearance: none;
-  border: 0;
-  -moz-border-start: 1px solid black;
-  min-width: 0;
-  width: 3px;
-  background-color: transparent;
-  -moz-margin-end: -3px;
-  position: relative;
-  cursor: e-resize;
-}
-
-/* In-tools sidebar */
-
-.devtools-toolbox-side-iframe {
-  min-width: 465px;
-}
-
-.devtools-sidebar-tabs {
-  -moz-appearance: none;
-  margin: 0;
-}
-
-.devtools-sidebar-tabs > tabpanels {
-  -moz-appearance: none;
-  padding: 0;
-  border: 0;
-}
-
-.devtools-sidebar-tabs > tabs {
-  -moz-appearance: none;
-  position: static;
-  color: #b6babf;
-  margin-bottom: 0;
-  padding: 0;
-  background-color: #343c45;
-  border-width: 0 0 1px 0;
-  border-color: hsla(210,8%,5%,.6);
-  border-style: solid;
-  overflow: hidden;
-}
-
-.devtools-sidebar-tabs > tabs > .tabs-right,
-.devtools-sidebar-tabs > tabs > .tabs-left {
-  display: none;
-}
-
-.devtools-sidebar-tabs > tabs > tab {
-  -moz-appearance: none;
-  /* We want to match the height of a toolbar with a toolbarbutton
-   * First, we need to replicated the padding of toolbar (4px),
-   * then we need to take the border of the buttons into account (1px).
-   */
-  padding: 5px 3px;
-  -moz-padding-start: 6px;
-  margin: 0;
-  min-width: 78px;
-  /* toolbar's min-height is button min-height (25px) + padding (2 * 4px): 33px.
-   * -1px because the parent element (<tabs>) comes with a 1px bottom border.
-   */
-  min-height: 32px;
-  text-shadow: 0 -1px 0 hsla(210,8%,5%,.45);
-  text-align: center;
-  color: inherit;
-  -moz-box-flex: 1;
-  border-width: 0;
-  background: transparent;
-  border-radius: 0;
-  position: static;
-  -moz-margin-start: -1px;
-}
-
-.devtools-sidebar-tabs > tabs > tab:first-of-type {
-  -moz-margin-start: -3px;
-}
-
-.devtools-sidebar-tabs > tabs > tab {
-  background-size: calc(100% - 2px) 100%, 1px 100%;
-  background-repeat: no-repeat;
-  background-position: 1px, 0;
-}
-
-.devtools-sidebar-tabs:-moz-locale-dir(rtl) > tabs > tab {
-  background-position: calc(100% - 1px), 100%;
-}
-
-%filter substitution
-%define smallSeparator linear-gradient(transparent 15%, #5a6169 15%, #5a6169 85%, transparent 85%)
-%define solidSeparator linear-gradient(#2d5b7d, #2d5b7d)
-
-.devtools-sidebar-tabs > tabs > tab {
-  background-image: linear-gradient(transparent, transparent), @smallSeparator@;
-}
-
-.devtools-sidebar-tabs > tabs > tab:hover {
-  background-image: linear-gradient(hsla(206,37%,4%,.2), hsla(206,37%,4%,.2)), @smallSeparator@;
-}
-
-.devtools-sidebar-tabs > tabs > tab:hover:active {
-  background-image: linear-gradient(hsla(206,37%,4%,.4), hsla(206,37%,4%,.4)), @smallSeparator@;
-}
-
-.devtools-sidebar-tabs > tabs > tab[selected=true] + tab {
-  background-image: linear-gradient(transparent, transparent), @solidSeparator@;
-}
-
-.devtools-sidebar-tabs > tabs > tab[selected=true] + tab:hover {
-  background-image: linear-gradient(hsla(206,37%,4%,.2), hsla(206,37%,4%,.2)), @solidSeparator@;
-}
-
-.devtools-sidebar-tabs > tabs > tab[selected=true] + tab:hover:active {
-  background-image: linear-gradient(hsla(206,37%,4%,.4), hsla(206,37%,4%,.4)), @solidSeparator@;
-}
-
-.devtools-sidebar-tabs > tabs > tab[selected=true] {
-  color: #f5f7fa;
-  background-image: linear-gradient(#1d4f73, #1d4f73), @solidSeparator@;
-}
-
-.devtools-sidebar-tabs > tabs > tab[selected=true]:hover {
-  background-image: linear-gradient(#274f64, #274f64), @solidSeparator@;
-}
-
-.devtools-sidebar-tabs > tabs > tab[selected=true]:hover:active {
-  background-image: linear-gradient(#1f3e4f, #1f3e4f), @solidSeparator@;
-}
-
-%include ../../shared/devtools/common.inc.css
deleted file mode 100644
--- a/browser/themes/linux/devtools/toolbox.css
+++ /dev/null
@@ -1,288 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#toolbox-controls {
-  margin: 0 4px;
-}
-
-#toolbox-controls > toolbarbutton,
-#toolbox-dock-buttons > toolbarbutton {
-  -moz-appearance: none;
-  margin: 0 4px;
-  min-width: 16px;
-  width: 16px;
-}
-
-#toolbox-dock-bottom {
-  list-style-image: url("chrome://browser/skin/devtools/dock-bottom.png");
-}
-
-#toolbox-dock-side {
-  list-style-image: url("chrome://browser/skin/devtools/dock-side.png");
-}
-
-#toolbox-dock-window {
-  list-style-image: url("chrome://browser/skin/devtools/undock.png");
-}
-
-#toolbox-dock-window,
-#toolbox-dock-bottom,
-#toolbox-dock-side {
-  opacity: 0.6;
-}
-
-#toolbox-dock-window:hover,
-#toolbox-dock-bottom:hover,
-#toolbox-dock-side:hover {
-  opacity: 1;
-}
-
-#toolbox-controls-separator {
-  width: 3px;
-  background-image: linear-gradient(hsla(204,45%,98%,0), hsla(204,45%,98%,.1), hsla(204,45%,98%,0)),
-                    linear-gradient(hsla(206,37%,4%,0), hsla(206,37%,4%,.6), hsla(206,37%,4%,0)),
-                    linear-gradient(hsla(204,45%,98%,0), hsla(204,45%,98%,.1), hsla(204,45%,98%,0));
-  background-size: 1px 100%;
-  background-repeat: no-repeat;
-  background-position: 0, 1px, 2px;
-  -moz-margin-start: 8px;
-}
-
-/* Command buttons */
-
-.command-button {
-  -moz-appearance: none;
-  padding: 0 8px;
-  margin: 0;
-  width: 16px;
-}
-
-.command-button:hover {
-  background-color: hsla(206,37%,4%,.2);
-}
-.command-button:hover:active, .command-button[checked=true]:not(:hover) {
-  background-color: hsla(206,37%,4%,.4);
-}
-
-#command-button-paintflashing {
-  list-style-image: url("chrome://browser/skin/devtools/command-paintflashing.png");
-  -moz-image-region: rect(0px, 16px, 16px, 0px);
-}
-#command-button-paintflashing:hover {
-  -moz-image-region: rect(0px, 32px, 16px, 16px);
-}
-#command-button-paintflashing:hover:active {
-  -moz-image-region: rect(0px, 48px, 16px, 32px);
-}
-#command-button-paintflashing[checked=true] {
-  -moz-image-region: rect(0px, 64px, 16px, 48px);
-}
-
-#command-button-responsive {
-  list-style-image: url("chrome://browser/skin/devtools/command-responsivemode.png");
-  -moz-image-region: rect(0px, 16px, 16px, 0px);
-}
-#command-button-responsive:hover {
-  -moz-image-region: rect(0px, 32px, 16px, 16px);
-}
-#command-button-responsive:hover:active {
-  -moz-image-region: rect(0px, 48px, 16px, 32px);
-}
-#command-button-responsive[checked=true] {
-  -moz-image-region: rect(0px, 64px, 16px, 48px);
-}
-
-#command-button-tilt {
-  list-style-image: url("chrome://browser/skin/devtools/command-tilt.png");
-  -moz-image-region: rect(0px, 16px, 16px, 0px);
-}
-#command-button-tilt:hover {
-  -moz-image-region: rect(0px, 32px, 16px, 16px);
-}
-
-#command-button-tilt:hover:active {
-  -moz-image-region: rect(0px, 48px, 16px, 32px);
-}
-
-#command-button-tilt[checked=true] {
-  -moz-image-region: rect(0px, 64px, 16px, 48px);
-}
-
-#command-button-scratchpad {
-  list-style-image: url("chrome://browser/skin/devtools/command-scratchpad.png");
-  -moz-image-region: rect(0px, 16px, 16px, 0px);
-}
-
-#command-button-scratchpad:hover {
-  -moz-image-region: rect(0px, 32px, 16px, 16px);
-}
-
-#command-button-scratchpad:hover:active {
-  -moz-image-region: rect(0px, 48px, 16px, 32px);
-}
-
-/* Tabs */
-
-.devtools-tabbar {
-  -moz-appearance: none;
-  background-image: url("background-noise-toolbar.png"),
-                    linear-gradient(#303840, #2d3640);
-  border-color: #060a0d;
-  border-style: solid;
-  border-width: 1px 0;
-  box-shadow: 0 1px 0 hsla(204,45%,98%,.05) inset,
-              0 -1px 0 hsla(206,37%,4%,.1) inset;
-  min-height: 32px;
-  padding: 0;
-}
-
-#toolbox-tabs {
-  margin: 0;
-}
-
-.devtools-tab {
-  -moz-appearance: none;
-  min-width: 32px;
-  min-height: 32px;
-  max-width: 127px;
-  color: #b6babf;
-  margin: 0;
-  padding: 0;
-  background-image: linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1)),
-                    linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1));
-  background-size: 1px 100%;
-  background-repeat: no-repeat;
-  background-position: left, right;
-  border-right: 1px solid hsla(206,37%,4%,.45);
-  -moz-box-align: center;
-}
-
-.devtools-tab > image {
-  border: none;
-  -moz-margin-end: 0;
-  -moz-margin-start: 4px;
-  opacity: 0.6;
-  max-height: 16px;
-  width: 16px; /* Prevents collapse during theme switching */
-}
-
-#toolbox-tab-options > image {
-  margin: 0 8px;
-}
-
-.devtools-tab > label {
-  white-space: nowrap;
-}
-
-.devtools-tab:hover > image {
-  opacity: 0.8;
-}
-
-.devtools-tab:active > image,
-.devtools-tab[selected=true] > label {
-  opacity: 1;
-}
-
-.devtools-tab:hover {
-  background-image: linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1)),
-                    linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1)),
-                    linear-gradient(hsla(206,37%,4%,.1), hsla(206,37%,4%,.2));
-  background-size: 1px 100%,
-                   1px 100%,
-                   100%;
-  background-repeat: no-repeat,
-                     no-repeat,
-                     repeat-x;
-  background-position: left, right;
-  color: #ced3d9;
-}
-.devtools-tab:hover:active {
-  background-color: hsla(206,37%,4%,.2);
-  color: #f5f7fa;
-}
-
-.devtools-tab[selected=true] {
-  color: #f5f7fa;
-  background-image: radial-gradient(farthest-corner at center top, #9fdfff, hsla(200,100%,70%,.3)),
-                    radial-gradient(farthest-side at center top, hsla(200,100%,70%,.4), hsla(200,100%,70%,0)),
-                    linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1)),
-                    linear-gradient(hsla(204,45%,98%,.02), hsla(204,45%,98%,.04)),
-                    linear-gradient(hsla(206,37%,4%,.2), hsla(206,37%,4%,.3));
-  background-size: 100% 1px,
-                   100% 5px,
-                   1px 100%,
-                   1px 100%,
-                   100%;
-  background-repeat: no-repeat,
-                     no-repeat,
-                     no-repeat,
-                     no-repeat,
-                     repeat-x;
-  background-position: top right, top left, left, right;
-  box-shadow: 1px -1px 0 hsla(206,37%,4%,.2) inset;
-}
-
-.devtools-tab:not([selected=true]).highlighted {
-  color: #f5f7fa;
-  background-image: radial-gradient(farthest-corner at center top, #c0ff40, hsla(80,100%,63%,.5) 70%, hsla(80,100%,63%,.3) 97%),
-                    radial-gradient(farthest-side at center top, hsla(80,100%,35%,.5), hsla(80,100%,35%,0)),
-                    linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1)),
-                    linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1)),
-                    linear-gradient(hsla(99,100%,14%,.2), hsla(99,100%,14%,.2));
-  background-size: 100% 1px,
-                   100% 5px,
-                   1px 100%,
-                   1px 100%,
-                   100%;
-  background-repeat: no-repeat,
-                     no-repeat,
-                     no-repeat,
-                     no-repeat,
-                     repeat-x;
-  background-position: top right, top left, left, right;
-}
-
-.devtools-tab:not(.highlighted) > .highlighted-icon,
-.devtools-tab[selected=true] > .highlighted-icon,
-.devtools-tab:not([selected=true]).highlighted > .default-icon {
-  visibility: collapse;
-}
-
-.options-vertical-pane {
-  margin: 5px;
-  width: calc(50% - 30px);
-  min-width: 400px;
-  -moz-padding-start: 5px;
-}
-
-.options-vertical-pane > label {
-  padding: 2px 0;
-  font-size: 1.4rem;
-}
-
-.options-groupbox {
-  -moz-margin-start: 15px;
-  padding: 2px;
-}
-
-.options-groupbox > * {
-  padding: 2px;
-}
-
-.options-citation-label {
-  font-size: 1rem !important;
-  /* !important is required otherwise font-size will still be 1.4rem */
-  font-style: italic;
-  padding: 4px 0 0; /* To align it with the checkbox */
-}
-
-.options-citation-label + label {
-  padding: 3px 0 0 !important; /* To align it with the checkbox */
-  font-style: italic;
-}
-
-.hidden-labels-box:not(.visible) > label,
-.hidden-labels-box.visible ~ .hidden-labels-box > label:last-child {
-  display: none;
-}
--- a/browser/themes/linux/jar.mn
+++ b/browser/themes/linux/jar.mn
@@ -141,19 +141,19 @@ browser.jar:
   skin/classic/browser/tabbrowser/tab-stroke-start.png      (tabbrowser/tab-stroke-start.png)
   skin/classic/browser/tabbrowser/tabDragIndicator.png      (tabbrowser/tabDragIndicator.png)
   skin/classic/browser/tabbrowser/tab-separator.png         (tabbrowser/tab-separator.png)
   skin/classic/browser/tabview/edit-light.png         (tabview/edit-light.png)
   skin/classic/browser/tabview/search.png             (tabview/search.png)
   skin/classic/browser/tabview/stack-expander.png     (tabview/stack-expander.png)
   skin/classic/browser/tabview/tabview.png            (tabview/tabview.png)
   skin/classic/browser/tabview/tabview.css            (tabview/tabview.css)
-* skin/classic/browser/devtools/common.css            (devtools/common.css)
-  skin/classic/browser/devtools/dark-theme.css        (../shared/devtools/dark-theme.css)
-  skin/classic/browser/devtools/light-theme.css       (../shared/devtools/light-theme.css)
+* skin/classic/browser/devtools/common.css            (../shared/devtools/common.css)
+* skin/classic/browser/devtools/dark-theme.css        (../shared/devtools/dark-theme.css)
+* skin/classic/browser/devtools/light-theme.css       (../shared/devtools/light-theme.css)
   skin/classic/browser/devtools/controls.png          (../shared/devtools/controls.png)
 * skin/classic/browser/devtools/widgets.css           (devtools/widgets.css)
   skin/classic/browser/devtools/commandline-icon.png  (devtools/commandline-icon.png)
   skin/classic/browser/devtools/command-paintflashing.png  (devtools/command-paintflashing.png)
   skin/classic/browser/devtools/command-responsivemode.png (devtools/command-responsivemode.png)
   skin/classic/browser/devtools/command-scratchpad.png (devtools/command-scratchpad.png)
   skin/classic/browser/devtools/command-tilt.png      (devtools/command-tilt.png)
   skin/classic/browser/devtools/alerticon-warning.png (devtools/alerticon-warning.png)
@@ -224,17 +224,16 @@ browser.jar:
   skin/classic/browser/devtools/responsive-background.png (devtools/responsive-background.png)
   skin/classic/browser/devtools/toggle-tools.png          (devtools/toggle-tools.png)
   skin/classic/browser/devtools/dock-bottom.png           (devtools/dock-bottom.png)
   skin/classic/browser/devtools/dock-side.png             (devtools/dock-side.png)
   skin/classic/browser/devtools/floating-scrollbars.css   (devtools/floating-scrollbars.css)
   skin/classic/browser/devtools/floating-scrollbars-light.css (devtools/floating-scrollbars-light.css)
   skin/classic/browser/devtools/inspector.css             (devtools/inspector.css)
   skin/classic/browser/devtools/profiler-stopwatch.png    (devtools/profiler-stopwatch.png)
-  skin/classic/browser/devtools/toolbox.css               (devtools/toolbox.css)
   skin/classic/browser/devtools/tool-options.png          (devtools/tool-options.png)
   skin/classic/browser/devtools/tool-webconsole.png       (devtools/tool-webconsole.png)
   skin/classic/browser/devtools/tool-debugger.png         (devtools/tool-debugger.png)
   skin/classic/browser/devtools/tool-debugger-paused.png  (devtools/tool-debugger-paused.png)
   skin/classic/browser/devtools/tool-inspector.png        (devtools/tool-inspector.png)
   skin/classic/browser/devtools/tool-styleeditor.png      (devtools/tool-styleeditor.png)
   skin/classic/browser/devtools/tool-profiler.png         (devtools/tool-profiler.png)
   skin/classic/browser/devtools/tool-network.png          (devtools/tool-network.png)
deleted file mode 100644
--- a/browser/themes/osx/devtools/common.css
+++ /dev/null
@@ -1,354 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-%include ../shared.inc
-
-/* Font for code */
-
-:root {
-  font: message-box;
-}
-
-.devtools-monospace {
-  font-family: Menlo, monospace;
-}
-
-/* Toolbar and Toolbar items */
-
-.devtools-toolbar {
-  -moz-appearance: none;
-  padding: 4px 3px;
-  border-bottom-width: 1px;
-  border-bottom-style: solid;
-}
-
-.devtools-menulist,
-.devtools-toolbarbutton {
-  -moz-appearance: none;
-  -moz-box-align: center;
-  min-width: 78px;
-  min-height: 22px;
-  text-shadow: 0 -1px 0 hsla(210,8%,5%,.45);
-  border: 1px solid hsla(210,8%,5%,.45);
-  border-radius: @toolbarbuttonCornerRadius@;
-  background: linear-gradient(hsla(212,7%,57%,.35), hsla(212,7%,57%,.1)) padding-box;
-  box-shadow: 0 1px 0 hsla(210,16%,76%,.15) inset, 0 0 0 1px hsla(210,16%,76%,.15) inset, 0 1px 0 hsla(210,16%,76%,.15);
-  color: inherit;
-}
-
-.devtools-toolbarbutton > .toolbarbutton-menubutton-button {
-  -moz-box-orient: horizontal;
-}
-
-.devtools-menulist {
-  margin: 0 2px;
-}
-
-.devtools-menulist:-moz-focusring,
-.devtools-toolbarbutton:-moz-focusring {
-  outline: 1px dotted hsla(210,30%,85%,0.7);
-  outline-offset: -4px;
-}
-
-.devtools-toolbarbutton > .toolbarbutton-text {
-  margin: 1px 6px;
-}
-
-.devtools-toolbarbutton:not([label]) {
-  min-width: 32px;
-}
-
-.devtools-toolbarbutton:not([label]) > .toolbarbutton-text {
-  display: none;
-}
-
-.devtools-toolbarbutton:not([checked=true]):hover:active {
-  border-color: hsla(210,8%,5%,.6);
-  background: linear-gradient(hsla(220,6%,10%,.3), hsla(212,7%,57%,.15) 65%, hsla(212,7%,57%,.3));
-  box-shadow: 0 0 3px hsla(210,8%,5%,.25) inset, 0 1px 3px hsla(210,8%,5%,.25) inset, 0 1px 0 hsla(210,16%,76%,.15);
-}
-
-.devtools-menulist[open=true],
-.devtools-toolbarbutton[open=true],
-.devtools-toolbarbutton[checked=true] {
-  border-color: hsla(210,8%,5%,.6);
-  background: linear-gradient(hsla(220,6%,10%,.6), hsla(210,11%,18%,.45) 75%, hsla(210,11%,30%,.4));
-  box-shadow: 0 1px 3px hsla(210,8%,5%,.25) inset, 0 1px 3px hsla(210,8%,5%,.25) inset, 0 1px 0 hsla(210,16%,76%,.15);
-}
-
-.devtools-toolbarbutton[checked=true] {
-  color: hsl(208,100%,60%) !important;
-}
-
-.devtools-toolbarbutton[checked=true]:hover:active {
-  background-color: hsla(210,8%,5%,.2);
-}
-
-.devtools-option-toolbarbutton {
-  -moz-appearance: none;
-  list-style-image: url("chrome://browser/skin/devtools/option-icon.png");
-  -moz-image-region: rect(0px 16px 16px 0px);
-  background: none;
-  border: none;
-}
-
-.devtools-option-toolbarbutton[open=true] {
-  -moz-image-region: rect(0px 32px 16px 16px);
-}
-
-.devtools-menulist > .menulist-label-box {
-  text-align: center;
-}
-
-.devtools-menulist > .menulist-dropmarker {
-  -moz-appearance: none;
-  background-color: transparent;
-  display: -moz-box;
-  list-style-image: url("chrome://browser/skin/devtools/dropmarker.png");
-  border-width: 0;
-  min-width: 18px;
-}
-
-.devtools-toolbarbutton[type=menu-button] > .toolbarbutton-menubutton-button {
-  -moz-appearance: none;
-  border-width: 0;
-  -moz-border-end: 1px solid hsla(210,8%,5%,.45);
-  box-shadow: -1px 0 0 hsla(210,16%,76%,.15) inset, 1px 0 0 hsla(210,16%,76%,.15);
-  padding: 0 1px;
-}
-
-.devtools-toolbarbutton[type=menu-button]:-moz-locale-dir(rtl) > .toolbarbutton-menubutton-button {
-  box-shadow: 1px 0 0 hsla(210,16%,76%,.15) inset, -1px 0 0 hsla(210,16%,76%,.15);
-}
-
-.devtools-toolbarbutton[type=menu-button] {
-  padding: 0 1px;
-  -moz-box-align: stretch;
-}
-
-.devtools-toolbarbutton[type=menu] > .toolbarbutton-menu-dropmarker,
-.devtools-toolbarbutton[type=menu-button] > .toolbarbutton-menubutton-dropmarker {
-  -moz-appearance: none !important;
-  list-style-image: url("chrome://browser/skin/devtools/dropmarker.png");
-  border: 0;
-}
-
-/* Text input */
-
-.devtools-textinput,
-.devtools-searchinput {
-  -moz-appearance: none;
-  margin: 0 3px;
-  min-height: 22px;
-  background-color: transparent;
-  border: 1px solid hsla(210,8%,5%,.6);
-  border-radius: 20px;
-  background-image: linear-gradient(hsla(210,16%,76%,.15), hsla(210,16%,76%,.35));
-  padding: 3px 8px;
-  box-shadow: 0 1px 1px hsla(210,8%,5%,.3) inset,
-              0 0 0 1px hsla(210,16%,76%,.1) inset,
-              0 1px 0 hsla(210,16%,76%,.15);
-  color: inherit;
-}
-
-.devtools-searchinput {
-  background-image: url(magnifying-glass.png), linear-gradient(hsla(210,16%,76%,.15), hsla(210,16%,76%,.35));
-  background-repeat: no-repeat;
-  background-position: 4px center, top left, top left;
-  padding-top: 0;
-  padding-bottom: 0;
-  -moz-padding-start: 18px;
-  -moz-padding-end: 12px;
-  font-size: inherit;
-}
-
-.devtools-searchinput:-moz-locale-dir(rtl) {
-  background-position: calc(100% - 4px) center, top left, top left;
-}
-
-.devtools-searchinput > .textbox-input-box > .textbox-search-icons {
-  display: none;
-}
-
-.devtools-searchinput > .textbox-input-box > .textbox-input::-moz-placeholder {
-  opacity: 1.0;
-  color: hsl(208,10%,66%);
-}
-
-.devtools-no-search-result {
-  box-shadow: inset 0 0 0 1px hsla(0,68%,6%,.35);
-  border-color: hsl(10,70%,40%) hsl(10,75%,37%) hsl(10,80%,35%) !important;
-  background-image: url(magnifying-glass.png), linear-gradient(hsla(1,16%,76%,.45), hsla(1,16%,76%,.75));
-}
-
-/* Close button */
-
-.devtools-closebutton {
-  list-style-image: url("chrome://browser/skin/devtools/close.png");
-  -moz-appearance: none;
-  border: none;
-  margin: 0 4px;
-  min-width: 16px;
-  width: 16px;
-  opacity: 0.6;
-}
-
-.devtools-closebutton > .toolbarbutton-text {
-  display: none;
-}
-
-.devtools-closebutton:hover {
-  opacity: 0.8;
-}
-
-.devtools-closebutton:active {
-  opacity: 1;
-}
-
-/* Splitters */
-
-.devtools-horizontal-splitter {
-  -moz-appearance: none;
-  background-image: none;
-  border-top: 1px solid black;
-  border-bottom-width: 0;
-  min-height: 3px;
-  height: 3px;
-  margin-bottom: -3px;
-  position: relative;
-}
-
-.devtools-side-splitter {
-  -moz-appearance: none;
-  background-image: none;
-  border: 0;
-  -moz-border-start: 1px solid black;
-  min-width: 0;
-  width: 3px;
-  -moz-margin-end: -3px;
-  position: relative;
-  cursor: e-resize;
-}
-
-/* In-tools sidebar */
-
-.devtools-toolbox-side-iframe {
-  min-width: 465px;
-}
-
-.devtools-sidebar-tabs {
-  -moz-appearance: none;
-  margin: 0;
-}
-
-.devtools-sidebar-tabs > tabpanels {
-  padding: 0;
-}
-
-.devtools-sidebar-tabs > tabs {
-  -moz-appearance: none;
-  font: inherit;
-  position: static;
-  color: #b6babf;
-  margin-bottom: 0;
-  padding: 0;
-  background-color: #343c45;
-  border-width: 0 0 1px 0;
-  border-color: hsla(210,8%,5%,.6);
-  border-style: solid;
-  overflow: hidden;
-}
-
-.devtools-sidebar-tabs > tabs > .tabs-right,
-.devtools-sidebar-tabs > tabs > .tabs-left {
-  display: none;
-}
-
-.devtools-sidebar-tabs > tabs > tab {
-  -moz-appearance: none;
-  /* We want to match the height of a toolbar with a toolbarbutton
-   * First, we need to replicated the padding of toolbar (4px),
-   * then we need to take the border of the buttons into account (1px).
-   */
-  padding: 5px 3px !important;
-  -moz-padding-start: 6px;
-  padding: 0;
-  min-width: 78px;
-  /* toolbar's min-height is button min-height (25px) + padding (2 * 4px): 33px.
-   * -1px because the parent element (<tabs>) comes with a 1px bottom border.
-   */
-  min-height: 32px;
-  text-shadow: 0 -1px 0 hsla(210,8%,5%,.45);
-  text-align: center;
-  color: inherit;
-  -moz-box-flex: 1;
-  border-width: 0;
-  position: static;
-  -moz-margin-start: -1px;
-}
-
-.devtools-sidebar-tabs > tabs > tab:-moz-focusring {
-  position: static;
-}
-
-.devtools-sidebar-tabs > tabs > tab:first-of-type {
-  -moz-margin-start: -3px;
-}
-
-.devtools-sidebar-tabs > tabs > tab {
-  background-size: calc(100% - 2px) 100%, 1px 100%;
-  background-repeat: no-repeat;
-  background-position: 1px, 0;
-}
-
-.devtools-sidebar-tabs:-moz-locale-dir(rtl) > tabs > tab {
-  background-position: calc(100% - 1px), 100%;
-}
-
-.devtools-sidebar-tabs > tabs > tab:last-of-type {
-  -moz-border-end-width: 0;
-}
-
-%define smallSeparator linear-gradient(transparent 15%, #5a6169 15%, #5a6169 85%, transparent 85%)
-%define solidSeparator linear-gradient(#2d5b7d, #2d5b7d)
-
-.devtools-sidebar-tabs > tabs > tab {
-  background-image: linear-gradient(transparent, transparent), @smallSeparator@;
-}
-
-.devtools-sidebar-tabs > tabs > tab:hover {
-  background-image: linear-gradient(hsla(206,37%,4%,.2), hsla(206,37%,4%,.2)), @smallSeparator@;
-}
-
-.devtools-sidebar-tabs > tabs > tab:hover:active {
-  background-image: linear-gradient(hsla(206,37%,4%,.4), hsla(206,37%,4%,.4)), @smallSeparator@;
-}
-
-.devtools-sidebar-tabs > tabs > tab[selected=true] + tab {
-  background-image: linear-gradient(transparent, transparent), @solidSeparator@;
-}
-
-.devtools-sidebar-tabs > tabs > tab[selected=true] + tab:hover {
-  background-image: linear-gradient(hsla(206,37%,4%,.2), hsla(206,37%,4%,.2)), @solidSeparator@;
-}
-
-.devtools-sidebar-tabs > tabs > tab[selected=true] + tab:hover:active {
-  background-image: linear-gradient(hsla(206,37%,4%,.4), hsla(206,37%,4%,.4)), @solidSeparator@;
-}
-
-.devtools-sidebar-tabs > tabs > tab[selected=true] {
-  color: #f5f7fa;
-  background-image: linear-gradient(#1d4f73, #1d4f73), @solidSeparator@;
-}
-
-.devtools-sidebar-tabs > tabs > tab[selected=true]:hover {
-  background-image: linear-gradient(#274f64, #274f64), @solidSeparator@;
-}
-
-.devtools-sidebar-tabs > tabs > tab[selected=true]:hover:active {
-  background-image: linear-gradient(#1f3e4f, #1f3e4f), @solidSeparator@;
-}
-
-%include ../../shared/devtools/common.inc.css
deleted file mode 100644
--- a/browser/themes/osx/devtools/toolbox.css
+++ /dev/null
@@ -1,274 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#toolbox-controls {
-  margin: 0 4px;
-}
-
-#toolbox-controls > toolbarbutton,
-#toolbox-dock-buttons > toolbarbutton {
-  margin: 0 4px;
-  min-width: 16px;
-  width: 16px;
-}
-
-#toolbox-dock-bottom {
-  list-style-image: url("chrome://browser/skin/devtools/dock-bottom.png");
-}
-
-#toolbox-dock-side {
-  list-style-image: url("chrome://browser/skin/devtools/dock-side.png");
-}
-
-#toolbox-dock-window {
-  list-style-image: url("chrome://browser/skin/devtools/undock.png");
-}
-
-#toolbox-dock-window,
-#toolbox-dock-bottom,
-#toolbox-dock-side {
-  opacity: 0.6;
-}
-
-#toolbox-dock-window:hover,
-#toolbox-dock-bottom:hover,
-#toolbox-dock-side:hover {
-  opacity: 1;
-}
-
-/* Command buttons */
-
-.command-button {
-  padding: 0 8px;
-  margin: 0;
-  border-width: 0;
-  width: 16px;
-}
-
-.command-button:hover {
-  background-color: hsla(206,37%,4%,.2);
-}
-.command-button:hover:active, .command-button[checked=true]:not(:hover) {
-  background-color: hsla(206,37%,4%,.4);
-}
-
-#command-button-paintflashing {
-  list-style-image: url("chrome://browser/skin/devtools/command-paintflashing.png");
-  -moz-image-region: rect(0px, 16px, 16px, 0px);
-}
-#command-button-paintflashing:hover {
-  -moz-image-region: rect(0px, 32px, 16px, 16px);
-}
-#command-button-paintflashing:hover:active {
-  -moz-image-region: rect(0px, 48px, 16px, 32px);
-}
-#command-button-paintflashing[checked=true] {
-  -moz-image-region: rect(0px, 64px, 16px, 48px);
-}
-
-#command-button-responsive {
-  list-style-image: url("chrome://browser/skin/devtools/command-responsivemode.png");
-  -moz-image-region: rect(0px, 16px, 16px, 0px);
-}
-#command-button-responsive:hover {
-  -moz-image-region: rect(0px, 32px, 16px, 16px);
-}
-#command-button-responsive:hover:active {
-  -moz-image-region: rect(0px, 48px, 16px, 32px);
-}
-#command-button-responsive[checked=true] {
-  -moz-image-region: rect(0px, 64px, 16px, 48px);
-}
-
-#command-button-tilt {
-  list-style-image: url("chrome://browser/skin/devtools/command-tilt.png");
-  -moz-image-region: rect(0px, 16px, 16px, 0px);
-}
-#command-button-tilt:hover {
-  -moz-image-region: rect(0px, 32px, 16px, 16px);
-}
-
-#command-button-tilt:hover:active {
-  -moz-image-region: rect(0px, 48px, 16px, 32px);
-}
-
-#command-button-tilt[checked=true] {
-  -moz-image-region: rect(0px, 64px, 16px, 48px);
-}
-
-#command-button-scratchpad {
-  list-style-image: url("chrome://browser/skin/devtools/command-scratchpad.png");
-  -moz-image-region: rect(0px, 16px, 16px, 0px);
-}
-
-#command-button-scratchpad:hover {
-  -moz-image-region: rect(0px, 32px, 16px, 16px);
-}
-
-#command-button-scratchpad:hover:active {
-  -moz-image-region: rect(0px, 48px, 16px, 32px);
-}
-
-/* Tabs */
-
-.devtools-tabbar {
-  -moz-appearance: none;
-  background-image: url("background-noise-toolbar.png"),
-                    linear-gradient(#303840, #2d3640);
-  border-color: #060a0d;
-  border-style: solid;
-  border-width: 1px 0;
-  box-shadow: 0 1px 0 hsla(204,45%,98%,.05) inset,
-              0 -1px 0 hsla(206,37%,4%,.1) inset;
-  min-height: 32px;
-  padding: 0;
-}
-
-#toolbox-tabs {
-  margin: 0;
-  border-left: 1px solid hsla(206,37%,4%,.45);
-}
-
-.devtools-tab {
-  -moz-appearance: none;
-  min-width: 32px;
-  min-height: 32px;
-  max-width: 110px;
-  color: #b6babf;
-  margin: 0;
-  padding: 0;
-  background-image: linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1)),
-                    linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1));
-  background-size: 1px 100%;
-  background-repeat: no-repeat;
-  background-position: left, right;
-  border-right: 1px solid hsla(206,37%,4%,.45);
-}
-
-.devtools-tab > image {
-  -moz-margin-end: 0;
-  -moz-margin-start: 4px;
-  opacity: 0.6;
-  width: 16px; /* Prevents collapse during theme switching */
-}
-
-#toolbox-tab-options > image {
-  margin: 0 8px;
-}
-
-.devtools-tab > label {
-  white-space: nowrap;
-}
-
-.devtools-tab:hover > image {
-  opacity: 0.8;
-}
-
-.devtools-tab:active > image,
-.devtools-tab[selected=true] > image {
-  opacity: 1;
-}
-
-.devtools-tab:hover {
-  background-image: linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1)),
-                    linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1)),
-                    linear-gradient(hsla(206,37%,4%,.1), hsla(206,37%,4%,.2));
-  background-size: 1px 100%,
-                   1px 100%,
-                   100%;
-  background-repeat: no-repeat,
-                     no-repeat,
-                     repeat-x;
-  background-position: left, right;
-  color: #ced3d9;
-}
-.devtools-tab:hover:active {
-  background-color: hsla(206,37%,4%,.2);
-  color: #f5f7fa;
-}
-
-.devtools-tab[selected=true] {
-  color: #f5f7fa;
-  background-image: radial-gradient(farthest-corner at center top, #9fdfff, hsla(200,100%,70%,.3)),
-                    radial-gradient(farthest-side at center top, hsla(200,100%,70%,.4), hsla(200,100%,70%,0)),
-                    linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1)),
-                    linear-gradient(hsla(204,45%,98%,.02), hsla(204,45%,98%,.04)),
-                    linear-gradient(hsla(206,37%,4%,.2), hsla(206,37%,4%,.3));
-  background-size: 100% 1px,
-                   100% 5px,
-                   1px 100%,
-                   1px 100%,
-                   100%;
-  background-repeat: no-repeat,
-                     no-repeat,
-                     no-repeat,
-                     no-repeat,
-                     repeat-x;
-  background-position: top right, top left, left, right;
-  box-shadow: 1px -1px 0 hsla(206,37%,4%,.2) inset;
-}
-
-.devtools-tab:not([selected=true]).highlighted {
-  color: #f5f7fa;
-  background-image: radial-gradient(farthest-corner at center top, #c0ff40, hsla(80,100%,63%,.5) 70%, hsla(80,100%,63%,.3) 97%),
-                    radial-gradient(farthest-side at center top, hsla(80,100%,35%,.5), hsla(80,100%,35%,0)),
-                    linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1)),
-                    linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1)),
-                    linear-gradient(hsla(99,100%,14%,.2), hsla(99,100%,14%,.2));
-  background-size: 100% 1px,
-                   100% 5px,
-                   1px 100%,
-                   1px 100%,
-                   100%;
-  background-repeat: no-repeat,
-                     no-repeat,
-                     no-repeat,
-                     no-repeat,
-                     repeat-x;
-  background-position: top right, top left, left, right;
-}
-
-.devtools-tab:not(.highlighted) > .highlighted-icon,
-.devtools-tab[selected=true] > .highlighted-icon,
-.devtools-tab:not([selected=true]).highlighted > .default-icon {
-  visibility: collapse;
-}
-
-.options-vertical-pane {
-  margin: 5px;
-  width: calc(50% - 30px);
-  min-width: 400px;
-  -moz-padding-start: 5px;
-}
-
-.options-vertical-pane > label {
-  padding: 2px 0;
-  font-size: 1.4rem;
-}
-
-.options-groupbox {
-  -moz-margin-start: 15px;
-  padding: 2px;
-}
-
-.options-groupbox > * {
-  padding: 2px;
-}
-
-.options-citation-label {
-  font-size: 1rem !important;
-  /* !important is required otherwise font-size will still be 1.4rem */
-  font-style: italic;
-  padding: 4px 0 0; /* To align it with the checkbox */
-}
-
-.options-citation-label + label {
-  padding: 3px 0 0 !important; /* To align it with the checkbox */
-  font-style: italic;
-}
-
-.hidden-labels-box:not(.visible) > label,
-.hidden-labels-box.visible ~ .hidden-labels-box > label:last-child {
-  display: none;
-}
--- a/browser/themes/osx/jar.mn
+++ b/browser/themes/osx/jar.mn
@@ -243,19 +243,19 @@ browser.jar:
   skin/classic/browser/tabbrowser/tab-separator.png                      (tabbrowser/tab-separator.png)
   skin/classic/browser/tabbrowser/tab-separator@2x.png                   (tabbrowser/tab-separator@2x.png)
   skin/classic/browser/tabview/close.png                    (tabview/close.png)
   skin/classic/browser/tabview/edit-light.png               (tabview/edit-light.png)
   skin/classic/browser/tabview/search.png                   (tabview/search.png)
   skin/classic/browser/tabview/stack-expander.png           (tabview/stack-expander.png)
   skin/classic/browser/tabview/tabview.png                  (tabview/tabview.png)
   skin/classic/browser/tabview/tabview.css                  (tabview/tabview.css)
-* skin/classic/browser/devtools/common.css                  (devtools/common.css)
-  skin/classic/browser/devtools/dark-theme.css              (../shared/devtools/dark-theme.css)
-  skin/classic/browser/devtools/light-theme.css             (../shared/devtools/light-theme.css)
+* skin/classic/browser/devtools/common.css                  (../shared/devtools/common.css)
+* skin/classic/browser/devtools/dark-theme.css              (../shared/devtools/dark-theme.css)
+* skin/classic/browser/devtools/light-theme.css             (../shared/devtools/light-theme.css)
   skin/classic/browser/devtools/controls.png                (../shared/devtools/controls.png)
 * skin/classic/browser/devtools/widgets.css                 (devtools/widgets.css)
   skin/classic/browser/devtools/commandline-icon.png        (devtools/commandline-icon.png)
   skin/classic/browser/devtools/command-paintflashing.png   (devtools/command-paintflashing.png)
   skin/classic/browser/devtools/command-responsivemode.png  (devtools/command-responsivemode.png)
   skin/classic/browser/devtools/command-scratchpad.png      (devtools/command-scratchpad.png)
   skin/classic/browser/devtools/command-tilt.png            (devtools/command-tilt.png)
   skin/classic/browser/devtools/alerticon-warning.png       (devtools/alerticon-warning.png)
@@ -326,17 +326,16 @@ browser.jar:
   skin/classic/browser/devtools/responsive-vertical-resizer.png (devtools/responsive-vertical-resizer.png)
   skin/classic/browser/devtools/responsive-horizontal-resizer.png (devtools/responsive-horizontal-resizer.png)
   skin/classic/browser/devtools/responsive-background.png   (devtools/responsive-background.png)
   skin/classic/browser/devtools/toggle-tools.png            (devtools/toggle-tools.png)
   skin/classic/browser/devtools/dock-bottom.png             (devtools/dock-bottom.png)
   skin/classic/browser/devtools/dock-side.png               (devtools/dock-side.png)
 * skin/classic/browser/devtools/inspector.css               (devtools/inspector.css)
   skin/classic/browser/devtools/profiler-stopwatch.png      (devtools/profiler-stopwatch.png)
-  skin/classic/browser/devtools/toolbox.css                 (devtools/toolbox.css)
   skin/classic/browser/devtools/tool-options.png            (devtools/tool-options.png)
   skin/classic/browser/devtools/tool-webconsole.png         (devtools/tool-webconsole.png)
   skin/classic/browser/devtools/tool-debugger.png           (devtools/tool-debugger.png)
   skin/classic/browser/devtools/tool-debugger-paused.png    (devtools/tool-debugger-paused.png)
   skin/classic/browser/devtools/tool-inspector.png          (devtools/tool-inspector.png)
   skin/classic/browser/devtools/tool-styleeditor.png        (devtools/tool-styleeditor.png)
   skin/classic/browser/devtools/tool-profiler.png           (devtools/tool-profiler.png)
   skin/classic/browser/devtools/tool-network.png            (devtools/tool-network.png)
--- a/browser/themes/shared/UITour.inc.css
+++ b/browser/themes/shared/UITour.inc.css
@@ -2,19 +2,20 @@
 /* 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/. */
 %endif
 
 /* UI Tour */
 
 html|div#UITourHighlight {
-  border-radius: 20px;
-  border: 2px #5B9CD9 solid;
-  box-shadow: 0 0 2px #5B9CD9, inset 0 0 1px #5B9CD9;
+  background-image: radial-gradient(50% 100%, rgba(0,149,220,0.4) 50%, rgba(0,149,220,0.6) 100%);
+  border-radius: 40px;
+  border: 1px solid white;
+  box-shadow: 0 0 3px 0 rgba(0,0,0,0.5);
   min-height: 32px;
   min-width: 32px;
 }
 
 #UITourTooltip {
   max-width: 20em;
 }
 
new file mode 100644
--- /dev/null
+++ b/browser/themes/shared/devtools/common.css
@@ -0,0 +1,219 @@
+%if 0
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+%endif
+
+:root {
+  font: message-box;
+}
+
+.devtools-monospace {
+%ifdef XP_MACOSX
+  font-family: Menlo, monospace;
+%endif
+%ifdef XP_LINUX
+  font-family: monospace;
+  font-size: 80%;
+%endif
+%ifdef XP_WIN
+  font-family: Consolas, monospace;
+%endif
+}
+
+/* Splitters */
+.devtools-horizontal-splitter {
+  -moz-appearance: none;
+  border-top: 1px solid black;
+  border-bottom-width: 0;
+  min-height: 3px;
+  height: 3px;
+  margin-bottom: -3px;
+  position: relative;
+}
+
+.devtools-side-splitter {
+  -moz-appearance: none;
+  border: 0;
+  -moz-border-start: 1px solid black;
+  min-width: 0;
+  width: 3px;
+  background-color: transparent;
+  -moz-margin-end: -3px;
+  position: relative;
+  cursor: e-resize;
+}
+
+.devtools-toolbox-side-iframe {
+  min-width: 465px;
+}
+
+/* Autocomplete Popup */
+/* Dark and light theme */
+
+.devtools-autocomplete-popup {
+  -moz-appearance: none !important;
+  border: 1px solid hsl(210,11%,10%);
+  box-shadow: 0 1px 0 hsla(209,29%,72%,.25) inset;
+  background-color: transparent;
+  background-image: linear-gradient(to bottom, hsla(209,18%,18%,0.9), hsl(210,11%,16%));
+  border-radius: 3px;
+  overflow-x: hidden;
+%ifdef XP_LINUX
+  max-height: 32rem;
+%else
+  max-height: 40rem;
+%endif
+}
+
+.devtools-autocomplete-listbox {
+  -moz-appearance: none !important;
+  background-color: transparent;
+  border-width: 0px !important;
+}
+
+.devtools-autocomplete-listbox > richlistitem,
+.devtools-autocomplete-listbox > richlistitem[selected] {
+  width: 100%;
+  background-color: transparent;
+  border-radius: 4px;
+}
+
+.devtools-autocomplete-listbox.dark-theme > richlistitem[selected],
+.devtools-autocomplete-listbox.dark-theme > richlistitem:hover {
+  background-color: rgba(0,0,0,0.5);
+}
+
+.devtools-autocomplete-listbox.dark-theme > richlistitem[selected] > .autocomplete-value,
+.devtools-autocomplete-listbox:focus.dark-theme > richlistitem[selected] > .initial-value {
+  color: hsl(208,100%,60%);
+}
+
+.devtools-autocomplete-listbox.dark-theme > richlistitem[selected] > label {
+  color: #eee;
+}
+
+.devtools-autocomplete-listbox.dark-theme > richlistitem > label {
+  color: #ccc;
+}
+
+.devtools-autocomplete-listbox > richlistitem > .initial-value,
+.devtools-autocomplete-listbox > richlistitem > .autocomplete-value {
+  margin: 0;
+  padding: 1px 0;
+}
+
+.devtools-autocomplete-listbox > richlistitem > .autocomplete-count {
+  text-align: right;
+}
+
+/* Rest of the light theme */
+
+.devtools-autocomplete-popup.light-theme {
+  border: 1px solid hsl(210,24%,90%);
+  box-shadow: 0 1px 0 hsla(209,29%,90%,.25) inset;
+  background-image: linear-gradient(to bottom, hsla(209,18%,100%,0.9), hsl(210,24%,95%));
+}
+
+.devtools-autocomplete-listbox.light-theme > richlistitem[selected],
+.devtools-autocomplete-listbox.light-theme > richlistitem:hover {
+  background-color: rgba(128,128,128,0.3);
+}
+
+.devtools-autocomplete-listbox.light-theme > richlistitem[selected] > .autocomplete-value,
+.devtools-autocomplete-listbox:focus.light-theme > richlistitem[selected] > .initial-value {
+  color: #222;
+}
+
+.devtools-autocomplete-listbox.light-theme > richlistitem > label {
+  color: #666;
+}
+
+/* Responsive container */
+
+.devtools-responsive-container {
+  -moz-box-orient: horizontal;
+}
+
+@media (max-width: 700px) {
+  .devtools-responsive-container {
+    -moz-box-orient: vertical;
+  }
+
+  .devtools-responsive-container > .devtools-side-splitter {
+    border: 0;
+    margin: 0;
+    border-top: 1px solid black;
+    min-height: 3px;
+    height: 3px;
+    margin-bottom: -3px;
+    /* In some edge case the cursor is not changed to n-resize */
+    cursor: n-resize;
+  }
+
+  .devtools-responsive-container > .devtools-sidebar-tabs {
+    min-height: 35vh;
+    max-height: 75vh;
+  }
+}
+
+/* Tooltip widget (see browser/devtools/shared/widgets/Tooltip.js) */
+
+.devtools-tooltip .panel-arrowcontent {
+  padding: 4px;
+}
+
+.devtools-tooltip .panel-arrowcontainer {
+  /* Reseting the transition used when panels are shown */
+  transition: none;
+  /* Panels slide up/down/left/right when they appear using a transform.
+  Since we want to remove the transition, we don't need to transform anymore
+  plus it can interfeer by causing mouseleave events on the underlying nodes */
+  transform: none;
+}
+
+.devtools-tooltip[clamped-dimensions] {
+  max-height: 400px;
+  max-width: 400px;
+}
+.devtools-tooltip[clamped-dimensions] .panel-arrowcontent {
+  overflow: hidden;
+}
+
+/* Tooltip: Simple Text */
+
+.devtools-tooltip-simple-text {
+  max-width: 400px;
+  margin: 0 -4px; /* Compensate for the .panel-arrowcontent padding. */
+  padding: 8px 12px;
+  white-space: pre-wrap;
+}
+
+.devtools-tooltip-simple-text:first-child {
+  margin-top: -4px;
+}
+
+.devtools-tooltip-simple-text:last-child {
+  margin-bottom: -4px;
+}
+
+/* Tooltip: Variables View */
+
+.devtools-tooltip-variables-view-box {
+  margin: -4px; /* Compensate for the .panel-arrowcontent padding. */
+}
+
+/* Tooltip: Tiles */
+
+.devtools-tooltip-tiles {
+  background-color: #eee;
+  background-image: linear-gradient(45deg, #ccc 25%, transparent 25%, transparent 75%, #ccc 75%, #ccc),
+    linear-gradient(45deg, #ccc 25%, transparent 25%, transparent 75%, #ccc 75%, #ccc);
+  background-size: 20px 20px;
+  background-position: 0 0, 10px 10px;
+}
+
+.devtools-tooltip-iframe {
+  border: none;
+  background: transparent;
+}
deleted file mode 100644
--- a/browser/themes/shared/devtools/common.inc.css
+++ /dev/null
@@ -1,175 +0,0 @@
-%if 0
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-%endif
-
-/* Autocomplete Popup */
-/* Dark and light theme */
-
-.devtools-autocomplete-popup {
-  -moz-appearance: none !important;
-  border: 1px solid hsl(210,11%,10%);
-  box-shadow: 0 1px 0 hsla(209,29%,72%,.25) inset;
-  background-color: transparent;
-  background-image: linear-gradient(to bottom, hsla(209,18%,18%,0.9), hsl(210,11%,16%));
-  border-radius: 3px;
-  overflow-x: hidden;
-%ifdef XP_LINUX
-  max-height: 32rem;
-%else
-  max-height: 40rem;
-%endif
-}
-
-.devtools-autocomplete-listbox {
-  -moz-appearance: none !important;
-  background-color: transparent;
-  border-width: 0px !important;
-}
-
-.devtools-autocomplete-listbox > richlistitem,
-.devtools-autocomplete-listbox > richlistitem[selected] {
-  width: 100%;
-  background-color: transparent;
-  border-radius: 4px;
-}
-
-.devtools-autocomplete-listbox.dark-theme > richlistitem[selected],
-.devtools-autocomplete-listbox.dark-theme > richlistitem:hover {
-  background-color: rgba(0,0,0,0.5);
-}
-
-.devtools-autocomplete-listbox.dark-theme > richlistitem[selected] > .autocomplete-value,
-.devtools-autocomplete-listbox:focus.dark-theme > richlistitem[selected] > .initial-value {
-  color: hsl(208,100%,60%);
-}
-
-.devtools-autocomplete-listbox.dark-theme > richlistitem[selected] > label {
-  color: #eee;
-}
-
-.devtools-autocomplete-listbox.dark-theme > richlistitem > label {
-  color: #ccc;
-}
-
-.devtools-autocomplete-listbox > richlistitem > .initial-value,
-.devtools-autocomplete-listbox > richlistitem > .autocomplete-value {
-  margin: 0;
-  padding: 1px 0;
-}
-
-.devtools-autocomplete-listbox > richlistitem > .autocomplete-count {
-  text-align: right;
-}
-
-/* Rest of the light theme */
-
-.devtools-autocomplete-popup.light-theme {
-  border: 1px solid hsl(210,24%,90%);
-  box-shadow: 0 1px 0 hsla(209,29%,90%,.25) inset;
-  background-image: linear-gradient(to bottom, hsla(209,18%,100%,0.9), hsl(210,24%,95%));
-}
-
-.devtools-autocomplete-listbox.light-theme > richlistitem[selected],
-.devtools-autocomplete-listbox.light-theme > richlistitem:hover {
-  background-color: rgba(128,128,128,0.3);
-}
-
-.devtools-autocomplete-listbox.light-theme > richlistitem[selected] > .autocomplete-value,
-.devtools-autocomplete-listbox:focus.light-theme > richlistitem[selected] > .initial-value {
-  color: #222;
-}
-
-.devtools-autocomplete-listbox.light-theme > richlistitem > label {
-  color: #666;
-}
-
-/* Responsive container */
-
-.devtools-responsive-container {
-  -moz-box-orient: horizontal;
-}
-
-@media (max-width: 700px) {
-  .devtools-responsive-container {
-    -moz-box-orient: vertical;
-  }
-
-  .devtools-responsive-container > .devtools-side-splitter {
-    border: 0;
-    margin: 0;
-    border-top: 1px solid black;
-    min-height: 3px;
-    height: 3px;
-    margin-bottom: -3px;
-    /* In some edge case the cursor is not changed to n-resize */
-    cursor: n-resize;
-  }
-
-  .devtools-responsive-container > .devtools-sidebar-tabs {
-    min-height: 35vh;
-    max-height: 75vh;
-  }
-}
-
-/* Tooltip widget (see browser/devtools/shared/widgets/Tooltip.js) */
-
-.devtools-tooltip .panel-arrowcontent {
-  padding: 4px;
-}
-
-.devtools-tooltip .panel-arrowcontainer {
-  /* Reseting the transition used when panels are shown */
-  transition: none;
-  /* Panels slide up/down/left/right when they appear using a transform.
-  Since we want to remove the transition, we don't need to transform anymore
-  plus it can interfeer by causing mouseleave events on the underlying nodes */
-  transform: none;
-}
-
-.devtools-tooltip[clamped-dimensions] {
-  max-height: 400px;
-  max-width: 400px;
-}
-.devtools-tooltip[clamped-dimensions] .panel-arrowcontent {
-  overflow: hidden;
-}
-
-/* Tooltip: Simple Text */
-
-.devtools-tooltip-simple-text {
-  max-width: 400px;
-  margin: 0 -4px; /* Compensate for the .panel-arrowcontent padding. */
-  padding: 8px 12px;
-  white-space: pre-wrap;
-}
-
-.devtools-tooltip-simple-text:first-child {
-  margin-top: -4px;
-}
-
-.devtools-tooltip-simple-text:last-child {
-  margin-bottom: -4px;
-}
-
-/* Tooltip: Variables View */
-
-.devtools-tooltip-variables-view-box {
-  margin: -4px; /* Compensate for the .panel-arrowcontent padding. */
-}
-
-/* Tooltip: Tiles */
-
-.devtools-tooltip-tiles {
-  background-color: #eee;
-  background-image: linear-gradient(45deg, #ccc 25%, transparent 25%, transparent 75%, #ccc 75%, #ccc),
-    linear-gradient(45deg, #ccc 25%, transparent 25%, transparent 75%, #ccc 75%, #ccc);
-  background-size: 20px 20px;
-  background-position: 0 0, 10px 10px;
-}
-
-.devtools-tooltip-iframe {
-  border: none;
-  background: transparent;
-}
--- a/browser/themes/shared/devtools/dark-theme.css
+++ b/browser/themes/shared/devtools/dark-theme.css
@@ -42,18 +42,17 @@
 .theme-checkbox[checked] {
   background-position: -42px 0;
 }
 
 .theme-selected {
   background: #26394D;
 }
 
-.theme-bg-darker,
-.cm-s-mozilla .CodeMirror-gutters {
+.theme-bg-darker {
   background-color: rgba(0,0,0,0.5);
 }
 
 .theme-bg-contrast { /* contrast bg color to attract attention on a container */
   background: #a18650;
 }
 
 .theme-link,
@@ -215,16 +214,17 @@ div.CodeMirror span.eval-text {
 }
 
 .cm-s-mozilla .CodeMirror-linenumber { /* line number text */
   color: #5f7387;
 }
 
 .cm-s-mozilla .CodeMirror-gutters { /* vertical line next to line numbers */
   border-right-color: #343c45;
+  background-color: #181d20;
 }
 
 .cm-s-markup-view pre {
   line-height: 1.4em;
   min-height: 1.4em;
 }
 
 /* XUL panel styling (see browser/devtools/shared/widgets/Tooltip.js) */
@@ -274,8 +274,10 @@ div.CodeMirror span.eval-text {
 .theme-tooltip-panel .devtools-tooltip-simple-text {
   color: white;
   border-bottom: 1px solid #434850;
 }
 
 .theme-tooltip-panel .devtools-tooltip-simple-text:last-child {
   border-bottom: 0;
 }
+
+%include toolbars.inc.css
--- a/browser/themes/shared/devtools/light-theme.css
+++ b/browser/themes/shared/devtools/light-theme.css
@@ -42,18 +42,17 @@
 .theme-checkbox[checked] {
   background-position: -14px 0;
 }
 
 .theme-selected {
   background-color: #CCC;
 }
 
-.theme-bg-darker,
-.cm-s-mozilla .CodeMirror-gutters {
+.theme-bg-darker {
   background: #EFEFEF;
 }
 
 .theme-bg-contrast { /* contrast bg color to attract attention on a container */
   background: #a18650;
 }
 
 .theme-link,
@@ -214,16 +213,17 @@ div.CodeMirror span.eval-text {
 }
 
 .cm-s-mozilla .CodeMirror-linenumber { /* line number text */
   color: #667380;
 }
 
 .cm-s-mozilla .CodeMirror-gutters { /* vertical line next to line numbers */
   border-right-color: #a6a6a6;
+  background-color: #f7f7f7;
 }
 
 .cm-s-markup-view pre {
   line-height: 1.4em;
   min-height: 1.4em;
 }
 
 /* XUL panel styling (see browser/devtools/shared/widgets/Tooltip.js) */
@@ -273,8 +273,10 @@ div.CodeMirror span.eval-text {
 .theme-tooltip-panel .devtools-tooltip-simple-text {
   color: black;
   border-bottom: 1px solid #d9e1e8;
 }
 
 .theme-tooltip-panel .devtools-tooltip-simple-text:last-child {
   border-bottom: 0;
 }
+
+%include toolbars.inc.css
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/browser/themes/shared/devtools/toolbars.inc.css
@@ -0,0 +1,575 @@
+%if 0
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+%endif
+%filter substitution
+%define smallSeparator linear-gradient(transparent 15%, #5a6169 15%, #5a6169 85%, transparent 85%)
+%define solidSeparator linear-gradient(#2d5b7d, #2d5b7d)
+
+.devtools-toolbar {
+  -moz-appearance: none;
+  padding: 4px 3px;
+  border-bottom-width: 1px;
+  border-bottom-style: solid;
+}
+
+.devtools-menulist,
+.devtools-toolbarbutton {
+  -moz-appearance: none;
+  -moz-box-align: center;
+  min-width: 78px;
+  min-height: 22px;
+  text-shadow: 0 -1px 0 hsla(210,8%,5%,.45);
+  border: 1px solid hsla(210,8%,5%,.45);
+  border-radius: 3px;
+  background: linear-gradient(hsla(212,7%,57%,.35), hsla(212,7%,57%,.1)) padding-box;
+  box-shadow: 0 1px 0 hsla(210,16%,76%,.15) inset, 0 0 0 1px hsla(210,16%,76%,.15) inset, 0 1px 0 hsla(210,16%,76%,.15);
+  margin: 0 3px;
+  color: inherit;
+}
+
+.devtools-toolbarbutton > .toolbarbutton-menubutton-button {
+  -moz-box-orient: horizontal;
+}
+
+.devtools-menulist:-moz-focusring,
+.devtools-toolbarbutton:-moz-focusring {
+  outline: 1px dotted hsla(210,30%,85%,0.7);
+  outline-offset: -4px;
+}
+
+.devtools-toolbarbutton:not([label]) {
+  min-width: 32px;
+}
+
+.devtools-toolbarbutton:not([label]) > .toolbarbutton-text {
+  display: none;
+}
+
+.devtools-toolbarbutton:not([checked=true]):hover:active {
+  border-color: hsla(210,8%,5%,.6);
+  background: linear-gradient(hsla(220,6%,10%,.3), hsla(212,7%,57%,.15) 65%, hsla(212,7%,57%,.3));
+  box-shadow: 0 0 3px hsla(210,8%,5%,.25) inset, 0 1px 3px hsla(210,8%,5%,.25) inset, 0 1px 0 hsla(210,16%,76%,.15);
+}
+
+.devtools-menulist[open=true],
+.devtools-toolbarbutton[open=true],
+.devtools-toolbarbutton[checked=true] {
+  border-color: hsla(210,8%,5%,.6) !important;
+  background: linear-gradient(hsla(220,6%,10%,.6), hsla(210,11%,18%,.45) 75%, hsla(210,11%,30%,.4));
+  box-shadow: 0 1px 3px hsla(210,8%,5%,.25) inset, 0 1px 3px hsla(210,8%,5%,.25) inset, 0 1px 0 hsla(210,16%,76%,.15);
+}
+
+.devtools-toolbarbutton[checked=true] {
+  color: hsl(208,100%,60%);
+}
+
+.devtools-toolbarbutton[checked=true]:hover {
+  background-color: transparent !important;
+}
+
+.devtools-toolbarbutton[checked=true]:hover:active {
+  background-color: hsla(210,8%,5%,.2) !important;
+}
+
+.devtools-option-toolbarbutton {
+  -moz-appearance: none;
+  list-style-image: url("chrome://browser/skin/devtools/option-icon.png");
+  -moz-image-region: rect(0px 16px 16px 0px);
+  background: none;
+  border: none;
+}
+
+.devtools-option-toolbarbutton[open=true] {
+  -moz-image-region: rect(0px 32px 16px 16px);
+}
+
+.devtools-menulist > .menulist-label-box {
+  text-align: center;
+}
+
+.devtools-menulist > .menulist-dropmarker {
+  -moz-appearance: none;
+  display: -moz-box;
+  list-style-image: url("chrome://browser/skin/devtools/dropmarker.png");
+  -moz-box-align: center;
+  min-width: 16px;
+}
+
+.devtools-toolbarbutton[type=menu-button] > .toolbarbutton-menubutton-button {
+  -moz-appearance: none;
+  color: inherit;
+  border-width: 0;
+  -moz-border-end: 1px solid hsla(210,8%,5%,.45);
+  box-shadow: -1px 0 0 hsla(210,16%,76%,.15) inset, 1px 0 0 hsla(210,16%,76%,.15);
+}
+
+.devtools-toolbarbutton[type=menu-button]:-moz-locale-dir(rtl) > .toolbarbutton-menubutton-button {
+  box-shadow: 1px 0 0 hsla(210,16%,76%,.15) inset, -1px 0 0 hsla(210,16%,76%,.15);
+}
+
+.devtools-toolbarbutton[type=menu-button] {
+  padding: 0 1px;
+  -moz-box-align: stretch;
+}
+
+.devtools-toolbarbutton[type=menu] > .toolbarbutton-menu-dropmarker,
+.devtools-toolbarbutton[type=menu-button] > .toolbarbutton-menubutton-dropmarker {
+  -moz-appearance: none !important;
+  list-style-image: url("chrome://browser/skin/devtools/dropmarker.png");
+  -moz-box-align: center;
+  padding: 0 3px;
+}
+
+/* Text input */
+
+.devtools-textinput,
+.devtools-searchinput {
+  -moz-appearance: none;
+  margin: 0 3px;
+  min-height: 22px;
+  border: 1px solid hsla(210,8%,5%,.6);
+  border-radius: 20px;
+  background-color: transparent;
+  background-image: linear-gradient(hsla(210,16%,76%,.15), hsla(210,16%,76%,.35));
+  padding: 3px;
+  box-shadow: 0 1px 1px hsla(210,8%,5%,.3) inset,
+              0 0 0 1px hsla(210,16%,76%,.1) inset,
+              0 1px 0 hsla(210,16%,76%,.15);
+  color: inherit;
+}
+
+.devtools-searchinput {
+  padding-top: 0;
+  padding-bottom: 0;
+  -moz-padding-start: 18px;
+  -moz-padding-end: 12px;
+  background-image: url(magnifying-glass.png), linear-gradient(hsla(210,16%,76%,.15), hsla(210,16%,76%,.35));
+  background-position: 4px center, top left, top left;
+  background-repeat: no-repeat;
+  font-size: inherit;
+}
+
+.devtools-searchinput:-moz-locale-dir(rtl) {
+  background-position: calc(100% - 4px) center, top left, top left;
+}
+
+.devtools-searchinput > .textbox-input-box > .textbox-search-icons {
+  display: none;
+}
+
+.devtools-searchinput > .textbox-input-box > .textbox-input::-moz-placeholder {
+  color: hsl(208,10%,66%);
+  opacity: 1.0;
+}
+
+.devtools-no-search-result {
+  box-shadow: inset 0 0 0 1px hsla(0,68%,6%,.35);
+  border-color: hsl(10,70%,40%) hsl(10,75%,37%) hsl(10,80%,35%) !important;
+  background-image: url(magnifying-glass.png), linear-gradient(hsla(1,16%,76%,.45), hsla(1,16%,76%,.75));
+}
+
+/* Close button */
+
+.devtools-closebutton {
+  list-style-image: url("chrome://browser/skin/devtools/close.png");
+  -moz-appearance: none;
+  border: none;
+  margin: 0 4px;
+  min-width: 16px;
+  width: 16px;
+  opacity: 0.6;
+}
+
+.devtools-closebutton > .toolbarbutton-icon {
+  /* XXX Buttons have padding in widget/ that we don't want here but can't override with good CSS, so we must
+     use evil CSS to give the impression of smaller content */
+  margin: -4px;
+}
+
+.devtools-closebutton > .toolbarbutton-text {
+  display: none;
+}
+
+.devtools-closebutton:hover {
+  opacity: 0.8;
+}
+
+.devtools-closebutton:hover:active {
+  opacity: 1;
+}
+
+/* In-tools sidebar */
+
+.devtools-sidebar-tabs {
+  -moz-appearance: none;
+  margin: 0;
+}
+
+.devtools-sidebar-tabs > tabpanels {
+  -moz-appearance: none;
+  padding: 0;
+  border: 0;
+}
+
+.devtools-sidebar-tabs > tabs {
+  -moz-appearance: none;
+  position: static;
+  font: inherit;
+  color: #b6babf;
+  margin-bottom: 0;
+  padding: 0;
+  background-color: #343c45;
+  border-width: 0 0 1px 0;
+  border-color: hsla(210,8%,5%,.6);
+  border-style: solid;
+  overflow: hidden;
+}
+
+.devtools-sidebar-tabs > tabs > .tabs-right,
+.devtools-sidebar-tabs > tabs > .tabs-left {
+  display: none;
+}
+
+.devtools-sidebar-tabs > tabs > tab {
+  -moz-appearance: none;
+  /* We want to match the height of a toolbar with a toolbarbutton
+   * First, we need to replicated the padding of toolbar (4px),
+   * then we need to take the border of the buttons into account (1px).
+   */
+  padding: 5px 3px;
+  -moz-padding-start: 6px;
+  margin: 0;
+  min-width: 78px;
+  /* toolbar's min-height is button min-height (25px) + padding (2 * 4px): 33px.
+   * -1px because the parent element (<tabs>) comes with a 1px bottom border.
+   */
+  min-height: 32px;
+  text-shadow: 0 -1px 0 hsla(210,8%,5%,.45);
+  text-align: center;
+  color: inherit;
+  -moz-box-flex: 1;
+  border-width: 0;
+  position: static;
+  -moz-margin-start: -1px;
+}
+
+.devtools-sidebar-tabs > tabs > tab:first-of-type {
+  -moz-margin-start: -3px;
+}
+
+.devtools-sidebar-tabs > tabs > tab {
+  background-size: calc(100% - 2px) 100%, 1px 100%;
+  background-repeat: no-repeat;
+  background-position: 1px, 0;
+}
+
+.devtools-sidebar-tabs:-moz-locale-dir(rtl) > tabs > tab {
+  background-position: calc(100% - 1px), 100%;
+}
+
+.devtools-sidebar-tabs > tabs > tab {
+  background-color: transparent;
+  background-image: linear-gradient(transparent, transparent), @smallSeparator@;
+}
+
+.devtools-sidebar-tabs > tabs > tab:hover {
+  background-image: linear-gradient(hsla(206,37%,4%,.2), hsla(206,37%,4%,.2)), @smallSeparator@;
+}
+
+.devtools-sidebar-tabs > tabs > tab:hover:active {
+  background-image: linear-gradient(hsla(206,37%,4%,.4), hsla(206,37%,4%,.4)), @smallSeparator@;
+}
+
+.devtools-sidebar-tabs > tabs > tab[selected=true] + tab {
+  background-image: linear-gradient(transparent, transparent), @solidSeparator@;
+}
+
+.devtools-sidebar-tabs > tabs > tab[selected=true] + tab:hover {
+  background-image: linear-gradient(hsla(206,37%,4%,.2), hsla(206,37%,4%,.2)), @solidSeparator@;
+}
+
+.devtools-sidebar-tabs > tabs > tab[selected=true] + tab:hover:active {
+  background-image: linear-gradient(hsla(206,37%,4%,.4), hsla(206,37%,4%,.4)), @solidSeparator@;
+}
+
+.devtools-sidebar-tabs > tabs > tab[selected=true] {
+  color: #f5f7fa;
+  background-image: linear-gradient(#1d4f73, #1d4f73), @solidSeparator@;
+}
+
+.devtools-sidebar-tabs > tabs > tab[selected=true]:hover {
+  background-image: linear-gradient(#274f64, #274f64), @solidSeparator@;
+}
+
+.devtools-sidebar-tabs > tabs > tab[selected=true]:hover:active {
+  background-image: linear-gradient(#1f3e4f, #1f3e4f), @solidSeparator@;
+}
+
+/* Toolbox - moved from toolbox.css.
+ * Rules that apply to the global toolbox like command buttons,
+ * devtools tabs, docking buttons, etc. */
+
+#toolbox-controls {
+  margin: 0 4px;
+}
+
+#toolbox-controls > toolbarbutton,
+#toolbox-dock-buttons > toolbarbutton {
+  -moz-appearance: none;
+  margin: 0 4px;
+  min-width: 16px;
+  width: 16px;
+}
+
+#toolbox-controls > toolbarbutton > .toolbarbutton-text,
+#toolbox-dock-buttons > toolbarbutton > .toolbarbutton-text,
+.command-button > .toolbarbutton-text {
+  display: none;
+}
+
+#toolbox-dock-bottom {
+  list-style-image: url("chrome://browser/skin/devtools/dock-bottom.png");
+}
+
+#toolbox-dock-side {
+  list-style-image: url("chrome://browser/skin/devtools/dock-side.png");
+}
+
+#toolbox-dock-window {
+  list-style-image: url("chrome://browser/skin/devtools/undock.png");
+}
+
+#toolbox-dock-window,
+#toolbox-dock-bottom,
+#toolbox-dock-side {
+  opacity: 0.6;
+}
+
+#toolbox-dock-window:hover,
+#toolbox-dock-bottom:hover,
+#toolbox-dock-side:hover {
+  opacity: 1;
+}
+
+#toolbox-controls-separator {
+  width: 3px;
+  background-image: linear-gradient(hsla(204,45%,98%,0), hsla(204,45%,98%,.1), hsla(204,45%,98%,0)),
+                    linear-gradient(hsla(206,37%,4%,0), hsla(206,37%,4%,.6), hsla(206,37%,4%,0)),
+                    linear-gradient(hsla(204,45%,98%,0), hsla(204,45%,98%,.1), hsla(204,45%,98%,0));
+  background-size: 1px 100%;
+  background-repeat: no-repeat;
+  background-position: 0, 1px, 2px;
+  -moz-margin-start: 8px;
+}
+
+/* Command buttons */
+
+.command-button {
+  -moz-appearance: none;
+  padding: 0 8px;
+  margin: 0;
+  width: 16px;
+}
+
+.command-button:hover {
+  background-color: hsla(206,37%,4%,.2);
+}
+.command-button:hover:active, .command-button[checked=true]:not(:hover) {
+  background-color: hsla(206,37%,4%,.4);
+}
+
+#command-button-paintflashing {
+  list-style-image: url("chrome://browser/skin/devtools/command-paintflashing.png");
+  -moz-image-region: rect(0px, 16px, 16px, 0px);
+}
+#command-button-paintflashing:hover {
+  -moz-image-region: rect(0px, 32px, 16px, 16px);
+}
+#command-button-paintflashing:hover:active {
+  -moz-image-region: rect(0px, 48px, 16px, 32px);
+}
+#command-button-paintflashing[checked=true] {
+  -moz-image-region: rect(0px, 64px, 16px, 48px);
+}
+
+#command-button-responsive {
+  list-style-image: url("chrome://browser/skin/devtools/command-responsivemode.png");
+  -moz-image-region: rect(0px, 16px, 16px, 0px);
+}
+#command-button-responsive:hover {
+  -moz-image-region: rect(0px, 32px, 16px, 16px);
+}
+#command-button-responsive:hover:active {
+  -moz-image-region: rect(0px, 48px, 16px, 32px);
+}
+#command-button-responsive[checked=true] {
+  -moz-image-region: rect(0px, 64px, 16px, 48px);
+}
+
+#command-button-tilt {
+  list-style-image: url("chrome://browser/skin/devtools/command-tilt.png");
+  -moz-image-region: rect(0px, 16px, 16px, 0px);
+}
+#command-button-tilt:hover {
+  -moz-image-region: rect(0px, 32px, 16px, 16px);
+}
+
+#command-button-tilt:hover:active {
+  -moz-image-region: rect(0px, 48px, 16px, 32px);
+}
+
+#command-button-tilt[checked=true] {
+  -moz-image-region: rect(0px, 64px, 16px, 48px);
+}
+
+#command-button-scratchpad {
+  list-style-image: url("chrome://browser/skin/devtools/command-scratchpad.png");
+  -moz-image-region: rect(0px, 16px, 16px, 0px);
+}
+
+#command-button-scratchpad:hover {
+  -moz-image-region: rect(0px, 32px, 16px, 16px);
+}
+
+#command-button-scratchpad:hover:active {
+  -moz-image-region: rect(0px, 48px, 16px, 32px);
+}
+
+/* Tabs */
+
+.devtools-tabbar {
+  -moz-appearance: none;
+  background-image: url("background-noise-toolbar.png"),
+                    linear-gradient(#303840, #2d3640);
+  border-color: #060a0d;
+  border-style: solid;
+  border-width: 1px 0;
+  box-shadow: 0 1px 0 hsla(204,45%,98%,.05) inset,
+              0 -1px 0 hsla(206,37%,4%,.1) inset;
+  min-height: 32px;
+  padding: 0;
+}
+
+#toolbox-tabs {
+  margin: 0;
+}
+
+.devtools-tab {
+  -moz-binding: url("chrome://global/content/bindings/general.xml#control-item");
+  -moz-box-align: center;
+}
+
+.devtools-tab {
+  -moz-appearance: none;
+  min-width: 32px;
+  min-height: 32px;
+  max-width: 127px;
+  color: #b6babf;
+  margin: 0;
+  padding: 0;
+  background-image: linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1)),
+                    linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1));
+  background-size: 1px 100%;
+  background-repeat: no-repeat;
+  background-position: left, right;
+  border-right: 1px solid hsla(206,37%,4%,.45);
+  -moz-box-align: center;
+}
+
+.devtools-tab > image {
+  border: none;
+  -moz-margin-end: 0;
+  -moz-margin-start: 4px;
+  opacity: 0.6;
+  max-height: 16px;
+  width: 16px; /* Prevents collapse during theme switching */
+}
+
+#toolbox-tab-options > image {
+  margin: 0 8px;
+}
+
+.devtools-tab > label {
+  white-space: nowrap;
+}
+
+.devtools-tab:hover > image {
+  opacity: 0.8;
+}
+
+.devtools-tab:active > image,
+.devtools-tab[selected=true] > label {
+  opacity: 1;
+}
+
+.devtools-tab:hover {
+  background-image: linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1)),
+                    linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1)),
+                    linear-gradient(hsla(206,37%,4%,.1), hsla(206,37%,4%,.2));
+  background-size: 1px 100%,
+                   1px 100%,
+                   100%;
+  background-repeat: no-repeat,
+                     no-repeat,
+                     repeat-x;
+  background-position: left, right;
+  color: #ced3d9;
+}
+.devtools-tab:hover:active {
+  background-color: hsla(206,37%,4%,.2);
+  color: #f5f7fa;
+}
+
+.devtools-tab[selected=true] {
+  color: #f5f7fa;
+  background-image: radial-gradient(farthest-corner at center top, #9fdfff, hsla(200,100%,70%,.3)),
+                    radial-gradient(farthest-side at center top, hsla(200,100%,70%,.4), hsla(200,100%,70%,0)),
+                    linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1)),
+                    linear-gradient(hsla(204,45%,98%,.02), hsla(204,45%,98%,.04)),
+                    linear-gradient(hsla(206,37%,4%,.2), hsla(206,37%,4%,.3));
+  background-size: 100% 1px,
+                   100% 5px,
+                   1px 100%,
+                   1px 100%,
+                   100%;
+  background-repeat: no-repeat,
+                     no-repeat,
+                     no-repeat,
+                     no-repeat,
+                     repeat-x;
+  background-position: top right, top left, left, right;
+  box-shadow: 1px -1px 0 hsla(206,37%,4%,.2) inset;
+}
+
+.devtools-tab:not([selected=true]).highlighted {
+  color: #f5f7fa;
+  background-image: radial-gradient(farthest-corner at center top, #c0ff40, hsla(80,100%,63%,.5) 70%, hsla(80,100%,63%,.3) 97%),
+                    radial-gradient(farthest-side at center top, hsla(80,100%,35%,.5), hsla(80,100%,35%,0)),
+                    linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1)),
+                    linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1)),
+                    linear-gradient(hsla(99,100%,14%,.2), hsla(99,100%,14%,.2));
+  background-size: 100% 1px,
+                   100% 5px,
+                   1px 100%,
+                   1px 100%,
+                   100%;
+  background-repeat: no-repeat,
+                     no-repeat,
+                     no-repeat,
+                     no-repeat,
+                     repeat-x;
+  background-position: top right, top left, left, right;
+}
+
+.devtools-tab:not(.highlighted) > .highlighted-icon,
+.devtools-tab[selected=true] > .highlighted-icon,
+.devtools-tab:not([selected=true]).highlighted > .default-icon {
+  visibility: collapse;
+}
+
+.hidden-labels-box:not(.visible) > label,
+.hidden-labels-box.visible ~ .hidden-labels-box > label:last-child {
+  display: none;
+}
deleted file mode 100644
--- a/browser/themes/windows/devtools/common.css
+++ /dev/null
@@ -1,364 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* Font for code */
-
-:root {
-  font: message-box;
-}
-
-.devtools-monospace {
-  font-family: Consolas, monospace;
-}
-
-/* Toolbar and Toolbar items */
-
-.devtools-toolbar {
-  -moz-appearance: none;
-  padding: 4px 3px;
-  border-bottom-width: 1px;
-  border-bottom-style: solid;
-}
-
-.devtools-menulist,
-.devtools-toolbarbutton {
-  -moz-appearance: none;
-  -moz-box-align: center;
-  min-width: 78px;
-  min-height: 22px;
-  text-shadow: 0 -1px 0 hsla(210,8%,5%,.45);
-  border: 1px solid hsla(211,68%,6%,.5);
-  border-radius: 3px;
-  background: linear-gradient(hsla(209,13%,54%,.35), hsla(209,13%,54%,.1) 85%, hsla(209,13%,54%,.2)) padding-box;
-  box-shadow: 0 1px 0 hsla(209,29%,72%,.15) inset, 0 0 0 1px hsla(209,29%,72%,.1) inset, 0 0 0 1px hsla(209,29%,72%,.1), 0 1px 0 hsla(210,16%,76%,.1);
-  margin: 0;
-  -moz-margin-end: 3px;
-  color: inherit;
-}
-
-.devtools-toolbarbutton > .toolbarbutton-menubutton-button {
-  -moz-box-orient: horizontal;
-}
-
-.devtools-menulist:-moz-focusring,
-.devtools-toolbarbutton:-moz-focusring {
-  outline: 1px dotted hsla(210,30%,85%,0.7);
-  outline-offset: -4px;
-}
-
-.devtools-toolbarbutton > .toolbarbutton-icon {
-  margin: 0;
-}
-
-.devtools-toolbarbutton:not([label]) {
-  min-width: 32px;
-}
-
-.devtools-toolbarbutton:not([label]) > .toolbarbutton-text {
-  display: none;
-}
-
-.devtools-toolbarbutton:not([checked=true]):hover:active {
-  background-color: hsla(210,18%,9%,.1);
-  background-image: linear-gradient(hsla(209,13%,54%,.35), hsla(209,13%,54%,.1) 85%, hsla(209,13%,54%,.2));
-  box-shadow: 0 1px 3px hsla(211,68%,6%,.5) inset, 0 0 0 1px hsla(209,29%,72%,.1), 0 1px 0 hsla(210,16%,76%,.1);
-}
-
-.devtools-menulist[open=true],
-.devtools-toolbarbutton[open=true],
-.devtools-toolbarbutton[checked=true] {
-  border-color: hsla(211,68%,6%,.6);
-  background: linear-gradient(hsla(211,68%,6%,.1), hsla(211,68%,6%,.2));
-  box-shadow: 0 1px 3px hsla(211,68%,6%,.5) inset, 0 0 0 1px hsla(209,29%,72%,.1), 0 1px 0 hsla(210,16%,76%,.1);
-}
-
-.devtools-toolbarbutton[checked=true] {
-  color: hsl(200,100%,60%) !important;
-}
-
-.devtools-toolbarbutton[checked=true]:hover:active {
-  background-color: hsla(211,68%,6%,.2);
-}
-
-.devtools-option-toolbarbutton {
-  -moz-appearance: none;
-  list-style-image: url("chrome://browser/skin/devtools/option-icon.png");
-  -moz-image-region: rect(0px 16px 16px 0px);
-  background: none;
-  border: none;
-}
-
-.devtools-option-toolbarbutton[open=true] {
-  -moz-image-region: rect(0px 32px 16px 16px);
-}
-
-.devtools-menulist > .menulist-label-box {
-  text-align: center;
-}
-
-.devtools-menulist > .menulist-dropmarker {
-  -moz-appearance: none;
-  list-style-image: url("chrome://browser/skin/devtools/dropmarker.png");
-  border-width: 0;
-  background-color: transparent;
-}
-
-.devtools-menulist:focus:not([open="true"]):not(.menulist-compact) > .menulist-label-box {
-  color: hsl(210,30%,85%) !important;
-  background-color: transparent;
-}
-
-.devtools-toolbarbutton[type=menu-button] > .toolbarbutton-menubutton-button {
-  -moz-appearance: none;
-  color: inherit;
-  border-width: 0;
-  -moz-border-end: 1px solid hsla(210,8%,5%,.45);
-  box-shadow: -1px 0 0 hsla(210,16%,76%,.15) inset, 1px 0 0 hsla(210,16%,76%,.15);
-}
-
-.devtools-toolbarbutton[type=menu-button]:-moz-locale-dir(rtl) > .toolbarbutton-menubutton-button {
-  box-shadow: 1px 0 0 hsla(210,16%,76%,.15) inset, -1px 0 0 hsla(210,16%,76%,.15);
-}
-
-.devtools-toolbarbutton[type=menu-button] {
-  padding: 0 1px;
-  -moz-box-align: stretch;
-}
-
-.devtools-toolbarbutton[type=menu] > .toolbarbutton-menu-dropmarker,
-.devtools-toolbarbutton[type=menu-button] > .toolbarbutton-menubutton-dropmarker {
-  -moz-appearance: none !important;
-  list-style-image: url("chrome://browser/skin/devtools/dropmarker.png");
-  -moz-box-align: center;
-}
-
-/* Text input */
-
-.devtools-textinput,
-.devtools-searchinput {
-  -moz-appearance: none;
-  margin: 0 3px;
-  min-height: 22px;
-  border: 1px solid hsla(211,68%,6%,.6);
-  box-shadow: inset 0 1px 0 hsla(211,68%,6%,.05), 0 0 0 1px hsla(210,40%,83%,.1);
-  border-radius: 2px;
-  background-color: transparent;
-  background-image: linear-gradient(hsla(210,16%,76%,.15), hsla(210,16%,76%,.35));
-  padding: 3px;
-  transition-property: background-color, border-color, box-shadow;
-  transition-duration: 150ms;
-  transition-timing-function: ease;
-  color: inherit;
-}
-
-.devtools-searchinput {
-  background-image: url(magnifying-glass.png), linear-gradient(hsla(210,16%,76%,.15), hsla(210,16%,76%,.35));
-  background-repeat: no-repeat;
-  background-position: 4px center, top left, top left;
-  padding-top: 0;
-  padding-bottom: 0;
-  -moz-padding-start: 18px;
-  -moz-padding-end: 12px;
-  font-size: inherit;
-}
-
-.devtools-searchinput[focused] {
-  border-color: hsl(200,70%,40%) hsl(200,75%,37%) hsl(200,80%,35%);
-  background-origin: padding-box;
-  background-clip: padding-box;
-  box-shadow: inset 0 0 0 1px hsla(211,68%,6%,.1);
-}
-
-.devtools-searchinput:-moz-locale-dir(rtl) {
-  background-position: calc(100% - 4px) center, top left, top left;
-}
-
-.devtools-searchinput > .textbox-input-box > .textbox-search-icons {
-  display: none;
-}
-
-.devtools-searchinput > .textbox-input-box > .textbox-input::-moz-placeholder {
-  opacity: 1.0;
-  color: hsl(208,10%,66%);
-}
-
-.devtools-no-search-result {
-  box-shadow: inset 0 0 0 1px hsla(0,68%,6%,.35);
-  border-color: hsl(10,70%,40%) hsl(10,75%,37%) hsl(10,80%,35%) !important;
-  background-image: url(magnifying-glass.png), linear-gradient(hsla(1,16%,76%,.45), hsla(1,16%,76%,.75));
-}
-
-/* Close button */
-
-.devtools-closebutton {
-  list-style-image: url("chrome://browser/skin/devtools/close.png");
-  -moz-appearance: none;
-  border: none;
-  margin: 0 4px;
-  min-width: 16px;
-  width: 16px;
-  opacity: 0.6;
-}
-
-.devtools-closebutton > .toolbarbutton-text {
-  display: none;
-}
-
-.devtools-closebutton:hover {
-  opacity: 0.8;
-}
-
-.devtools-closebutton:hover:active {
-  opacity: 1;
-}
-
-/* Splitters */
-
-.devtools-horizontal-splitter {
-  -moz-appearance: none;
-  border-width: 1px 0 0 0;
-  -moz-border-top-colors: black;
-  background-color: transparent;
-  min-height: 3px;
-  height: 3px;
-  margin-bottom: -3px;
-  position: relative;
-}
-
-.devtools-side-splitter {
-  border: 0;
-  -moz-border-start: 1px solid #242b33;
-  min-width: 0;
-  width: 3px;
-  background-color: transparent;
-  -moz-margin-end: -3px;
-  position: relative;
-  cursor: e-resize;
-}
-
-/* In-tools sidebar */
-
-.devtools-toolbox-side-iframe {
-  min-width: 465px;
-}
-
-.devtools-sidebar-tabs {
-  -moz-appearance: none;
-  margin: 0;
-}
-
-.devtools-sidebar-tabs > tabpanels {
-  -moz-appearance: none;
-  padding: 0;
-  border: 0;
-}
-
-.devtools-sidebar-tabs > tabs {
-  -moz-appearance: none;
-  position: static;
-  color: #b6babf;
-  margin-bottom: 0;
-  padding: 0;
-  background-color: #343c45;
-  border-width: 0 0 1px 0;
-  border-color: hsla(210,8%,5%,.6);
-  border-style: solid;
-  overflow: hidden;
-}
-
-.devtools-sidebar-tabs > tabs > .tabs-right,
-.devtools-sidebar-tabs > tabs > .tabs-left {
-  display: none;
-}
-
-.devtools-sidebar-tabs > tabs > tab {
-  -moz-appearance: none;
-  /* We want to match the height of a toolbar with a toolbarbutton
-   * First, we need to replicated the padding of toolbar (4px),
-   * then we need to take the border of the buttons into account (1px).
-   */
-  padding: 5px 3px;
-  -moz-padding-start: 6px;
-  margin: 0;
-  min-width: 78px;
-  /* toolbar's min-height is button min-height (25px) + padding (2 * 4px): 33px.
-   * -1px because the parent element (<tabs>) comes with a 1px bottom border.
-   */
-  min-height: 32px;
-  text-shadow: 0 -1px 0 hsla(210,8%,5%,.45);
-  text-align: center;
-  color: inherit;
-  -moz-box-flex: 1;
-  border-width: 0;
-  background: transparent;
-  border-radius: 0;
-  position: static;
-  -moz-margin-start: -1px;
-}
-
-.devtools-sidebar-tabs > tabs > tab:-moz-focusring {
-  position: static;
-}
-
-.devtools-sidebar-tabs > tabs > tab:last-of-type {
-  -moz-border-end-width: 0;
-}
-
-.devtools-sidebar-tabs > tabs > tab:first-of-type {
-  -moz-margin-start: -3px;
-}
-
-.devtools-sidebar-tabs > tabs > tab {
-  background-size: calc(100% - 2px) 100%, 1px 100%;
-  background-repeat: no-repeat;
-  background-position: 1px, 0;
-}
-
-.devtools-sidebar-tabs:-moz-locale-dir(rtl) > tabs > tab {
-  background-position: calc(100% - 1px), 100%;
-}
-
-%filter substitution
-%define smallSeparator linear-gradient(transparent 15%, #5a6169 15%, #5a6169 85%, transparent 85%)
-%define solidSeparator linear-gradient(#2d5b7d, #2d5b7d)
-
-.devtools-sidebar-tabs > tabs > tab {
-  background-image: linear-gradient(transparent, transparent), @smallSeparator@;
-}
-
-.devtools-sidebar-tabs > tabs > tab:hover {
-  background-image: linear-gradient(hsla(206,37%,4%,.2), hsla(206,37%,4%,.2)), @smallSeparator@;
-}
-
-.devtools-sidebar-tabs > tabs > tab:hover:active {
-  background-image: linear-gradient(hsla(206,37%,4%,.4), hsla(206,37%,4%,.4)), @smallSeparator@;
-}
-
-.devtools-sidebar-tabs > tabs > tab[selected=true] + tab {
-  background-image: linear-gradient(transparent, transparent), @solidSeparator@;
-}
-
-.devtools-sidebar-tabs > tabs > tab[selected=true] + tab:hover {
-  background-image: linear-gradient(hsla(206,37%,4%,.2), hsla(206,37%,4%,.2)), @solidSeparator@;
-}
-
-.devtools-sidebar-tabs > tabs > tab[selected=true] + tab:hover:active {
-  background-image: linear-gradient(hsla(206,37%,4%,.4), hsla(206,37%,4%,.4)), @solidSeparator@;
-}
-
-.devtools-sidebar-tabs > tabs > tab[selected=true] {
-  color: #f5f7fa;
-  background-image: linear-gradient(#1d4f73, #1d4f73), @solidSeparator@;
-}
-
-.devtools-sidebar-tabs > tabs > tab[selected=true]:hover {
-  background-image: linear-gradient(#274f64, #274f64), @solidSeparator@;
-}
-
-.devtools-sidebar-tabs > tabs > tab[selected=true]:hover:active {
-  background-image: linear-gradient(#1f3e4f, #1f3e4f), @solidSeparator@;
-}
-
-%include ../../shared/devtools/common.inc.css
deleted file mode 100644
--- a/browser/themes/windows/devtools/toolbox.css
+++ /dev/null
@@ -1,283 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#toolbox-controls {
-  margin: 0 4px;
-}
-
-#toolbox-controls > toolbarbutton,
-#toolbox-dock-buttons > toolbarbutton {
-  -moz-appearance: none;
-  border: none;
-  margin: 0 4px;
-  min-width: 16px;
-  width: 16px;
-}
-
-#toolbox-dock-bottom {
-  list-style-image: url("chrome://browser/skin/devtools/dock-bottom.png");
-}
-
-#toolbox-dock-side {
-  list-style-image: url("chrome://browser/skin/devtools/dock-side.png");
-}
-
-#toolbox-dock-window {
-  list-style-image: url("chrome://browser/skin/devtools/undock.png");
-}
-
-#toolbox-dock-window,
-#toolbox-dock-bottom,
-#toolbox-dock-side {
-  opacity: 0.6;
-}
-
-#toolbox-dock-window:hover,
-#toolbox-dock-bottom:hover,
-#toolbox-dock-side:hover {
-  opacity: 1;
-}
-
-#toolbox-controls-separator {
-  width: 3px;
-  background-image: linear-gradient(hsla(204,45%,98%,0), hsla(204,45%,98%,.1), hsla(204,45%,98%,0)),
-                    linear-gradient(hsla(206,37%,4%,0), hsla(206,37%,4%,.6), hsla(206,37%,4%,0)),
-                    linear-gradient(hsla(204,45%,98%,0), hsla(204,45%,98%,.1), hsla(204,45%,98%,0));
-  background-size: 1px 100%;
-  background-repeat: no-repeat;
-  background-position: 0, 1px, 2px;
-  -moz-margin-start: 8px;
-}
-
-
-/* Command buttons */
-
-.command-button {
-  -moz-appearance: none;
-  border: none;
-  margin: 0;
-  padding: 0 8px;
-  width: 16px;
-}
-
-.command-button:hover {
-  background-color: hsla(206,37%,4%,.2);
-}
-.command-button:hover:active, .command-button[checked=true]:not(:hover) {
-  background-color: hsla(206,37%,4%,.4);
-}
-
-#command-button-paintflashing {
-  list-style-image: url("chrome://browser/skin/devtools/command-paintflashing.png");
-  -moz-image-region: rect(0px, 16px, 16px, 0px);
-}
-#command-button-paintflashing:hover {
-  -moz-image-region: rect(0px, 32px, 16px, 16px);
-}
-#command-button-paintflashing:hover:active {
-  -moz-image-region: rect(0px, 48px, 16px, 32px);
-}
-#command-button-paintflashing[checked=true] {
-  -moz-image-region: rect(0px, 64px, 16px, 48px);
-}
-
-#command-button-responsive {
-  list-style-image: url("chrome://browser/skin/devtools/command-responsivemode.png");
-  -moz-image-region: rect(0px, 16px, 16px, 0px);
-}
-#command-button-responsive:hover {
-  -moz-image-region: rect(0px, 32px, 16px, 16px);
-}
-#command-button-responsive:hover:active {
-  -moz-image-region: rect(0px, 48px, 16px, 32px);
-}
-#command-button-responsive[checked=true] {
-  -moz-image-region: rect(0px, 64px, 16px, 48px);
-}
-
-#command-button-tilt {
-  list-style-image: url("chrome://browser/skin/devtools/command-tilt.png");
-  -moz-image-region: rect(0px, 16px, 16px, 0px);
-}
-#command-button-tilt:hover {
-  -moz-image-region: rect(0px, 32px, 16px, 16px);
-}
-
-#command-button-tilt:hover:active {
-  -moz-image-region: rect(0px, 48px, 16px, 32px);
-}
-
-#command-button-tilt[checked=true] {
-  -moz-image-region: rect(0px, 64px, 16px, 48px);
-}
-
-#command-button-scratchpad {
-  list-style-image: url("chrome://browser/skin/devtools/command-scratchpad.png");
-  -moz-image-region: rect(0px, 16px, 16px, 0px);
-}
-
-#command-button-scratchpad:hover {
-  -moz-image-region: rect(0px, 32px, 16px, 16px);
-}
-
-#command-button-scratchpad:hover:active {
-  -moz-image-region: rect(0px, 48px, 16px, 32px);
-}
-
-/* Tabs */
-
-.devtools-tabbar {
-  -moz-appearance: none;
-  background-image: url("background-noise-toolbar.png"),
-                    linear-gradient(#303840, #2d3640);
-  border-bottom: 1px solid #060a0d;
-  box-shadow: 0 1px 0 hsla(204,45%,98%,.05) inset,
-              0 -1px 0 hsla(206,37%,4%,.1) inset;
-  min-height: 32px;
-  padding: 0;
-}
-
-#toolbox-tabs {
-  margin: 0;
-}
-
-.devtools-tab {
-  -moz-appearance: none;
-  min-width: 32px;
-  min-height: 32px;
-  max-width: 110px;
-  color: #b6babf;
-  margin: 0;
-  padding: 0;
-  background-image: linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1)),
-                    linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1));
-  background-size: 1px 100%;
-  background-repeat: no-repeat;
-  background-position: left, right;
-  border-top: 1px solid #060a0d;
-  border-right: 1px solid hsla(206,37%,4%,.45);
-}
-
-.devtools-tab > image {
-  -moz-margin-end: 0;
-  -moz-margin-start: 4px;
-  opacity: 0.6;
-  width: 16px; /* Prevents collapse during theme switching */
-}
-
-#toolbox-tab-options > image {
-  margin: 0 8px;
-}
-
-.devtools-tab:hover > image {
-  opacity: 0.8;
-}
-
-.devtools-tab:active > image,
-.devtools-tab[selected=true] > image {
-  opacity: 1;
-}
-
-.devtools-tab:hover {
-  background-image: linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1)),
-                    linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1)),
-                    linear-gradient(hsla(206,37%,4%,.1), hsla(206,37%,4%,.2));
-  background-size: 1px 100%,
-                   1px 100%,
-                   100%;
-  background-repeat: no-repeat,
-                     no-repeat,
-                     repeat-x;
-  background-position: left, right;
-  color: #ced3d9;
-}
-.devtools-tab:hover:active {
-  background-color: hsla(206,37%,4%,.2);
-  color: #f5f7fa;
-}
-
-.devtools-tab[selected=true] {
-  color: #f5f7fa;
-  background-image: radial-gradient(farthest-corner at center top, #9fdfff, hsla(200,100%,70%,.3)),
-                    radial-gradient(farthest-side at center top, hsla(200,100%,70%,.4), hsla(200,100%,70%,0)),
-                    linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1)),
-                    linear-gradient(hsla(204,45%,98%,.02), hsla(204,45%,98%,.04)),
-                    linear-gradient(hsla(206,37%,4%,.2), hsla(206,37%,4%,.3));
-  background-size: 100% 1px,
-                   100% 5px,
-                   1px 100%,
-                   1px 100%,
-                   100%;
-  background-repeat: no-repeat,
-                     no-repeat,
-                     no-repeat,
-                     no-repeat,
-                     repeat-x;
-  background-position: top right, top left, left, right;
-  box-shadow: 1px -1px 0 hsla(206,37%,4%,.2) inset;
-}
-
-.devtools-tab:not([selected=true]).highlighted {
-  color: #f5f7fa;
-  background-image: radial-gradient(farthest-corner at center top, #c0ff40, hsla(80,100%,63%,.5) 70%, hsla(80,100%,63%,.3) 97%),
-                    radial-gradient(farthest-side at center top, hsla(80,100%,35%,.5), hsla(80,100%,35%,0)),
-                    linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1)),
-                    linear-gradient(hsla(204,45%,98%,.05), hsla(204,45%,98%,.1)),
-                    linear-gradient(hsla(99,100%,14%,.2), hsla(99,100%,14%,.2));
-  background-size: 100% 1px,
-                   100% 5px,
-                   1px 100%,
-                   1px 100%,
-                   100%;
-  background-repeat: no-repeat,
-                     no-repeat,
-                     no-repeat,
-                     no-repeat,
-                     repeat-x;
-  background-position: top right, top left, left, right;
-}
-
-.devtools-tab:not(.highlighted) > .highlighted-icon,
-.devtools-tab[selected=true] > .highlighted-icon,
-.devtools-tab:not([selected=true]).highlighted > .default-icon {
-  visibility: collapse;
-}
-
-.options-vertical-pane {
-  margin: 5px;
-  width: calc(50% - 30px);
-  min-width: 400px;
-  -moz-padding-start: 5px;
-}
-
-.options-vertical-pane > label {
-  padding: 2px 0;
-  font-size: 1.4rem;
-}
-
-.options-groupbox {
-  -moz-margin-start: 15px;
-  padding: 2px;
-}
-
-.options-groupbox > * {
-  padding: 2px;
-}
-
-.options-citation-label {
-  font-size: 1rem !important;
-  /* !important is required otherwise font-size will still be 1.4rem */
-  font-style: italic;
-  padding: 4px 0 0; /* To align it with the checkbox */
-}
-
-.options-citation-label + label {
-  padding: 3px 0 0 !important; /* To align it with the checkbox */
-  font-style: italic;
-}
-
-.hidden-labels-box:not(.visible) > label,
-.hidden-labels-box.visible ~ .hidden-labels-box > label:last-child {
-  display: none;
-}
--- a/browser/themes/windows/jar.mn
+++ b/browser/themes/windows/jar.mn
@@ -165,19 +165,19 @@ browser.jar:
         skin/classic/browser/tabview/close.png                      (tabview/close.png)
         skin/classic/browser/tabview/edit-light.png                 (tabview/edit-light.png)
         skin/classic/browser/tabview/grain.png                      (tabview/grain.png)
         skin/classic/browser/tabview/search.png                     (tabview/search.png)
         skin/classic/browser/tabview/stack-expander.png             (tabview/stack-expander.png)
         skin/classic/browser/tabview/tabview.png                    (tabview/tabview.png)
         skin/classic/browser/tabview/tabview-inverted.png           (tabview/tabview-inverted.png)
         skin/classic/browser/tabview/tabview.css                    (tabview/tabview.css)
-*       skin/classic/browser/devtools/common.css                    (devtools/common.css)
-        skin/classic/browser/devtools/dark-theme.css                (../shared/devtools/dark-theme.css)
-        skin/classic/browser/devtools/light-theme.css               (../shared/devtools/light-theme.css)
+*       skin/classic/browser/devtools/common.css                    (../shared/devtools/common.css)
+*       skin/classic/browser/devtools/dark-theme.css                (../shared/devtools/dark-theme.css)
+*       skin/classic/browser/devtools/light-theme.css               (../shared/devtools/light-theme.css)
         skin/classic/browser/devtools/controls.png                  (../shared/devtools/controls.png)
 *       skin/classic/browser/devtools/widgets.css                   (devtools/widgets.css)
         skin/classic/browser/devtools/commandline-icon.png          (devtools/commandline-icon.png)
         skin/classic/browser/devtools/alerticon-warning.png         (devtools/alerticon-warning.png)
         skin/classic/browser/devtools/ruleview.css                  (devtools/ruleview.css)
         skin/classic/browser/devtools/commandline.css               (devtools/commandline.css)
         skin/classic/browser/devtools/command-paintflashing.png     (devtools/command-paintflashing.png)
         skin/classic/browser/devtools/command-responsivemode.png    (devtools/command-responsivemode.png)
@@ -248,17 +248,16 @@ browser.jar:
         skin/classic/browser/devtools/responsive-background.png     (devtools/responsive-background.png)
         skin/classic/browser/devtools/toggle-tools.png              (devtools/toggle-tools.png)
         skin/classic/browser/devtools/dock-bottom.png               (devtools/dock-bottom.png)
         skin/classic/browser/devtools/dock-side.png                 (devtools/dock-side.png)
         skin/classic/browser/devtools/floating-scrollbars.css       (devtools/floating-scrollbars.css)
         skin/classic/browser/devtools/floating-scrollbars-light.css (devtools/floating-scrollbars-light.css)
         skin/classic/browser/devtools/inspector.css                 (devtools/inspector.css)
         skin/classic/browser/devtools/profiler-stopwatch.png        (devtools/profiler-stopwatch.png)
-        skin/classic/browser/devtools/toolbox.css                   (devtools/toolbox.css)
         skin/classic/browser/devtools/tool-options.png              (devtools/tool-options.png)
         skin/classic/browser/devtools/tool-webconsole.png           (devtools/tool-webconsole.png)
         skin/classic/browser/devtools/tool-debugger.png             (devtools/tool-debugger.png)
         skin/classic/browser/devtools/tool-debugger-paused.png      (devtools/tool-debugger-paused.png)
         skin/classic/browser/devtools/tool-inspector.png            (devtools/tool-inspector.png)
         skin/classic/browser/devtools/tool-styleeditor.png          (devtools/tool-styleeditor.png)
         skin/classic/browser/devtools/tool-profiler.png             (devtools/tool-profiler.png)
         skin/classic/browser/devtools/tool-network.png              (devtools/tool-network.png)
@@ -467,19 +466,19 @@ browser.jar:
         skin/classic/aero/browser/tabview/close.png                  (tabview/close.png)
         skin/classic/aero/browser/tabview/edit-light.png             (tabview/edit-light.png)
         skin/classic/aero/browser/tabview/grain.png                  (tabview/grain.png)
         skin/classic/aero/browser/tabview/search.png                 (tabview/search.png)
         skin/classic/aero/browser/tabview/stack-expander.png         (tabview/stack-expander.png)
         skin/classic/aero/browser/tabview/tabview.png                (tabview/tabview.png)
         skin/classic/aero/browser/tabview/tabview-inverted.png       (tabview/tabview-inverted.png)
         skin/classic/aero/browser/tabview/tabview.css                (tabview/tabview.css)
-*       skin/classic/aero/browser/devtools/common.css                (devtools/common.css)
-        skin/classic/aero/browser/devtools/dark-theme.css            (../shared/devtools/dark-theme.css)
-        skin/classic/aero/browser/devtools/light-theme.css           (../shared/devtools/light-theme.css)
+*       skin/classic/aero/browser/devtools/common.css                (../shared/devtools/common.css)
+*       skin/classic/aero/browser/devtools/dark-theme.css            (../shared/devtools/dark-theme.css)
+*       skin/classic/aero/browser/devtools/light-theme.css           (../shared/devtools/light-theme.css)
         skin/classic/aero/browser/devtools/controls.png              (../shared/devtools/controls.png)
 *       skin/classic/aero/browser/devtools/widgets.css               (devtools/widgets.css)
         skin/classic/aero/browser/devtools/commandline-icon.png      (devtools/commandline-icon.png)
         skin/classic/aero/browser/devtools/command-paintflashing.png  (devtools/command-paintflashing.png)
         skin/classic/aero/browser/devtools/command-responsivemode.png (devtools/command-responsivemode.png)
         skin/classic/aero/browser/devtools/command-scratchpad.png    (devtools/command-scratchpad.png)
         skin/classic/aero/browser/devtools/command-tilt.png          (devtools/command-tilt.png)
         skin/classic/aero/browser/devtools/alerticon-warning.png     (devtools/alerticon-warning.png)
@@ -550,17 +549,16 @@ browser.jar:
         skin/classic/aero/browser/devtools/responsive-background.png (devtools/responsive-background.png)
         skin/classic/aero/browser/devtools/toggle-tools.png          (devtools/toggle-tools.png)
         skin/classic/aero/browser/devtools/dock-bottom.png           (devtools/dock-bottom.png)
         skin/classic/aero/browser/devtools/dock-side.png             (devtools/dock-side.png)
         skin/classic/aero/browser/devtools/floating-scrollbars.css   (devtools/floating-scrollbars.css)
         skin/classic/aero/browser/devtools/floating-scrollbars-light.css (devtools/floating-scrollbars-light.css)
         skin/classic/aero/browser/devtools/inspector.css             (devtools/inspector.css)
         skin/classic/aero/browser/devtools/profiler-stopwatch.png    (devtools/profiler-stopwatch.png)
-        skin/classic/aero/browser/devtools/toolbox.css               (devtools/toolbox.css)
         skin/classic/aero/browser/devtools/tool-options.png          (devtools/tool-options.png)
         skin/classic/aero/browser/devtools/tool-webconsole.png       (devtools/tool-webconsole.png)
         skin/classic/aero/browser/devtools/tool-debugger.png         (devtools/tool-debugger.png)
         skin/classic/aero/browser/devtools/tool-debugger-paused.png  (devtools/tool-debugger-paused.png)
         skin/classic/aero/browser/devtools/tool-inspector.png        (devtools/tool-inspector.png)
         skin/classic/aero/browser/devtools/tool-styleeditor.png      (devtools/tool-styleeditor.png)
         skin/classic/aero/browser/devtools/tool-profiler.png         (devtools/tool-profiler.png)
         skin/classic/aero/browser/devtools/tool-network.png          (devtools/tool-network.png)
--- a/build/mobile/robocop/Makefile.in
+++ b/build/mobile/robocop/Makefile.in
@@ -26,17 +26,20 @@ ANDROID_ASSETS_DIR := $(TESTPATH)/assets
   FennecNativeDriver.java \
   FennecNativeElement.java \
   RoboCopException.java \
   RobocopUtils.java \
   PaintedSurface.java \
   $(NULL)
 
 java-harness := $(addprefix $(srcdir)/,$(_JAVA_HARNESS))
-java-tests   := $(wildcard $(TESTPATH)/*.java)
+java-tests   := \
+  $(wildcard $(TESTPATH)/*.java) \
+  $(wildcard $(TESTPATH)/components/*.java) \
+  $(wildcard $(TESTPATH)/helpers/*.java)
 
 # pre-process TestConstants.java.in
 PP_TARGETS         += testconstants
 testconstants-dep  := $(dir-tests)/TestConstants.java
 testconstants      := $(TESTPATH)/TestConstants.java.in
 testconstants_PATH := $(dir-tests)
 
 PP_TARGETS        += manifest
--- a/mobile/android/base/ActionModeCompatView.java
+++ b/mobile/android/base/ActionModeCompatView.java
@@ -1,20 +1,24 @@
 /* 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/. */
 
 package org.mozilla.gecko;
 
+import org.mozilla.gecko.animation.AnimationUtils;
 import org.mozilla.gecko.menu.GeckoMenu;
 import org.mozilla.gecko.menu.MenuPopup;
 import org.mozilla.gecko.menu.MenuPanel;
 import org.mozilla.gecko.menu.MenuItemActionBar;
 import org.mozilla.gecko.widget.GeckoPopupMenu;
 
+import android.view.animation.Animation;
+import android.view.animation.TranslateAnimation;
+import android.view.animation.ScaleAnimation;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.MenuInflater;
 import android.view.ViewGroup;
 import android.view.LayoutInflater;
 import android.widget.LinearLayout;
 import android.view.View;
 import android.view.ViewGroup;
@@ -151,9 +155,23 @@ class ActionModeCompatView extends Linea
     public void openMenu() {
         mPopupMenu.openMenu();
     }
 
     public void closeMenu() {
         mPopupMenu.dismiss();
     }
 
+    public void animateIn() {
+        long duration = AnimationUtils.getShortDuration(getContext());
+        TranslateAnimation t = new TranslateAnimation(Animation.RELATIVE_TO_SELF, -0.5f, Animation.RELATIVE_TO_SELF, 0f,
+                                                      Animation.RELATIVE_TO_SELF,  0f,   Animation.RELATIVE_TO_SELF, 0f);
+        t.setDuration(duration);
+
+        ScaleAnimation s = new ScaleAnimation(1f, 1f, 0f, 1f,
+                                              Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
+        s.setDuration((long) (duration * 1.5f));
+
+        mTitleView.startAnimation(t);
+        mActionButtonBar.startAnimation(s);
+        mMenuButton.startAnimation(s);
+    }
 }
--- a/mobile/android/base/BrowserApp.java
+++ b/mobile/android/base/BrowserApp.java
@@ -2534,19 +2534,27 @@ abstract public class BrowserApp extends
 
     /* Implementing ActionModeCompat.Presenter */
     @Override
     public void startActionModeCompat(final ActionModeCompat.Callback callback) {
         // If actionMode is null, we're not currently showing one. Flip to the action mode view
         if (mActionMode == null) {
             mViewFlipper.showNext();
             LayerMarginsAnimator margins = mLayerView.getLayerMarginsAnimator();
-            margins.setMaxMargins(0, mViewFlipper.getHeight(), 0, 0);
+
+            // If the toolbar is dynamic and not currently showing, just slide it in
+            if (isDynamicToolbarEnabled() && !margins.areMarginsShown()) {
+                margins.setMaxMargins(0, mViewFlipper.getHeight(), 0, 0);
+                margins.showMargins(false);
+            } else {
+                // Otherwise, we animate the actionbar itself
+                mActionBar.animateIn();
+            }
+
             margins.setMarginsPinned(true);
-            margins.showMargins(false);
         } else {
             // Otherwise, we're already showing an action mode. Just finish it and show the new one
             mActionMode.finish();
         }
 
         mActionMode = new ActionModeCompat(BrowserApp.this, callback, mActionBar);
         if (callback.onCreateActionMode(mActionMode, mActionMode.getMenu())) {
             mActionMode.invalidate();
--- a/mobile/android/base/GeckoAppShell.java
+++ b/mobile/android/base/GeckoAppShell.java
@@ -10,16 +10,17 @@ import org.mozilla.gecko.gfx.BitmapUtils
 import org.mozilla.gecko.gfx.GeckoLayerClient;
 import org.mozilla.gecko.gfx.LayerView;
 import org.mozilla.gecko.gfx.PanZoomController;
 import org.mozilla.gecko.mozglue.JNITarget;
 import org.mozilla.gecko.mozglue.generatorannotations.OptionalGeneratedParameter;
 import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
 import org.mozilla.gecko.prompts.PromptService;
 import org.mozilla.gecko.mozglue.GeckoLoader;
+import org.mozilla.gecko.mozglue.RobocopTarget;
 import org.mozilla.gecko.util.EventDispatcher;
 import org.mozilla.gecko.util.GeckoEventListener;
 import org.mozilla.gecko.util.HardwareUtils;
 import org.mozilla.gecko.util.ThreadUtils;
 
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.PendingIntent;
@@ -2415,16 +2416,17 @@ public class GeckoAppShell
             return;
         }
 
         SmsManager.getInstance().clearMessageList(aListId);
     }
 
     /* Called by JNI from AndroidBridge, and by reflection from tests/BaseTest.java.in */
     @WrapElementForJNI
+    @RobocopTarget
     public static boolean isTablet() {
         return HardwareUtils.isTablet();
     }
 
     public static void viewSizeChanged() {
         LayerView v = getLayerView();
         if (v != null && v.isIMEEnabled()) {
             sendEventToGecko(GeckoEvent.createBroadcastEvent(
--- a/mobile/android/base/InputMethods.java
+++ b/mobile/android/base/InputMethods.java
@@ -1,15 +1,17 @@
 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
  * 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/. */
 
 package org.mozilla.gecko;
 
+import org.mozilla.gecko.mozglue.RobocopTarget;
+
 import android.content.Context;
 import android.os.Build;
 import android.provider.Settings.Secure;
 import android.view.inputmethod.InputMethodInfo;
 import android.view.inputmethod.InputMethodManager;
 
 import java.util.Collection;
 import java.util.Locale;
@@ -56,16 +58,17 @@ final public class InputMethods {
         return Build.VERSION.SDK_INT >= 17 && (METHOD_ANDROID_LATINIME.equals(inputMethod) ||
                                                METHOD_GOOGLE_LATINIME.equals(inputMethod));
     }
 
     public static boolean shouldCommitCharAsKey(String inputMethod) {
         return METHOD_HTC_TOUCH_INPUT.equals(inputMethod);
     }
 
+    @RobocopTarget
     public static boolean shouldDisableUrlBarUpdate(Context context) {
         String inputMethod = getCurrentInputMethod(context);
         return METHOD_HTC_TOUCH_INPUT.equals(inputMethod);
     }
 
     public static boolean shouldDelayUrlBarUpdate(Context context) {
         String inputMethod = getCurrentInputMethod(context);
         return METHOD_SAMSUNG.equals(inputMethod) ||
--- a/mobile/android/base/TextSelection.java
+++ b/mobile/android/base/TextSelection.java
@@ -241,17 +241,17 @@ class TextSelection extends Layer implem
             // action mode.
             menu.clear();
 
             int length = mItems.length();
             for (int i = 0; i < length; i++) {
                 try {
                     final JSONObject obj = mItems.getJSONObject(i);
                     final GeckoMenuItem menuitem = (GeckoMenuItem) menu.add(0, i, 0, obj.optString("label"));
-                    menuitem.setShowAsAction(obj.optBoolean("showAsAction") ? 1 : 0);
+                    menuitem.setShowAsAction(obj.optBoolean("showAsAction") ? 1 : 0, R.attr.menuItemActionModeStyle);
 
                     BitmapUtils.getDrawable(mStartHandle.getContext(), obj.optString("icon"), new BitmapLoader() {
                         public void onBitmapFound(Drawable d) {
                             if (d != null) {
                                 menuitem.setIcon(d);
                             }
                         }
                     });
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/animation/AnimationUtils.java
@@ -0,0 +1,21 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
+/* 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/. */
+
+
+package org.mozilla.gecko.animation;
+
+import android.content.Context;
+
+public class AnimationUtils {
+    private static long mShortDuration;
+
+    public static long getShortDuration(Context context) {
+        if (mShortDuration < 0) {
+            mShortDuration = context.getResources().getInteger(android.R.integer.config_shortAnimTime);
+        }
+        return mShortDuration;
+    }
+}
+
--- a/mobile/android/base/gfx/LayerMarginsAnimator.java
+++ b/mobile/android/base/gfx/LayerMarginsAnimator.java
@@ -134,16 +134,24 @@ public class LayerMarginsAnimator implem
     public void setMarginsPinned(boolean pin) {
         if (pin == mMarginsPinned) {
             return;
         }
 
         mMarginsPinned = pin;
     }
 
+    public boolean areMarginsShown() {
+        final ImmutableViewportMetrics metrics = mTarget.getViewportMetrics();
+        return metrics.marginLeft != 0  ||
+               metrics.marginRight != 0 ||
+               metrics.marginTop != 0   ||
+               metrics.marginBottom != 0;
+    }
+
     /**
      * This function will scroll a margin down to zero, or up to the maximum
      * specified margin size and return the left-over delta.
      * aMargins are in/out parameters. In specifies the current margin size,
      * and out specifies the modified margin size. They are specified in the
      * order of start-margin, then end-margin.
      * This function will also take into account how far the touch point has
      * moved and react accordingly. If a touch point hasn't moved beyond a
--- a/mobile/android/base/home/HomePager.java
+++ b/mobile/android/base/home/HomePager.java
@@ -3,16 +3,17 @@
  * 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/. */
 
 package org.mozilla.gecko.home;
 
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.animation.PropertyAnimator;
 import org.mozilla.gecko.animation.ViewHelper;
+import org.mozilla.gecko.mozglue.RobocopTarget;
 import org.mozilla.gecko.util.HardwareUtils;
 
 import android.content.Context;
 import android.os.Build;
 import android.os.Bundle;
 import android.support.v4.app.Fragment;
 import android.support.v4.app.FragmentManager;
 import android.support.v4.app.FragmentStatePagerAdapter;
@@ -32,16 +33,17 @@ public class HomePager extends ViewPager
     // Subpage fragment tag
     public static final String SUBPAGE_TAG = "home_pager_subpage";
 
     private final Context mContext;
     private volatile boolean mLoaded;
     private Decor mDecor;
 
     // List of pages in order.
+    @RobocopTarget
     public enum Page {
         HISTORY,
         TOP_SITES,
         BOOKMARKS,
         READING_LIST
     }
 
     // This is mostly used by UI tests to easily fetch
--- a/mobile/android/base/home/SuggestClient.java
+++ b/mobile/android/base/home/SuggestClient.java
@@ -1,24 +1,24 @@
 /* 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/. */
 
 package org.mozilla.gecko.home;
 
 import org.mozilla.gecko.GeckoAppShell;
+import org.mozilla.gecko.mozglue.RobocopTarget;
 
 import org.json.JSONArray;
 
 import android.content.Context;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
 import android.text.TextUtils;
 import android.util.Log;
-import org.mozilla.gecko.mozglue.RobocopTarget;
 
 import java.io.BufferedInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.HttpURLConnection;
 import java.net.URL;
 import java.net.URLEncoder;
 import java.util.ArrayList;
--- a/mobile/android/base/menu/GeckoMenuItem.java
+++ b/mobile/android/base/menu/GeckoMenuItem.java
@@ -285,28 +285,37 @@ public class GeckoMenuItem implements Me
 
     @Override
     public MenuItem setShortcut(char numericChar, char alphaChar) {
         return this;
     }
 
     @Override
     public void setShowAsAction(int actionEnum) {
+        setShowAsAction(actionEnum, 0);
+    }
+
+    public void setShowAsAction(int actionEnum, int style) {
         if (mShowAsActionChangedListener == null)
             return;
 
         if (mActionItem == (actionEnum > 0))
             return;
 
         if (actionEnum > 0) {
             if (!mShowAsActionChangedListener.hasActionItemBar())
                 return;
 
             // Change the type to just an icon
-            MenuItemActionBar actionView = new MenuItemActionBar(mMenu.getContext(), null);
+            MenuItemActionBar actionView;
+            if (style != 0) {
+                actionView = new MenuItemActionBar(mMenu.getContext(), null, style);
+            } else {
+                actionView = new MenuItemActionBar(mMenu.getContext());
+            }
             actionView.initialize(this);
             mActionView = actionView;
 
             mActionItem = (actionEnum > 0);
         }
 
         mShowAsActionChangedListener.onShowAsActionChanged(this, mActionItem);
     }
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -88,16 +88,17 @@ if CONFIG['MOZ_WEBRTC']:
 
 gbjar = add_java_jar('gecko-browser')
 gbjar.sources += [
     'AboutPages.java',
     'ActionModeCompat.java',
     'ActionModeCompatView.java',
     'ActivityHandlerHelper.java',
     'AlertNotification.java',
+    'animation/AnimationUtils.java',
     'animation/AnimatorProxy.java',
     'animation/HeightChangeAnimation.java',
     'animation/PropertyAnimator.java',
     'animation/Rotate3DAnimation.java',
     'animation/ViewHelper.java',
     'ANRReporter.java',
     'AppNotificationClient.java',
     'BaseGeckoInterface.java',
@@ -636,16 +637,17 @@ ANDROID_RESFILES += [
     'resources/drawable-mdpi/pin.png',
     'resources/drawable-mdpi/play.png',
     'resources/drawable-mdpi/progress_spinner.png',
     'resources/drawable-mdpi/reader.png',
     'resources/drawable-mdpi/reader_active.png',
     'resources/drawable-mdpi/reader_cropped.png',
     'resources/drawable-mdpi/reading_list.png',
     'resources/drawable-mdpi/scrollbar.png',
+    'resources/drawable-mdpi/select_all.png',
     'resources/drawable-mdpi/shadow.png',
     'resources/drawable-mdpi/shield.png',
     'resources/drawable-mdpi/shield_doorhanger.png',
     'resources/drawable-mdpi/spinner_default.9.png',
     'resources/drawable-mdpi/spinner_focused.9.png',
     'resources/drawable-mdpi/spinner_pressed.9.png',
     'resources/drawable-mdpi/start.png',
     'resources/drawable-mdpi/tab_close.png',
index 55f8ae5a633f19ce0bb45c19619f5d1206a000b8..844a544bb745db8ab556623040cd4a6982125d70
GIT binary patch
literal 230
zc%17D@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^S7>k44ofy`glX(f`uqAoByD<C*
z!3BGlPX>x`7I;J!Gca%qgD@k*tT_@uLG}_)Usv|K+|puV1{=cU(t$#0o-U3d5r^Mi
z*~ob~frs_scb_QdE}e%Hjpt{JH-4Ee$;0*M=v{_K&P<{wLUI|cjJQvH{dw*sTb1qi
zoJf<zLoJ-bYCbazV2lka(a~XdBW$1c$~m0-{_t4K-_=Z!A5y=t`!I>W712yd0@}#n
M>FVdQ&MBb@0B9^r>Hq)$
index 73096537606a3b5e0da23ef3d7fa593382eef71f..9243ec26f1c781a43a46c977ac05c6cb804dadd4
GIT binary patch
literal 757
zc$@+C0t)?!P)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm00001b5ch_0Itp)
z=>Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2i*%A
z7djXPtk7Wq00MPML_t(&-tCyrYZE~jhM$z$D(xu;K}u^;5ux-Tgdp^w7LisPgP<Nn
z@X&vwJ=MQKMDXUVNGS;t1koNUrNo0sP)miz(u+uMMM|ad@&<;$Zf3XpV;1s3Aj!^V
z-e>2__q{W@R;xvpqmPV751<Fo1IT#vdtE3L3USRj0?YwpzyQz$J^+pOfO@@ta)6j(
z3V7Tx@1$NeV8!JWItM)Qd1x~NaTegF#e6d^1Dv-QGwL$HahA*IC@^d>Za1<r8d2nd
z`#{lhe9aYrGphABj5)poKY)_Q%2$A|X#@02^qe5tX|ZB7ss?ZuxS&S1ttY<~X(tX5
zMWst#pZ9?(u--AQ2|SP8N*FN?+ygEFhrmxgu^nB%3_LPQ;9uaa?7>lLUdU)HWg}+?
zfvbA03Ti^v{sA8){vdTTCvjz;Qd>6OZwly-Gj3G*+^tXi2404#-$^vG5sUi|(-a>?
zCq5$O@B`ShxPLf|0ZR&C)#CoMzydID)PH9Hwz@!6jP6<lmVk%AkSkRP)%0!Pwi?=L
zd77HO2e<+}P%7Qhwy_GVCGj80d7X`h*wkNBZ!oPy1^5*7htk^AZvdZx>oRkB;3+T-
zyaB!$JF{8fqB{GD%v_W!V8#$|r^8M+B-YPPSA(uVTsyJ@U>R7H%|M>X&zh86JeAl7
zUIEW!JGzClrxLre*_l3-h(%A506P|Anl1yZS)2{M3sgdLxkLf>fY;i&d5QlLM0^tG
zLY=X$R4S>VodSLV?+ssNEj|r^_DZ}6?R^aKE>@vH;(e_|7Q|;}1-!&(0>Dqa^8nq%
nI}KnX-dO-!@lFB+5fAVm;kbG%02mb<00000NkvXXu0mjfHdsCF
index 130d442b9cbc3aab9cf070078c3a99c311787004..e4650d4394ca68b54cacd66b059c5c0a2fd43ef0
GIT binary patch
literal 222
zc%17D@N?(olHy`uVBq!ia0vp^QXtI11|(N{`J4k%jKx9jP7LeL$-D$|*pj^6T^Rm@
z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-AbW|YuPggqZfP+w(ceL*6o5i;o-U3d9>?Ea
zGvsP;5OBWelEccq{?XjMb6OR)-IvxmCl>8-iN9ZRSqEcivh;y%UrX;boO``4yEW(a
zBF|<ajerFXjZ9k=Zui_e@!u-e-}2>29nbR{pYMGgD{!Gf{5y9Mw>0yki+U4*HZgd*
L`njxgN@xNAJ_$=$
index 698b0e034c8102503f2795013cc0a5a68aca5a1d..8364e3e58e389840c2b4d74a68df83092dfa9e7a
GIT binary patch
literal 573
zc$@(}0>b@?P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800001b5ch_0Itp)
z=>Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2i*%B
z03R4kiqaMU00F&8L_t(o!|m6<YZO5g2k_4ZK}3WI5=kL~2r-o)SHwa@%b*A%D3bp{
z@PDwdQL)!b#KJC3{8fo4;ZQ6jq83V!pd1ncBBJDMUSK$G*1Pp?xADOgJ8yQr-<^5y
z``#AaZda2wp<(+^pm74*dM8?~R@J@s;ye!G8=l}PwA<~$2~@P5xQxkop2h+;@vM$3
zIFf*;HeXi^?8(ee)<IwvhcmwSLkHmywjXD42&;I3xx~MYyW=1*g)?ZOgIib*-*e0a
z_%eP}C9n@Cu^aF32s>~J$717qk!HV>_uj^+t^;wTmy-CH#nB+Mi6uN7<m;*uIM*jQ
zr?7(C*ci7IPiNMyjv72iV67xBcGW@Pe%y6xUqj=s;54?6tr$fVU&ZkVybpMgWWhX6
zV6jgYjD!GujFH-}5SGWG0~aDy7ZV*g5GS>PSNQoi0!436I7B(_Rl?6bO4z}5bjr%{
zztn<H0dONua;{H-x>!dsTEXj#Z>Fwt+{w(Z*G1rE25hM`0E=Q|1is@M-bA*1!JVz1
zFb6)$o=||^9Ax1Zcq46jQ4|xUIxuGN=6+22f!9VL2VM(-GI00<K~G#KRl(;{00000
LNkvXXu0mjf5Tx=y
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..e0dd67c69445979727fc9fdec76c60386524ba92
GIT binary patch
literal 166
zc%17D@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJTu&Frkch*{fByfsKkUGCERbEn
z`oNJRDa+Qc&;Rx8?Ceap`Ig0MvdfvJq@^?8J^uBp>X4#?_Gx$LhBX2VnTOIOHaT|&
zI+t+-TxMLXXduP3`00TQJdGD)Kukr0D88OE0umeQ4rW}>aj{}xIApN+Laee-KG0$Y
MPgg&ebxsLQ05jY>M*si-
index 28aeaa77b7fdfd3dde728b6f19956767fe230b51..a3fbaa1967762b720e845ee8c37bff727f6d55c5
GIT binary patch
literal 250
zc%17D@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nC-#^NA%Cx&(BWL^R}Y)RhkE)4%c
zaKYZ?lYt_f1s;*b3=G`DAk4@xYmNj^kiEpy*OmP)x3rj;lJom~eV|a4r;B4q#=W<<
zHgYmK2)JC7H5BE^IW%eQ`5O)f^1{xSg)Q&pCse*Ey14Z18a>Z+HSP4JZ*AtS|2nHR
z_S|yIGir?u_`n~gPd}$_IO_Ij%fA)Lw|CxOXU4?zY44V~yz?IHVSKVqg0-`8{d}M+
O7(8A5T-G@yGywp<z+5>1
index be26fd0cec08ae708b4fcab739bd9c4f5493a0c0..bc07fde8b9590b633276ba233b43c15536c62d4d
GIT binary patch
literal 1033
zc$@(V1or!hP)<h;3K|Lk000e1NJLTq002M$002M;1^@s6s%dfF00001b5ch_0Itp)
z=>Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2i*%B
z03I-4BulLT00W6hL_t(|+U=UpOB7)k$3J6P#HNIYLPCfLQ6ehw5Lj7xNTMG^7!lnK
z4-s@KIz*@X2f73uI&?@%%7}hhM0k-UlPF8XiU@Iuh%`cW(+=|tOvCKXytCuZ%)9f2
zW!d@h?mVA;-sgRu=UroQagl0P4OOlbKnfrQkOD{nqySO?)vM)R7qqvxNA+xtzz(2Q
zKK}*Y1H-@%`-RzTcIf~_<duhjZWj;T2<!(2fT4<bKm<Agbe1?@3mgZQ0Z(*`0h>LH
zx9g}(6RiMrDL(sNodDF>0-lP;Xak@=!1Jup3BY`Sd;aJIU>%TGyyvqH%U~mL1lS(n
z-r*zzXaEiZ9Rcru3ydZaKn6G<>wT^5_-|kk7z6r%rV?Yk25u%T6I?0lb~muf5&WJ?
zR%ZpmE5IJf3mR<K&PW<O8rDNq0zeJ0OWeKQcDx{Sco3L%+*1Ia$*WEvd>1dNY&BS9
z?QOBS??)h4teBJlx7KldL=4aQ_`X>eK#>4w0D6Enmva-qEnr$cw*tpp=J7ai2l$$p
zet>8_aMt0%b~OX%fqwbbTO8-V0C#~8iED_6tDi1mygkUBavaM6_kb)hl^+1RUFNWt
zegO}FSHJ=>mLCABJ+XP<V!+%!k`mNQO##;X6(mG{02l$rHFN?ntvF^Ln9~Ws8^tke
zfeVDtt%(bO$C87qs0la&oC7u_9Y7wq;UlUqNI^5>k|6a;!y}Q)pw)S~44f?D+Br#u
z$E8~901n%dr#4`l6hHSRPl$yKuRlq-Y>hPoo1`}Q348+H6^R91F6D0?b64jPA@ua1
zysfby0K#m5JOo~%-U|#3KqdMCzokeT;{O&{Myks$Nt>Phy*6N{ZOY{_H%Fg`SyWZR
z1DtBa+}7Ial5Y%%k-fl{5@QTY%qb+n1Kbj;YnVH|J@RgW=@XC1c#L6rQQ3XLDE9@X
zfU5#y+7UDSs6&ErVgXnh11`z0sTvGBbpT*#1ar?{Ma?<^$OL$v)j9!~L%n-6rxSnz
z>fPcgodAHj5u&29{wQS_M(hBL$g1E+FM!E%jE|!S09^O*gaT%({dT#=N0kZs=|A*~
zC+w4Cr%o!*NhzSdg<*VL0a%)lS9rC*VZ=TNE?wipFoIQsIvZaV9#G17?E!chuQdQa
z#%l|}ukl&}P%&OR0IJ4o1t5s=+5iY@ycPh;F&^L_KN+t_Ji&0-00000NkvXXu0mjf
DVS%q=
--- a/mobile/android/base/resources/layout/actionbar.xml
+++ b/mobile/android/base/resources/layout/actionbar.xml
@@ -10,17 +10,17 @@
             android:layout_width="wrap_content"
             style="@style/GeckoActionBar.Title"/>
 
     <!-- Draw a separator to the left of the title -->
     <View android:layout_height="fill_parent"
           android:layout_width="1dp"
           android:layout_marginTop="10dp"
           android:layout_marginBottom="10dp"
-          android:background="@android:color/darker_gray"/>
+          android:background="@color/text_color_secondary_inverse"/>
 
     <LinearLayout android:id="@+id/actionbar_buttons"
                   android:layout_height="fill_parent"
                   android:layout_width="0dip"
                   android:layout_weight="1"
                   style="@style/GeckoActionBar.Buttons"/>
 
     <ImageButton android:id="@+id/actionbar_menu"
--- a/mobile/android/base/resources/layout/gecko_app.xml
+++ b/mobile/android/base/resources/layout/gecko_app.xml
@@ -53,39 +53,39 @@
                         android:layout_width="wrap_content"
                         android:layout_alignParentRight="true"
                         android:layout_alignParentBottom="true">
         </RelativeLayout>
 
         <FrameLayout android:id="@+id/search_container"
                      android:layout_width="fill_parent"
                      android:layout_height="fill_parent"
-                     android:layout_below="@+id/browser_toolbar"
+                     android:layout_below="@+id/browser_actionbar"
                      android:background="@android:color/white"
                      android:visibility="invisible"/>
 
         <!-- When focus is cleared from from BrowserToolbar's EditText to
              lower the virtual keyboard, focus will be returned to the root
              view. To make sure the EditText is not the first focusable view in
              the root view, BrowserToolbar should be specified as low in the
              view hierarchy as possible. -->
 
-        <ViewFlipper android:id="@+id/browser_actionbar"
+        <ViewFlipper android:id="@id/browser_actionbar"
                 android:layout_width="fill_parent"
                 android:layout_height="@dimen/browser_toolbar_height"
                 android:clickable="true"
                 android:focusable="true">
 
             <org.mozilla.gecko.toolbar.BrowserToolbar
-                android:id="@id/browser_toolbar"
-                    style="@style/BrowserToolbar"
-                    android:layout_width="fill_parent"
-                    android:layout_height="@dimen/browser_toolbar_height"
-                    android:clickable="true"
-                    android:focusable="true"
+                android:id="@+id/browser_toolbar"
+                style="@style/BrowserToolbar"
+                android:layout_width="fill_parent"
+                android:layout_height="@dimen/browser_toolbar_height"
+                android:clickable="true"
+                android:focusable="true"
                 android:background="@drawable/url_bar_bg"/>
 
             <org.mozilla.gecko.ActionModeCompatView android:id="@+id/actionbar"
                                                     android:layout_height="fill_parent"
                                                     android:layout_width="fill_parent"
                                                     style="@style/GeckoActionBar"/>
 
         </ViewFlipper>
--- a/mobile/android/base/resources/values-v11/styles.xml
+++ b/mobile/android/base/resources/values-v11/styles.xml
@@ -80,14 +80,18 @@
 
     <style name="GeckoActionBar.Title" parent="@android:style/TextAppearance.Holo.Widget.ActionBar.Title">
         <item name="android:drawableLeft">?android:attr/actionModeCloseDrawable</item>
         <item name="android:background">@android:color/transparent</item>
         <item name="android:paddingLeft">15dp</item>
         <item name="android:paddingRight">15dp</item>
     </style>
 
+    <style name="GeckoActionBar.Button" parent="android:style/Widget.Holo.Light.ActionButton">
+        <item name="android:padding">12dp</item>
+    </style>
+
     <style name="GeckoActionBar.Button.MenuButton" parent="android:style/Widget.Holo.Light.ActionButton.Overflow">
         <item name="android:scaleType">center</item>
         <item name="android:background">@android:color/transparent</item>
     </style>
 
 </resources>
--- a/mobile/android/base/resources/values-v11/themes.xml
+++ b/mobile/android/base/resources/values-v11/themes.xml
@@ -43,11 +43,12 @@
         <item name="menuItemActionViewStyle">@style/Widget.MenuItemActionView</item>
         <item name="menuItemDefaultStyle">@style/Widget.MenuItemDefault</item>
         <item name="menuItemShareActionButtonStyle">@style/Widget.MenuItemShareActionButton</item>
         <item name="bookmarksListViewStyle">@style/Widget.BookmarksListView</item>
         <item name="topSitesGridItemViewStyle">@style/Widget.TopSitesGridItemView</item>
         <item name="topSitesGridViewStyle">@style/Widget.TopSitesGridView</item>
         <item name="topSitesThumbnailViewStyle">@style/Widget.TopSitesThumbnailView</item>
         <item name="homeListViewStyle">@style/Widget.HomeListView</item>
+        <item name="menuItemActionModeStyle">@style/GeckoActionBar.Button</item>
     </style>
 
 </resources>
--- a/mobile/android/base/resources/values/attrs.xml
+++ b/mobile/android/base/resources/values/attrs.xml
@@ -6,16 +6,19 @@
 <resources>
 
     <!-- Theme level attributes -->
     <declare-styleable name="GeckoTheme">
 
         <!-- Style for MenuItemActionBar -->
         <attr name="menuItemActionBarStyle" format="reference"/>
 
+        <!-- Style for MenuItemActionBar -->
+        <attr name="menuItemActionModeStyle" format="reference"/>
+
         <!-- Style for MenuItemActionView -->
         <attr name="menuItemActionViewStyle" format="reference"/>
 
         <!-- Style for MenuItemDefault -->
         <attr name="menuItemDefaultStyle" format="reference"/>
 
         <!-- Style for MenuItemActionView's ShareActionButton -->
         <attr name="menuItemShareActionButtonStyle" format="reference"/>
--- a/mobile/android/base/resources/values/styles.xml
+++ b/mobile/android/base/resources/values/styles.xml
@@ -551,18 +551,17 @@
         <item name="android:textAppearance">@style/TextAppearance.Medium</item>
         <item name="android:drawableLeft">@drawable/ab_done</item>
         <item name="android:paddingLeft">15dp</item>
         <item name="android:paddingRight">15dp</item>
         <item name="android:contentDescription">@string/actionbar_done</item>
     </style>
 
     <style name="GeckoActionBar.Button" parent="Widget.MenuItemActionBar">
-        <item name="android:background">@android:color/transparent</item>
-        <item name="android:gravity">center</item>
+        <item name="android:padding">8dp</item>
     </style>
 
     <style name="GeckoActionBar.Button.MenuButton">
         <item name="android:scaleType">center</item>
         <item name="android:src">@drawable/menu_light</item>
         <item name="android:contentDescription">@string/actionbar_menu</item>
         <item name="android:background">@android:color/transparent</item>
     </style>
--- a/mobile/android/base/resources/values/themes.xml
+++ b/mobile/android/base/resources/values/themes.xml
@@ -79,13 +79,14 @@
         <item name="android:spinnerStyle">@style/Widget.Spinner</item>
         <item name="bookmarksListViewStyle">@style/Widget.BookmarksListView</item>
         <item name="topSitesGridItemViewStyle">@style/Widget.TopSitesGridItemView</item>
         <item name="topSitesGridViewStyle">@style/Widget.TopSitesGridView</item>
         <item name="topSitesThumbnailViewStyle">@style/Widget.TopSitesThumbnailView</item>
         <item name="homeListViewStyle">@style/Widget.HomeListView</item>
         <item name="menuItemDefaultStyle">@style/Widget.MenuItemDefault</item>
         <item name="menuItemActionBarStyle">@style/Widget.MenuItemActionBar</item>
+        <item name="menuItemActionModeStyle">@style/GeckoActionBar.Button</item>
     </style>
 
     <style name="Gecko.Preferences" parent="GeckoPreferencesBase"/>
 
 </resources>
--- a/mobile/android/base/tests/StringHelper.java
+++ b/mobile/android/base/tests/StringHelper.java
@@ -1,13 +1,13 @@
 package org.mozilla.gecko.tests;
 
 import org.mozilla.gecko.*;
 
-class StringHelper {
+public class StringHelper {
     // Note: DEFAULT_BOOKMARKS_TITLES.length == DEFAULT_BOOKMARKS_URLS.length
     public static final String[] DEFAULT_BOOKMARKS_TITLES = new String[] {
         "Firefox: About your browser",
         "Firefox: Support",
         "Firefox: Customize with add-ons"
     };
     public static final String[] DEFAULT_BOOKMARKS_URLS = new String[] {
         "about:firefox",
@@ -15,32 +15,36 @@ class StringHelper {
         "https://addons.mozilla.org/en-US/android/"
     };
     public static final int DEFAULT_BOOKMARKS_COUNT = DEFAULT_BOOKMARKS_TITLES.length;
 
     // About pages
     public static final String ABOUT_BLANK_URL = "about:blank";
     public static final String ABOUT_FIREFOX_URL = "about:firefox";
     public static final String ABOUT_DOWNLOADS_URL = "about:downloads";
+    public static final String ABOUT_HOME_URL = "about:home";
     public static final String ABOUT_ADDONS_URL = "about:addons";
     public static final String ABOUT_APPS_URL = "about:apps";
 
+    // About pages' titles
+    public static final String ABOUT_HOME_TITLE = "";
+
     // Context Menu menu items
     public static final String[] CONTEXT_MENU_ITEMS_IN_PRIVATE_TAB = new String[] {
-        "Open Link in Private Tab", 
-        "Copy Link", 
-        "Share Link", 
+        "Open Link in Private Tab",
+        "Copy Link",
+        "Share Link",
         "Bookmark Link"
     };
 
     public static final String[] CONTEXT_MENU_ITEMS_IN_NORMAL_TAB = new String[] {
         "Open Link in New Tab",
-        "Open Link in Private Tab", 
-        "Copy Link", 
-        "Share Link", 
+        "Open Link in Private Tab",
+        "Copy Link",
+        "Share Link",
         "Bookmark Link"
     };
 
     public static final String[] BOOKMARK_CONTEXT_MENU_ITEMS = new String[] {
         "Open in New Tab",
         "Open in Private Tab",
         "Edit",
         "Remove",
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/tests/UITest.java
@@ -0,0 +1,224 @@
+/* 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/. */
+
+package org.mozilla.gecko.tests;
+
+import org.mozilla.gecko.Actions;
+import org.mozilla.gecko.Assert;
+import org.mozilla.gecko.Driver;
+import org.mozilla.gecko.FennecInstrumentationTestRunner;
+import org.mozilla.gecko.FennecMochitestAssert;
+import org.mozilla.gecko.FennecNativeActions;
+import org.mozilla.gecko.FennecNativeDriver;
+import org.mozilla.gecko.FennecTalosAssert;
+import org.mozilla.gecko.TestConstants;
+import org.mozilla.gecko.tests.components.*;
+import org.mozilla.gecko.tests.helpers.*;
+
+import com.jayway.android.robotium.solo.Solo;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.test.ActivityInstrumentationTestCase2;
+import android.text.TextUtils;
+
+import java.util.HashMap;
+
+/**
+ * A base test class for Robocop (UI-centric) tests. This and the related classes attempt to
+ * provide a framework to improve upon the issues discovered with the previous BaseTest
+ * implementation by providing simple test authorship and framework extension, consistency,
+ * and reliability.
+ */
+abstract class UITest extends ActivityInstrumentationTestCase2<Activity>
+                      implements UITestContext {
+
+    protected enum Type {
+        MOCHITEST,
+        TALOS
+    }
+
+    private static final String LAUNCHER_ACTIVITY = TestConstants.ANDROID_PACKAGE_NAME + ".App";
+    private static final String TARGET_PACKAGE_ID = "org.mozilla.gecko";
+
+    private final static Class<Activity> sLauncherActivityClass;
+
+    private Activity mActivity;
+    private Solo mSolo;
+    private Driver mDriver;
+    private Actions mActions;
+    private Assert mAsserter;
+
+    // Base to build hostname URLs
+    private String mBaseHostnameUrl;
+    // Base to build IP URLs
+    private String mBaseIpUrl;
+
+    protected AboutHomeComponent mAboutHome;
+    protected ToolbarComponent mToolbar;
+
+    static {
+        try {
+            sLauncherActivityClass = (Class<Activity>) Class.forName(LAUNCHER_ACTIVITY);
+        } catch (ClassNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public UITest() {
+        super(sLauncherActivityClass);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        final String rootPath = FennecInstrumentationTestRunner.getFennecArguments().getString("deviceroot");
+        final HashMap config = loadConfigTable(rootPath);
+        final Intent intent = createActivityIntent(config);
+        setActivityIntent(intent);
+
+        // Start the activity.
+        mActivity = getActivity();
+
+        if (getTestType() == Type.TALOS) {
+            mAsserter = new FennecTalosAssert();
+        } else {
+            mAsserter = new FennecMochitestAssert();
+        }
+
+        final String logFile = (String) config.get("logfile");
+        mAsserter.setLogFile(logFile);
+        mAsserter.setTestName(this.getClass().getName());
+
+        mSolo = new Solo(getInstrumentation(), mActivity);
+        mDriver = new FennecNativeDriver(mActivity, mSolo, rootPath);
+        mActions = new FennecNativeActions(mActivity, mSolo, getInstrumentation(), mAsserter);
+
+        mBaseHostnameUrl = ((String) config.get("host")).replaceAll("(/$)", "");
+        mBaseIpUrl = ((String) config.get("rawhost")).replaceAll("(/$)", "");
+
+        // Helpers depend on components so initialize them first.
+        initComponents();
+        initHelpers();
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        try {
+            mAsserter.endTest();
+            mSolo.finishOpenedActivities();
+        } catch (Throwable e) {
+            e.printStackTrace();
+        }
+
+        super.tearDown();
+    }
+
+    private void initComponents() {
+        mAboutHome = new AboutHomeComponent(this);
+        mToolbar = new ToolbarComponent(this);
+    }
+
+    private void initHelpers() {
+        // Other helpers make assertions so init AssertionHelper first.
+        AssertionHelper.init(this);
+
+        DeviceHelper.init(this);
+        GeckoHelper.init(this);
+        GestureHelper.init(this);
+        NavigationHelper.init(this);
+        WaitHelper.init(this);
+    }
+
+    @Override
+    public Solo getSolo() {
+        return mSolo;
+    }
+
+    @Override
+    public Assert getAsserter() {
+        return mAsserter;
+    }
+
+    @Override
+    public Driver getDriver() {
+        return mDriver;
+    }
+
+    @Override
+    public Actions getActions() {
+        return mActions;
+    }
+
+    @Override
+    public void dumpLog(final String message) {
+        mAsserter.dumpLog(message);
+    }
+
+    @Override
+    public void dumpLog(final String message, final Throwable t) {
+        mAsserter.dumpLog(message, t);
+    }
+
+    @Override
+    public BaseComponent getComponent(final ComponentType type) {
+        switch (type) {
+            case ABOUTHOME:
+                return mAboutHome;
+
+            case TOOLBAR:
+                return mToolbar;
+
+            default:
+                fail("Unknown component type, " + type + ".");
+                return null; // Should not reach this statement but required by javac.
+        }
+    }
+
+    /**
+     * Returns the test type. By default this returns MOCHITEST, but tests can override this
+     * method in order to change the type of the test.
+     */
+    protected Type getTestType() {
+        return Type.MOCHITEST;
+    }
+
+    @Override
+    public String getAbsoluteHostnameUrl(final String url) {
+        return getAbsoluteUrl(mBaseHostnameUrl, url);
+    }
+
+    @Override
+    public String getAbsoluteIpUrl(final String url) {
+        return getAbsoluteUrl(mBaseIpUrl, url);
+    }
+
+    private String getAbsoluteUrl(final String baseUrl, final String url) {
+        return baseUrl + "/" + url.replaceAll("(^/)", "");
+    }
+
+    private static HashMap loadConfigTable(final String rootPath) {
+        final String configFile = FennecNativeDriver.getFile(rootPath + "/robotium.config");
+        return FennecNativeDriver.convertTextToTable(configFile);
+    }
+
+    private static Intent createActivityIntent(final HashMap config) {
+        final Intent intent = new Intent(Intent.ACTION_MAIN);
+
+        final String profile = (String) config.get("profile");
+        intent.putExtra("args", "-no-remote -profile " + profile);
+
+        final String envString = (String) config.get("envvars");
+        if (!TextUtils.isEmpty(envString)) {
+            final String[] envStrings = envString.split(",");
+
+            for (int iter = 0; iter < envStrings.length; iter++) {
+                intent.putExtra("env" + iter, envStrings[iter]);
+            }
+        }
+
+        return intent;
+    }
+}
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/tests/UITestContext.java
@@ -0,0 +1,48 @@
+/* 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/. */
+
+package org.mozilla.gecko.tests;
+
+import org.mozilla.gecko.Actions;
+import org.mozilla.gecko.Assert;
+import org.mozilla.gecko.Driver;
+import org.mozilla.gecko.tests.components.BaseComponent;
+
+import com.jayway.android.robotium.solo.Solo;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+
+/**
+ * Interface to the global information about a UITest environment.
+ */
+public interface UITestContext {
+
+    public static enum ComponentType {
+        ABOUTHOME,
+        TOOLBAR
+    }
+
+    public Activity getActivity();
+    public Solo getSolo();
+    public Assert getAsserter();
+    public Driver getDriver();
+    public Actions getActions();
+    public Instrumentation getInstrumentation();
+
+    public void dumpLog(final String message);
+    public void dumpLog(final String message, final Throwable t);
+
+    /**
+     * Returns the absolute version of the given URL using the host's hostname.
+     */
+    public String getAbsoluteHostnameUrl(final String url);
+
+    /**
+     * Returns the absolute version of the given URL using the host's IP address.
+     */
+    public String getAbsoluteIpUrl(final String url);
+
+    public BaseComponent getComponent(final ComponentType type);
+}
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/tests/components/AboutHomeComponent.java
@@ -0,0 +1,105 @@
+/* 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/. */
+
+package org.mozilla.gecko.tests.components;
+
+import static org.mozilla.gecko.tests.helpers.AssertionHelper.*;
+
+import org.mozilla.gecko.Actions;
+import org.mozilla.gecko.home.HomePager.Page;
+import org.mozilla.gecko.R;
+import org.mozilla.gecko.tests.helpers.*;
+import org.mozilla.gecko.tests.UITestContext;
+
+import com.jayway.android.robotium.solo.Condition;
+import com.jayway.android.robotium.solo.Solo;
+
+import android.support.v4.view.PagerAdapter;
+import android.support.v4.view.ViewPager;
+import android.view.View;
+
+/**
+ * A class representing any interactions that take place on the Awesomescreen.
+ */
+public class AboutHomeComponent extends BaseComponent {
+    public AboutHomeComponent(final UITestContext testContext) {
+        super(testContext);
+    }
+
+    private ViewPager getHomePagerView() {
+        return (ViewPager) mSolo.getView(R.id.home_pager);
+    }
+
+    public AboutHomeComponent assertCurrentPage(final Page expectedPage) {
+        assertVisible();
+
+        // TODO: A "PhonePage" and "TabletPage" enum should be set explicitly or decided
+        // dynamically, likely with the work done in bug 940565. The current solution should only
+        // be temporary.
+        int expectedPageIndex = expectedPage.ordinal();
+        if (DeviceHelper.isTablet()) {
+            // Left circular shift Page enum since the History tab is moved to the rightmost.
+            expectedPageIndex -= 1;
+            expectedPageIndex =
+                    (expectedPageIndex >= 0) ? expectedPageIndex : Page.values().length - 1;
+        }
+
+        assertEquals("The current HomePager page is " + Page.values()[expectedPageIndex],
+                     expectedPageIndex, getHomePagerView().getCurrentItem());
+        return this;
+    }
+
+    public AboutHomeComponent assertNotVisible() {
+        assertFalse("The HomePager is not visible",
+                    getHomePagerView().getVisibility() == View.VISIBLE);
+        return this;
+    }
+
+    public AboutHomeComponent assertVisible() {
+        assertEquals("The HomePager is visible",
+                     View.VISIBLE, getHomePagerView().getVisibility());
+        return this;
+    }
+
+    // TODO: Take specific page as parameter rather than swipe in a direction?
+    public AboutHomeComponent swipeToPageOnRight() {
+        swipe(Solo.LEFT);
+        return this;
+    }
+
+    public AboutHomeComponent swipeToPageOnLeft() {
+        swipe(Solo.RIGHT);
+        return this;
+    }
+
+    private void swipe(final int direction) {
+        assertVisible();
+
+        final int pageIndex = getHomePagerView().getCurrentItem();
+        if (direction == Solo.LEFT) {
+            GestureHelper.swipeLeft();
+        } else {
+            GestureHelper.swipeRight();
+        }
+
+        final PagerAdapter adapter = getHomePagerView().getAdapter();
+        assertNotNull("The HomePager's PagerAdapter is not null", adapter);
+
+        // Swiping left goes to next, swiping right goes to previous
+        final int unboundedPageIndex = pageIndex + (direction == Solo.LEFT ? 1 : -1);
+        final int expectedPageIndex = Math.min(Math.max(0, unboundedPageIndex), adapter.getCount() - 1);
+
+        waitForPageIndex(expectedPageIndex);
+    }
+
+    private void waitForPageIndex(final int expectedIndex) {
+        final String pageName = Page.values()[expectedIndex].toString();
+        WaitHelper.waitFor("HomePager " + pageName + " page", new Condition() {
+            @Override
+            public boolean isSatisfied() {
+                return (getHomePagerView().getCurrentItem() == expectedIndex);
+            }
+        });
+    }
+}
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/tests/components/BaseComponent.java
@@ -0,0 +1,37 @@
+/* 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/. */
+
+package org.mozilla.gecko.tests.components;
+
+import org.mozilla.gecko.Actions;
+import org.mozilla.gecko.tests.UITestContext;
+
+import com.jayway.android.robotium.solo.Solo;
+
+import android.app.Activity;
+
+/**
+ * A base class for constructing components - an abstraction over small bits of Firefox
+ * functionality. For example, the Toolbar or the about:home screen could be considered a
+ * component. Components should not need to know about each others existences and should be
+ * combined via helpers. Helpers can also handle a series of actions taken on one component
+ * (e.g. clicking the toolbar, entering a url, and waiting for page load).
+ */
+public abstract class BaseComponent {
+    private final UITestContext mTestContext;
+    protected final Activity mActivity;
+    protected final Solo mSolo;
+    protected final Actions mActions;
+
+    public BaseComponent(final UITestContext testContext) {
+        mTestContext = testContext;
+        mActivity = mTestContext.getActivity();
+        mSolo = mTestContext.getSolo();
+        mActions = mTestContext.getActions();
+    }
+
+    protected UITestContext getTestContext() {
+        return mTestContext;
+    }
+}
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/tests/components/ToolbarComponent.java
@@ -0,0 +1,225 @@
+/* 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/. */
+
+package org.mozilla.gecko.tests.components;
+
+import static org.mozilla.gecko.tests.helpers.AssertionHelper.*;
+
+import org.mozilla.gecko.InputMethods;
+import org.mozilla.gecko.tests.helpers.*;
+import org.mozilla.gecko.tests.UITestContext;
+import org.mozilla.gecko.R;
+
+import com.jayway.android.robotium.solo.Condition;
+import com.jayway.android.robotium.solo.Solo;
+
+import android.view.View;
+import android.widget.EditText;
+import android.widget.ImageButton;
+import android.widget.TextView;
+
+/**
+ * A class representing any interactions that take place on the Toolbar.
+ */
+public class ToolbarComponent extends BaseComponent {
+    public ToolbarComponent(final UITestContext testContext) {
+        super(testContext);
+    }
+
+    public ToolbarComponent assertIsEditing() {
+        assertTrue("The toolbar is in the editing state", isEditing());
+        return this;
+    }
+
+    public ToolbarComponent assertIsNotEditing() {
+        assertFalse("The toolbar is not in the editing state", isEditing());
+        return this;
+    }
+
+    public ToolbarComponent assertTitle(final String expected) {
+        assertEquals("The Toolbar title is " + expected, expected, getTitle());
+        return this;
+    }
+
+    public ToolbarComponent assertUrl(final String expected) {
+        assertIsEditing();
+        assertEquals("The Toolbar url is " + expected, expected, getUrlEditText().getText());
+        return this;
+    }
+
+    /**
+     * Returns the root View for the browser toolbar.
+     */
+    private View getToolbarView() {
+        return mSolo.getView(R.id.browser_toolbar);
+    }
+
+    private EditText getUrlEditText() {
+        return (EditText) getToolbarView().findViewById(R.id.url_edit_text);
+    }
+
+    private View getUrlDisplayContainer() {
+        return getToolbarView().findViewById(R.id.url_display_container);
+    }
+
+    private TextView getUrlTitleText() {
+        return (TextView) getToolbarView().findViewById(R.id.url_bar_title);
+    }
+
+    /**
+     * Returns the View for the go button in the browser toolbar.
+     */
+    private ImageButton getGoButton() {
+        return (ImageButton) getToolbarView().findViewById(R.id.go);
+    }
+
+    private ImageButton getBackButton() {
+        DeviceHelper.assertIsTablet();
+        return (ImageButton) getToolbarView().findViewById(R.id.back);
+    }
+
+    private ImageButton getForwardButton() {
+        DeviceHelper.assertIsTablet();
+        return (ImageButton) getToolbarView().findViewById(R.id.forward);
+    }
+
+    private CharSequence getTitle() {
+        return getTitleHelper(true);
+    }
+
+    /**
+     * Returns the title of the page. Note that this makes no assertions to Toolbar state and
+     * may return a value that may never be visible to the user. Callers likely want to use
+     * {@link assertTitle} instead.
+     */
+    public CharSequence getPotentiallyInconsistentTitle() {
+        return getTitleHelper(false);
+    }
+
+    private CharSequence getTitleHelper(final boolean shouldAssertNotEditing) {
+        if (shouldAssertNotEditing) {
+            assertIsNotEditing();
+        }
+
+        return getUrlTitleText().getText();
+    }
+
+    private boolean isEditing() {
+        return getUrlDisplayContainer().getVisibility() != View.VISIBLE &&
+                getUrlEditText().getVisibility() == View.VISIBLE;
+    }
+
+    public ToolbarComponent enterEditingMode() {
+        assertIsNotEditing();
+
+        mSolo.clickOnView(getUrlTitleText(), true);
+
+        waitForEditing();
+        WaitHelper.waitFor("UrlEditText to be input method target", new Condition() {
+            @Override
+            public boolean isSatisfied() {
+                return getUrlEditText().isInputMethodTarget();
+            }
+        });
+
+        return this;
+    }
+
+    public ToolbarComponent commitEditingMode() {
+        assertIsEditing();
+
+        WaitHelper.waitForPageLoad(new Runnable() {
+            @Override
+            public void run() {
+                if (InputMethods.shouldDisableUrlBarUpdate(mActivity)) {
+                    // Bug 945521 workaround: Some IMEs do not allow the go button
+                    // to be displayed in the toolbar so we hit enter instead.
+                    mSolo.sendKey(Solo.ENTER);
+                } else {
+                    mSolo.clickOnView(getGoButton());
+                }
+            }
+        });
+        waitForNotEditing();
+
+        return this;
+    }
+
+    public ToolbarComponent dismissEditingMode() {
+        assertIsEditing();
+
+        if (getUrlEditText().isInputMethodTarget()) {
+            // Drop the soft keyboard.
+            // TODO: Solo.hideSoftKeyboard() does not clear focus, causing unexpected
+            // behavior, but we may want to use it over goBack().
+            mSolo.goBack();
+        }
+
+        mSolo.goBack();
+
+        waitForNotEditing();
+
+        return this;
+    }
+
+    public ToolbarComponent enterUrl(final String url) {
+        assertNotNull("url is not null", url);
+
+        assertIsEditing();
+
+        final EditText urlEditText = getUrlEditText();
+        assertTrue("The UrlEditText is the input method target",
+                urlEditText.isInputMethodTarget());
+
+        mSolo.clearEditText(urlEditText);
+        mSolo.enterText(urlEditText, url);
+
+        return this;
+    }
+
+    public ToolbarComponent pressBackButton() {
+        final ImageButton backButton = getBackButton();
+        return pressButton(backButton, "back");
+    }
+
+    public ToolbarComponent pressForwardButton() {
+        final ImageButton forwardButton = getForwardButton();
+        return pressButton(forwardButton, "forward");
+    }
+
+    private ToolbarComponent pressButton(final View view, final String buttonName) {
+        assertNotNull("The " + buttonName + " button View is not null", view);
+        assertTrue("The " + buttonName + " button is enabled", view.isEnabled());
+        assertEquals("The " + buttonName + " button is visible",
+                View.VISIBLE, view.getVisibility());
+        assertIsNotEditing();
+
+        WaitHelper.waitForPageLoad(new Runnable() {
+            @Override
+            public void run() {
+                mSolo.clickOnView(view);
+            }
+        });
+
+        return this;
+    }
+
+    private void waitForEditing() {
+        WaitHelper.waitFor("Toolbar to enter editing mode", new Condition() {
+            @Override
+            public boolean isSatisfied() {
+                return isEditing();
+            }
+        });
+    }
+
+    private void waitForNotEditing() {
+        WaitHelper.waitFor("Toolbar to exit editing mode", new Condition() {
+            @Override
+            public boolean isSatisfied() {
+                return !isEditing();
+            }
+        });
+    }
+}
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/tests/helpers/AssertionHelper.java
@@ -0,0 +1,53 @@
+/* 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/. */
+
+package org.mozilla.gecko.tests.helpers;
+
+import org.mozilla.gecko.Assert;
+import org.mozilla.gecko.tests.UITestContext;
+
+// TODO: Add ispixel assertions.
+/**
+ * Provides assertions in a JUnit-like API that wraps the robocop Assert interface.
+ */
+public final class AssertionHelper {
+    // Assert.ok has a "diag" ("diagnostic") parameter that has no useful purpose.
+    private static final String DIAG_STRING = "";
+
+    private static Assert sAsserter;
+
+    private AssertionHelper() { /* To disallow instantation. */ }
+
+    public static void init(final UITestContext context) {
+        sAsserter = context.getAsserter();
+    }
+
+    public static void assertEquals(final String message, final Object expected, final Object actual) {
+        sAsserter.is(actual, expected, message);
+    }
+
+    public static void assertEquals(final String message, final int expected, final int actual) {
+        sAsserter.is(actual, expected, message);
+    }
+
+    public static void assertFalse(final String message, final boolean actual) {
+        sAsserter.ok(!actual, message, DIAG_STRING);
+    }
+
+    public static void assertNotNull(final String message, final Object actual) {
+        sAsserter.isnot(actual, null, message);
+    }
+
+    public static void assertNull(final String message, final Object actual) {
+        sAsserter.is(actual, null, message);
+    }
+
+    public static void assertTrue(final String message, final boolean actual) {
+        sAsserter.ok(actual, message, DIAG_STRING);
+    }
+
+    public static void fail(final String message) {
+        sAsserter.ok(false, message, DIAG_STRING);
+    }
+}
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/tests/helpers/DeviceHelper.java
@@ -0,0 +1,109 @@
+/* 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/. */
+
+package org.mozilla.gecko.tests.helpers;
+
+import static org.mozilla.gecko.tests.helpers.AssertionHelper.*;
+
+import org.mozilla.gecko.GeckoAppShell;
+import org.mozilla.gecko.tests.UITestContext;
+
+import com.jayway.android.robotium.solo.Solo;
+
+import android.app.Activity;
+import android.content.pm.ActivityInfo;
+import android.os.Build;
+import android.util.DisplayMetrics;
+
+/**
+ * Provides general hardware (ex: configuration) and software (ex: version) information
+ * about the current test device and allows changing its configuration.
+ */
+public final class DeviceHelper {
+    public enum Type {
+        PHONE,
+        TABLET
+    }
+
+    public enum AndroidVersion {
+        v2x,
+        v3x,
+        v4x
+    }
+
+    private static Activity sActivity;
+    private static Solo sSolo;
+
+    private static Type sDeviceType;
+    private static AndroidVersion sAndroidVersion;
+
+    private static int sScreenHeight;
+    private static int sScreenWidth;
+
+    private DeviceHelper() { /* To disallow instantiation. */ }
+
+    public static void assertIsTablet() {
+        assertTrue("The device is a tablet", isTablet());
+    }
+
+    public static void init(final UITestContext context) {
+        sActivity = context.getActivity();
+        sSolo = context.getSolo();
+
+        setAndroidVersion();
+        setScreenDimensions();
+        setDeviceType();
+    }
+
+    private static void setAndroidVersion() {
+        int sdk = Build.VERSION.SDK_INT;
+        if (sdk < Build.VERSION_CODES.HONEYCOMB) {
+            sAndroidVersion = AndroidVersion.v2x;
+        } else if (sdk > Build.VERSION_CODES.HONEYCOMB_MR2) {
+            sAndroidVersion = AndroidVersion.v4x;
+        } else {
+            sAndroidVersion = AndroidVersion.v3x;
+        }
+    }
+
+    private static void setScreenDimensions() {
+        final DisplayMetrics dm = new DisplayMetrics();
+        sActivity.getWindowManager().getDefaultDisplay().getMetrics(dm);
+
+        sScreenHeight = dm.heightPixels;
+        sScreenWidth = dm.widthPixels;
+    }
+
+    private static void setDeviceType() {
+        sDeviceType = (GeckoAppShell.isTablet() ? Type.TABLET : Type.PHONE);
+    }
+
+    public static int getScreenHeight() {
+        return sScreenHeight;
+    }
+
+    public static int getScreenWidth() {
+        return sScreenWidth;
+    }
+
+    public static AndroidVersion getAndroidVersion() {
+        return sAndroidVersion;
+    }
+
+    public static boolean isPhone() {
+        return (sDeviceType == Type.PHONE);
+    }
+
+    public static boolean isTablet() {
+        return (sDeviceType == Type.TABLET);
+    }
+
+    public static void setLandscapeRotation() {
+        sSolo.setActivityOrientation(Solo.LANDSCAPE);
+    }
+
+    public static void setPortraitOrientation() {
+        sSolo.setActivityOrientation(Solo.LANDSCAPE);
+    }
+}
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/tests/helpers/GeckoHelper.java
@@ -0,0 +1,39 @@
+/* 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/. */
+
+package org.mozilla.gecko.tests.helpers;
+
+import org.mozilla.gecko.Actions;
+import org.mozilla.gecko.Actions.EventExpecter;
+import org.mozilla.gecko.GeckoThread;
+import org.mozilla.gecko.GeckoThread.LaunchState;
+import org.mozilla.gecko.tests.UITestContext;
+
+import android.app.Activity;
+
+/**
+ * Provides helper functions for accessing the underlying Gecko engine.
+ */
+public final class GeckoHelper {
+    private static Activity sActivity;
+    private static Actions sActions;
+
+    private GeckoHelper() { /* To disallow instantiation. */ }
+
+    public static void init(final UITestContext context) {
+        sActivity = context.getActivity();
+        sActions = context.getActions();
+    }
+
+    public static void blockForReady() {
+        final EventExpecter geckoReady = sActions.expectGeckoEvent("Gecko:Ready");
+
+        final boolean isReady = GeckoThread.checkLaunchState(LaunchState.GeckoRunning);
+        if (!isReady) {
+            geckoReady.blockForEvent();
+        }
+
+        geckoReady.unregisterListener();
+    }
+}
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/tests/helpers/GestureHelper.java
@@ -0,0 +1,44 @@
+/* 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/. */
+
+package org.mozilla.gecko.tests.helpers;
+
+import org.mozilla.gecko.Driver;
+import org.mozilla.gecko.tests.UITestContext;
+
+import com.jayway.android.robotium.solo.Solo;
+
+/**
+ * Provides simplified gestures wrapping the Robotium gestures API.
+ */
+public final class GestureHelper {
+    private static int DEFAULT_DRAG_STEP_COUNT = 10;
+
+    private static Solo sSolo;
+    private static Driver sDriver;
+
+    private GestureHelper() { /* To disallow instantation. */ }
+
+    public static void init(final UITestContext context) {
+        sSolo = context.getSolo();
+        sDriver = context.getDriver();
+    }
+
+    private static void swipeOnScreen(final int direction) {
+        final int halfWidth = sDriver.getGeckoWidth() / 2;
+        final int halfHeight = sDriver.getGeckoHeight() / 2;
+
+        sSolo.drag(direction == Solo.LEFT ? halfWidth : 0,
+                   direction == Solo.LEFT ? 0 : halfWidth,
+                   halfHeight, halfHeight, DEFAULT_DRAG_STEP_COUNT);
+    }
+
+    public static void swipeLeft() {
+        swipeOnScreen(Solo.LEFT);
+    }
+
+    public static void swipeRight() {
+        swipeOnScreen(Solo.RIGHT);
+    }
+}
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/tests/helpers/NavigationHelper.java
@@ -0,0 +1,96 @@
+/* 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/. */
+
+package org.mozilla.gecko.tests.helpers;
+
+import static org.mozilla.gecko.tests.helpers.AssertionHelper.*;
+
+import org.mozilla.gecko.tests.components.ToolbarComponent;
+import org.mozilla.gecko.tests.UITestContext;
+import org.mozilla.gecko.tests.UITestContext.ComponentType;
+
+import com.jayway.android.robotium.solo.Solo;
+
+import android.text.TextUtils;
+
+/**
+ * Provides helper functionality for navigating around the Firefox UI. These functions will often
+ * combine actions taken on multiple components to perform larger interactions.
+ */
+final public class NavigationHelper {
+    private static UITestContext sContext;
+    private static Solo sSolo;
+
+    private static ToolbarComponent sToolbar;
+
+    public static void init(final UITestContext context) {
+        sContext = context;
+        sSolo = context.getSolo();
+
+        sToolbar = (ToolbarComponent) context.getComponent(ComponentType.TOOLBAR);
+    }
+
+    public static void enterAndLoadUrl(String url) {
+        assertNotNull("url is not null", url);
+
+        url = adjustUrl(url);
+        sToolbar.enterEditingMode()
+                .enterUrl(url)
+                .commitEditingMode();
+    }
+
+    /**
+     * Returns a new URL with the docshell HTTP server host prefix.
+     */
+    private static String adjustUrl(final String url) {
+        assertNotNull("url is not null", url);
+
+        if (!url.startsWith("about:")) {
+            return sContext.getAbsoluteHostnameUrl(url);
+        }
+
+        return url;
+    }
+
+    public static void goBack() {
+        if (DeviceHelper.isTablet()) {
+            sToolbar.pressBackButton(); // Waits for page load & asserts isNotEditing.
+            return;
+        }
+
+        sToolbar.assertIsNotEditing();
+        WaitHelper.waitForPageLoad(new Runnable() {
+            @Override
+            public void run() {
+                // TODO: Lower soft keyboard first if applicable. Note that
+                // Solo.hideSoftKeyboard() does not clear focus (which might be fine since
+                // Gecko would be the element focused).
+                sSolo.goBack();
+            }
+        });
+    }
+
+    public static void goForward() {
+        if (DeviceHelper.isTablet()) {
+            sToolbar.pressForwardButton(); // Waits for page load & asserts isNotEditing.
+            return;
+        }
+
+        sToolbar.assertIsNotEditing();
+        WaitHelper.waitForPageLoad(new Runnable() {
+            @Override
+            public void run() {
+                // TODO: Press forward with APPMENU component
+                throw new UnsupportedOperationException("Not yet implemented.");
+            }
+        });
+    }
+
+    public static void reload() {
+        // TODO: On tablets, press reload in TOOLBAR. Note that this is technically
+        // an app menu item so tread carefully.
+        //       On phones, press reload in APPMENU.
+        throw new UnsupportedOperationException("Not yet implemented.");
+    }
+}
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/tests/helpers/WaitHelper.java
@@ -0,0 +1,154 @@
+/* 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/. */
+
+package org.mozilla.gecko.tests.helpers;
+
+import static org.mozilla.gecko.tests.helpers.AssertionHelper.*;
+
+import org.mozilla.gecko.Actions;
+import org.mozilla.gecko.Actions.EventExpecter;
+import org.mozilla.gecko.tests.components.ToolbarComponent;
+import org.mozilla.gecko.tests.UITestContext;
+import org.mozilla.gecko.tests.UITestContext.ComponentType;
+
+import com.jayway.android.robotium.solo.Condition;
+import com.jayway.android.robotium.solo.Solo;
+
+/**
+ * Provides functionality related to waiting on certain events to happen.
+ */
+public final class WaitHelper {
+    // TODO: Make public for when Solo.waitForCondition is used directly (i.e. do not want
+    // assertion from waitFor)?
+    private static final int DEFAULT_MAX_WAIT_MS = 5000;
+    private static final int PAGE_LOAD_WAIT_MS = 10000;
+    private static final int CHANGE_WAIT_MS = 5000;
+
+    // TODO: via lucasr - Add ThrobberVisibilityChangeVerifier?
+    private static final ChangeVerifier[] PAGE_LOAD_VERIFIERS = new ChangeVerifier[] {
+        new ToolbarTitleTextChangeVerifier()
+    };
+
+    private static UITestContext sContext;
+    private static Solo sSolo;
+    private static Actions sActions;
+
+    private static ToolbarComponent sToolbar;
+
+    private WaitHelper() { /* To disallow instantiation. */ }
+
+    public static void init(final UITestContext context) {
+        sContext = context;
+        sSolo = context.getSolo();
+        sActions = context.getActions();
+
+        sToolbar = (ToolbarComponent) context.getComponent(ComponentType.TOOLBAR);
+    }
+
+    /**
+     * Waits for the given {@link solo.Condition} using the default wait duration; will throw an
+     * AssertionError if the duration is elapsed and the condition is not satisfied.
+     */
+    public static void waitFor(String message, final Condition condition) {
+        message = "Waiting for " + message + ".";
+        assertTrue(message, sSolo.waitForCondition(condition, DEFAULT_MAX_WAIT_MS));
+    }
+
+    /**
+     * Waits for the given {@link solo.Condition} using the given wait duration; will throw an
+     * AssertionError if the duration is elapsed and the condition is not satisfied.
+     */
+    public static void waitFor(String message, final Condition condition, final int waitMillis) {
+        message = "Waiting for " + message + " with timeout " + waitMillis + ".";
+        assertTrue(message, sSolo.waitForCondition(condition, waitMillis));
+    }
+
+    /**
+     * Waits for the Gecko event declaring the page has loaded. Takes in and runs a Runnable
+     * that will perform the action that will cause the page to load.
+     */
+    public static void waitForPageLoad(final Runnable initiatingAction) {
+        assertNotNull("initiatingAction is not null", initiatingAction);
+
+        // Some changes to the UI occur in response to the same event we listen to for when
+        // the page has finished loading (e.g. a page title update). As such, we ensure this
+        // UI state has changed before returning from this method; here we store the initial
+        // state.
+        final ChangeVerifier[] pageLoadVerifiers = PAGE_LOAD_VERIFIERS;
+        for (final ChangeVerifier verifier : pageLoadVerifiers) {
+            verifier.storeState();
+        }
+
+        // Wait for the page load and title changed event.
+        final EventExpecter contentEventExpecter = sActions.expectGeckoEvent("DOMContentLoaded");
+        final EventExpecter titleEventExpecter = sActions.expectGeckoEvent("DOMTitleChanged");
+
+        initiatingAction.run();
+
+        contentEventExpecter.blockForEventDataWithTimeout(PAGE_LOAD_WAIT_MS);
+        contentEventExpecter.unregisterListener();
+        titleEventExpecter.blockForEventDataWithTimeout(PAGE_LOAD_WAIT_MS);
+        titleEventExpecter.unregisterListener();
+
+        // Verify remaining state has changed.
+        for (final ChangeVerifier verifier : pageLoadVerifiers) {
+            // If we timeout, either the state is set to the same value (which is fine), or
+            // the state has not yet changed. Since we can't be sure it will ever change, move
+            // on and let the assertions fail if applicable.
+            final boolean hasTimedOut = !sSolo.waitForCondition(new Condition() {
+                @Override
+                public boolean isSatisfied() {
+                    return verifier.hasStateChanged();
+                }
+            }, CHANGE_WAIT_MS);
+
+            if (hasTimedOut) {
+                sContext.dumpLog(verifier.getClass().getName() + " timed out.");
+            }
+        }
+    }
+
+    /**
+     * Implementations of this interface verify that the state of the test has changed from
+     * the invocation of storeState to the invocation of hasStateChanged. A boolean will be
+     * returned from hasStateChanged, indicating this change of status.
+     */
+    private static interface ChangeVerifier {
+        /**
+         * Stores the initial state of the system. This system state is used to diff against
+         * the end state to determine if the system has changed. Since this is just a diff
+         * (with a timeout), this method could potentially store state inconsistent with
+         * what is visible to the user.
+         */
+        public void storeState();
+        public boolean hasStateChanged();
+    }
+
+    private static class ToolbarTitleTextChangeVerifier implements ChangeVerifier {
+        // A regex that matches the page title that shows up while the page is loading.
+        private static final String LOADING_REGEX = "^[A-Za-z]{3,9}://";
+
+        private CharSequence oldTitleText;
+
+        @Override
+        public void storeState() {
+            oldTitleText = sToolbar.getPotentiallyInconsistentTitle();
+        }
+
+        @Override
+        public boolean hasStateChanged() {
+            // TODO: Additionally, consider Solo.waitForText.
+            // TODO: Robocop sleeps .5 sec between calls. Cache title view?
+            final CharSequence title = sToolbar.getPotentiallyInconsistentTitle();
+
+            // TODO: Handle the case where the URL is shown instead of page title by preference.
+            // HACK: We want to wait until the title changes to the state a tester may assert
+            // (e.g. the page title). However, the title is set to the URL before the title is
+            // loaded from the server and set as the final page title; we ignore the
+            // intermediate URL loading state here.
+            final boolean isLoading = title.toString().matches(LOADING_REGEX);
+            return !isLoading && !oldTitleText.equals(title);
+        }
+    }
+}
--- a/mobile/android/base/tests/robocop.ini
+++ b/mobile/android/base/tests/robocop.ini
@@ -1,16 +1,15 @@
 # [test_bug720538] # disabled on fig - bug 897072
 [testAboutPage]
 [testAddonManager]
 # disabled on x86 only; bug 936216
 skip-if = processor == "x86"
 [testAddSearchEngine]
 [testAwesomebar]
-# [testAwesomebarSwipes] # disabled on fig - bug 880060
 [testAxisLocking]
 # disabled on x86 only; bug 927476
 skip-if = processor == "x86"
 # [testBookmark] # see bug 915350
 [testBookmarksPage]
 [testBookmarkFolders]
 # [testBookmarklets] # see bug 915350
 # [testBookmarkKeyword] # see bug 915350
@@ -59,18 +58,22 @@ skip-if = processor == "x86"
 [testSessionOOMRestore]
 [testSettingsMenuItems]
 [testMozPay]
 [testSharedPreferences]
 # [testShareLink] # see bug 915897
 [testSystemPages]
 # disabled on x86 only; bug 907383
 skip-if = processor == "x86"
-# [testTabHistory] # see bug 915350
 # [testThumbnails] # see bug 813107
 # [testVkbOverlap] # see bug 907274
 
 
 # Used for Talos, please don't use in mochitest
 #[testPan]
 #[testCheck]
 #[testCheck2]
 #[testBrowserProviderPerf]
+
+# Using UITest
+[testAboutHomePageNavigation]
+[testAboutHomeVisibility]
+[testSessionHistory]
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/tests/testAboutHomePageNavigation.java
@@ -0,0 +1,113 @@
+package org.mozilla.gecko.tests;
+
+import static org.mozilla.gecko.tests.helpers.AssertionHelper.*;
+
+import org.mozilla.gecko.home.HomePager.Page;
+import org.mozilla.gecko.tests.helpers.*;
+
+/**
+ * Tests functionality related to navigating between the various about:home pages.
+ */
+public class testAboutHomePageNavigation extends UITest {
+    // TODO: Define this test dynamically by creating dynamic representations of the Page
+    // enum for both phone and tablet, then swiping through the pages. This will also
+    // benefit having a HomePager with custom pages.
+    public void testAboutHomePageNavigation() {
+        GeckoHelper.blockForReady();
+
+        mAboutHome.assertVisible()
+                  .assertCurrentPage(Page.TOP_SITES);
+
+        mAboutHome.swipeToPageOnRight();
+        mAboutHome.assertCurrentPage(Page.BOOKMARKS);
+
+        mAboutHome.swipeToPageOnRight();
+        mAboutHome.assertCurrentPage(Page.READING_LIST);
+
+        // Ideally these helpers would just be their own tests. However, by keeping this within
+        // one method, we're saving test setUp and tearDown resources.
+        if (DeviceHelper.isTablet()) {
+            helperTestTablet();
+        } else {
+            helperTestPhone();
+        }
+    }
+
+    private void helperTestTablet() {
+        mAboutHome.swipeToPageOnRight();
+        mAboutHome.assertCurrentPage(Page.HISTORY);
+
+        // Edge case.
+        mAboutHome.swipeToPageOnRight();
+        mAboutHome.assertCurrentPage(Page.HISTORY);
+
+        mAboutHome.swipeToPageOnLeft();
+        mAboutHome.assertCurrentPage(Page.READING_LIST);
+
+        mAboutHome.swipeToPageOnLeft();
+        mAboutHome.assertCurrentPage(Page.BOOKMARKS);
+
+        mAboutHome.swipeToPageOnLeft();
+        mAboutHome.assertCurrentPage(Page.TOP_SITES);
+
+        // Edge case.
+        mAboutHome.swipeToPageOnLeft();
+        mAboutHome.assertCurrentPage(Page.TOP_SITES);
+    }
+
+    private void helperTestPhone() {
+        // Edge case.
+        mAboutHome.swipeToPageOnRight();
+        mAboutHome.assertCurrentPage(Page.READING_LIST);
+
+        mAboutHome.swipeToPageOnLeft();
+        mAboutHome.assertCurrentPage(Page.BOOKMARKS);
+
+        mAboutHome.swipeToPageOnLeft();
+        mAboutHome.assertCurrentPage(Page.TOP_SITES);
+
+        mAboutHome.swipeToPageOnLeft();
+        mAboutHome.assertCurrentPage(Page.HISTORY);
+
+        // Edge case.
+        mAboutHome.swipeToPageOnLeft();
+        mAboutHome.assertCurrentPage(Page.HISTORY);
+
+        mAboutHome.swipeToPageOnRight();
+        mAboutHome.assertCurrentPage(Page.TOP_SITES);
+    }
+
+    // TODO: bug 943706 - reimplement this old test code.
+    /*
+        //  Removed by Bug 896576 - [fig] Remove [getAllPagesList] from BaseTest
+        //  ListView list = getAllPagesList("about:firefox");
+
+        // Test normal sliding of the list left and right
+        ViewPager pager = (ViewPager)mSolo.getView(ViewPager.class, 0);
+        mAsserter.is(pager.getCurrentItem(), 0, "All pages is selected");
+
+        int width = mDriver.getGeckoWidth() / 2;
+        int y = mDriver.getGeckoHeight() / 2;
+        mActions.drag(width, 0, y, y);
+        mAsserter.is(pager.getCurrentItem(), 1, "Bookmarks page is selected");
+
+        mActions.drag(0, width, y, y);
+        mAsserter.is(pager.getCurrentItem(), 0, "All pages is selected");
+
+        // Test tapping on the tab strip changes tabs
+        TabWidget tabwidget = (TabWidget)mSolo.getView(TabWidget.class, 0);
+        mSolo.clickOnView(tabwidget.getChildAt(1));
+        mAsserter.is(pager.getCurrentItem(), 1, "Clicking on tab selected bookmarks page");
+
+        // Test typing in the awesomebar changes tabs and prevents panning
+        mSolo.typeText(0, "woot");
+        mAsserter.is(pager.getCurrentItem(), 0, "Searching switched to all pages tab");
+        mSolo.scrollToSide(Solo.LEFT);
+        mAsserter.is(pager.getCurrentItem(), 0, "Dragging left is not allowed when searching");
+
+        mSolo.scrollToSide(Solo.RIGHT);
+        mAsserter.is(pager.getCurrentItem(), 0, "Dragging right is not allowed when searching");
+
+        mActions.sendSpecialKey(Actions.SpecialKey.BACK);
+    */
+}
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/tests/testAboutHomeVisibility.java
@@ -0,0 +1,47 @@
+package org.mozilla.gecko.tests;
+
+import static org.mozilla.gecko.tests.helpers.AssertionHelper.*;
+
+import org.mozilla.gecko.home.HomePager.Page;
+import org.mozilla.gecko.tests.helpers.*;
+
+/**
+ * Tests the visibility of about:home after various interactions with the browser.
+ */
+public class testAboutHomeVisibility extends UITest {
+    public void testAboutHomeVisibility() {
+        GeckoHelper.blockForReady();
+
+        // Check initial state on about:home.
+        mToolbar.assertTitle(StringHelper.ABOUT_HOME_TITLE);
+        mAboutHome.assertVisible()
+                  .assertCurrentPage(Page.TOP_SITES);
+
+        // Go to blank 01.
+        NavigationHelper.enterAndLoadUrl(StringHelper.ROBOCOP_BLANK_PAGE_01_URL);
+        mToolbar.assertTitle(StringHelper.ROBOCOP_BLANK_PAGE_01_TITLE);
+        mAboutHome.assertNotVisible();
+
+        // Go to blank 02.
+        NavigationHelper.enterAndLoadUrl(StringHelper.ROBOCOP_BLANK_PAGE_02_URL);
+        mToolbar.assertTitle(StringHelper.ROBOCOP_BLANK_PAGE_02_TITLE);
+        mAboutHome.assertNotVisible();
+
+        // Enter editing mode, where the about:home UI should be visible.
+        mToolbar.enterEditingMode();
+        mAboutHome.assertVisible()
+                  .assertCurrentPage(Page.TOP_SITES);
+
+        // Dismiss editing mode, where the about:home UI should be gone.
+        mToolbar.dismissEditingMode();
+        mAboutHome.assertNotVisible();
+
+        // Loading about:home should show about:home again.
+        NavigationHelper.enterAndLoadUrl(StringHelper.ABOUT_HOME_URL);
+        mToolbar.assertTitle(StringHelper.ABOUT_HOME_TITLE);
+        mAboutHome.assertVisible()
+                  .assertCurrentPage(Page.TOP_SITES);
+
+        // TODO: Type in a url and assert the go button is visible.
+    }
+}
deleted file mode 100644
--- a/mobile/android/base/tests/testAwesomebarSwipes.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package org.mozilla.gecko.tests;
-
-import com.jayway.android.robotium.solo.Solo;
-
-import android.widget.ListView;
-import android.widget.TabWidget;
-import android.support.v4.view.ViewPager;
-
-import org.mozilla.gecko.*;
-
-/* Tests swiping between tabs on the awesome bar and other basic
-   awesome bar tab selections.
-*/
-
-public class testAwesomebarSwipes extends BaseTest {
-    @Override
-    protected int getTestType() {
-        return TEST_MOCHITEST;
-    }
-
-    public void testAwesomebarSwipes() {
-        blockForGeckoReady();
-
-        //  Removed by Bug 896576 - [fig] Remove [getAllPagesList] from BaseTest
-        //  ListView list = getAllPagesList("about:firefox");
-
-        // Test normal sliding of the list left and right
-        ViewPager pager = (ViewPager)mSolo.getView(ViewPager.class, 0);
-        mAsserter.is(pager.getCurrentItem(), 0, "All pages is selected");
-
-        int width = mDriver.getGeckoWidth() / 2;
-        int y = mDriver.getGeckoHeight() / 2;
-        mActions.drag(width, 0, y, y);
-        mAsserter.is(pager.getCurrentItem(), 1, "Bookmarks page is selected");
-
-        mActions.drag(0, width, y, y);
-        mAsserter.is(pager.getCurrentItem(), 0, "All pages is selected");
-
-        // Test tapping on the tab strip changes tabs
-        TabWidget tabwidget = (TabWidget)mSolo.getView(TabWidget.class, 0);
-        mSolo.clickOnView(tabwidget.getChildAt(1));
-        mAsserter.is(pager.getCurrentItem(), 1, "Clicking on tab selected bookmarks page");
-
-        // Test typing in the awesomebar changes tabs and prevents panning
-        mSolo.typeText(0, "woot");
-        mAsserter.is(pager.getCurrentItem(), 0, "Searching switched to all pages tab");
-        mSolo.scrollToSide(Solo.LEFT);
-        mAsserter.is(pager.getCurrentItem(), 0, "Dragging left is not allowed when searching");
-
-        mSolo.scrollToSide(Solo.RIGHT);
-        mAsserter.is(pager.getCurrentItem(), 0, "Dragging right is not allowed when searching");
-
-        mActions.sendSpecialKey(Actions.SpecialKey.BACK);
-    }
-}
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/tests/testSessionHistory.java
@@ -0,0 +1,38 @@
+package org.mozilla.gecko.tests;
+
+import static org.mozilla.gecko.tests.helpers.AssertionHelper.*;
+
+import org.mozilla.gecko.tests.helpers.*;
+
+/**
+ * Tests that navigating through session history (ex: forward, back) sets the correct UI state.
+ */
+public class testSessionHistory extends UITest {
+    public void testSessionHistory() {
+        GeckoHelper.blockForReady();
+
+        NavigationHelper.enterAndLoadUrl(StringHelper.ROBOCOP_BLANK_PAGE_01_URL);
+        mToolbar.assertTitle(StringHelper.ROBOCOP_BLANK_PAGE_01_TITLE);
+
+        NavigationHelper.enterAndLoadUrl(StringHelper.ROBOCOP_BLANK_PAGE_02_URL);
+        mToolbar.assertTitle(StringHelper.ROBOCOP_BLANK_PAGE_02_TITLE);
+
+        NavigationHelper.enterAndLoadUrl(StringHelper.ROBOCOP_BLANK_PAGE_03_URL);
+        mToolbar.assertTitle(StringHelper.ROBOCOP_BLANK_PAGE_03_TITLE);
+
+        NavigationHelper.goBack();
+        mToolbar.assertTitle(StringHelper.ROBOCOP_BLANK_PAGE_02_TITLE);
+
+        NavigationHelper.goBack();
+        mToolbar.assertTitle(StringHelper.ROBOCOP_BLANK_PAGE_01_TITLE);
+
+        // TODO: Implement this functionality and uncomment.
+        /*
+        NavigationHelper.goForward();
+        mToolbar.assertTitle(StringHelper.ROBOCOP_BLANK_PAGE_02_TITLE);
+
+        NavigationHelper.reload();
+        mToolbar.assertTitle(StringHelper.ROBOCOP_BLANK_PAGE_02_TITLE);
+        */
+    }
+}
deleted file mode 100644
--- a/mobile/android/base/tests/testTabHistory.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package org.mozilla.gecko.tests;
-
-public class testTabHistory extends BaseTest {
-
-    @Override
-    protected int getTestType() {
-        return TEST_MOCHITEST;
-    }
-
-    /* This test will check the functionality of the Back, Forward and Reload buttons.
-    First it will determine the Device and the OS.
-    Then it will create the appropriate navigation mechanisms for back, forward and reload depending on device type and OS.
-    Finally it will run the tests */
-
-    public void testTabHistory() {
-        blockForGeckoReady();
-
-        String url = getAbsoluteUrl("/robocop/robocop_blank_01.html");
-        String url2 = getAbsoluteUrl("/robocop/robocop_blank_02.html");
-        String url3 = getAbsoluteUrl("/robocop/robocop_blank_03.html");
-
-        // Create tab history
-        inputAndLoadUrl(url);
-        verifyPageTitle("Browser Blank Page 01");
-        inputAndLoadUrl(url2);
-        verifyPageTitle("Browser Blank Page 02");
-        inputAndLoadUrl(url3);
-        verifyPageTitle("Browser Blank Page 03");
-
-        // Get the device information and create the navigation for it
-        Navigation nav = new Navigation(mDevice);
-        mAsserter.dumpLog("device type: "+mDevice.type);
-        mAsserter.dumpLog("device version: "+mDevice.version);
-        mAsserter.dumpLog("device width: "+mDevice.width);
-        mAsserter.dumpLog("device height: "+mDevice.height);
-
-        // Go to the 2nd page
-        nav.back();
-        waitForText("Browser Blank Page 02");
-        verifyPageTitle("Browser Blank Page 02");
-
-        // Go to the first page
-        nav.back();
-        waitForText("Browser Blank Page 01");
-        verifyPageTitle("Browser Blank Page 01");
-
-        // Go forward to the second page
-        nav.forward();
-        waitForText("Browser Blank Page 02");
-        verifyPageTitle("Browser Blank Page 02");
-
-        // Reload page
-        nav.reload();
-        waitForText("Browser Blank Page 02");
-        verifyPageTitle("Browser Blank Page 02");
-    }
-}
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -1634,17 +1634,17 @@ pref("font.blacklist.underline_offset", 
 
 pref("images.dither", "auto");
 pref("security.directory",              "");
 
 pref("signed.applets.codebase_principal_support", false);
 pref("security.checkloaduri", true);
 pref("security.xpconnect.plugin.unrestricted", true);
 // security-sensitive dialogs should delay button enabling. In milliseconds.
-pref("security.dialog_enable_delay", 2000);
+pref("security.dialog_enable_delay", 1000);
 pref("security.notification_enable_delay", 500);
 
 pref("security.csp.enable", true);
 pref("security.csp.debug", false);
 pref("security.csp.experimentalEnabled", false);
 
 // Mixed content blocking
 pref("security.mixed_content.block_active_content", false);
--- a/netwerk/base/src/BackgroundFileSaver.cpp
+++ b/netwerk/base/src/BackgroundFileSaver.cpp
@@ -556,17 +556,17 @@ BackgroundFileSaver::ProcessStateChange(
   } else {
     creationIoFlags = (append ? PR_APPEND : PR_TRUNCATE) | PR_CREATE_FILE;
   }
 
   // Create the target file, or append to it if we already started writing it.
   nsCOMPtr<nsIOutputStream> outputStream;
   rv = NS_NewLocalFileOutputStream(getter_AddRefs(outputStream),
                                    mActualTarget,
-                                   PR_WRONLY | creationIoFlags, 0600);
+                                   PR_WRONLY | creationIoFlags, 0644);
   NS_ENSURE_SUCCESS(rv, rv);
 
   outputStream = NS_BufferOutputStream(outputStream, BUFFERED_IO_SIZE);
   if (!outputStream) {
     return NS_ERROR_FAILURE;
   }
 
   // Wrap the output stream so that it feeds the digest context if needed.
--- a/toolkit/components/thumbnails/content/backgroundPageThumbsContent.js
+++ b/toolkit/components/thumbnails/content/backgroundPageThumbsContent.js
@@ -5,16 +5,20 @@
 (function () { // bug 673569 workaround :(
 
 const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 
 Cu.import("resource://gre/modules/PageThumbs.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
+const STATE_LOADING = 1;
+const STATE_CAPTURING = 2;
+const STATE_CANCELED = 3;
+
 const backgroundPageThumbsContent = {
 
   init: function () {
     Services.obs.addObserver(this, "document-element-inserted", true);
 
     // We want a low network priority for this service - lower than b/g tabs
     // etc - so set it to the lowest priority available.
     this._webNav.QueryInterface(Ci.nsIDocumentLoader).
@@ -51,65 +55,113 @@ const backgroundPageThumbsContent = {
     }
   },
 
   get _webNav() {
     return docShell.QueryInterface(Ci.nsIWebNavigation);
   },
 
   _onCapture: function (msg) {
-    this._webNav.loadURI(msg.json.url,
+    this._nextCapture = {
+      id: msg.data.id,
+      url: msg.data.url,
+    };
+    if (this._currentCapture) {
+      if (this._state == STATE_LOADING) {
+        // Cancel the current capture.
+        this._state = STATE_CANCELED;
+        this._loadAboutBlank();
+      }
+      // Let the current capture finish capturing, or if it was just canceled,
+      // wait for onStateChange due to the about:blank load.
+      return;
+    }
+    this._startNextCapture();
+  },
+
+  _startNextCapture: function () {
+    if (!this._nextCapture)
+      return;
+    this._currentCapture = this._nextCapture;
+    delete this._nextCapture;
+    this._state = STATE_LOADING;
+    this._currentCapture.pageLoadStartDate = new Date();
+    this._webNav.loadURI(this._currentCapture.url,
                          Ci.nsIWebNavigation.LOAD_FLAGS_STOP_CONTENT,
                          null, null, null);
-    // If a page was already loading, onStateChange is synchronously called at
-    // this point by loadURI.
-    this._requestID = msg.json.id;
-    this._requestDate = new Date();
   },
 
   onStateChange: function (webProgress, req, flags, status) {
-    if (!webProgress.isTopLevel ||
-        !(flags & Ci.nsIWebProgressListener.STATE_STOP) ||
-        req.name == "about:blank")
-      return;
+    if (webProgress.isTopLevel &&
+        (flags & Ci.nsIWebProgressListener.STATE_STOP) &&
+        this._currentCapture) {
+      if (req.name == "about:blank") {
+        if (this._state == STATE_CAPTURING) {
+          // about:blank has loaded, ending the current capture.
+          this._finishCurrentCapture();
+          delete this._currentCapture;
+          this._startNextCapture();
+        }
+        else if (this._state == STATE_CANCELED) {
+          // A capture request was received while the current capture's page
+          // was still loading.
+          delete this._currentCapture;
+          this._startNextCapture();
+        }
+      }
+      else if (this._state == STATE_LOADING) {
+        // The requested page has loaded.  Capture it.
+        this._state = STATE_CAPTURING;
+        this._captureCurrentPage();
+      }
+    }
+  },
 
-    let requestID = this._requestID;
-    let pageLoadTime = new Date() - this._requestDate;
-    delete this._requestID;
+  _captureCurrentPage: function () {
+    let capture = this._currentCapture;
+    capture.finalURL = this._webNav.currentURI.spec;
+    capture.pageLoadTime = new Date() - capture.pageLoadStartDate;
 
     let canvas = PageThumbs._createCanvas(content);
-    let captureDate = new Date();
+    let canvasDrawDate = new Date();
     PageThumbs._captureToCanvas(content, canvas);
-    let captureTime = new Date() - captureDate;
+    capture.canvasDrawTime = new Date() - canvasDrawDate;
 
-    let finalURL = this._webNav.currentURI.spec;
+    canvas.toBlob(blob => {
+      capture.imageBlob = blob;
+      // Load about:blank to finish the capture and wait for onStateChange.
+      this._loadAboutBlank();
+    });
+  },
+
+  _finishCurrentCapture: function () {
+    let capture = this._currentCapture;
     let fileReader = Cc["@mozilla.org/files/filereader;1"].
                      createInstance(Ci.nsIDOMFileReader);
     fileReader.onloadend = () => {
       sendAsyncMessage("BackgroundPageThumbs:didCapture", {
-        id: requestID,
+        id: capture.id,
         imageData: fileReader.result,
-        finalURL: finalURL,
+        finalURL: capture.finalURL,
         telemetry: {
-          CAPTURE_PAGE_LOAD_TIME_MS: pageLoadTime,
-          CAPTURE_CANVAS_DRAW_TIME_MS: captureTime,
+          CAPTURE_PAGE_LOAD_TIME_MS: capture.pageLoadTime,
+          CAPTURE_CANVAS_DRAW_TIME_MS: capture.canvasDrawTime,
         },
       });
     };
-    canvas.toBlob(blob => fileReader.readAsArrayBuffer(blob));
+    fileReader.readAsArrayBuffer(capture.imageBlob);
+  },
 
-    // If no other pages are loading, load about:blank to cause the captured
-    // window to be collected... eventually.  Calling loadURI at this point
-    // trips an assertion in nsLoadGroup::Cancel, so do it on another stack.
-    Services.tm.mainThread.dispatch(() => {
-      if (!("_requestID" in this))
-        this._webNav.loadURI("about:blank",
-                             Ci.nsIWebNavigation.LOAD_FLAGS_STOP_CONTENT,
-                             null, null, null);
-    }, Ci.nsIEventTarget.DISPATCH_NORMAL);
+  // We load about:blank to finish all captures, even canceled captures.  Two
+  // reasons: GC the captured page, and ensure it can't possibly load any more
+  // resources.
+  _loadAboutBlank: function _loadAboutBlank() {
+    this._webNav.loadURI("about:blank",
+                         Ci.nsIWebNavigation.LOAD_FLAGS_STOP_CONTENT,
+                         null, null, null);
   },
 
   QueryInterface: XPCOMUtils.generateQI([
     Ci.nsIWebProgressListener,
     Ci.nsISupportsWeakReference,
     Ci.nsIObserver,
   ]),
 };
--- a/toolkit/devtools/server/actors/webbrowser.js
+++ b/toolkit/devtools/server/actors/webbrowser.js
@@ -791,19 +791,23 @@ BrowserTabActor.prototype = {
     this._nestedEventLoopDepth++;
   },
 
   /**
    * Prepare to exit a nested event loop by enabling debuggee events.
    */
   postNest: function BTA_postNest(aNestData) {
     if (!this.window) {
-      // The tab is already closed.
-      dbg_assert(this._nestedEventLoopDepth === 0,
-                 "window shouldn't be closed before all nested event loops have been popped");
+      // The tab is already closed, so there is no way to resume events and
+      // timeouts.
+      // TODO: this wouldn't be necessary if closing a browser window could be
+      // identified early enough while this.window is still available. This is
+      // still cauisng leaks that we need to fix (bug 933950).
+      this._nestedEventLoopDepth--;
+      this._pendingNavigation = null;
       return;
     }
     let windowUtils = this.window
                           .QueryInterface(Ci.nsIInterfaceRequestor)
                           .getInterface(Ci.nsIDOMWindowUtils);
     windowUtils.resumeTimeouts();
     windowUtils.suppressEventHandling(false);
     if (this._pendingNavigation) {
--- a/toolkit/mozapps/downloads/nsHelperAppDlg.js
+++ b/toolkit/mozapps/downloads/nsHelperAppDlg.js
@@ -1,16 +1,18 @@
 /* -*- Mode: javascript; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /*
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */
 
+Components.utils.import("resource://gre/modules/Services.jsm");
+
 ///////////////////////////////////////////////////////////////////////////////
 //// Helper Functions
 
 /**
  * Determines if a given directory is able to be used to download to.
  *
  * @param aDirectory
  *        The directory to check.
@@ -475,20 +477,21 @@ nsUnknownContentTypeDialog.prototype = {
       var openHandler = this.dialogElement("openHandler");
       openHandler.parentNode.removeChild(openHandler);
       var openHandlerBox = this.dialogElement("openHandlerBox");
       openHandlerBox.appendChild(openHandler);
     }
 
     this.mDialog.setTimeout("dialog.postShowCallback()", 0);
 
+    let acceptDelay = Services.prefs.getIntPref("security.dialog_enable_delay");
     this.mDialog.document.documentElement.getButton("accept").disabled = true;
     this._showTimer = Components.classes["@mozilla.org/timer;1"]
                                 .createInstance(nsITimer);
-    this._showTimer.initWithCallback(this, 250, nsITimer.TYPE_ONE_SHOT);
+    this._showTimer.initWithCallback(this, acceptDelay, nsITimer.TYPE_ONE_SHOT);
   },
 
   notify: function (aTimer) {
     if (aTimer == this._showTimer) {
       if (!this.mDialog) {
         this.reallyShow();
       } else {
         // The user may have already canceled the dialog.
--- a/toolkit/mozapps/extensions/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/XPIProvider.jsm
@@ -1722,17 +1722,18 @@ var XPIProvider = {
   // The value of the minCompatiblePlatformVersion preference
   minCompatiblePlatformVersion: null,
   // A dictionary of the file descriptors for bootstrappable add-ons by ID
   bootstrappedAddons: {},
   // A dictionary of JS scopes of loaded bootstrappable add-ons by ID
   bootstrapScopes: {},
   // True if the platform could have activated extensions
   extensionsActive: false,
-
+  // File / directory state of installed add-ons
+  installStates: [],
   // True if all of the add-ons found during startup were installed in the
   // application install location
   allAppGlobal: true,
   // A string listing the enabled add-ons for annotating crash reports
   enabledAddons: null,
   // An array of add-on IDs of add-ons that were inactive during startup
   inactiveAddonIDs: [],
   // Keep track of startup phases for telemetry
@@ -3366,17 +3367,18 @@ var XPIProvider = {
     for (let location of knownLocations) {
       let addons = XPIDatabase.getAddonsInLocation(location);
       for (let aOldAddon of addons) {
         changed = removeMetadata(aOldAddon) || changed;
       }
     }
 
     // Cache the new install location states
-    let cache = JSON.stringify(this.getInstallLocationStates());
+    this.installStates = this.getInstallLocationStates();
+    let cache = JSON.stringify(this.installStates);
     Services.prefs.setCharPref(PREF_INSTALL_CACHE, cache);
     this.persistBootstrappedAddons();
 
     // Clear out any cached migration data.
     XPIDatabase.migrateData = null;
 
     return changed;
   },
@@ -3440,63 +3442,73 @@ var XPIProvider = {
     // This will be true if the previous session made changes that affect the
     // active state of add-ons but didn't commit them properly (normally due
     // to the application crashing)
     let hasPendingChanges = Prefs.getBoolPref(PREF_PENDING_OPERATIONS);
     if (hasPendingChanges) {
       updateReasons.push("hasPendingChanges");
     }
 
-    // If the schema appears to have changed then we should update the database
-    if (DB_SCHEMA != Prefs.getIntPref(PREF_DB_SCHEMA, 0)) {
-      updateReasons.push("schemaChanged");
-    }
-
     // If the application has changed then check for new distribution add-ons
     if (aAppChanged !== false &&
         Prefs.getBoolPref(PREF_INSTALL_DISTRO_ADDONS, true))
     {
       updated = this.installDistributionAddons(manifests);
       if (updated) {
         updateReasons.push("installDistributionAddons");
       }
     }
 
     // Telemetry probe added around getInstallLocationStates() to check perf
     let telemetryCaptureTime = Date.now();
-    let state = this.getInstallLocationStates();
+    this.installStates = this.getInstallLocationStates();
     let telemetry = Services.telemetry;
     telemetry.getHistogramById("CHECK_ADDONS_MODIFIED_MS").add(Date.now() - telemetryCaptureTime);
 
     // If the install directory state has changed then we must update the database
-    let cache = Prefs.getCharPref(PREF_INSTALL_CACHE, null);
+    let cache = Prefs.getCharPref(PREF_INSTALL_CACHE, "[]");
     // For a little while, gather telemetry on whether the deep comparison
     // makes a difference
-    if (cache != JSON.stringify(state)) {
-      if (directoryStateDiffers(state, cache)) {
+    let newState = JSON.stringify(this.installStates);
+    if (cache != newState) {
+      LOG("Directory state JSON differs: cache " + cache + " state " + newState);
+      if (directoryStateDiffers(this.installStates, cache)) {
         updateReasons.push("directoryState");
       }
       else {
         AddonManagerPrivate.recordSimpleMeasure("XPIDB_startup_state_badCompare", 1);
       }
     }
 
+    // If the schema appears to have changed then we should update the database
+    if (DB_SCHEMA != Prefs.getIntPref(PREF_DB_SCHEMA, 0)) {
+      // If we don't have any add-ons, just update the pref, since we don't need to
+      // write the database
+      if (this.installStates.length == 0) {
+        LOG("Empty XPI database, setting schema version preference to " + DB_SCHEMA);
+        Services.prefs.setIntPref(PREF_DB_SCHEMA, DB_SCHEMA);
+      }
+      else {
+        updateReasons.push("schemaChanged");
+      }
+    }
+
     // If the database doesn't exist and there are add-ons installed then we
     // must update the database however if there are no add-ons then there is
     // no need to update the database.
     let dbFile = FileUtils.getFile(KEY_PROFILEDIR, [FILE_DATABASE], true);
-    if (!dbFile.exists() && state.length > 0) {
+    if (!dbFile.exists() && this.installStates.length > 0) {
       updateReasons.push("needNewDatabase");
     }
 
     if (updateReasons.length == 0) {
       let bootstrapDescriptors = [this.bootstrappedAddons[b].descriptor
                                   for (b in this.bootstrappedAddons)];
 
-      state.forEach(function(aInstallLocationState) {
+      this.installStates.forEach(function(aInstallLocationState) {
         for (let id in aInstallLocationState.addons) {
           let pos = bootstrapDescriptors.indexOf(aInstallLocationState.addons[id].descriptor);
           if (pos != -1)
             bootstrapDescriptors.splice(pos, 1);
         }
       });
 
       if (bootstrapDescriptors.length > 0) {
@@ -3509,17 +3521,17 @@ var XPIProvider = {
     try {
       let extensionListChanged = false;
       // If the database needs to be updated then open it and then update it
       // from the filesystem
       if (updateReasons.length > 0) {
         AddonManagerPrivate.recordSimpleMeasure("XPIDB_startup_load_reasons", updateReasons);
         XPIDatabase.syncLoadDB(false);
         try {
-          extensionListChanged = this.processFileChanges(state, manifests,
+          extensionListChanged = this.processFileChanges(this.installStates, manifests,
                                                          aAppChanged,
                                                          aOldAppVersion,
                                                          aOldPlatformVersion);
         }
         catch (e) {
           ERROR("Failed to process extension changes at startup", e);
         }
       }
@@ -3561,17 +3573,17 @@ var XPIProvider = {
     }
     catch (e) {
       ERROR("Error during startup file checks", e);
     }
 
     // Check that the add-ons list still exists
     let addonsList = FileUtils.getFile(KEY_PROFILEDIR, [FILE_XPI_ADDONS_LIST],
                                        true);
-    if (addonsList.exists() == (state.length == 0)) {
+    if (addonsList.exists() == (this.installStates.length == 0)) {
       LOG("Add-ons list is invalid, rebuilding");
       XPIDatabase.writeAddonsList();
     }
 
     return false;
   },
 
   /**
--- a/toolkit/mozapps/extensions/XPIProviderUtils.js
+++ b/toolkit/mozapps/extensions/XPIProviderUtils.js
@@ -611,16 +611,19 @@ this.XPIDatabase = {
       if (inputAddons.schemaVersion != DB_SCHEMA) {
         // Handle mismatched JSON schema version. For now, we assume
         // compatibility for JSON data, though we throw away any fields we
         // don't know about (bug 902956)
         AddonManagerPrivate.recordSimpleMeasure("XPIDB_startupError",
                                                 "schemaMismatch-" + inputAddons.schemaVersion);
         LOG("JSON schema mismatch: expected " + DB_SCHEMA +
             ", actual " + inputAddons.schemaVersion);
+        // When we rev the schema of the JSON database, we need to make sure we
+        // force the DB to save so that the DB_SCHEMA value in the JSON file and
+        // the preference are updated.
       }
       // If we got here, we probably have good data
       // Make AddonInternal instances from the loaded data and save them
       let addonDB = new Map();
       for (let loadedAddon of inputAddons.addons) {
         let newAddon = new DBAddonInternal(loadedAddon);
         addonDB.set(newAddon._key, newAddon);
       };
@@ -651,16 +654,17 @@ this.XPIDatabase = {
    * Upgrade database from earlier (sqlite or RDF) version if available
    */
   upgradeDB: function(aRebuildOnError) {
     let upgradeTimer = AddonManagerPrivate.simpleTimer("XPIDB_upgradeDB_MS");
     try {
       let schemaVersion = Services.prefs.getIntPref(PREF_DB_SCHEMA);
       if (schemaVersion <= LAST_SQLITE_DB_SCHEMA) {
         // we should have an older SQLITE database
+        LOG("Attempting to upgrade from SQLITE database");
         this.migrateData = this.getMigrateDataFromSQLITE();
       }
       else {
         // we've upgraded before but the JSON file is gone, fall through
         // and rebuild from scratch
         AddonManagerPrivate.recordSimpleMeasure("XPIDB_startupError", "dbMissing");
       }
     }
@@ -751,50 +755,58 @@ this.XPIDatabase = {
    *         A boolean indicating whether add-on information should be loaded
    *         from the install locations if the database needs to be rebuilt.
    *         (if false, caller is XPIProvider.checkForChanges() which will rebuild)
    */
   rebuildDatabase: function XIPDB_rebuildDatabase(aRebuildOnError) {
     this.addonDB = new Map();
     this.initialized = true;
 
+    if (XPIProvider.installStates && XPIProvider.installStates.length == 0) {
+      // No extensions installed, so we're done
+      LOG("Rebuilding XPI database with no extensions");
+      return;
+    }
+
     // If there is no migration data then load the list of add-on directories
     // that were active during the last run
     if (!this.migrateData)
       this.activeBundles = this.getActiveBundles();
 
     if (aRebuildOnError) {
       WARN("Rebuilding add-ons database from installed extensions.");
       try {
-        let state = XPIProvider.getInstallLocationStates();
-        XPIProvider.processFileChanges(state, {}, false);
+        XPIProvider.processFileChanges(XPIProvider.installStates, {}, false);
       }
       catch (e) {
         ERROR("Failed to rebuild XPI database from installed extensions", e);
       }
-      // Make to update the active add-ons and add-ons list on shutdown
+      // Make sure to update the active add-ons and add-ons list on shutdown
       Services.prefs.setBoolPref(PREF_PENDING_OPERATIONS, true);
     }
   },
 
   /**
    * Gets the list of file descriptors of active extension directories or XPI
    * files from the add-ons list. This must be loaded from disk since the
    * directory service gives no easy way to get both directly. This list doesn't
    * include themes as preferences already say which theme is currently active
    *
    * @return an array of persistent descriptors for the directories
    */
   getActiveBundles: function XPIDB_getActiveBundles() {
     let bundles = [];
 
+    // non-bootstrapped extensions
     let addonsList = FileUtils.getFile(KEY_PROFILEDIR, [FILE_XPI_ADDONS_LIST],
                                        true);
 
     if (!addonsList.exists())
+      // XXX Irving believes this is broken in the case where there is no
+      // extensions.ini but there are bootstrap extensions (e.g. Android)
       return null;
 
     try {
       let iniFactory = Cc["@mozilla.org/xpcom/ini-parser-factory;1"]
                          .getService(Ci.nsIINIParserFactory);
       let parser = iniFactory.createINIParser(addonsList);
       let keys = parser.getKeys("ExtensionDirs");
 
--- a/toolkit/mozapps/extensions/test/xpcshell/head_addons.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/head_addons.js
@@ -372,20 +372,18 @@ let gXPISaveError = null;
  *         application has changed version since the last run. If not passed it
  *         defaults to true
  */
 function startupManager(aAppChanged) {
   if (gInternalManager)
     do_throw("Test attempt to startup manager that was already started.");
 
   if (aAppChanged || aAppChanged === undefined) {
-    var file = gProfD.clone();
-    file.append("extensions.ini");
-    if (file.exists())
-      file.remove(true);
+    if (gExtensionsINI.exists())
+      gExtensionsINI.remove(true);
   }
 
   gInternalManager = AM_Cc["@mozilla.org/addons/integration;1"].
                      getService(AM_Ci.nsIObserver).
                      QueryInterface(AM_Ci.nsITimerCallback);
 
   gInternalManager.observe(null, "addons-startup", null);
 
@@ -468,24 +466,22 @@ function loadAddonsList() {
     return dirs;
   }
 
   gAddonsList = {
     extensions: [],
     themes: []
   };
 
-  var file = gProfD.clone();
-  file.append("extensions.ini");
-  if (!file.exists())
+  if (!gExtensionsINI.exists())
     return;
 
   var factory = AM_Cc["@mozilla.org/xpcom/ini-parser-factory;1"].
                 getService(AM_Ci.nsIINIParserFactory);
-  var parser = factory.createINIParser(file);
+  var parser = factory.createINIParser(gExtensionsINI);
   gAddonsList.extensions = readDirectories("ExtensionDirs");
   gAddonsList.themes = readDirectories("ThemeDirs");
 }
 
 function isItemInAddonsList(aType, aDir, aId) {
   var path = aDir.clone();
   path.append(aId);
   var xpiPath = aDir.clone();
@@ -1209,16 +1205,24 @@ if ("nsIWindowsRegKey" in AM_Ci) {
   registrar.registerFactory(Components.ID("{0478de5b-0f38-4edb-851d-4c99f1ed8eba}"),
                             "Mock Windows Registry Implementation",
                             "@mozilla.org/windows-registry-key;1", WinRegFactory);
 }
 
 // Get the profile directory for tests to use.
 const gProfD = do_get_profile();
 
+const EXTENSIONS_DB = "extensions.json";
+let gExtensionsJSON = gProfD.clone();
+gExtensionsJSON.append(EXTENSIONS_DB);
+
+const EXTENSIONS_INI = "extensions.ini";
+let gExtensionsINI = gProfD.clone();
+gExtensionsINI.append(EXTENSIONS_INI);
+
 // Enable more extensive EM logging
 Services.prefs.setBoolPref("extensions.logging.enabled", true);
 
 // By default only load extensions from the profile install location
 Services.prefs.setIntPref("extensions.enabledScopes", AddonManager.SCOPE_PROFILE);
 
 // By default don't disable add-ons from any scope
 Services.prefs.setIntPref("extensions.autoDisableScopes", 0);
@@ -1394,20 +1398,16 @@ function do_exception_wrap(func) {
       func.apply(null, arguments);
     }
     catch(e) {
       do_report_unexpected_exception(e);
     }
   };
 }
 
-const EXTENSIONS_DB = "extensions.json";
-let gExtensionsJSON = gProfD.clone();
-gExtensionsJSON.append(EXTENSIONS_DB);
-
 /**
  * Change the schema version of the JSON extensions database
  */
 function changeXPIDBVersion(aNewVersion) {
   let jData = loadJSON(gExtensionsJSON);
   jData.schemaVersion = aNewVersion;
   saveJSON(jData, gExtensionsJSON);
 }
--- a/toolkit/mozapps/extensions/test/xpcshell/test_bootstrap.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_bootstrap.js
@@ -162,19 +162,17 @@ function run_test() {
   do_test_pending();
 
   resetPrefs();
 
   startupManager();
 
   do_check_false(gExtensionsJSON.exists());
 
-  let file = gProfD.clone();
-  file.leafName = "extensions.ini";
-  do_check_false(file.exists());
+  do_check_false(gExtensionsINI.exists());
 
   do_check_bootstrappedPref(run_test_1);
 }
 
 // Tests that installing doesn't require a restart
 function run_test_1() {
   prepare_test({ }, [
     "onNewInstall"
@@ -218,19 +216,17 @@ function run_test_1() {
       // startup should not have been called yet.
       do_check_eq(getActiveVersion(), -1);
     });
     install.install();
   });
 }
 
 function check_test_1(installSyncGUID) {
-  let file = gProfD.clone();
-  file.leafName = "extensions.ini";
-  do_check_false(file.exists());
+  do_check_false(gExtensionsINI.exists());
 
   AddonManager.getAllInstalls(function(installs) {
     // There should be no active installs now since the install completed and
     // doesn't require a restart.
     do_check_eq(installs.length, 0);
 
     AddonManager.getAddonByID("bootstrap1@tests.mozilla.org", function(b1) {
       do_check_neq(b1, null);
@@ -308,19 +304,17 @@ function run_test_3() {
   do_check_eq(getShutdownNewVersion(), 0);
   startupManager(false);
   do_check_eq(getInstalledVersion(), 1);
   do_check_eq(getActiveVersion(), 0);
   do_check_eq(getShutdownReason(), ADDON_DISABLE);
   do_check_eq(getShutdownNewVersion(), 0);
   do_check_not_in_crash_annotation("bootstrap1@tests.mozilla.org", "1.0");
 
-  let file = gProfD.clone();
-  file.append("extensions.ini");
-  do_check_false(file.exists());
+  do_check_false(gExtensionsINI.exists());
 
   AddonManager.getAddonByID("bootstrap1@tests.mozilla.org", function(b1) {
     do_check_neq(b1, null);
     do_check_eq(b1.version, "1.0");
     do_check_false(b1.appDisabled);
     do_check_true(b1.userDisabled);
     do_check_false(b1.isActive);
 
--- a/toolkit/mozapps/extensions/test/xpcshell/test_bug455906.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_bug455906.js
@@ -138,22 +138,22 @@ var PluginHostFactory = {
       throw Components.results.NS_ERROR_NO_AGGREGATION;
     return PluginHost.QueryInterface(iid);
   }
 };
 
 // Don't need the full interface, attempts to call other methods will just
 // throw which is just fine
 var WindowWatcher = {
-  openWindow: function(parent, url, name, features, arguments) {
+  openWindow: function(parent, url, name, features, windowArguments) {
     // Should be called to list the newly blocklisted items
     do_check_eq(url, URI_EXTENSION_BLOCKLIST_DIALOG);
 
     if (gNotificationCheck) {
-      var args = arguments.wrappedJSObject;
+      var args = windowArguments.wrappedJSObject;
       gNotificationCheck(args);
     }
 
     //run the code after the blocklist is closed
     Services.obs.notifyObservers(null, "addon-blocklist-closed", null);
 
     // Call the next test after the blocklist has finished up
     do_timeout(0, gTestCheck);
@@ -200,20 +200,22 @@ function create_addon(addon) {
                    "    </em:targetApplication>\n" +
                    "    <em:name>" + addon.name + "</em:name>\n" +
                    "  </Description>\n" +
                    "</RDF>\n";
   var target = gProfD.clone();
   target.append("extensions");
   target.append(addon.id);
   target.append("install.rdf");
-  target.create(target.NORMAL_FILE_TYPE, 0644);
+  target.create(target.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
   var stream = Cc["@mozilla.org/network/file-output-stream;1"].
                createInstance(Ci.nsIFileOutputStream);
-  stream.init(target, 0x04 | 0x08 | 0x20, 0664, 0); // write, create, truncate
+  stream.init(target,
+              FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE | FileUtils.MODE_TRUNCATE,
+              FileUtils.PERMS_FILE, 0);
   stream.write(installrdf, installrdf.length);
   stream.close();
 }
 
 function load_blocklist(file) {
   Services.prefs.setCharPref("extensions.blocklist.url", "http://localhost:" + gPort + "/data/" + file);
   var blocklist = Cc["@mozilla.org/extensions/blocklist;1"].
                   getService(Ci.nsITimerCallback);
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_no_addons.js
@@ -0,0 +1,98 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+// Test startup and restart when no add-ons are installed
+// bug 944006
+
+Components.utils.import("resource://gre/modules/Promise.jsm");
+
+// Load XPI Provider to get schema version ID
+let XPIScope = Components.utils.import("resource://gre/modules/XPIProvider.jsm");
+const DB_SCHEMA = XPIScope.DB_SCHEMA;
+
+createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
+
+function run_test() {
+  // Kick off the task-based tests...
+  run_next_test();
+}
+
+// Test for a preference to either exist with a specified value, or not exist at all
+function checkPending() {
+  try {
+    do_check_false(Services.prefs.getBoolPref("extensions.pendingOperations"));
+  }
+  catch (e) {
+    // OK
+  }
+}
+
+function checkString(aPref, aValue) {
+  try {
+    do_check_eq(Services.prefs.getCharPref(aPref), aValue)
+  }
+  catch (e) {
+    //OK
+  }
+}
+
+// Make sure all our extension state is empty/nonexistent
+function check_empty_state() {
+  do_check_false(gExtensionsJSON.exists());
+  do_check_false(gExtensionsINI.exists());
+
+  do_check_eq(Services.prefs.getIntPref("extensions.databaseSchema"), DB_SCHEMA);
+
+  checkString("extensions.bootstrappedAddons", "{}");
+  checkString("extensions.installCache", "[]");
+  checkPending();
+}
+
+// After first run with no add-ons, we expect:
+// no extensions.json is created
+// no extensions.ini
+// database schema version preference is set
+// bootstrap add-ons preference is not found
+// add-on directory state preference is an empty array
+// no pending operations
+add_task(function first_run() {
+  startupManager();
+  check_empty_state();
+  yield true;
+});
+
+// Now do something that causes a DB load, and re-check
+function trigger_db_load() {
+  let addonDefer = Promise.defer();
+  AddonManager.getAddonsByTypes(['extension'], addonDefer.resolve);
+  let addonList = yield addonDefer.promise;
+
+  do_check_eq(addonList.length, 0);
+  check_empty_state();
+
+  yield true;
+};
+add_task(trigger_db_load);
+
+// Now restart the manager and check again
+add_task(function restart_and_recheck() {
+  restartManager();
+  check_empty_state();
+  yield true;
+});
+
+// and reload the DB again
+add_task(trigger_db_load);
+
+// When we start up with no DB and an old database schema, we should update the
+// schema number but not create a database
+add_task(function upgrade_schema_version() {
+  shutdownManager();
+  Services.prefs.setIntPref("extensions.databaseSchema", 1);
+
+  startupManager();
+  do_check_eq(Services.prefs.getIntPref("extensions.databaseSchema"), DB_SCHEMA);
+  check_empty_state();
+});
+
--- a/toolkit/mozapps/extensions/test/xpcshell/test_startup.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_startup.js
@@ -127,22 +127,19 @@ function run_test() {
 
   startupManager();
   check_startup_changes(AddonManager.STARTUP_CHANGE_INSTALLED, []);
   check_startup_changes(AddonManager.STARTUP_CHANGE_CHANGED, []);
   check_startup_changes(AddonManager.STARTUP_CHANGE_UNINSTALLED, []);
   check_startup_changes(AddonManager.STARTUP_CHANGE_DISABLED, []);
   check_startup_changes(AddonManager.STARTUP_CHANGE_ENABLED, []);
 
-  let file = gProfD.clone();
-  file.append("extensions.json");
-  do_check_false(file.exists());
+  do_check_false(gExtensionsJSON.exists());
 
-  file.leafName = "extensions.ini";
-  do_check_false(file.exists());
+  do_check_false(gExtensionsINI.exists());
 
   AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
                                "addon2@tests.mozilla.org",
                                "addon3@tests.mozilla.org",
                                "addon4@tests.mozilla.org",
                                "addon5@tests.mozilla.org",
                                "addon6@tests.mozilla.org",
                                "addon7@tests.mozilla.org"],
@@ -185,20 +182,18 @@ function run_test_1() {
                                       "addon2@tests.mozilla.org",
                                       "addon3@tests.mozilla.org"]);
   check_startup_changes(AddonManager.STARTUP_CHANGE_CHANGED, []);
   check_startup_changes(AddonManager.STARTUP_CHANGE_UNINSTALLED, []);
   check_startup_changes(AddonManager.STARTUP_CHANGE_DISABLED, []);
   check_startup_changes(AddonManager.STARTUP_CHANGE_ENABLED, []);
   do_check_true(gCachePurged);
 
-  let file = gProfD.clone();
-  file.append = "extensions.ini";
-  do_print("Checking for " + file.path);
-  do_check_true(file.exists());
+  do_print("Checking for " + gExtensionsINI.path);
+  do_check_true(gExtensionsINI.exists());
 
   AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
                                "addon2@tests.mozilla.org",
                                "addon3@tests.mozilla.org",
                                "addon4@tests.mozilla.org",
                                "addon5@tests.mozilla.org",
                                "addon6@tests.mozilla.org",
                                "addon7@tests.mozilla.org"],
@@ -297,19 +292,17 @@ function run_test_2() {
   restartManager();
   check_startup_changes(AddonManager.STARTUP_CHANGE_INSTALLED, []);
   check_startup_changes(AddonManager.STARTUP_CHANGE_CHANGED, ["addon2@tests.mozilla.org"]);
   check_startup_changes(AddonManager.STARTUP_CHANGE_UNINSTALLED, ["addon3@tests.mozilla.org"]);
   check_startup_changes(AddonManager.STARTUP_CHANGE_DISABLED, []);
   check_startup_changes(AddonManager.STARTUP_CHANGE_ENABLED, []);
   do_check_true(gCachePurged);
 
-  var file = gProfD.clone();
-  file.append("extensions.ini");
-  do_check_true(file.exists());
+  do_check_true(gExtensionsINI.exists());
 
   AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
                                "addon2@tests.mozilla.org",
                                "addon3@tests.mozilla.org",
                                "addon4@tests.mozilla.org",
                                "addon5@tests.mozilla.org"],
                                function([a1, a2, a3, a4, a5]) {
 
--- a/toolkit/mozapps/extensions/test/xpcshell/test_upgrade.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_upgrade.js
@@ -174,19 +174,17 @@ function run_test_3() {
       maxVersion: "3"
     }],
     name: "Test Addon 4",
   }, globalDir);
   setExtensionModifiedTime(dest, gInstallTime);
 
   // Simulates a simple Build ID change, the platform deletes extensions.ini
   // whenever the application is changed.
-  var file = gProfD.clone();
-  file.append("extensions.ini");
-  file.remove(true);
+  gExtensionsINI.remove(true);
   restartManager();
 
   AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
                                "addon2@tests.mozilla.org",
                                "addon3@tests.mozilla.org",
                                "addon4@tests.mozilla.org"],
                                function([a1, a2, a3, a4]) {
 
--- a/toolkit/mozapps/extensions/test/xpcshell/test_upgrade_strictcompat.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_upgrade_strictcompat.js
@@ -177,19 +177,17 @@ function run_test_3() {
       maxVersion: "3"
     }],
     name: "Test Addon 4",
   }, globalDir);
   setExtensionModifiedTime(dest, gInstallTime);
 
   // Simulates a simple Build ID change, the platform deletes extensions.ini
   // whenever the application is changed.
-  var file = gProfD.clone();
-  file.append("extensions.ini");
-  file.remove(true);
+  gExtensionsINI.remove(true);
   restartManager();
 
   AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
                                "addon2@tests.mozilla.org",
                                "addon3@tests.mozilla.org",
                                "addon4@tests.mozilla.org"],
                                function([a1, a2, a3, a4]) {
 
--- a/toolkit/mozapps/extensions/test/xpcshell/xpcshell-shared.ini
+++ b/toolkit/mozapps/extensions/test/xpcshell/xpcshell-shared.ini
@@ -200,16 +200,17 @@ run-sequentially = Uses hardcoded ports 
 skip-if = os == "android"
 [test_migrate1.js]
 [test_migrate2.js]
 [test_migrate3.js]
 [test_migrate4.js]
 [test_migrate5.js]
 [test_migrateAddonRepository.js]
 [test_migrate_max_version.js]
+[test_no_addons.js]
 [test_onPropertyChanged_appDisabled.js]
 [test_permissions.js]
 [test_permissions_prefs.js]
 [test_plugins.js]
 [test_pluginchange.js]
 [test_pluginBlocklistCtp.js]
 # Bug 676992: test consistently fails on Android
 fail-if = os == "android"
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -1458,17 +1458,17 @@ nsresult nsExternalAppHandler::SetUpTemp
 
   // Add an additional .part to prevent the OS from running this file in the
   // default application.
   tempLeafName.Append(NS_LITERAL_CSTRING(".part"));
 
   rv = mTempFile->Append(NS_ConvertUTF8toUTF16(tempLeafName));
   // make this file unique!!!
   NS_ENSURE_SUCCESS(rv, rv);
-  rv = mTempFile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0600);
+  rv = mTempFile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0644);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Now save the temp leaf name, minus the ".part" bit, so we can use it later.
   // This is a bit broken in the case when createUnique actually had to append
   // some numbers, because then we now have a filename like foo.bar-1.part and
   // we'll end up with foo.bar-1.bar as our final filename if we end up using
   // this.  But the other options are all bad too....  Ideally we'd have a way
   // to tell createUnique to put its unique marker before the extension that
@@ -2284,17 +2284,17 @@ NS_IMETHODIMP nsExternalAppHandler::Laun
   }
 
 #ifdef XP_WIN
   fileToUse->Append(mSuggestedFileName + mTempFileExtension);
 #else
   fileToUse->Append(mSuggestedFileName);  
 #endif
 
-  nsresult rv = fileToUse->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0600);
+  nsresult rv = fileToUse->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0644);
   if(NS_SUCCEEDED(rv))
   {
     mFinalFileDestination = do_QueryInterface(fileToUse);
     // launch the progress window now that the user has picked the desired action.
     rv = CreateTransfer();
     if (NS_FAILED(rv)) {
       Cancel(rv);
     }