Merge fx-team to m-c a=merge
authorWes Kocher <wkocher@mozilla.com>
Tue, 04 Nov 2014 19:53:20 -0800
changeset 214019 62990ec7ad787549d4ddd2c2bada871fc141e44b
parent 213994 a1823d3c7365dda8735b99feff27143306c83f63 (current diff)
parent 214018 3b36af7151ec0af6632c5e0df1b8e4e4509070a0 (diff)
child 214020 9351fa0d14a29eb7e2ca80467747b4376a36c3b1
child 214115 bcccbf4f268cf8f922d7dfe36594c527a8da44eb
child 214188 02fd2ca11bfc0abab7054b046bb5c35b445e31fe
push id51393
push userkwierso@gmail.com
push dateWed, 05 Nov 2014 04:37:41 +0000
treeherdermozilla-inbound@9351fa0d14a2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone36.0a1
first release with
nightly linux32
62990ec7ad78 / 36.0a1 / 20141105030203 / files
nightly linux64
62990ec7ad78 / 36.0a1 / 20141105030203 / files
nightly mac
62990ec7ad78 / 36.0a1 / 20141105030203 / files
nightly win32
62990ec7ad78 / 36.0a1 / 20141105030203 / files
nightly win64
62990ec7ad78 / 36.0a1 / 20141105030203 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge fx-team to m-c a=merge
dom/base/nsDOMWindowUtils.cpp
dom/interfaces/base/nsIDOMWindowUtils.idl
mobile/android/base/resources/layout/new_tablet_tabs_item_cell.xml
toolkit/components/places/tests/migration/places_alpha.sqlite
toolkit/components/places/tests/migration/places_v10_from_v14.sqlite
toolkit/components/places/tests/migration/places_v6_no_frecency.sqlite
toolkit/components/places/tests/migration/places_v6_no_indices.sqlite
toolkit/components/places/tests/migration/test_current_from_v10.js
toolkit/components/places/tests/migration/test_current_from_v10_migrated_from_v14.js
toolkit/components/places/tests/migration/test_database_from_alpha.js
toolkit/components/places/tests/migration/test_database_from_v6_no_frecency.js
toolkit/components/places/tests/migration/test_database_from_v6_no_indices.js
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1799,8 +1799,10 @@ pref("privacy.trackingprotection.ui.enab
 #endif
 
 // Temporary pref to allow printing in e10s windows on some platforms.
 #ifdef UNIX_BUT_NOT_MAC
 pref("print.enable_e10s_testing", false);
 #else
 pref("print.enable_e10s_testing", true);
 #endif
+
+pref("browser.defaultbrowser.notificationbar", false);
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -116,17 +116,17 @@ skip-if = os == "linux" || e10s # Bug 10
 skip-if = os == "linux" || e10s # Bug 1073339 - Investigate autocomplete test unreliability on Linux/e10s
 [browser_action_searchengine_alias.js]
 skip-if = os == "linux" || e10s # Bug 1073339 - Investigate autocomplete test unreliability on Linux/e10s
 [browser_addKeywordSearch.js]
 skip-if = e10s
 [browser_search_favicon.js]
 skip-if = os == "linux" || e10s # Bug 1073339 - Investigate autocomplete test unreliability on Linux/e10s
 [browser_alltabslistener.js]
-skip-if = os == "linux" || e10s # Linux: Intermittent failures, bug 951680; e10s: Bug ?????? - notifications don't work correctly.
+skip-if = os == "linux" || e10s # Linux: Intermittent failures, bug 951680; e10s: Bug 1093594 - notifications for tabs come in in the wrong order / unexpectedly
 [browser_autocomplete_a11y_label.js]
 skip-if = e10s # Bug ????? - no e10s switch-to-tab support yet
 [browser_backButtonFitts.js]
 skip-if = os != "win" || e10s # The Fitts Law back button is only supported on Windows (bug 571454) / e10s - Bug ?????? test touches content (attempts to add an event listener directly to the contentWindow)
 [browser_blob-channelname.js]
 [browser_bookmark_titles.js]
 skip-if = buildapp == 'mulet' || toolkit == "windows" || e10s # Disabled on Windows due to frequent failures (bugs 825739, 841341) / e10s - Bug ?????? test checks event.target on load event, which our e10s utils don't support
 [browser_bug304198.js]
@@ -153,17 +153,17 @@ skip-if = e10s # Bug 1056146 - zoom test
 skip-if = e10s # Bug 1093155 - tries to use context menu from browser-chrome and gets in a mess when in e10s mode
 [browser_bug419612.js]
 skip-if = e10s # Bug 1056146 - zoom tests use FullZoomHelper and break in e10s
 [browser_bug422590.js]
 [browser_bug846489.js]
 [browser_bug423833.js]
 skip-if = true # bug 428712
 [browser_bug424101.js]
-skip-if = e10s # Bug ?????? - test directly manipulates content
+skip-if = e10s # Bug 1093155 - tries to use context menu from browser-chrome and gets in a mess when in e10s mode
 [browser_bug427559.js]
 skip-if = e10s # Bug ?????? - "content window is focused - Got [object ChromeWindow], expected [object XrayWrapper [object Window]]"
 [browser_bug431826.js]
 skip-if = e10s # Bug ?????? - test directly manipulates content (eg, var expertDiv = gBrowser.contentDocument.getElementById("expertContent");)
 [browser_bug432599.js]
 [browser_bug435035.js]
 [browser_bug435325.js]
 skip-if = buildapp == 'mulet' || e10s # Bug ?????? - test directly manipulates content
@@ -197,17 +197,17 @@ skip-if = e10s # Bug ?????? - some weird
 [browser_bug521216.js]
 [browser_bug533232.js]
 [browser_bug537013.js]
 skip-if = buildapp == 'mulet' || e10s # Bug 1093206 - need to re-enable tests relying on swapFrameLoaders et al for e10s (test calls replaceTabWithWindow)
 [browser_bug537474.js]
 skip-if = e10s # Bug ?????? - test doesn't wait for document to be created before it checks it
 [browser_bug550565.js]
 [browser_bug553455.js]
-skip-if = buildapp == 'mulet' || e10s # Bug 1066070 - I don't think either popup notifications nor addon install stuff works?
+skip-if = buildapp == 'mulet' || e10s # Bug 1066070 - I don't think either popup notifications nor addon install stuff works on mulet? ; for e10s, indefinite waiting halfway through the test, tracked in bug 1093586
 [browser_bug555224.js]
 skip-if = e10s # Bug 1056146 - zoom tests use FullZoomHelper and break in e10s
 [browser_bug555767.js]
 skip-if = e10s # Bug 1093373 - relies on browser.sessionHistory
 [browser_bug556061.js]
 [browser_bug559991.js]
 [browser_bug561623.js]
 skip-if = e10s
@@ -267,17 +267,17 @@ skip-if = buildapp == 'mulet' || os == "
 skip-if = e10s # Bug ?????? - Obscure non-windows failures ("Snapshot array has correct length of 1 after loading one page. - Got 0, expected 1" and more)
 [browser_bug710878.js]
 skip-if = e10s # Bug ?????? - test directly manipulates content (doc.querySelector)
 [browser_bug719271.js]
 skip-if = e10s # Bug 1056146 - zoom tests use FullZoomHelper and break in e10s
 [browser_bug724239.js]
 skip-if = e10s # Bug 1077738
 [browser_bug734076.js]
-skip-if = e10s # Bug ?????? - test directly manipulates content
+skip-if = e10s # Bug 1093155 - tries to use context menu from browser-chrome and gets in a mess when in e10s mode
 [browser_bug735471.js]
 [browser_bug749738.js]
 skip-if = e10s # Bug 921935 - focusmanager issues with e10s
 [browser_bug763468_perwindowpb.js]
 skip-if = e10s
 [browser_bug767836_perwindowpb.js]
 skip-if = e10s # Bug ?????? - test reports a leaked nsGlobalWindow with e10s enabled.
 [browser_bug771331.js]
@@ -289,19 +289,19 @@ skip-if = e10s # Bug 1093373 - relies on
 [browser_bug822367.js]
 [browser_bug832435.js]
 [browser_bug839103.js]
 [browser_bug880101.js]
 [browser_bug882977.js]
 [browser_bug902156.js]
 skip-if = e10s
 [browser_bug906190.js]
-skip-if = buildapp == "mulet" || e10s # Bug ?????? - test directly manipulates content (strange - gets an element from a child which it tries to treat as a string, but that fails)
+skip-if = buildapp == "mulet" || e10s # Bug 1093642 - test manipulates content and relies on content focus
 [browser_bug970746.js]
-skip-if = e10s # Bug ?????? - test directly manipulates content (directly gets elements from the content)
+skip-if = e10s # Bug 1093155 - tries to use context menu from browser-chrome and gets in a mess when in e10s mode
 [browser_bug1015721.js]
 skip-if = os == 'win' || e10s # Bug 1056146 - zoom tests use FullZoomHelper and break in e10s
 [browser_bug1064280_changeUrlInPinnedTab.js]
 [browser_canonizeURL.js]
 skip-if = e10s # Bug ?????? - [JavaScript Error: "Error in AboutHome.sendAboutHomeData TypeError: target.messageManager is undefined" {file: "resource:///modules/AboutHome.jsm" line: 208}]
 [browser_contentAreaClick.js]
 skip-if = e10s
 [browser_contextSearchTabPosition.js]
@@ -358,31 +358,31 @@ skip-if = os != "win" || e10s # The Fitt
 skip-if = e10s # Bug 921952 - Content:Click event issues
 [browser_minimize.js]
 skip-if = e10s # Bug ?????? - test directly manipulates content (TypeError: gBrowser.docShell is null)
 [browser_mixedcontent_securityflags.js]
 skip-if = e10s # Bug ?????? - test directly manipulates content ("cannot ipc non-cpow object")
 [browser_notification_tab_switching.js]
 skip-if = buildapp == 'mulet' || e10s # Bug ?????? - uncaught exception - Error: cannot ipc non-cpow object at chrome://mochitests/content/browser/browser/base/content/test/general/browser_notification_tab_switching.js:32
 [browser_offlineQuotaNotification.js]
-skip-if = buildapp == 'mulet' || e10s # Bug ?????? - test directly manipulates content (gBrowser.selectedBrowser.contentWindow.applicationCache.oncached = function() {...})
+skip-if = buildapp == 'mulet' || e10s # Bug 1093603 - test breaks with PopupNotifications.panel.firstElementChild is null
 [browser_overflowScroll.js]
 [browser_pageInfo.js]
 skip-if = buildapp == 'mulet' || e10s # Bug 866413 - PageInfo doesn't work in e10s
 [browser_page_style_menu.js]
 skip-if = e10s # Bug ?????? - test directly manipulates content
 
 [browser_parsable_css.js]
 skip-if = e10s
 [browser_parsable_script.js]
 skip-if = asan # Disabled because it takes a long time (see test for more information)
 
 [browser_pinnedTabs.js]
 [browser_plainTextLinks.js]
-skip-if = e10s # Bug ?????? - test directly manipulates content (creates and fetches elements directly from content document)
+skip-if = e10s # Bug 1093155 - tries to use context menu from browser-chrome and gets in a mess when in e10s mode
 [browser_popupUI.js]
 skip-if = buildapp == 'mulet' || e10s # Bug ?????? - test directly manipulates content (tries to get a popup element directly from content)
 [browser_popup_blocker.js]
 [browser_printpreview.js]
 skip-if = buildapp == 'mulet' || e10s # Bug ?????? - timeout after logging "Error: Channel closing: too late to send/recv, messages will be lost"
 [browser_private_browsing_window.js]
 skip-if = buildapp == 'mulet'
 [browser_private_no_prompt.js]
@@ -440,17 +440,17 @@ skip-if = e10s # Bug 921935 - focusmanag
 [browser_tabkeynavigation.js]
 skip-if = e10s
 [browser_tabopen_reflows.js]
 skip-if = e10s # Bug ?????? - test needs to be updated for e10s (captures a stack that isn't correct in e10s)
 [browser_tabs_isActive.js]
 skip-if = e10s # Bug ?????? - test directly manipulates content (tries to get/set attributes directly on content docshell)
 [browser_tabs_owner.js]
 [browser_trackingUI.js]
-skip-if = e10s
+skip-if = e10s # Bug 1093155 - tries to use context menu from browser-chrome and gets in a mess when in e10s mode
 support-files =
   trackingPage.html
   benignPage.html
 [browser_typeAheadFind.js]
 skip-if = buildapp == 'mulet' || e10s # Bug 921935 - focusmanager issues with e10s (test calls waitForFocus)
 [browser_unloaddialogs.js]
 skip-if = e10s # Bug ?????? - test uses chrome windowMediator to try and see alert() from content
 [browser_urlHighlight.js]
--- a/browser/components/loop/content/js/conversation.js
+++ b/browser/components/loop/content/js/conversation.js
@@ -13,17 +13,17 @@ loop.conversation = (function(mozL10n) {
 
   var sharedViews = loop.shared.views;
   var sharedMixins = loop.shared.mixins;
   var sharedModels = loop.shared.models;
   var sharedActions = loop.shared.actions;
 
   var OutgoingConversationView = loop.conversationViews.OutgoingConversationView;
   var CallIdentifierView = loop.conversationViews.CallIdentifierView;
-  var EmptyRoomView = loop.roomViews.EmptyRoomView;
+  var DesktopRoomView = loop.roomViews.DesktopRoomView;
 
   var IncomingCallView = React.createClass({displayName: 'IncomingCallView',
     mixins: [sharedMixins.DropdownMenuMixin],
 
     propTypes: {
       model: React.PropTypes.object.isRequired,
       video: React.PropTypes.bool.isRequired
     },
@@ -571,17 +571,17 @@ loop.conversation = (function(mozL10n) {
         }
         case "outgoing": {
           return (OutgoingConversationView({
             store: this.props.conversationStore, 
             dispatcher: this.props.dispatcher}
           ));
         }
         case "room": {
-          return (EmptyRoomView({
+          return (DesktopRoomView({
             mozLoop: navigator.mozLoop, 
             localRoomStore: this.props.localRoomStore}
           ));
         }
         case "failed": {
           return (GenericFailureView({
             cancelCall: this.closeWindow}
           ));
--- a/browser/components/loop/content/js/conversation.jsx
+++ b/browser/components/loop/content/js/conversation.jsx
@@ -13,17 +13,17 @@ loop.conversation = (function(mozL10n) {
 
   var sharedViews = loop.shared.views;
   var sharedMixins = loop.shared.mixins;
   var sharedModels = loop.shared.models;
   var sharedActions = loop.shared.actions;
 
   var OutgoingConversationView = loop.conversationViews.OutgoingConversationView;
   var CallIdentifierView = loop.conversationViews.CallIdentifierView;
-  var EmptyRoomView = loop.roomViews.EmptyRoomView;
+  var DesktopRoomView = loop.roomViews.DesktopRoomView;
 
   var IncomingCallView = React.createClass({
     mixins: [sharedMixins.DropdownMenuMixin],
 
     propTypes: {
       model: React.PropTypes.object.isRequired,
       video: React.PropTypes.bool.isRequired
     },
@@ -571,17 +571,17 @@ loop.conversation = (function(mozL10n) {
         }
         case "outgoing": {
           return (<OutgoingConversationView
             store={this.props.conversationStore}
             dispatcher={this.props.dispatcher}
           />);
         }
         case "room": {
-          return (<EmptyRoomView
+          return (<DesktopRoomView
             mozLoop={navigator.mozLoop}
             localRoomStore={this.props.localRoomStore}
           />);
         }
         case "failed": {
           return (<GenericFailureView
             cancelCall={this.closeWindow}
           />);
--- a/browser/components/loop/content/js/roomViews.js
+++ b/browser/components/loop/content/js/roomViews.js
@@ -5,34 +5,18 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* global loop:true, React */
 
 var loop = loop || {};
 loop.roomViews = (function(mozL10n) {
   "use strict";
 
-  /**
-   * Root object, by default set to window.
-   * @type {DOMWindow|Object}
-   */
-  var rootObject = window;
-
-  /**
-   * Sets a new root object. This is useful for testing native DOM events so we
-   * can fake them.
-   *
-   * @param {Object}
-   */
-  function setRootObject(obj) {
-    rootObject = obj;
-  }
-
-  var EmptyRoomView = React.createClass({displayName: 'EmptyRoomView',
-    mixins: [Backbone.Events],
+  var DesktopRoomView = React.createClass({displayName: 'DesktopRoomView',
+    mixins: [Backbone.Events, loop.shared.mixins.DocumentTitleMixin],
 
     propTypes: {
       mozLoop:
         React.PropTypes.object.isRequired,
       localRoomStore:
         React.PropTypes.instanceOf(loop.store.LocalRoomStore).isRequired,
     },
 
@@ -40,70 +24,38 @@ loop.roomViews = (function(mozL10n) {
       return this.props.localRoomStore.getStoreState();
     },
 
     componentWillMount: function() {
       this.listenTo(this.props.localRoomStore, "change",
         this._onLocalRoomStoreChanged);
     },
 
-    componentDidMount: function() {
-      // XXXremoveMe (just the conditional itself) in patch 2 for bug 1074686,
-      // once the addCallback stuff lands
-      if (this.props.mozLoop.rooms && this.props.mozLoop.rooms.addCallback) {
-        this.props.mozLoop.rooms.addCallback(
-          this.state.localRoomId,
-          "RoomCreationError", this.onCreationError);
-      }
-    },
-
-    /**
-     * Attached to the "RoomCreationError" with mozLoop.rooms.addCallback,
-     * which is fired mozLoop.rooms.createRoom from the panel encounters an
-     * error while attempting to create the room for this view.
-     *
-     * @param {Error} err - JS Error object with info about the problem
-     */
-    onCreationError: function(err) {
-      // XXX put up a user friendly error instead of this
-      rootObject.console.error("EmptyRoomView creation error: ", err);
-    },
-
     /**
      * Handles a "change" event on the localRoomStore, and updates this.state
      * to match the store.
      *
      * @private
      */
     _onLocalRoomStoreChanged: function() {
       this.setState(this.props.localRoomStore.getStoreState());
     },
 
     componentWillUnmount: function() {
       this.stopListening(this.props.localRoomStore);
-
-      // XXXremoveMe (just the conditional itself) in patch 2 for bug 1074686,
-      // once the addCallback stuff lands
-      if (this.props.mozLoop.rooms && this.props.mozLoop.rooms.removeCallback) {
-        this.props.mozLoop.rooms.removeCallback(
-          this.state.localRoomId,
-          "RoomCreationError", this.onCreationError);
-      }
     },
 
     render: function() {
-      // XXX switch this to use the document title mixin once bug 1081079 lands
       if (this.state.serverData && this.state.serverData.roomName) {
-        rootObject.document.title = this.state.serverData.roomName;
+        this.setTitle(this.state.serverData.roomName);
       }
 
       return (
         React.DOM.div({className: "goat"})
       );
     }
   });
 
   return {
-    setRootObject: setRootObject,
-    EmptyRoomView: EmptyRoomView
+    DesktopRoomView: DesktopRoomView
   };
 
 })(document.mozL10n || navigator.mozL10n);;
--- a/browser/components/loop/content/js/roomViews.jsx
+++ b/browser/components/loop/content/js/roomViews.jsx
@@ -5,34 +5,18 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* global loop:true, React */
 
 var loop = loop || {};
 loop.roomViews = (function(mozL10n) {
   "use strict";
 
-  /**
-   * Root object, by default set to window.
-   * @type {DOMWindow|Object}
-   */
-  var rootObject = window;
-
-  /**
-   * Sets a new root object. This is useful for testing native DOM events so we
-   * can fake them.
-   *
-   * @param {Object}
-   */
-  function setRootObject(obj) {
-    rootObject = obj;
-  }
-
-  var EmptyRoomView = React.createClass({
-    mixins: [Backbone.Events],
+  var DesktopRoomView = React.createClass({
+    mixins: [Backbone.Events, loop.shared.mixins.DocumentTitleMixin],
 
     propTypes: {
       mozLoop:
         React.PropTypes.object.isRequired,
       localRoomStore:
         React.PropTypes.instanceOf(loop.store.LocalRoomStore).isRequired,
     },
 
@@ -40,70 +24,38 @@ loop.roomViews = (function(mozL10n) {
       return this.props.localRoomStore.getStoreState();
     },
 
     componentWillMount: function() {
       this.listenTo(this.props.localRoomStore, "change",
         this._onLocalRoomStoreChanged);
     },
 
-    componentDidMount: function() {
-      // XXXremoveMe (just the conditional itself) in patch 2 for bug 1074686,
-      // once the addCallback stuff lands
-      if (this.props.mozLoop.rooms && this.props.mozLoop.rooms.addCallback) {
-        this.props.mozLoop.rooms.addCallback(
-          this.state.localRoomId,
-          "RoomCreationError", this.onCreationError);
-      }
-    },
-
-    /**
-     * Attached to the "RoomCreationError" with mozLoop.rooms.addCallback,
-     * which is fired mozLoop.rooms.createRoom from the panel encounters an
-     * error while attempting to create the room for this view.
-     *
-     * @param {Error} err - JS Error object with info about the problem
-     */
-    onCreationError: function(err) {
-      // XXX put up a user friendly error instead of this
-      rootObject.console.error("EmptyRoomView creation error: ", err);
-    },
-
     /**
      * Handles a "change" event on the localRoomStore, and updates this.state
      * to match the store.
      *
      * @private
      */
     _onLocalRoomStoreChanged: function() {
       this.setState(this.props.localRoomStore.getStoreState());
     },
 
     componentWillUnmount: function() {
       this.stopListening(this.props.localRoomStore);
-
-      // XXXremoveMe (just the conditional itself) in patch 2 for bug 1074686,
-      // once the addCallback stuff lands
-      if (this.props.mozLoop.rooms && this.props.mozLoop.rooms.removeCallback) {
-        this.props.mozLoop.rooms.removeCallback(
-          this.state.localRoomId,
-          "RoomCreationError", this.onCreationError);
-      }
     },
 
     render: function() {
-      // XXX switch this to use the document title mixin once bug 1081079 lands
       if (this.state.serverData && this.state.serverData.roomName) {
-        rootObject.document.title = this.state.serverData.roomName;
+        this.setTitle(this.state.serverData.roomName);
       }
 
       return (
         <div className="goat"/>
       );
     }
   });
 
   return {
-    setRootObject: setRootObject,
-    EmptyRoomView: EmptyRoomView
+    DesktopRoomView: DesktopRoomView
   };
 
 })(document.mozL10n || navigator.mozL10n);;
--- a/browser/components/loop/content/shared/css/panel.css
+++ b/browser/components/loop/content/shared/css/panel.css
@@ -162,17 +162,17 @@ body {
   font-size: 1rem;
   margin: 0 auto;
   padding: .5rem 1rem;
   border-radius: 3px;
 }
 
 .room-list {
   max-height: 335px; /* XXX better computation needed */
-  overflow: scroll;
+  overflow: auto;
 }
 
 .room-list > .room-entry {
   padding: 1rem 1rem 0 .5rem;
 }
 
 .room-list > .room-entry > h2 {
   font-size: .85rem;
--- a/browser/components/loop/content/shared/js/mixins.js
+++ b/browser/components/loop/content/shared/js/mixins.js
@@ -53,16 +53,27 @@ loop.shared.mixins = (function() {
    */
   var DocumentLocationMixin = {
     locationReload: function() {
       rootObject.location.reload();
     }
   };
 
   /**
+   * Document title mixin.
+   *
+   * @type {Object}
+   */
+  var DocumentTitleMixin = {
+    setTitle: function(newTitle) {
+      rootObject.document.title = newTitle;
+    }
+  };
+
+  /**
    * Dropdown menu mixin.
    * @type {Object}
    */
   var DropdownMenuMixin = {
     get documentBody() {
       return rootObject.document.body;
     },
 
@@ -179,11 +190,12 @@ loop.shared.mixins = (function() {
   };
 
   return {
     AudioMixin: AudioMixin,
     setRootObject: setRootObject,
     DropdownMenuMixin: DropdownMenuMixin,
     DocumentVisibilityMixin: DocumentVisibilityMixin,
     DocumentLocationMixin: DocumentLocationMixin,
+    DocumentTitleMixin: DocumentTitleMixin,
     UrlHashChangeMixin: UrlHashChangeMixin
   };
 })();
--- a/browser/components/loop/test/desktop-local/conversation_test.js
+++ b/browser/components/loop/test/desktop-local/conversation_test.js
@@ -196,23 +196,23 @@ describe("loop.conversation", function()
       conversationAppStore.setStoreState({windowType: "incoming"});
 
       ccView = mountTestComponent();
 
       TestUtils.findRenderedComponentWithType(ccView,
         loop.conversation.IncomingConversationView);
     });
 
-    it("should display the EmptyRoomView for rooms", function() {
+    it("should display the RoomView for rooms", function() {
       conversationAppStore.setStoreState({windowType: "room"});
 
       ccView = mountTestComponent();
 
       TestUtils.findRenderedComponentWithType(ccView,
-        loop.roomViews.EmptyRoomView);
+        loop.roomViews.DesktopRoomView);
     });
 
     it("should display the GenericFailureView for failures", function() {
       conversationAppStore.setStoreState({windowType: "failed"});
 
       ccView = mountTestComponent();
 
       TestUtils.findRenderedComponentWithType(ccView,
--- a/browser/components/loop/test/desktop-local/roomViews_test.js
+++ b/browser/components/loop/test/desktop-local/roomViews_test.js
@@ -13,82 +13,46 @@ describe("loop.roomViews", function () {
     fakeAddCallback =
       sandbox.stub().withArgs(fakeRoomId, "RoomCreationError");
     fakeRemoveCallback =
       sandbox.stub().withArgs(fakeRoomId, "RoomCreationError");
     fakeMozLoop = { rooms: { addCallback: fakeAddCallback,
                              removeCallback: fakeRemoveCallback } };
 
     fakeWindow = { document: {} };
-    loop.roomViews.setRootObject(fakeWindow);
+    loop.shared.mixins.setRootObject(fakeWindow);
 
     store = new loop.store.LocalRoomStore({
       dispatcher: { register: function() {} },
       mozLoop: fakeMozLoop
     });
     store.setStoreState({localRoomId: fakeRoomId});
   });
 
   afterEach(function() {
     sinon.sandbox.restore();
-    loop.roomViews.setRootObject(window);
+    loop.shared.mixins.setRootObject(window);
   });
 
-  describe("EmptyRoomView", function() {
+  describe("DesktopRoomView", function() {
     function mountTestComponent() {
       return TestUtils.renderIntoDocument(
-        new loop.roomViews.EmptyRoomView({
+        new loop.roomViews.DesktopRoomView({
           mozLoop: fakeMozLoop,
           localRoomStore: store
         }));
     }
 
-    describe("#componentDidMount", function() {
-       it("should add #onCreationError using mozLoop.rooms.addCallback",
-         function() {
-
-           var testComponent = mountTestComponent();
-
-           sinon.assert.calledOnce(fakeMozLoop.rooms.addCallback);
-           sinon.assert.calledWithExactly(fakeMozLoop.rooms.addCallback,
-             fakeRoomId, "RoomCreationError", testComponent.onCreationError);
-         });
-    });
-
-    describe("#componentWillUnmount", function () {
-      it("should remove #onCreationError using mozLoop.rooms.addCallback",
-        function () {
-          var testComponent = mountTestComponent();
-
-          testComponent.componentWillUnmount();
-
-          sinon.assert.calledOnce(fakeMozLoop.rooms.removeCallback);
-          sinon.assert.calledWithExactly(fakeMozLoop.rooms.removeCallback,
-            fakeRoomId, "RoomCreationError", testComponent.onCreationError);
-        });
-      });
-
-    describe("#onCreationError", function() {
-      it("should log an error using console.error", function() {
-        fakeWindow.console = { error: sandbox.stub() };
-        var testComponent = mountTestComponent();
-
-        testComponent.onCreationError(new Error("fake error"));
-
-        sinon.assert.calledOnce(fakeWindow.console.error);
-      });
-    });
-
     describe("#render", function() {
       it("should set document.title to store.serverData.roomName",
         function() {
           var fakeRoomName = "Monkey";
           store.setStoreState({serverData: {roomName: fakeRoomName},
                                localRoomId: fakeRoomId});
 
           mountTestComponent();
 
           expect(fakeWindow.document.title).to.equal(fakeRoomName);
-        })
+        });
     });
 
   });
 });
--- a/browser/components/loop/test/shared/mixins_test.js
+++ b/browser/components/loop/test/shared/mixins_test.js
@@ -16,17 +16,17 @@ describe("loop.shared.mixins", function(
   beforeEach(function() {
     sandbox = sinon.sandbox.create();
   });
 
   afterEach(function() {
     sandbox.restore();
   });
 
-  describe("loop.webapp.UrlHashChangeMixin", function() {
+  describe("loop.shared.mixins.UrlHashChangeMixin", function() {
     function createTestComponent(onUrlHashChange) {
       var TestComp = React.createClass({
         mixins: [loop.shared.mixins.UrlHashChangeMixin],
         onUrlHashChange: onUrlHashChange || function(){},
         render: function() {
           return React.DOM.div();
         }
       });
@@ -56,17 +56,17 @@ describe("loop.shared.mixins", function(
       var onUrlHashChange = sandbox.stub();
 
       TestUtils.renderIntoDocument(createTestComponent(onUrlHashChange));
 
       sinon.assert.calledOnce(onUrlHashChange);
     });
   });
 
-  describe("loop.webapp.DocumentLocationMixin", function() {
+  describe("loop.shared.mixins.DocumentLocationMixin", function() {
     var reloadStub, TestComp;
 
     beforeEach(function() {
       reloadStub = sandbox.stub();
 
       sharedMixins.setRootObject({
         location: {
           reload: reloadStub
@@ -85,17 +85,43 @@ describe("loop.shared.mixins", function(
       var comp = TestUtils.renderIntoDocument(TestComp());
 
       comp.locationReload();
 
       sinon.assert.calledOnce(reloadStub);
     });
   });
 
-  describe("loop.panel.DocumentVisibilityMixin", function() {
+  describe("loop.shared.mixins.DocumentTitleMixin", function() {
+    var TestComp, rootObject;
+
+    beforeEach(function() {
+      rootObject = {
+        document: {}
+      };
+      sharedMixins.setRootObject(rootObject);
+
+      TestComp = React.createClass({
+        mixins: [loop.shared.mixins.DocumentTitleMixin],
+        render: function() {
+          return React.DOM.div();
+        }
+      });
+    });
+
+    it("should set window.document.title", function() {
+      var comp = TestUtils.renderIntoDocument(TestComp());
+
+      comp.setTitle("It's a Fake!");
+
+      expect(rootObject.document.title).eql("It's a Fake!");
+    });
+  });
+
+  describe("loop.shared.mixins.DocumentVisibilityMixin", function() {
     var comp, TestComp, onDocumentVisibleStub, onDocumentHiddenStub;
 
     beforeEach(function() {
       onDocumentVisibleStub = sandbox.stub();
       onDocumentHiddenStub = sandbox.stub();
 
       TestComp = React.createClass({
         mixins: [loop.shared.mixins.DocumentVisibilityMixin],
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -497,19 +497,16 @@ BrowserGlue.prototype = {
     this._isPlacesShutdownObserver = true;
     os.addObserver(this, "handle-xul-text-link", false);
     os.addObserver(this, "profile-before-change", false);
 #ifdef MOZ_SERVICES_HEALTHREPORT
     os.addObserver(this, "keyword-search", false);
 #endif
     os.addObserver(this, "browser-search-engine-modified", false);
     os.addObserver(this, "browser-search-service", false);
-#ifdef NIGHTLY_BUILD
-    Services.prefs.addObserver(POLARIS_ENABLED, this, false);
-#endif
   },
 
   // cleanup (called on application shutdown)
   _dispose: function BG__dispose() {
     let os = Services.obs;
     os.removeObserver(this, "prefservice:after-app-defaults");
     os.removeObserver(this, "final-ui-startup");
     os.removeObserver(this, "sessionstore-windows-restored");
@@ -596,16 +593,20 @@ BrowserGlue.prototype = {
     FormValidationHandler.init();
 
     ContentClick.init();
     RemotePrompt.init();
     ContentPrefServiceParent.init();
 
     LoginManagerParent.init();
 
+#ifdef NIGHTLY_BUILD
+    Services.prefs.addObserver(POLARIS_ENABLED, this, false);
+#endif
+
     Services.obs.notifyObservers(null, "browser-ui-startup-complete", "");
   },
 
   _checkForOldBuildUpdates: function () {
     // check for update if our build is old
     if (Services.prefs.getBoolPref("app.update.enabled") &&
         Services.prefs.getBoolPref("app.update.checkInstallTime")) {
 
@@ -2280,38 +2281,33 @@ let DefaultBrowserCheck = {
       claimAllTypes = (parseFloat(version) < 6.2);
     } catch (ex) { }
 #endif
     try {
       ShellService.setDefaultBrowser(claimAllTypes, false);
     } catch (ex) {
       Cu.reportError(ex);
     }
-    this.closePrompt();
   },
 
-  _createPopup: function(win, bundle) {
+  _createPopup: function(win, notNowStrings, neverStrings) {
     let doc = win.document;
     let popup = doc.createElement("menupopup");
     popup.id = this.OPTIONPOPUP;
 
     let notNowItem = doc.createElement("menuitem");
     notNowItem.id = "defaultBrowserNotNow";
-    let label = bundle.getString("setDefaultBrowserNotNow.label");
-    notNowItem.setAttribute("label", label);
-    let accesskey = bundle.getString("setDefaultBrowserNotNow.accesskey");
-    notNowItem.setAttribute("accesskey", accesskey);
+    notNowItem.setAttribute("label", notNowStrings.label);
+    notNowItem.setAttribute("accesskey", notNowStrings.accesskey);
     popup.appendChild(notNowItem);
 
     let neverItem = doc.createElement("menuitem");
     neverItem.id = "defaultBrowserNever";
-    label = bundle.getString("setDefaultBrowserNever.label");
-    neverItem.setAttribute("label", label);
-    accesskey = bundle.getString("setDefaultBrowserNever.accesskey");
-    neverItem.setAttribute("accesskey", accesskey);
+    neverItem.setAttribute("label", neverStrings.label);
+    neverItem.setAttribute("accesskey", neverStrings.accesskey);
     popup.appendChild(neverItem);
 
     popup.addEventListener("command", this);
 
     let popupset = doc.getElementById("mainPopupSet");
     popupset.appendChild(popup);
   },
 
@@ -2327,50 +2323,82 @@ let DefaultBrowserCheck = {
   prompt: function(win) {
     let brandBundle = win.document.getElementById("bundle_brand");
     let shellBundle = win.document.getElementById("bundle_shell");
 
     let brandShortName = brandBundle.getString("brandShortName");
     let promptMessage = shellBundle.getFormattedString("setDefaultBrowserMessage2",
                                                        [brandShortName]);
 
-    let confirmMessage = shellBundle.getFormattedString("setDefaultBrowserConfirm.label",
-                                                        [brandShortName]);
-    let confirmKey = shellBundle.getString("setDefaultBrowserConfirm.accesskey");
+    let yesButton = shellBundle.getFormattedString("setDefaultBrowserConfirm.label",
+                                                   [brandShortName]);
+
+    let notNowButton = shellBundle.getString("setDefaultBrowserNotNow.label");
+    let notNowButtonKey = shellBundle.getString("setDefaultBrowserNotNow.accesskey");
+
+    let neverLabel = shellBundle.getString("setDefaultBrowserNever.label");
+    let neverKey = shellBundle.getString("setDefaultBrowserNever.accesskey");
 
-    let optionsMessage = shellBundle.getString("setDefaultBrowserOptions.label");
-    let optionsKey = shellBundle.getString("setDefaultBrowserOptions.accesskey");
+    let useNotificationBar = Services.prefs.getBoolPref("browser.defaultbrowser.notificationbar");
+    if (useNotificationBar) {
+      let optionsMessage = shellBundle.getString("setDefaultBrowserOptions.label");
+      let optionsKey = shellBundle.getString("setDefaultBrowserOptions.accesskey");
+
+      let yesButtonKey = shellBundle.getString("setDefaultBrowserConfirm.accesskey");
 
-    let selectedBrowser = win.gBrowser.selectedBrowser;
-    let notificationBox = win.document.getElementById("high-priority-global-notificationbox");
+      let notificationBox = win.document.getElementById("high-priority-global-notificationbox");
 
-    this._createPopup(win, shellBundle);
+      this._createPopup(win, {
+        label: notNowButton,
+        accesskey: notNowButtonKey
+      }, {
+        label: neverLabel,
+        accesskey: neverKey
+      });
 
-    let buttons = [
-      {
-        label: confirmMessage,
-        accessKey: confirmKey,
-        callback: this.setAsDefault.bind(this)
-      },
-      {
-        label: optionsMessage,
-        accessKey: optionsKey,
-        popup: this.OPTIONPOPUP
+      let buttons = [
+        {
+          label: yesButton,
+          accessKey: yesButtonKey,
+          callback: () => {
+            this.setAsDefault();
+            this.closePrompt();
+          }
+        },
+        {
+          label: optionsMessage,
+          accessKey: optionsKey,
+          popup: this.OPTIONPOPUP
+        }
+      ];
+
+      let iconPixels = win.devicePixelRatio > 1 ? "32" : "16";
+      let iconURL = "chrome://branding/content/icon" + iconPixels + ".png";
+      const priority = notificationBox.PRIORITY_WARNING_HIGH;
+      let callback = this._onNotificationEvent.bind(this);
+      this._notification = notificationBox.appendNotification(promptMessage, "default-browser",
+                                                              iconURL, priority, buttons,
+                                                              callback);
+    } else {
+      // Modal prompt
+      let promptTitle = shellBundle.getString("setDefaultBrowserTitle");
+
+      let ps = Services.prompt;
+      let dontAsk = { value: false };
+      let buttonFlags = (ps.BUTTON_TITLE_IS_STRING * ps.BUTTON_POS_0) +
+                        (ps.BUTTON_TITLE_IS_STRING * ps.BUTTON_POS_1) +
+                        ps.BUTTON_POS_0_DEFAULT;
+      let rv = ps.confirmEx(win, promptTitle, promptMessage, buttonFlags,
+                            yesButton, notNowButton, null, neverLabel, dontAsk);
+      if (rv == 0) {
+        this.setAsDefault();
+      } else if (dontAsk.value) {
+        ShellService.shouldCheckDefaultBrowser = false;
       }
-    ];
-
-
-    let iconPixels = win.devicePixelRatio > 1 ? "32" : "16";
-    let iconURL = "chrome://branding/content/icon" + iconPixels + ".png";
-    const priority = notificationBox.PRIORITY_WARNING_HIGH;
-    let callback = this._onNotificationEvent.bind(this);
-    this._notification = notificationBox.appendNotification(promptMessage, "default-browser",
-                                                            iconURL, priority, buttons,
-                                                            callback);
-    this._notification.persistence = -1;
+    }
   },
 
   _onNotificationEvent: function(eventType) {
     if (eventType == "removed") {
       let doc = this._notification.ownerDocument;
       let popup = doc.getElementById(this.OPTIONPOPUP);
       popup.removeEventListener("command", this);
       popup.remove();
--- a/browser/components/preferences/in-content/privacy.xul
+++ b/browser/components/preferences/in-content/privacy.xul
@@ -75,17 +75,17 @@
 <groupbox id="trackingGroup" data-category="panePrivacy" hidden="true" align="start">
   <caption><label>&tracking.label;</label></caption>
   <vbox id="trackingprotectionbox" hidden="true">
     <hbox align="center">
       <checkbox id="trackingProtection"
                 preference="privacy.trackingprotection.enabled"
                 accesskey="&trackingProtection.accesskey;"
                 label="&trackingProtection.label;" />
-      <image id="trackingProtectionImage" src="chrome://browser/skin/bad-content-blocked-16.png"/>
+      <image id="trackingProtectionImage"/>
     </hbox>
     <label id="trackingProtectionLearnMore"
            class="text-link"
            value="&trackingProtectionLearnMore.label;"/>
     <separator/>
   </vbox>
   <checkbox id="privacyDoNotTrackCheckbox"
             label="&dntTrackingNotOkay.label2;"
--- a/browser/devtools/framework/toolbox.js
+++ b/browser/devtools/framework/toolbox.js
@@ -263,17 +263,17 @@ Toolbox.prototype = {
     let deferred = promise.defer();
 
     return this._host.create().then(iframe => {
       let deferred = promise.defer();
 
       let domReady = () => {
         this.isReady = true;
 
-        this._listFrames();
+        let framesPromise = this._listFrames();
 
         this.closeButton = this.doc.getElementById("toolbox-close");
         this.closeButton.addEventListener("command", this.destroy, true);
 
         gDevTools.on("pref-changed", this._prefChanged);
 
         let framesMenu = this.doc.getElementById("command-button-frames");
         framesMenu.addEventListener("command", this.selectFrame, true);
@@ -304,17 +304,18 @@ Toolbox.prototype = {
           // console input will receive focus.
           let splitConsolePromise = promise.resolve();
           if (Services.prefs.getBoolPref(SPLITCONSOLE_ENABLED_PREF)) {
             splitConsolePromise = this.openSplitConsole();
           }
 
           promise.all([
             splitConsolePromise,
-            buttonsPromise
+            buttonsPromise,
+            framesPromise
           ]).then(() => {
             this.emit("ready");
             deferred.resolve();
           }, deferred.reject);
         });
       };
 
       // Load the toolbox-level actor fronts and utilities now
@@ -1224,23 +1225,23 @@ Toolbox.prototype = {
                                toolName, this.target.url || this.target.name);
     this._host.setTitle(title);
   },
 
   _listFrames: function (event) {
     if (!this._target.form || !this._target.form.actor) {
       // We are not targetting a regular TabActor
       // it can be either an addon or browser toolbox actor
-      return;
+      return promise.resolve();
     }
     let packet = {
       to: this._target.form.actor,
       type: "listFrames"
     };
-    this._target.client.request(packet, resp => {
+    return this._target.client.request(packet, resp => {
       this._updateFrames(null, { frames: resp.frames });
     });
   },
 
   selectFrame: function (event) {
     let windowId = event.target.getAttribute("data-window-id");
     let packet = {
       to: this._target.form.actor,
--- a/browser/themes/osx/devedition.css
+++ b/browser/themes/osx/devedition.css
@@ -65,19 +65,19 @@
   box-shadow: none;
 }
 
 /* Use forward-facing magnifying glass for the search box */
 .search-go-button {
   list-style-image: url("chrome://browser/skin/devedition/search.svg#search-icon-mac-inverted");
 }
 
-/* Don't use default colors when in full screen */
-#main-window:not([customizing]) #navigator-toolbox[inFullscreen] > #TabsToolbar:not(:-moz-lwtheme) {
-  -moz-appearance: none;
+/* Don't use the default background for tabs toolbar */
+#TabsToolbar {
+  -moz-appearance: none !important;
 }
 
 /* Tab styling - make sure to use an inverted icon for the selected tab
    (brighttext only covers the unselected tabs) */
 .tab-close-button[selected=true]:not(:hover) {
   -moz-image-region: rect(0, 64px, 16px, 48px);
 }
 @media (min-resolution: 2dppx) {
--- a/browser/themes/shared/incontentprefs/preferences.css
+++ b/browser/themes/shared/incontentprefs/preferences.css
@@ -290,16 +290,28 @@ description > html|a {
   margin-top: 8px;
   margin-bottom: 8px;
 }
 
 .indent {
   -moz-margin-start: 33px;
 }
 
+#trackingProtectionImage {
+  width: 16px;
+  height: 16px;
+  list-style-image: url(chrome://browser/skin/bad-content-blocked-16.png);
+}
+
+@media (min-resolution: 2dppx) {
+  #trackingProtectionImage {
+    list-style-image: url(chrome://browser/skin/bad-content-blocked-16@2x.png);
+  }
+}
+
 /**
  * Sub-dialog
  */
 
 #dialogOverlay {
   background-color: rgba(0,0,0,0.5);
   visibility: hidden;
 }
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -3474,17 +3474,17 @@ nsDOMWindowUtils::LoadSheet(nsIURI *aShe
   NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
 
   nsIDocument::additionalSheetType type = convertSheetType(aSheetType);
 
   return doc->LoadAdditionalStyleSheet(type, aSheetURI);
 }
 
 NS_IMETHODIMP
-nsDOMWindowUtils::LoadSheetFromURIString(const nsACString& aSheetURI, uint32_t aSheetType)
+nsDOMWindowUtils::LoadSheetUsingURIString(const nsACString& aSheetURI, uint32_t aSheetType)
 {
   MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
 
   nsCOMPtr<nsIURI> uri;
   nsresult rv = NS_NewURI(getter_AddRefs(uri), aSheetURI);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return LoadSheet(uri, aSheetType);
@@ -3527,16 +3527,28 @@ nsDOMWindowUtils::RemoveSheet(nsIURI *aS
 
   nsIDocument::additionalSheetType type = convertSheetType(aSheetType);
 
   doc->RemoveAdditionalStyleSheet(type, aSheetURI);
   return NS_OK;
 }
 
 NS_IMETHODIMP
+nsDOMWindowUtils::RemoveSheetUsingURIString(const nsACString& aSheetURI, uint32_t aSheetType)
+{
+  MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
+
+  nsCOMPtr<nsIURI> uri;
+  nsresult rv = NS_NewURI(getter_AddRefs(uri), aSheetURI);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return RemoveSheet(uri, aSheetType);
+}
+
+NS_IMETHODIMP
 nsDOMWindowUtils::GetIsHandlingUserInput(bool* aHandlingUserInput)
 {
   MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
 
   *aHandlingUserInput = EventStateManager::IsHandlingUserInput();
 
   return NS_OK;
 }
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
@@ -46,17 +46,17 @@ interface nsIDOMClientRect;
 interface nsIURI;
 interface nsIDOMEventTarget;
 interface nsIRunnable;
 interface nsICompositionStringSynthesizer;
 interface nsITranslationNodeList;
 interface nsIJSRAIIHelper;
 interface nsIContentPermissionRequest;
 
-[scriptable, uuid(f7e4d5da-4dd0-455a-b448-d0224c17fd10)]
+[scriptable, uuid(e293355b-ae7f-4ef7-9237-452bcf3e9e6b)]
 interface nsIDOMWindowUtils : nsISupports {
 
   /**
    * Image animation mode of the window. When this attribute's value
    * is changed, the implementation should set all images in the window
    * to the given value. That is, when set to kDontAnimMode, all images
    * will stop animating. The attribute's value must be one of the
    * animationMode values from imgIContainer.
@@ -1596,17 +1596,17 @@ interface nsIDOMWindowUtils : nsISupport
    *
    * Sheets added via this API take effect immediately on the document.
    */
   void loadSheet(in nsIURI sheetURI, in unsigned long type);
 
   /**
    * Same as the above method but allows passing the URI as a string.
    */
-  void loadSheetFromURIString(in ACString sheetURI, in unsigned long type);
+  void loadSheetUsingURIString(in ACString sheetURI, in unsigned long type);
 
   /**
    * Adds a style sheet to the list of additional style sheets of the document.
    *
    * Style sheets can be preloaded with nsIStyleSheetService.preloadSheet.
    *
    * Sheets added via this API take effect immediately on the document.
    */
@@ -1614,16 +1614,21 @@ interface nsIDOMWindowUtils : nsISupport
 
   /**
    * Remove the document style sheet at |sheetURI| from the list of additional 
    * style sheets of the document.  The removal takes effect immediately.
    */
   void removeSheet(in nsIURI sheetURI, in unsigned long type);
 
   /**
+   * Same as the above method but allows passing the URI as a string.
+   */
+  void removeSheetUsingURIString(in ACString sheetURI, in unsigned long type);
+
+  /**
    * Returns true if a user input is being handled.
    *
    * This calls EventStateManager::IsHandlingUserInput().
    */
   readonly attribute boolean isHandlingUserInput;
 
   /**
    * After calling the method, the window for which this DOMWindowUtils
--- a/mobile/android/base/BrowserApp.java
+++ b/mobile/android/base/BrowserApp.java
@@ -1321,20 +1321,24 @@ public class BrowserApp extends GeckoApp
                 if (mDynamicToolbar.isEnabled()) {
                     mDynamicToolbar.setVisible(visible, VisibilityTransition.IMMEDIATE);
                 }
             }
         });
     }
 
     private void updateSideBarState() {
+        if (NewTabletUI.isEnabled(this)) {
+            return;
+        }
+
         if (mMainLayoutAnimator != null)
             mMainLayoutAnimator.stop();
 
-        boolean isSideBar = !NewTabletUI.isEnabled(this) && (HardwareUtils.isTablet() && getOrientation() == Configuration.ORIENTATION_LANDSCAPE);
+        boolean isSideBar = (HardwareUtils.isTablet() && getOrientation() == Configuration.ORIENTATION_LANDSCAPE);
         final int sidebarWidth = getResources().getDimensionPixelSize(R.dimen.tabs_sidebar_width);
 
         ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) mTabsPanel.getLayoutParams();
         lp.width = (isSideBar ? sidebarWidth : ViewGroup.LayoutParams.MATCH_PARENT);
         mTabsPanel.requestLayout();
 
         final boolean sidebarIsShown = (isSideBar && mTabsPanel.isShown());
         final int mainLayoutScrollX = (sidebarIsShown ? -sidebarWidth : 0);
@@ -1724,16 +1728,20 @@ public class BrowserApp extends GeckoApp
     public void onPropertyAnimationStart() {
     }
 
     @Override
     public void onPropertyAnimationEnd() {
         if (!areTabsShown()) {
             mTabsPanel.setVisibility(View.INVISIBLE);
             mTabsPanel.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
+        } else {
+            // Cancel editing mode to return to page content when the TabsPanel closes. We cancel
+            // it here because there are graphical glitches if it's canceled while it's visible.
+            mBrowserToolbar.cancelEdit();
         }
 
         mTabsPanel.finishTabsAnimation();
 
         mMainLayoutAnimator = null;
     }
 
     @Override
--- a/mobile/android/base/NewTabletUI.java
+++ b/mobile/android/base/NewTabletUI.java
@@ -2,22 +2,25 @@
  * 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 android.content.Context;
 import android.content.SharedPreferences;
 
+import org.mozilla.gecko.AppConstants;
 import org.mozilla.gecko.preferences.GeckoPreferences;
 import org.mozilla.gecko.util.HardwareUtils;
 
 public class NewTabletUI {
-    // This value should be in sync with preferences_display.xml.
-    private static final boolean DEFAULT = false;
+    // This value should be in sync with preferences_display.xml. On non-release
+    // builds, the preference UI will be hidden and the (unused) default
+    // preference UI value will still be 'true'.
+    private static final boolean DEFAULT = !AppConstants.RELEASE_BUILD;
 
     private static Boolean sNewTabletUI;
 
     public static synchronized boolean isEnabled(Context context) {
         if (!HardwareUtils.isTablet()) {
             return false;
         }
 
rename from mobile/android/base/resources/layout/new_tablet_tabs_item_cell.xml
rename to mobile/android/base/resources/layout-v11/new_tablet_tabs_item_cell.xml
--- a/mobile/android/base/resources/layout/new_tablet_tabs_item_cell.xml
+++ b/mobile/android/base/resources/layout-v11/new_tablet_tabs_item_cell.xml
@@ -1,14 +1,15 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!-- This Source Code Form is subject to the terms of the Mozilla Public
    - License, v. 2.0. If a copy of the MPL was not distributed with this
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 
 <org.mozilla.gecko.tabs.TabsLayoutItemView xmlns:android="http://schemas.android.com/apk/res/android"
+                                           xmlns:gecko="http://schemas.android.com/apk/res-auto"
                                            style="@style/TabsItem"
                                            android:focusable="true"
                                            android:id="@+id/info"
                                            android:layout_width="wrap_content"
                                            android:layout_height="wrap_content"
                                            android:gravity="center"
                                            android:orientation="vertical"
                                            android:paddingBottom="@dimen/new_tablet_tab_panel_grid_padding">
@@ -16,31 +17,37 @@
     <LinearLayout android:layout_width="fill_parent"
                   android:layout_height="wrap_content"
                   android:orientation="horizontal"
                   android:duplicateParentState="true"
                   android:paddingLeft="@dimen/new_tablet_tab_highlight_stroke_width"
                   android:paddingRight="@dimen/new_tablet_tab_highlight_stroke_width"
                   android:paddingBottom="@dimen/new_tablet_tab_highlight_stroke_width">
 
-        <TextView android:id="@+id/title"
-                  android:layout_width="0dip"
-                  android:layout_height="wrap_content"
-                  android:layout_weight="1.0"
-                  style="@style/TabLayoutItemTextAppearance"
-                  android:textSize="14sp"
-                  android:textColor="@color/new_tablet_tab_item_title"
-                  android:singleLine="true"
-                  android:duplicateParentState="true"/>
+        <org.mozilla.gecko.widget.FadedTextView android:id="@+id/title"
+                                                android:layout_width="0dip"
+                                                android:layout_height="wrap_content"
+                                                android:layout_weight="1.0"
+                                                style="@style/TabLayoutItemTextAppearance"
+                                                android:textSize="14sp"
+                                                android:textColor="@color/new_tablet_tab_item_title"
+                                                android:singleLine="true"
+                                                android:duplicateParentState="true"
+                                                gecko:fadeWidth="15dp"
+                                                android:paddingRight="5dp"/>
 
+
+        <!-- Use of baselineAlignBottom only supported from API 11+ - if this needs to work on lower API versions
+             we'll need to override getBaseLine() and return image height, but we assume this won't happen -->
         <ImageButton android:id="@+id/close"
                      style="@style/TabsItemClose"
                      android:layout_width="wrap_content"
-                     android:layout_height="match_parent"
+                     android:layout_height="wrap_content"
                      android:scaleType="center"
+                     android:baselineAlignBottom="true"
                      android:background="@android:color/transparent"
                      android:contentDescription="@string/close_tab"
                      android:src="@drawable/new_tablet_tab_item_close_button"
                      android:duplicateParentState="true"/>
 
     </LinearLayout>
 
     <RelativeLayout android:layout_width="wrap_content"
--- a/mobile/android/base/resources/values/layout.xml
+++ b/mobile/android/base/resources/values/layout.xml
@@ -3,9 +3,10 @@
    - 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/. -->
 
 <resources>
     <item type="layout" name="tabs_panel">@layout/tabs_panel_default</item>
     <item type="layout" name="tabs_layout_item_view">@layout/tabs_item_row</item>
     <item type="layout" name="new_tablet_browser_toolbar">@null</item>
     <item type="layout" name="new_tablet_tab_strip">@null</item>
+    <item type="layout" name="new_tablet_tabs_item_cell">@null</item>
 </resources>
--- a/mobile/android/base/resources/xml/preferences_display.xml
+++ b/mobile/android/base/resources/xml/preferences_display.xml
@@ -22,17 +22,17 @@
                     android:persistent="false" />
 
     <CheckBoxPreference android:key="browser.chrome.dynamictoolbar"
                         android:title="@string/pref_scroll_title_bar2"
                         android:summary="@string/pref_scroll_title_bar_summary" />
 
     <CheckBoxPreference android:key="android.not_a_preference.new_tablet_ui"
                         android:title="@string/new_tablet_pref"
-                        android:defaultValue="false" />
+                        android:defaultValue="true" />
 
     <PreferenceCategory android:title="@string/pref_category_advanced">
 
         <CheckBoxPreference
                         android:key="browser.zoom.reflowOnZoom"
                         android:title="@string/pref_reflow_on_zoom"
                         android:defaultValue="false"
                         android:persistent="false" />
--- a/mobile/android/base/tabs/TabStrip.java
+++ b/mobile/android/base/tabs/TabStrip.java
@@ -77,19 +77,17 @@ public class TabStrip extends ThemedLine
     }
 
     private class TabsListener implements Tabs.OnTabsChangedListener {
         @Override
         public void onTabChanged(Tab tab, Tabs.TabEvents msg, Object data) {
             switch (msg) {
                 case RESTORED:
                 case ADDED:
-                    // Refresh the list to make sure the new tab is
-                    // added in the right position.
-                    tabStripView.refreshTabs();
+                    tabStripView.addTab(tab);
                     break;
 
                 case CLOSED:
                     tabStripView.removeTab(tab);
                     break;
 
                 case SELECTED:
                     // Update the selected position, then fall through...
--- a/mobile/android/base/tabs/TabStripView.java
+++ b/mobile/android/base/tabs/TabStripView.java
@@ -6,32 +6,41 @@
 package org.mozilla.gecko.tabs;
 
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
+import android.view.animation.AccelerateDecelerateInterpolator;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
 import android.view.ViewTreeObserver.OnPreDrawListener;
 
+import com.nineoldandroids.animation.Animator;
+import com.nineoldandroids.animation.AnimatorSet;
+import com.nineoldandroids.animation.ObjectAnimator;
+
 import java.util.ArrayList;
 import java.util.List;
 
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.Tab;
 import org.mozilla.gecko.Tabs;
 import org.mozilla.gecko.widget.TwoWayView;
 
 public class TabStripView extends TwoWayView {
     private static final String LOGTAG = "GeckoTabStrip";
 
+    private static final int ANIM_TIME_MS = 200;
+    private static final AccelerateDecelerateInterpolator ANIM_INTERPOLATOR =
+            new AccelerateDecelerateInterpolator();
+
     private final TabStripAdapter adapter;
     private final Drawable divider;
 
     // Filled by calls to ShapeDrawable.getPadding();
     // saved to prevent allocation in draw().
     private final Rect dividerPadding = new Rect();
 
     private boolean isPrivate;
@@ -66,22 +75,118 @@ public class TabStripView extends TwoWay
     private int getPositionForSelectedTab() {
         return adapter.getPositionForTab(Tabs.getInstance().getSelectedTab());
     }
 
     private void updateSelectedStyle(int selected) {
         setItemChecked(selected, true);
     }
 
-    private void updateSelectedPosition() {
+    private void updateSelectedPosition(boolean ensureVisible) {
         final int selected = getPositionForSelectedTab();
         if (selected != -1) {
             updateSelectedStyle(selected);
-            ensurePositionIsVisible(selected);
+
+            if (ensureVisible) {
+                ensurePositionIsVisible(selected);
+            }
+        }
+    }
+
+    private void animateRemoveTab(Tab removedTab) {
+        final int removedPosition = adapter.getPositionForTab(removedTab);
+
+        final View removedView = getViewForTab(removedTab);
+
+        // The removed position might not have a matching child view
+        // when it's not within the visible range of positions in the strip.
+        if (removedView == null) {
+            return;
         }
+
+        // We don't animate the removed child view (it just disappears)
+        // but we still need its size of animate all affected children
+        // within the visible viewport.
+        final int removedSize = removedView.getWidth() + getItemMargin();
+
+        getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() {
+            @Override
+            public boolean onPreDraw() {
+                getViewTreeObserver().removeOnPreDrawListener(this);
+
+                final int firstPosition = getFirstVisiblePosition();
+                final List<Animator> childAnimators = new ArrayList<Animator>();
+
+                final int childCount = getChildCount();
+                for (int i = removedPosition - firstPosition; i < childCount; i++) {
+                    final View child = getChildAt(i);
+
+                    // TODO: optimize with Valueresolver
+                    final ObjectAnimator animator =
+                            ObjectAnimator.ofFloat(child, "translationX", removedSize, 0);
+                    childAnimators.add(animator);
+                }
+
+                final AnimatorSet animatorSet = new AnimatorSet();
+                animatorSet.playTogether(childAnimators);
+                animatorSet.setDuration(ANIM_TIME_MS);
+                animatorSet.setInterpolator(ANIM_INTERPOLATOR);
+                animatorSet.start();
+
+                return true;
+            }
+        });
+    }
+
+    private void animateNewTab(Tab newTab) {
+        final int newPosition = adapter.getPositionForTab(newTab);
+        if (newPosition < 0) {
+            return;
+        }
+
+        getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() {
+            @Override
+            public boolean onPreDraw() {
+                getViewTreeObserver().removeOnPreDrawListener(this);
+
+                final int firstPosition = getFirstVisiblePosition();
+
+                final View newChild = getChildAt(newPosition - firstPosition);
+                if (newChild == null) {
+                    return true;
+                }
+
+                final List<Animator> childAnimators = new ArrayList<Animator>();
+                childAnimators.add(
+                        ObjectAnimator.ofFloat(newChild, "translationY", newChild.getHeight(), 0));
+
+                // This will momentaneously add a gap on the right side
+                // because TwoWayView doesn't provide APIs to control
+                // view recycling programatically to handle these transitory
+                // states in the container during animations.
+
+                final int tabSize = newChild.getWidth();
+                final int newIndex = newPosition - firstPosition;
+                final int childCount = getChildCount();
+                for (int i = newIndex + 1; i < childCount; i++) {
+                    final View child = getChildAt(i);
+
+                    childAnimators.add(
+                        ObjectAnimator.ofFloat(child, "translationX", -tabSize, 0));
+                }
+
+                final AnimatorSet animatorSet = new AnimatorSet();
+                animatorSet.playTogether(childAnimators);
+                animatorSet.setDuration(ANIM_TIME_MS);
+                animatorSet.setInterpolator(ANIM_INTERPOLATOR);
+                animatorSet.start();
+
+                return true;
+            }
+        });
     }
 
     private void ensurePositionIsVisible(final int position) {
         getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() {
             @Override
             public boolean onPreDraw() {
                 getViewTreeObserver().removeOnPreDrawListener(this);
                 smoothScrollToPosition(position);
@@ -106,34 +211,42 @@ public class TabStripView extends TwoWay
 
         for (Tab tab : Tabs.getInstance().getTabsInOrder()) {
             if (tab.isPrivate() == isPrivate) {
                 tabs.add(tab);
             }
         }
 
         adapter.refresh(tabs);
-        updateSelectedPosition();
+        updateSelectedPosition(true);
     }
 
     void clearTabs() {
         adapter.clear();
     }
 
+    void addTab(Tab tab) {
+        // Refresh the list to make sure the new tab is
+        // added in the right position.
+        refreshTabs();
+        animateNewTab(tab);
+    }
+
     void removeTab(Tab tab) {
+        animateRemoveTab(tab);
         adapter.removeTab(tab);
-        updateSelectedPosition();
+        updateSelectedPosition(false);
     }
 
     void selectTab(Tab tab) {
         if (tab.isPrivate() != isPrivate) {
             isPrivate = tab.isPrivate();
             refreshTabs();
         } else {
-            updateSelectedPosition();
+            updateSelectedPosition(true);
         }
     }
 
     void updateTab(Tab tab) {
         final TabStripItemView item = (TabStripItemView) getViewForTab(tab);
         if (item != null) {
             item.updateFromTab(tab);
         }
--- a/mobile/android/base/tabs/TabsLayoutItemView.java
+++ b/mobile/android/base/tabs/TabsLayoutItemView.java
@@ -4,23 +4,25 @@
 
 package org.mozilla.gecko.tabs;
 
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.Tab;
 import org.mozilla.gecko.widget.TabThumbnailWrapper;
 
 import android.content.Context;
+import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
+import android.view.TouchDelegate;
 import android.view.View;
+import android.view.ViewTreeObserver;
 import android.widget.Checkable;
 import android.widget.ImageButton;
 import android.widget.ImageView;
-import android.widget.ImageView.ScaleType;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
 public class TabsLayoutItemView extends LinearLayout
                                 implements Checkable {
     private static final String LOGTAG = "Gecko" + TabsLayoutItemView.class.getSimpleName();
     private static final int[] STATE_CHECKED = { android.R.attr.state_checked };
     private boolean mChecked;
@@ -80,16 +82,32 @@ public class TabsLayoutItemView extends 
 
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
         mTitle = (TextView) findViewById(R.id.title);
         mThumbnail = (ImageView) findViewById(R.id.thumbnail);
         mCloseButton = (ImageButton) findViewById(R.id.close);
         mThumbnailWrapper = (TabThumbnailWrapper) findViewById(R.id.wrapper);
+
+        getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+            @Override
+            public boolean onPreDraw() {
+                getViewTreeObserver().removeOnPreDrawListener(this);
+
+                final Rect r = new Rect();
+                mCloseButton.getHitRect(r);
+                r.left -= 25;
+                r.bottom += 25;
+
+                setTouchDelegate(new TouchDelegate(r, mCloseButton));
+
+                return true;
+            }
+        });
     }
 
     protected void assignValues(Tab tab)  {
         if (tab == null) {
             return;
         }
 
         mTabId = tab.getId();
--- a/mobile/android/base/toolbar/BrowserToolbar.java
+++ b/mobile/android/base/toolbar/BrowserToolbar.java
@@ -310,16 +310,20 @@ public abstract class BrowserToolbar ext
                     focusChangeListener.onFocusChange(v, hasFocus);
                 }
             }
         });
 
         tabsButton.setOnClickListener(new Button.OnClickListener() {
             @Override
             public void onClick(View v) {
+                // Clear focus so a back press with the tabs
+                // panel open does not go to the editing field.
+                urlEditLayout.clearFocus();
+
                 toggleTabs();
             }
         });
         tabsButton.setImageLevel(0);
 
         editCancel.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View v) {
@@ -336,16 +340,18 @@ public abstract class BrowserToolbar ext
 
         if (hasSoftMenuButton) {
             menuButton.setVisibility(View.VISIBLE);
             menuIcon.setVisibility(View.VISIBLE);
 
             menuButton.setOnClickListener(new Button.OnClickListener() {
                 @Override
                 public void onClick(View view) {
+                    // Drop the soft keyboard.
+                    urlEditLayout.clearFocus();
                     activity.openOptionsMenu();
                 }
             });
         }
     }
 
     @Override
     public void onDetachedFromWindow() {
--- a/toolkit/components/places/Bookmarks.jsm
+++ b/toolkit/components/places/Bookmarks.jsm
@@ -95,16 +95,30 @@ let Bookmarks = Object.freeze({
 
   /**
    * Default index used to append a bookmark-item at the end of a folder. 
    * This should stay consistent with nsINavBookmarksService.idl
    */
   DEFAULT_INDEX: -1,
 
   /**
+   * Special GUIDs associated with bookmark roots.
+   * It's guaranteed that the roots will always have these guids.
+   */
+
+   rootGuid:    "root________",
+   menuGuid:    "menu________",
+   toolbarGuid: "toolbar_____",
+   unfiledGuid: "unfiled_____",
+
+   // With bug 424160, tags will stop being bookmarks, thus this root will
+   // be removed.  Do not rely on this, rather use the tagging service API.
+   tagsGuid:    "tags________",
+
+  /**
    * Inserts a bookmark-item into the bookmarks tree.
    *
    * For creating a bookmark, the following set of properties is required:
    *  - type
    *  - parentGuid
    *  - url, only for bookmarked URLs
    *
    * If an index is not specified, it defaults to appending.
@@ -432,59 +446,63 @@ let Bookmarks = Object.freeze({
    */
   eraseEverything: Task.async(function* () {
     let db = yield DBConnPromised;
 
     yield db.executeTransaction(function* () {
       let rows = yield db.executeCached(
         `WITH RECURSIVE
          descendants(did) AS (
-           SELECT id FROM moz_bookmarks
-           WHERE parent IN (SELECT folder_id FROM moz_bookmarks_roots
-                            WHERE root_name IN ("toolbar", "menu", "unfiled"))
+           SELECT b.id FROM moz_bookmarks b
+           JOIN moz_bookmarks p ON b.parent = p.id
+           WHERE p.guid IN ( :toolbarGuid, :menuGuid, :unfiledGuid )
            UNION ALL
            SELECT id FROM moz_bookmarks
            JOIN descendants ON parent = did
          )
          SELECT b.id AS _id, b.parent AS _parentId, b.position AS 'index',
                 b.type, url, b.guid, p.guid AS parentGuid, b.dateAdded,
                 b.lastModified, b.title, p.parent AS _grandParentId,
                 NULL AS _childCount, NULL AS keyword
          FROM moz_bookmarks b
          JOIN moz_bookmarks p ON p.id = b.parent
          LEFT JOIN moz_places h ON b.fk = h.id
          WHERE b.id IN descendants
-        `);
+        `, { menuGuid: this.menuGuid, toolbarGuid: this.toolbarGuid,
+             unfiledGuid: this.unfiledGuid });
       let items = rowsToItemsArray(rows);
 
       yield db.executeCached(
         `WITH RECURSIVE
          descendants(did) AS (
-           SELECT id FROM moz_bookmarks
-           WHERE parent IN (SELECT folder_id FROM moz_bookmarks_roots
-                            WHERE root_name IN ("toolbar", "menu", "unfiled"))
+           SELECT b.id FROM moz_bookmarks b
+           JOIN moz_bookmarks p ON b.parent = p.id
+           WHERE p.guid IN ( :toolbarGuid, :menuGuid, :unfiledGuid )
            UNION ALL
            SELECT id FROM moz_bookmarks
            JOIN descendants ON parent = did
          )
          DELETE FROM moz_bookmarks WHERE id IN descendants
-        `);
+        `, { menuGuid: this.menuGuid, toolbarGuid: this.toolbarGuid,
+             unfiledGuid: this.unfiledGuid });
 
       // Clenup orphans.
       yield removeOrphanAnnotations(db);
       yield removeOrphanKeywords(db);
 
       // TODO (Bug 1087576): this may leave orphan tags behind.
 
       // Update roots' lastModified.
       yield db.executeCached(
         `UPDATE moz_bookmarks SET lastModified = :time
-         WHERE id IN (SELECT folder_id FROM moz_bookmarks_roots
-                      WHERE root_name IN ("places", "toolbar", "menu", "unfiled"));
-        `, { time: toPRTime(new Date()) });
+         WHERE id IN (SELECT id FROM moz_bookmarks
+                      WHERE guid IN ( :rootGuid, :toolbarGuid, :menuGuid, :unfiledGuid ))
+        `, { time: toPRTime(new Date()), rootGuid: this.rootGuid,
+             menuGuid: this.menuGuid, toolbarGuid: this.toolbarGuid,
+             unfiledGuid: this.unfiledGuid });
 
       let urls = [for (item of items) if (item.url) item.url];
       updateFrecency(db, urls).then(null, Cu.reportError);
 
       // Send onItemRemoved notifications to listeners.
       // TODO (Bug 1087580): this should send a single clear bookmarks
       // notification rather than notifying for each bookmark.
 
@@ -501,17 +519,17 @@ let Bookmarks = Object.freeze({
           for (let entry of (yield fetchBookmarksByURL(item))) {
             notify(observers, "onItemChanged", [ entry._id, "tags", false, "",
                                                  toPRTime(entry.lastModified),
                                                  entry.type, entry._parentId,
                                                  entry.guid, entry.parentGuid ]);
           }
         }
       }
-    });
+    }.bind(this));
   }),
 
   /**
    * Fetches information about a bookmark-item.
    *
    * REMARK: any successful call to this method resolves to a single
    *         bookmark-item (or null), even when multiple bookmarks may exist
    *         (fetching by url or keyword,).  If you wish to retrieve all of the
--- a/toolkit/components/places/Database.cpp
+++ b/toolkit/components/places/Database.cpp
@@ -252,17 +252,17 @@ ConnectionCloseCallback::ConnectionClose
 
 NS_IMPL_ISUPPORTS(
   ConnectionCloseCallback
 , mozIStorageCompletionCallback
 )
 
 nsresult
 CreateRoot(nsCOMPtr<mozIStorageConnection>& aDBConn,
-           const nsCString& aRootName,
+           const nsCString& aRootName, const nsCString& aGuid,
            const nsXPIDLString& titleString)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   // The position of the new item in its folder.
   static int32_t itemPosition = 0;
 
   // A single creation timestamp for all roots so that the root folder's
@@ -272,52 +272,51 @@ CreateRoot(nsCOMPtr<mozIStorageConnectio
     timestamp = PR_Now();
 
   // Create a new bookmark folder for the root.
   nsCOMPtr<mozIStorageStatement> stmt;
   nsresult rv = aDBConn->CreateStatement(NS_LITERAL_CSTRING(
     "INSERT INTO moz_bookmarks "
       "(type, position, title, dateAdded, lastModified, guid, parent) "
     "VALUES (:item_type, :item_position, :item_title,"
-            ":date_added, :last_modified, GENERATE_GUID(),"
+            ":date_added, :last_modified, :guid,"
             "IFNULL((SELECT id FROM moz_bookmarks WHERE parent = 0), 0))"
   ), getter_AddRefs(stmt));
   if (NS_FAILED(rv)) return rv;
 
   rv = stmt->BindInt32ByName(NS_LITERAL_CSTRING("item_type"),
                              nsINavBookmarksService::TYPE_FOLDER);
   if (NS_FAILED(rv)) return rv;
   rv = stmt->BindInt32ByName(NS_LITERAL_CSTRING("item_position"), itemPosition);
   if (NS_FAILED(rv)) return rv;
   rv = stmt->BindUTF8StringByName(NS_LITERAL_CSTRING("item_title"),
                                   NS_ConvertUTF16toUTF8(titleString));
   if (NS_FAILED(rv)) return rv;
   rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("date_added"), timestamp);
   if (NS_FAILED(rv)) return rv;
   rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("last_modified"), timestamp);
   if (NS_FAILED(rv)) return rv;
+  rv = stmt->BindUTF8StringByName(NS_LITERAL_CSTRING("guid"), aGuid);
+  if (NS_FAILED(rv)) return rv;
   rv = stmt->Execute();
   if (NS_FAILED(rv)) return rv;
 
   // Create an entry in moz_bookmarks_roots to link the folder to the root.
   nsCOMPtr<mozIStorageStatement> newRootStmt;
   rv = aDBConn->CreateStatement(NS_LITERAL_CSTRING(
     "INSERT INTO moz_bookmarks_roots (root_name, folder_id) "
-    "VALUES (:root_name, "
-              "(SELECT id from moz_bookmarks WHERE "
-              " position = :item_position AND "
-              " parent = IFNULL((SELECT MIN(folder_id) FROM moz_bookmarks_roots), 0)))"
+    "VALUES (:root_name, (SELECT id from moz_bookmarks WHERE guid = :guid))"
   ), getter_AddRefs(newRootStmt));
   if (NS_FAILED(rv)) return rv;
 
   rv = newRootStmt->BindUTF8StringByName(NS_LITERAL_CSTRING("root_name"),
                                          aRootName);
   if (NS_FAILED(rv)) return rv;
-  rv = newRootStmt->BindInt32ByName(NS_LITERAL_CSTRING("item_position"),
-                                    itemPosition);
+  rv = newRootStmt->BindUTF8StringByName(NS_LITERAL_CSTRING("guid"),
+                                         aGuid);
   if (NS_FAILED(rv)) return rv;
   rv = newRootStmt->Execute();
   if (NS_FAILED(rv)) return rv;
 
   // The 'places' root is a folder containing the other roots.
   // The first bookmark in a folder has position 0.
   if (!aRootName.EqualsLiteral("places"))
     ++itemPosition;
@@ -633,53 +632,22 @@ Database::InitSchema(bool* aDatabaseMigr
     // NOTE: The downgrade process is pretty much complicated by the fact old
     //       versions cannot know what a new version is going to implement.
     //       The only thing we will do for downgrades is setting back the schema
     //       version, so that next upgrades will run again the migration step.
 
     if (currentSchemaVersion < DATABASE_SCHEMA_VERSION) {
       *aDatabaseMigrated = true;
 
-      if (currentSchemaVersion < 6) {
-        // These are early Firefox 3.0 alpha versions that are not supported
+      if (currentSchemaVersion < 11) {
+        // These are versions older than Firefox 4 that are not supported
         // anymore.  In this case it's safer to just replace the database.
         return NS_ERROR_FILE_CORRUPTED;
       }
 
-      // Firefox 3.0 uses schema version 6.
-
-      if (currentSchemaVersion < 7) {
-        rv = MigrateV7Up();
-        NS_ENSURE_SUCCESS(rv, rv);
-      }
-
-      if (currentSchemaVersion < 8) {
-        rv = MigrateV8Up();
-        NS_ENSURE_SUCCESS(rv, rv);
-      }
-
-      // Firefox 3.5 uses schema version 8.
-
-      if (currentSchemaVersion < 9) {
-        rv = MigrateV9Up();
-        NS_ENSURE_SUCCESS(rv, rv);
-      }
-
-      if (currentSchemaVersion < 10) {
-        rv = MigrateV10Up();
-        NS_ENSURE_SUCCESS(rv, rv);
-      }
-
-      // Firefox 3.6 uses schema version 10.
-
-      if (currentSchemaVersion < 11) {
-        rv = MigrateV11Up();
-        NS_ENSURE_SUCCESS(rv, rv);
-      }
-
       // Firefox 4 uses schema version 11.
 
       // Firefox 8 uses schema version 12.
 
       if (currentSchemaVersion < 13) {
         rv = MigrateV13Up();
         NS_ENSURE_SUCCESS(rv, rv);
       }
@@ -745,18 +713,26 @@ Database::InitSchema(bool* aDatabaseMigr
       }
 
       // Firefox 24 uses schema version 23.
 
       if (currentSchemaVersion < 24) {
         rv = MigrateV24Up();
         NS_ENSURE_SUCCESS(rv, rv);
       }
+
       // Firefox 34 uses schema version 24.
 
+      if (currentSchemaVersion < 25) {
+        rv = MigrateV25Up();
+        NS_ENSURE_SUCCESS(rv, rv);
+      }
+
+      // Firefox 36 uses schema version 25.
+
       // Schema Upgrades must add migration code here.
 
       rv = UpdateBookmarkRootTitles();
       // We don't want a broken localization to cause us to think
       // the database is corrupt and needs to be replaced.
       MOZ_ASSERT(NS_SUCCEEDED(rv));
     }
   }
@@ -870,69 +846,63 @@ Database::CreateBookmarkRoots()
     services::GetStringBundleService();
   NS_ENSURE_STATE(bundleService);
   nsCOMPtr<nsIStringBundle> bundle;
   nsresult rv = bundleService->CreateBundle(PLACES_BUNDLE, getter_AddRefs(bundle));
   if (NS_FAILED(rv)) return rv;
 
   nsXPIDLString rootTitle;
   // The first root's title is an empty string.
-  rv = CreateRoot(mMainConn, NS_LITERAL_CSTRING("places"), rootTitle);
+  rv = CreateRoot(mMainConn, NS_LITERAL_CSTRING("places"),
+                  NS_LITERAL_CSTRING("root________"), rootTitle);
   if (NS_FAILED(rv)) return rv;
 
   // Fetch the internationalized folder name from the string bundle.
   rv = bundle->GetStringFromName(MOZ_UTF16("BookmarksMenuFolderTitle"),
                                  getter_Copies(rootTitle));
   if (NS_FAILED(rv)) return rv;
-  rv = CreateRoot(mMainConn, NS_LITERAL_CSTRING("menu"), rootTitle);
+  rv = CreateRoot(mMainConn, NS_LITERAL_CSTRING("menu"),
+                  NS_LITERAL_CSTRING("menu________"), rootTitle);
   if (NS_FAILED(rv)) return rv;
 
   rv = bundle->GetStringFromName(MOZ_UTF16("BookmarksToolbarFolderTitle"),
                                  getter_Copies(rootTitle));
   if (NS_FAILED(rv)) return rv;
-  rv = CreateRoot(mMainConn, NS_LITERAL_CSTRING("toolbar"), rootTitle);
+  rv = CreateRoot(mMainConn, NS_LITERAL_CSTRING("toolbar"),
+                  NS_LITERAL_CSTRING("toolbar_____"), rootTitle);
   if (NS_FAILED(rv)) return rv;
 
   rv = bundle->GetStringFromName(MOZ_UTF16("TagsFolderTitle"),
                                  getter_Copies(rootTitle));
   if (NS_FAILED(rv)) return rv;
-  rv = CreateRoot(mMainConn, NS_LITERAL_CSTRING("tags"), rootTitle);
+  rv = CreateRoot(mMainConn, NS_LITERAL_CSTRING("tags"),
+                  NS_LITERAL_CSTRING("tags________"), rootTitle);
   if (NS_FAILED(rv)) return rv;
 
   rv = bundle->GetStringFromName(MOZ_UTF16("UnsortedBookmarksFolderTitle"),
                                  getter_Copies(rootTitle));
   if (NS_FAILED(rv)) return rv;
-  rv = CreateRoot(mMainConn, NS_LITERAL_CSTRING("unfiled"), rootTitle);
+  rv = CreateRoot(mMainConn, NS_LITERAL_CSTRING("unfiled"),
+                  NS_LITERAL_CSTRING("unfiled_____"), rootTitle);
   if (NS_FAILED(rv)) return rv;
 
 #if DEBUG
   nsCOMPtr<mozIStorageStatement> stmt;
   rv = mMainConn->CreateStatement(NS_LITERAL_CSTRING(
-    "SELECT "
-      "(SELECT COUNT(*) FROM moz_bookmarks), "
-      "(SELECT COUNT(*) FROM moz_bookmarks_roots), "
-      "(SELECT SUM(position) FROM moz_bookmarks WHERE "
-        "id IN (SELECT folder_id FROM moz_bookmarks_roots))"
+    "SELECT count(*), sum(position) FROM moz_bookmarks"
   ), getter_AddRefs(stmt));
   if (NS_FAILED(rv)) return rv;
 
   bool hasResult;
   rv = stmt->ExecuteStep(&hasResult);
   if (NS_FAILED(rv)) return rv;
   MOZ_ASSERT(hasResult);
-  int32_t bookmarkCount = 0;
-  rv = stmt->GetInt32(0, &bookmarkCount);
-  if (NS_FAILED(rv)) return rv;
-  int32_t rootCount = 0;
-  rv = stmt->GetInt32(1, &rootCount);
-  if (NS_FAILED(rv)) return rv;
-  int32_t positionSum = 0;
-  rv = stmt->GetInt32(2, &positionSum);
-  if (NS_FAILED(rv)) return rv;
-  MOZ_ASSERT(bookmarkCount == 5 && rootCount == 5 && positionSum == 6);
+  int32_t bookmarkCount = stmt->AsInt32(0);
+  int32_t positionSum = stmt->AsInt32(1);
+  MOZ_ASSERT(bookmarkCount == 5 && positionSum == 6);
 #endif
 
   return NS_OK;
 }
 
 nsresult
 Database::InitFunctions()
 {
@@ -994,42 +964,46 @@ Database::UpdateBookmarkRootTitles()
   NS_ENSURE_STATE(bundleService);
 
   nsCOMPtr<nsIStringBundle> bundle;
   nsresult rv = bundleService->CreateBundle(PLACES_BUNDLE, getter_AddRefs(bundle));
   if (NS_FAILED(rv)) return rv;
 
   nsCOMPtr<mozIStorageAsyncStatement> stmt;
   rv = mMainConn->CreateAsyncStatement(NS_LITERAL_CSTRING(
-    "UPDATE moz_bookmarks SET title = :new_title WHERE id = "
-      "(SELECT folder_id FROM moz_bookmarks_roots WHERE root_name = :root_name)"
+    "UPDATE moz_bookmarks SET title = :new_title WHERE guid = :guid"
   ), getter_AddRefs(stmt));
   if (NS_FAILED(rv)) return rv;
 
   nsCOMPtr<mozIStorageBindingParamsArray> paramsArray;
   rv = stmt->NewBindingParamsArray(getter_AddRefs(paramsArray));
   if (NS_FAILED(rv)) return rv;
 
-  const char *rootNames[] = { "menu", "toolbar", "tags", "unfiled" };
-  const char *titleStringIDs[] = {
-    "BookmarksMenuFolderTitle", "BookmarksToolbarFolderTitle",
-    "TagsFolderTitle", "UnsortedBookmarksFolderTitle"
-  };
+  const char *rootGuids[] = { "menu________"
+                            , "toolbar_____"
+                            , "tags________"
+                            , "unfiled_____"
+                            };
+  const char *titleStringIDs[] = { "BookmarksMenuFolderTitle"
+                                 , "BookmarksToolbarFolderTitle"
+                                 , "TagsFolderTitle"
+                                 , "UnsortedBookmarksFolderTitle"
+                                 };
 
-  for (uint32_t i = 0; i < ArrayLength(rootNames); ++i) {
+  for (uint32_t i = 0; i < ArrayLength(rootGuids); ++i) {
     nsXPIDLString title;
     rv = bundle->GetStringFromName(NS_ConvertASCIItoUTF16(titleStringIDs[i]).get(),
                                    getter_Copies(title));
     if (NS_FAILED(rv)) return rv;
 
     nsCOMPtr<mozIStorageBindingParams> params;
     rv = paramsArray->NewBindingParams(getter_AddRefs(params));
     if (NS_FAILED(rv)) return rv;
-    rv = params->BindUTF8StringByName(NS_LITERAL_CSTRING("root_name"),
-                                      nsDependentCString(rootNames[i]));
+    rv = params->BindUTF8StringByName(NS_LITERAL_CSTRING("guid"),
+                                      nsDependentCString(rootGuids[i]));
     if (NS_FAILED(rv)) return rv;
     rv = params->BindUTF8StringByName(NS_LITERAL_CSTRING("new_title"),
                                       NS_ConvertUTF16toUTF8(title));
     if (NS_FAILED(rv)) return rv;
     rv = paramsArray->AddParams(params);
     if (NS_FAILED(rv)) return rv;
   }
 
@@ -1038,538 +1012,16 @@ Database::UpdateBookmarkRootTitles()
   nsCOMPtr<mozIStoragePendingStatement> pendingStmt;
   rv = stmt->ExecuteAsync(nullptr, getter_AddRefs(pendingStmt));
   if (NS_FAILED(rv)) return rv;
 
   return NS_OK;
 }
 
 nsresult
-Database::CheckAndUpdateGUIDs()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  // First, import any bookmark guids already set by Sync.
-  nsCOMPtr<mozIStorageStatement> updateStmt;
-  nsresult rv = mMainConn->CreateStatement(NS_LITERAL_CSTRING(
-    "UPDATE moz_bookmarks "
-    "SET guid = :guid "
-    "WHERE id = :item_id "
-  ), getter_AddRefs(updateStmt));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<mozIStorageStatement> stmt;
-  rv = mMainConn->CreateStatement(NS_LITERAL_CSTRING(
-    "SELECT item_id, content "
-    "FROM moz_items_annos "
-    "JOIN moz_anno_attributes "
-    "WHERE name = :anno_name "
-  ), getter_AddRefs(stmt));
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = stmt->BindUTF8StringByName(NS_LITERAL_CSTRING("anno_name"),
-                                  SYNCGUID_ANNO);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  bool hasResult;
-  while (NS_SUCCEEDED(stmt->ExecuteStep(&hasResult)) && hasResult) {
-    int64_t itemId;
-    rv = stmt->GetInt64(0, &itemId);
-    NS_ENSURE_SUCCESS(rv, rv);
-    nsAutoCString guid;
-    rv = stmt->GetUTF8String(1, guid);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    // If we have an invalid guid, we don't need to do any more work.
-    if (!IsValidGUID(guid)) {
-      continue;
-    }
-
-    mozStorageStatementScoper updateScoper(updateStmt);
-    rv = updateStmt->BindInt64ByName(NS_LITERAL_CSTRING("item_id"), itemId);
-    NS_ENSURE_SUCCESS(rv, rv);
-    rv = updateStmt->BindUTF8StringByName(NS_LITERAL_CSTRING("guid"), guid);
-    NS_ENSURE_SUCCESS(rv, rv);
-    rv = updateStmt->Execute();
-    if (rv == NS_ERROR_STORAGE_CONSTRAINT) {
-      // We just tried to insert a duplicate guid.  Ignore this error, and we
-      // will generate a new one next.
-      continue;
-    }
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  // Now, remove all the bookmark guid annotations that we just imported.
-  rv = mMainConn->CreateStatement(NS_LITERAL_CSTRING(
-    "DELETE FROM moz_items_annos "
-    "WHERE anno_attribute_id = ( "
-      "SELECT id "
-      "FROM moz_anno_attributes "
-      "WHERE name = :anno_name "
-    ") "
-  ), getter_AddRefs(stmt));
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = stmt->BindUTF8StringByName(NS_LITERAL_CSTRING("anno_name"),
-                                  SYNCGUID_ANNO);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = stmt->Execute();
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // Next, generate guids for any bookmark that does not already have one.
-  rv = mMainConn->CreateStatement(NS_LITERAL_CSTRING(
-    "UPDATE moz_bookmarks "
-    "SET guid = GENERATE_GUID() "
-    "WHERE guid IS NULL "
-  ), getter_AddRefs(stmt));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = stmt->Execute();
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // Now, import any history guids already set by Sync.
-  rv = mMainConn->CreateStatement(NS_LITERAL_CSTRING(
-    "UPDATE moz_places "
-    "SET guid = :guid "
-    "WHERE id = :place_id "
-  ), getter_AddRefs(updateStmt));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = mMainConn->CreateStatement(NS_LITERAL_CSTRING(
-    "SELECT place_id, content "
-    "FROM moz_annos "
-    "JOIN moz_anno_attributes "
-    "WHERE name = :anno_name "
-  ), getter_AddRefs(stmt));
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = stmt->BindUTF8StringByName(NS_LITERAL_CSTRING("anno_name"),
-                                  SYNCGUID_ANNO);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  while (NS_SUCCEEDED(stmt->ExecuteStep(&hasResult)) && hasResult) {
-    int64_t placeId;
-    rv = stmt->GetInt64(0, &placeId);
-    NS_ENSURE_SUCCESS(rv, rv);
-    nsAutoCString guid;
-    rv = stmt->GetUTF8String(1, guid);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    // If we have an invalid guid, we don't need to do any more work.
-    if (!IsValidGUID(guid)) {
-      continue;
-    }
-
-    mozStorageStatementScoper updateScoper(updateStmt);
-    rv = updateStmt->BindInt64ByName(NS_LITERAL_CSTRING("place_id"), placeId);
-    NS_ENSURE_SUCCESS(rv, rv);
-    rv = updateStmt->BindUTF8StringByName(NS_LITERAL_CSTRING("guid"), guid);
-    NS_ENSURE_SUCCESS(rv, rv);
-    rv = updateStmt->Execute();
-    if (rv == NS_ERROR_STORAGE_CONSTRAINT) {
-      // We just tried to insert a duplicate guid.  Ignore this error, and we
-      // will generate a new one next.
-      continue;
-    }
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  // Now, remove all the place guid annotations that we just imported.
-  rv = mMainConn->CreateStatement(NS_LITERAL_CSTRING(
-    "DELETE FROM moz_annos "
-    "WHERE anno_attribute_id = ( "
-      "SELECT id "
-      "FROM moz_anno_attributes "
-      "WHERE name = :anno_name "
-    ") "
-  ), getter_AddRefs(stmt));
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = stmt->BindUTF8StringByName(NS_LITERAL_CSTRING("anno_name"),
-                                  SYNCGUID_ANNO);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = stmt->Execute();
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // Finally, generate guids for any places that do not already have one.
-  rv = mMainConn->CreateStatement(NS_LITERAL_CSTRING(
-    "UPDATE moz_places "
-    "SET guid = GENERATE_GUID() "
-    "WHERE guid IS NULL "
-  ), getter_AddRefs(stmt));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = stmt->Execute();
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  return NS_OK;
-}
-
-nsresult
-Database::MigrateV7Up() 
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  // Some old v6 databases come from alpha versions that missed indices.
-  // Just bail out and replace the database in such a case.
-  bool URLUniqueIndexExists = false;
-  nsresult rv = mMainConn->IndexExists(NS_LITERAL_CSTRING(
-    "moz_places_url_uniqueindex"
-  ), &URLUniqueIndexExists);
-  NS_ENSURE_SUCCESS(rv, rv);
-  if (!URLUniqueIndexExists) {
-    return NS_ERROR_FILE_CORRUPTED;
-  }
-
-  // We need an index on lastModified to catch quickly last modified bookmark
-  // title for tag container's children. This will be useful for Sync, too.
-  bool lastModIndexExists = false;
-  rv = mMainConn->IndexExists(
-    NS_LITERAL_CSTRING("moz_bookmarks_itemlastmodifiedindex"),
-    &lastModIndexExists);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (!lastModIndexExists) {
-    rv = mMainConn->ExecuteSimpleSQL(CREATE_IDX_MOZ_BOOKMARKS_PLACELASTMODIFIED);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  // We need to do a one-time change of the moz_historyvisits.pageindex
-  // to speed up finding last visit date when joinin with moz_places.
-  // See bug 392399 for more details.
-  bool pageIndexExists = false;
-  rv = mMainConn->IndexExists(
-    NS_LITERAL_CSTRING("moz_historyvisits_pageindex"), &pageIndexExists);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (pageIndexExists) {
-    // drop old index
-    rv = mMainConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
-        "DROP INDEX IF EXISTS moz_historyvisits_pageindex"));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    // create the new multi-column index
-    rv = mMainConn->ExecuteSimpleSQL(CREATE_IDX_MOZ_HISTORYVISITS_PLACEDATE);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  // for existing profiles, we may not have a frecency column
-  nsCOMPtr<mozIStorageStatement> hasFrecencyStatement;
-  rv = mMainConn->CreateStatement(NS_LITERAL_CSTRING(
-      "SELECT frecency FROM moz_places"),
-    getter_AddRefs(hasFrecencyStatement));
-
-  if (NS_FAILED(rv)) {
-    // Add frecency column to moz_places, default to -1 so that all the
-    // frecencies are invalid
-    rv = mMainConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
-        "ALTER TABLE moz_places ADD frecency INTEGER DEFAULT -1 NOT NULL"));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    // create index for the frecency column
-    // XXX multi column index with typed, and visit_count?
-    rv = mMainConn->ExecuteSimpleSQL(CREATE_IDX_MOZ_PLACES_FRECENCY);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    // Invalidate all frecencies, since they need recalculation.
-    nsCOMPtr<mozIStorageAsyncStatement> stmt = GetAsyncStatement(
-      "UPDATE moz_places SET frecency = ( "
-        "CASE "
-        "WHEN url BETWEEN 'place:' AND 'place;' "
-        "THEN 0 "
-        "ELSE -1 "
-        "END "
-      ") "
-    );
-    NS_ENSURE_STATE(stmt);
-    nsCOMPtr<mozIStoragePendingStatement> ps;
-    (void)stmt->ExecuteAsync(nullptr, getter_AddRefs(ps));
-  }
-
-  // Temporary migration code for bug 396300
-  nsCOMPtr<mozIStorageStatement> moveUnfiledBookmarks;
-  rv = mMainConn->CreateStatement(NS_LITERAL_CSTRING(
-      "UPDATE moz_bookmarks "
-      "SET parent = ("
-        "SELECT folder_id "
-        "FROM moz_bookmarks_roots "
-        "WHERE root_name = :root_name "
-      ") "
-      "WHERE type = :item_type "
-      "AND parent = ("
-        "SELECT folder_id "
-        "FROM moz_bookmarks_roots "
-        "WHERE root_name = :parent_name "
-      ")"),
-    getter_AddRefs(moveUnfiledBookmarks));
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = moveUnfiledBookmarks->BindUTF8StringByName(
-    NS_LITERAL_CSTRING("root_name"), NS_LITERAL_CSTRING("unfiled")
-  );
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = moveUnfiledBookmarks->BindInt32ByName(
-    NS_LITERAL_CSTRING("item_type"), nsINavBookmarksService::TYPE_BOOKMARK
-  );
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = moveUnfiledBookmarks->BindUTF8StringByName(
-    NS_LITERAL_CSTRING("parent_name"), NS_LITERAL_CSTRING("places")
-  );
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = moveUnfiledBookmarks->Execute();
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // Create a statement to test for trigger creation
-  nsCOMPtr<mozIStorageStatement> triggerDetection;
-  rv = mMainConn->CreateStatement(NS_LITERAL_CSTRING(
-      "SELECT name "
-      "FROM sqlite_master "
-      "WHERE type = 'trigger' "
-      "AND name = :trigger_name"),
-    getter_AddRefs(triggerDetection));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // Check for existence
-  bool triggerExists;
-  rv = triggerDetection->BindUTF8StringByName(
-    NS_LITERAL_CSTRING("trigger_name"),
-    NS_LITERAL_CSTRING("moz_historyvisits_afterinsert_v1_trigger")
-  );
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = triggerDetection->ExecuteStep(&triggerExists);
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = triggerDetection->Reset();
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // We need to create two triggers on moz_historyvists to maintain the
-  // accuracy of moz_places.visit_count.  For this to work, we must ensure that
-  // all moz_places.visit_count values are correct.
-  // See bug 416313 for details.
-  if (!triggerExists) {
-    // First, we do a one-time reset of all the moz_places.visit_count values.
-    rv = mMainConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
-        "UPDATE moz_places SET visit_count = "
-          "(SELECT count(*) FROM moz_historyvisits "
-           "WHERE place_id = moz_places.id "
-            "AND visit_type NOT IN ") +
-              nsPrintfCString("(0,%d,%d,%d) ",
-                              nsINavHistoryService::TRANSITION_EMBED,
-                              nsINavHistoryService::TRANSITION_FRAMED_LINK,
-                              nsINavHistoryService::TRANSITION_DOWNLOAD) +
-          NS_LITERAL_CSTRING(")"));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    // We used to create two triggers here, but we no longer need that with
-    // schema version eight and greater.  We've removed their creation here as
-    // a result.
-  }
-
-  // Check for existence
-  rv = triggerDetection->BindUTF8StringByName(
-    NS_LITERAL_CSTRING("trigger_name"),
-    NS_LITERAL_CSTRING("moz_bookmarks_beforedelete_v1_trigger")
-  );
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = triggerDetection->ExecuteStep(&triggerExists);
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = triggerDetection->Reset();
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // We need to create one trigger on moz_bookmarks to remove unused keywords.
-  // See bug 421180 for details.
-  if (!triggerExists) {
-    // First, remove any existing dangling keywords
-    rv = mMainConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
-        "DELETE FROM moz_keywords "
-        "WHERE id IN ("
-          "SELECT k.id "
-          "FROM moz_keywords k "
-          "LEFT OUTER JOIN moz_bookmarks b "
-          "ON b.keyword_id = k.id "
-          "WHERE b.id IS NULL"
-        ")"));
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  // Add the moz_inputhistory table, if missing.
-  bool tableExists = false;
-  rv = mMainConn->TableExists(NS_LITERAL_CSTRING("moz_inputhistory"),
-                              &tableExists);
-  NS_ENSURE_SUCCESS(rv, rv);
-  if (!tableExists) {
-    rv = mMainConn->ExecuteSimpleSQL(CREATE_MOZ_INPUTHISTORY);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  return NS_OK;
-}
-
-
-nsresult
-Database::MigrateV8Up()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  nsresult rv = mMainConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
-      "DROP TRIGGER IF EXISTS moz_historyvisits_afterinsert_v1_trigger"));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = mMainConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
-      "DROP TRIGGER IF EXISTS moz_historyvisits_afterdelete_v1_trigger"));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-
-  // bug #381795 - remove unused indexes
-  rv = mMainConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
-      "DROP INDEX IF EXISTS moz_places_titleindex"));
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = mMainConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
-      "DROP INDEX IF EXISTS moz_annos_item_idindex"));
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = mMainConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
-      "DROP INDEX IF EXISTS moz_annos_place_idindex"));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // Do a one-time re-creation of the moz_annos indexes (bug 415201)
-  bool oldIndexExists = false;
-  rv = mMainConn->IndexExists(NS_LITERAL_CSTRING("moz_annos_attributesindex"), &oldIndexExists);
-  NS_ENSURE_SUCCESS(rv, rv);
-  if (oldIndexExists) {
-    // drop old uri annos index
-    rv = mMainConn->ExecuteSimpleSQL(
-        NS_LITERAL_CSTRING("DROP INDEX moz_annos_attributesindex"));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    // create new uri annos index
-    rv = mMainConn->ExecuteSimpleSQL(CREATE_IDX_MOZ_ANNOS_PLACEATTRIBUTE);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    // drop old item annos index
-    rv = mMainConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
-        "DROP INDEX IF EXISTS moz_items_annos_attributesindex"));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    // create new item annos index
-    rv = mMainConn->ExecuteSimpleSQL(CREATE_IDX_MOZ_ITEMSANNOS_PLACEATTRIBUTE);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  return NS_OK;
-}
-
-
-nsresult
-Database::MigrateV9Up()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  // Added in Bug 488966.  The last_visit_date column caches the last
-  // visit date, this enhances SELECT performances when we
-  // need to sort visits by visit date.
-  // The cached value is synced by triggers on every added or removed visit.
-  // See nsPlacesTriggers.h for details on the triggers.
-  bool oldIndexExists = false;
-  nsresult rv = mMainConn->IndexExists(
-    NS_LITERAL_CSTRING("moz_places_lastvisitdateindex"), &oldIndexExists);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (!oldIndexExists) {
-    // Add last_visit_date column to moz_places.
-    rv = mMainConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
-        "ALTER TABLE moz_places ADD last_visit_date INTEGER"));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    rv = mMainConn->ExecuteSimpleSQL(CREATE_IDX_MOZ_PLACES_LASTVISITDATE);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    // Now let's sync the column contents with real visit dates.
-    // This query can be really slow due to disk access, since it will basically
-    // dupe the table contents in the journal file, and then write them down
-    // in the database.
-    rv = mMainConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
-        "UPDATE moz_places SET last_visit_date = "
-          "(SELECT MAX(visit_date) "
-           "FROM moz_historyvisits "
-           "WHERE place_id = moz_places.id)"));
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  return NS_OK;
-}
-
-
-nsresult
-Database::MigrateV10Up()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  // LastModified is set to the same value as dateAdded on item creation.
-  // This way we can use lastModified index to sort.
-  nsresult rv = mMainConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
-      "UPDATE moz_bookmarks SET lastModified = dateAdded "
-      "WHERE lastModified IS NULL"));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  return NS_OK;
-}
-
-
-nsresult
-Database::MigrateV11Up()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  // Temp tables are going away.
-  // For triggers correctness, every time we pass through this migration
-  // step, we must ensure correctness of visit_count values.
-  nsresult rv = mMainConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
-    "UPDATE moz_places SET visit_count = "
-      "(SELECT count(*) FROM moz_historyvisits "
-       "WHERE place_id = moz_places.id "
-        "AND visit_type NOT IN ") +
-          nsPrintfCString("(0,%d,%d,%d) ",
-                          nsINavHistoryService::TRANSITION_EMBED,
-                          nsINavHistoryService::TRANSITION_FRAMED_LINK,
-                          nsINavHistoryService::TRANSITION_DOWNLOAD) +
-      NS_LITERAL_CSTRING(")")
-  );
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // For existing profiles, we may not have a moz_bookmarks.guid column
-  nsCOMPtr<mozIStorageStatement> hasGuidStatement;
-  rv = mMainConn->CreateStatement(NS_LITERAL_CSTRING(
-      "SELECT guid FROM moz_bookmarks"),
-    getter_AddRefs(hasGuidStatement));
-
-  if (NS_FAILED(rv)) {
-    // moz_bookmarks grew a guid column.  Add the column, but do not populate it
-    // with anything just yet.  We will do that soon.
-    rv = mMainConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
-      "ALTER TABLE moz_bookmarks "
-      "ADD COLUMN guid TEXT"
-    ));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    rv = mMainConn->ExecuteSimpleSQL(CREATE_IDX_MOZ_BOOKMARKS_GUID);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    // moz_places grew a guid column. Add the column, but do not populate it
-    // with anything just yet. We will do that soon.
-    rv = mMainConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
-      "ALTER TABLE moz_places "
-      "ADD COLUMN guid TEXT"
-    ));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    rv = mMainConn->ExecuteSimpleSQL(CREATE_IDX_MOZ_PLACES_GUID);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  // We need to update our guids before we do any real database work.
-  rv = CheckAndUpdateGUIDs();
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  return NS_OK;
-}
-
-nsresult
 Database::MigrateV13Up()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   // Dynamic containers are no longer supported.
   nsCOMPtr<mozIStorageAsyncStatement> deleteDynContainersStmt;
   nsresult rv = mMainConn->CreateAsyncStatement(NS_LITERAL_CSTRING(
       "DELETE FROM moz_bookmarks WHERE type = :item_type"),
@@ -1956,16 +1408,70 @@ Database::MigrateV24Up()
   NS_ENSURE_SUCCESS(rv, rv);
   mozStorageStatementScoper updateScoper(updateStmt);
   rv = updateStmt->Execute();
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
+nsresult
+Database::MigrateV25Up()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  // Change bookmark roots GUIDs to constant values.
+
+  // If moz_bookmarks_roots doesn't exist anymore, it's because we finally have
+  // been able to remove it.  In such a case, we already assigned constant GUIDs
+  // to the roots and we can skip this migration.
+  {
+    nsCOMPtr<mozIStorageStatement> stmt;
+    nsresult rv = mMainConn->CreateStatement(NS_LITERAL_CSTRING(
+      "SELECT root_name FROM moz_bookmarks_roots"
+    ), getter_AddRefs(stmt));
+    if (NS_FAILED(rv)) {
+      return NS_OK;
+    }
+  }
+
+  nsCOMPtr<mozIStorageStatement> stmt;
+  nsresult rv = mMainConn->CreateStatement(NS_LITERAL_CSTRING(
+    "UPDATE moz_bookmarks SET guid = :guid "
+    "WHERE id = (SELECT folder_id FROM moz_bookmarks_roots WHERE root_name = :name) "
+  ), getter_AddRefs(stmt));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  const char *rootNames[] = { "places", "menu", "toolbar", "tags", "unfiled" };
+  const char *rootGuids[] = { "root________"
+                            , "menu________"
+                            , "toolbar_____"
+                            , "tags________"
+                            , "unfiled_____"
+                            };
+
+  for (uint32_t i = 0; i < ArrayLength(rootNames); ++i) {
+    // Since this is using the synchronous API, we cannot use
+    // a BindingParamsArray.
+    mozStorageStatementScoper scoper(stmt);
+
+    rv = stmt->BindUTF8StringByName(NS_LITERAL_CSTRING("name"),
+                                      nsDependentCString(rootNames[i]));
+    NS_ENSURE_SUCCESS(rv, rv);
+    rv = stmt->BindUTF8StringByName(NS_LITERAL_CSTRING("guid"),
+                                      nsDependentCString(rootGuids[i]));
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    rv = stmt->Execute();
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
+  return NS_OK;
+}
+
 void
 Database::Shutdown()
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!mShuttingDown);
   MOZ_ASSERT(!mClosed);
 
   mShuttingDown = true;
--- a/toolkit/components/places/Database.h
+++ b/toolkit/components/places/Database.h
@@ -11,17 +11,17 @@
 #include "nsIObserver.h"
 #include "mozilla/storage.h"
 #include "mozilla/storage/StatementCache.h"
 #include "mozilla/Attributes.h"
 #include "nsIEventTarget.h"
 
 // This is the schema version. Update it at any schema change and add a
 // corresponding migrateVxx method below.
-#define DATABASE_SCHEMA_VERSION 24
+#define DATABASE_SCHEMA_VERSION 25
 
 // Fired after Places inited.
 #define TOPIC_PLACES_INIT_COMPLETE "places-init-complete"
 // Fired when initialization fails due to a locked database.
 #define TOPIC_DATABASE_LOCKED "places-database-locked"
 // This topic is received when the profile is about to be lost.  Places does
 // initial shutdown work and notifies TOPIC_PLACES_SHUTDOWN to all listeners.
 // Any shutdown work that requires the Places APIs should happen here.
@@ -255,36 +255,31 @@ protected:
   /**
    * Initializes triggers defined in nsPlacesTriggers.h
    */  
   nsresult InitTempTriggers();
 
   /**
    * Helpers used by schema upgrades.
    */
-  nsresult MigrateV7Up();
-  nsresult MigrateV8Up();
-  nsresult MigrateV9Up();
-  nsresult MigrateV10Up();
-  nsresult MigrateV11Up();
   nsresult MigrateV13Up();
   nsresult MigrateV14Up();
   nsresult MigrateV15Up();
   nsresult MigrateV16Up();
   nsresult MigrateV17Up();
   nsresult MigrateV18Up();
   nsresult MigrateV19Up();
   nsresult MigrateV20Up();
   nsresult MigrateV21Up();
   nsresult MigrateV22Up();
   nsresult MigrateV23Up();
   nsresult MigrateV24Up();
+  nsresult MigrateV25Up();
 
   nsresult UpdateBookmarkRootTitles();
-  nsresult CheckAndUpdateGUIDs();
 
 private:
   ~Database();
 
   /**
    * Singleton getter, invoked by class instantiation.
    */
   static already_AddRefed<Database> GetSingleton();
--- a/toolkit/components/places/PlacesBackups.jsm
+++ b/toolkit/components/places/PlacesBackups.jsm
@@ -497,19 +497,18 @@ this.PlacesBackups = {
    *         * iconuri: favicon's url
    *         * keyword: associated keyword
    *         * charset: last known charset
    *         * tags: csv string of tags
    *         * root: string describing whether this represents a root
    *         * children: array of child items in a folder
    */
   getBookmarksTree: Task.async(function* () {
-    let rootGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.placesRootId);
     let startTime = Date.now();
-    let root = yield PlacesUtils.promiseBookmarksTree(rootGuid, {
+    let root = yield PlacesUtils.promiseBookmarksTree(PlacesUtils.bookmarks.rootGuid, {
       excludeItemsCallback: aItem => {
         return aItem.annos &&
           aItem.annos.find(a => a.name == PlacesUtils.EXCLUDE_FROM_BACKUP_ANNO);
       },
       includeItemIds: true
     });
 
     try {
--- a/toolkit/components/places/PlacesDBUtils.jsm
+++ b/toolkit/components/places/PlacesDBUtils.jsm
@@ -329,39 +329,43 @@ this.PlacesDBUtils = {
     let deleteOrphanAnnos = DBConn.createAsyncStatement(
       `DELETE FROM moz_annos WHERE id IN (
          SELECT id FROM moz_annos a
          WHERE NOT EXISTS
            (SELECT id FROM moz_places WHERE id = a.place_id LIMIT 1)
        )`);
     cleanupStatements.push(deleteOrphanAnnos);
 
-    // MOZ_BOOKMARKS_ROOTS
+    // Bookmarks roots
     // C.1 fix missing Places root
     //     Bug 477739 shows a case where the root could be wrongly removed
     //     due to an endianness issue.  We try to fix broken roots here.
     let selectPlacesRoot = DBConn.createStatement(
       "SELECT id FROM moz_bookmarks WHERE id = :places_root");
     selectPlacesRoot.params["places_root"] = PlacesUtils.placesRootId;
     if (!selectPlacesRoot.executeStep()) {
       // We are missing the root, try to recreate it.
       let createPlacesRoot = DBConn.createAsyncStatement(
         `INSERT INTO moz_bookmarks (id, type, fk, parent, position, title,
                                     guid)
-         VALUES (:places_root, 2, NULL, 0, 0, :title, GENERATE_GUID())`);
+         VALUES (:places_root, 2, NULL, 0, 0, :title, :guid)`);
       createPlacesRoot.params["places_root"] = PlacesUtils.placesRootId;
       createPlacesRoot.params["title"] = "";
+      createPlacesRoot.params["guid"] = PlacesUtils.bookmarks.rootGuid;
       cleanupStatements.push(createPlacesRoot);
 
       // Now ensure that other roots are children of Places root.
       let fixPlacesRootChildren = DBConn.createAsyncStatement(
-        `UPDATE moz_bookmarks SET parent = :places_root WHERE id IN
-           (SELECT folder_id FROM moz_bookmarks_roots
-             WHERE folder_id <> :places_root)`);
+        `UPDATE moz_bookmarks SET parent = :places_root WHERE guid IN
+           ( :menuGuid, :toolbarGuid, :unfiledGuid, :tagsGuid )`);
       fixPlacesRootChildren.params["places_root"] = PlacesUtils.placesRootId;
+      fixPlacesRootChildren.params["menuGuid"] = PlacesUtils.bookmarks.menuGuid;
+      fixPlacesRootChildren.params["toolbarGuid"] = PlacesUtils.bookmarks.toolbarGuid;
+      fixPlacesRootChildren.params["unfiledGuid"] = PlacesUtils.bookmarks.unfiledGuid;
+      fixPlacesRootChildren.params["tagsGuid"] = PlacesUtils.bookmarks.tagsGuid;
       cleanupStatements.push(fixPlacesRootChildren);
     }
     selectPlacesRoot.finalize();
 
     // C.2 fix roots titles
     //     some alpha version has wrong roots title, and this also fixes them if
     //     locale has changed.
     let updateRootTitleSql = `UPDATE moz_bookmarks SET title = :title
@@ -395,127 +399,166 @@ this.PlacesDBUtils = {
     fixTagsRootTitle.params["title"] =
       PlacesUtils.getString("TagsFolderTitle");
     cleanupStatements.push(fixTagsRootTitle);
 
     // MOZ_BOOKMARKS
     // D.1 remove items without a valid place
     // if fk IS NULL we fix them in D.7
     let deleteNoPlaceItems = DBConn.createAsyncStatement(
-      `DELETE FROM moz_bookmarks WHERE id NOT IN (
-         SELECT folder_id FROM moz_bookmarks_roots /* skip roots */
+      `DELETE FROM moz_bookmarks WHERE guid NOT IN (
+         :rootGuid, :menuGuid, :toolbarGuid, :unfiledGuid, :tagsGuid  /* skip roots */
        ) AND id IN (
          SELECT b.id FROM moz_bookmarks b
          WHERE fk NOT NULL AND b.type = :bookmark_type
            AND NOT EXISTS (SELECT url FROM moz_places WHERE id = b.fk LIMIT 1)
        )`);
     deleteNoPlaceItems.params["bookmark_type"] = PlacesUtils.bookmarks.TYPE_BOOKMARK;
+    deleteNoPlaceItems.params["rootGuid"] = PlacesUtils.bookmarks.rootGuid;
+    deleteNoPlaceItems.params["menuGuid"] = PlacesUtils.bookmarks.menuGuid;
+    deleteNoPlaceItems.params["toolbarGuid"] = PlacesUtils.bookmarks.toolbarGuid;
+    deleteNoPlaceItems.params["unfiledGuid"] = PlacesUtils.bookmarks.unfiledGuid;
+    deleteNoPlaceItems.params["tagsGuid"] = PlacesUtils.bookmarks.tagsGuid;
     cleanupStatements.push(deleteNoPlaceItems);
 
     // D.2 remove items that are not uri bookmarks from tag containers
     let deleteBogusTagChildren = DBConn.createAsyncStatement(
-      `DELETE FROM moz_bookmarks WHERE id NOT IN (
-         SELECT folder_id FROM moz_bookmarks_roots /* skip roots */
+      `DELETE FROM moz_bookmarks WHERE guid NOT IN (
+         :rootGuid, :menuGuid, :toolbarGuid, :unfiledGuid, :tagsGuid  /* skip roots */
        ) AND id IN (
          SELECT b.id FROM moz_bookmarks b
          WHERE b.parent IN
            (SELECT id FROM moz_bookmarks WHERE parent = :tags_folder)
            AND b.type <> :bookmark_type
        )`);
     deleteBogusTagChildren.params["tags_folder"] = PlacesUtils.tagsFolderId;
     deleteBogusTagChildren.params["bookmark_type"] = PlacesUtils.bookmarks.TYPE_BOOKMARK;
+    deleteBogusTagChildren.params["rootGuid"] = PlacesUtils.bookmarks.rootGuid;
+    deleteBogusTagChildren.params["menuGuid"] = PlacesUtils.bookmarks.menuGuid;
+    deleteBogusTagChildren.params["toolbarGuid"] = PlacesUtils.bookmarks.toolbarGuid;
+    deleteBogusTagChildren.params["unfiledGuid"] = PlacesUtils.bookmarks.unfiledGuid;
+    deleteBogusTagChildren.params["tagsGuid"] = PlacesUtils.bookmarks.tagsGuid;
     cleanupStatements.push(deleteBogusTagChildren);
 
     // D.3 remove empty tags
     let deleteEmptyTags = DBConn.createAsyncStatement(
-      `DELETE FROM moz_bookmarks WHERE id NOT IN (
-         SELECT folder_id FROM moz_bookmarks_roots /* skip roots */
+      `DELETE FROM moz_bookmarks WHERE guid NOT IN (
+         :rootGuid, :menuGuid, :toolbarGuid, :unfiledGuid, :tagsGuid  /* skip roots */
        ) AND id IN (
          SELECT b.id FROM moz_bookmarks b
          WHERE b.id IN
            (SELECT id FROM moz_bookmarks WHERE parent = :tags_folder)
            AND NOT EXISTS
              (SELECT id from moz_bookmarks WHERE parent = b.id LIMIT 1)
        )`);
     deleteEmptyTags.params["tags_folder"] = PlacesUtils.tagsFolderId;
+    deleteEmptyTags.params["rootGuid"] = PlacesUtils.bookmarks.rootGuid;
+    deleteEmptyTags.params["menuGuid"] = PlacesUtils.bookmarks.menuGuid;
+    deleteEmptyTags.params["toolbarGuid"] = PlacesUtils.bookmarks.toolbarGuid;
+    deleteEmptyTags.params["unfiledGuid"] = PlacesUtils.bookmarks.unfiledGuid;
+    deleteEmptyTags.params["tagsGuid"] = PlacesUtils.bookmarks.tagsGuid;
     cleanupStatements.push(deleteEmptyTags);
 
     // D.4 move orphan items to unsorted folder
     let fixOrphanItems = DBConn.createAsyncStatement(
-      `UPDATE moz_bookmarks SET parent = :unsorted_folder WHERE id NOT IN (
-         SELECT folder_id FROM moz_bookmarks_roots /* skip roots */
+      `UPDATE moz_bookmarks SET parent = :unsorted_folder WHERE guid NOT IN (
+         :rootGuid, :menuGuid, :toolbarGuid, :unfiledGuid, :tagsGuid  /* skip roots */
        ) AND id IN (
          SELECT b.id FROM moz_bookmarks b
-         WHERE b.parent <> 0 /* exclude Places root */
-         AND NOT EXISTS
+         WHERE NOT EXISTS
            (SELECT id FROM moz_bookmarks WHERE id = b.parent LIMIT 1)
        )`);
     fixOrphanItems.params["unsorted_folder"] = PlacesUtils.unfiledBookmarksFolderId;
+    fixOrphanItems.params["rootGuid"] = PlacesUtils.bookmarks.rootGuid;
+    fixOrphanItems.params["menuGuid"] = PlacesUtils.bookmarks.menuGuid;
+    fixOrphanItems.params["toolbarGuid"] = PlacesUtils.bookmarks.toolbarGuid;
+    fixOrphanItems.params["unfiledGuid"] = PlacesUtils.bookmarks.unfiledGuid;
+    fixOrphanItems.params["tagsGuid"] = PlacesUtils.bookmarks.tagsGuid;
     cleanupStatements.push(fixOrphanItems);
 
     // D.5 fix wrong keywords
     let fixInvalidKeywords = DBConn.createAsyncStatement(
-      `UPDATE moz_bookmarks SET keyword_id = NULL WHERE id NOT IN (
-         SELECT folder_id FROM moz_bookmarks_roots /* skip roots */
+      `UPDATE moz_bookmarks SET keyword_id = NULL WHERE guid NOT IN (
+         :rootGuid, :menuGuid, :toolbarGuid, :unfiledGuid, :tagsGuid  /* skip roots */
        ) AND id IN (
          SELECT id FROM moz_bookmarks b
          WHERE keyword_id NOT NULL
            AND NOT EXISTS
              (SELECT id FROM moz_keywords WHERE id = b.keyword_id LIMIT 1)
        )`);
+    fixInvalidKeywords.params["rootGuid"] = PlacesUtils.bookmarks.rootGuid;
+    fixInvalidKeywords.params["menuGuid"] = PlacesUtils.bookmarks.menuGuid;
+    fixInvalidKeywords.params["toolbarGuid"] = PlacesUtils.bookmarks.toolbarGuid;
+    fixInvalidKeywords.params["unfiledGuid"] = PlacesUtils.bookmarks.unfiledGuid;
+    fixInvalidKeywords.params["tagsGuid"] = PlacesUtils.bookmarks.tagsGuid;
     cleanupStatements.push(fixInvalidKeywords);
 
     // D.6 fix wrong item types
     //     Folders and separators should not have an fk.
     //     If they have a valid fk convert them to bookmarks. Later in D.9 we
     //     will move eventual children to unsorted bookmarks.
     let fixBookmarksAsFolders = DBConn.createAsyncStatement(
-      `UPDATE moz_bookmarks SET type = :bookmark_type WHERE id NOT IN (
-         SELECT folder_id FROM moz_bookmarks_roots /* skip roots */
+      `UPDATE moz_bookmarks SET type = :bookmark_type WHERE guid NOT IN (
+         :rootGuid, :menuGuid, :toolbarGuid, :unfiledGuid, :tagsGuid  /* skip roots */
        ) AND id IN (
          SELECT id FROM moz_bookmarks b
          WHERE type IN (:folder_type, :separator_type)
            AND fk NOTNULL
        )`);
     fixBookmarksAsFolders.params["bookmark_type"] = PlacesUtils.bookmarks.TYPE_BOOKMARK;
     fixBookmarksAsFolders.params["folder_type"] = PlacesUtils.bookmarks.TYPE_FOLDER;
     fixBookmarksAsFolders.params["separator_type"] = PlacesUtils.bookmarks.TYPE_SEPARATOR;
+    fixBookmarksAsFolders.params["rootGuid"] = PlacesUtils.bookmarks.rootGuid;
+    fixBookmarksAsFolders.params["menuGuid"] = PlacesUtils.bookmarks.menuGuid;
+    fixBookmarksAsFolders.params["toolbarGuid"] = PlacesUtils.bookmarks.toolbarGuid;
+    fixBookmarksAsFolders.params["unfiledGuid"] = PlacesUtils.bookmarks.unfiledGuid;
+    fixBookmarksAsFolders.params["tagsGuid"] = PlacesUtils.bookmarks.tagsGuid;
     cleanupStatements.push(fixBookmarksAsFolders);
 
     // D.7 fix wrong item types
     //     Bookmarks should have an fk, if they don't have any, convert them to
     //     folders.
     let fixFoldersAsBookmarks = DBConn.createAsyncStatement(
-      `UPDATE moz_bookmarks SET type = :folder_type WHERE id NOT IN (
-         SELECT folder_id FROM moz_bookmarks_roots /* skip roots */
+      `UPDATE moz_bookmarks SET type = :folder_type WHERE guid NOT IN (
+         :rootGuid, :menuGuid, :toolbarGuid, :unfiledGuid, :tagsGuid  /* skip roots */
        ) AND id IN (
          SELECT id FROM moz_bookmarks b
          WHERE type = :bookmark_type
            AND fk IS NULL
        )`);
     fixFoldersAsBookmarks.params["bookmark_type"] = PlacesUtils.bookmarks.TYPE_BOOKMARK;
     fixFoldersAsBookmarks.params["folder_type"] = PlacesUtils.bookmarks.TYPE_FOLDER;
+    fixFoldersAsBookmarks.params["rootGuid"] = PlacesUtils.bookmarks.rootGuid;
+    fixFoldersAsBookmarks.params["menuGuid"] = PlacesUtils.bookmarks.menuGuid;
+    fixFoldersAsBookmarks.params["toolbarGuid"] = PlacesUtils.bookmarks.toolbarGuid;
+    fixFoldersAsBookmarks.params["unfiledGuid"] = PlacesUtils.bookmarks.unfiledGuid;
+    fixFoldersAsBookmarks.params["tagsGuid"] = PlacesUtils.bookmarks.tagsGuid;
     cleanupStatements.push(fixFoldersAsBookmarks);
 
     // D.9 fix wrong parents
     //     Items cannot have separators or other bookmarks
     //     as parent, if they have bad parent move them to unsorted bookmarks.
     let fixInvalidParents = DBConn.createAsyncStatement(
-      `UPDATE moz_bookmarks SET parent = :unsorted_folder WHERE id NOT IN (
-         SELECT folder_id FROM moz_bookmarks_roots /* skip roots */
+      `UPDATE moz_bookmarks SET parent = :unsorted_folder WHERE guid NOT IN (
+         :rootGuid, :menuGuid, :toolbarGuid, :unfiledGuid, :tagsGuid  /* skip roots */
        ) AND id IN (
          SELECT id FROM moz_bookmarks b
          WHERE EXISTS
            (SELECT id FROM moz_bookmarks WHERE id = b.parent
              AND type IN (:bookmark_type, :separator_type)
              LIMIT 1)
        )`);
     fixInvalidParents.params["unsorted_folder"] = PlacesUtils.unfiledBookmarksFolderId;
     fixInvalidParents.params["bookmark_type"] = PlacesUtils.bookmarks.TYPE_BOOKMARK;
     fixInvalidParents.params["separator_type"] = PlacesUtils.bookmarks.TYPE_SEPARATOR;
+    fixInvalidParents.params["rootGuid"] = PlacesUtils.bookmarks.rootGuid;
+    fixInvalidParents.params["menuGuid"] = PlacesUtils.bookmarks.menuGuid;
+    fixInvalidParents.params["toolbarGuid"] = PlacesUtils.bookmarks.toolbarGuid;
+    fixInvalidParents.params["unfiledGuid"] = PlacesUtils.bookmarks.unfiledGuid;
+    fixInvalidParents.params["tagsGuid"] = PlacesUtils.bookmarks.tagsGuid;
     cleanupStatements.push(fixInvalidParents);
 
     // D.10 recalculate positions
     //      This requires multiple related statements.
     //      We can detect a folder with bad position values comparing the sum of
     //      all distinct position values (+1 since position is 0-based) with the
     //      triangular numbers obtained by the number of children (n).
     //      SUM(DISTINCT position + 1) == (n * (n + 1) / 2).
--- a/toolkit/components/places/PlacesTransactions.jsm
+++ b/toolkit/components/places/PlacesTransactions.jsm
@@ -1329,21 +1329,20 @@ PT.Tag.prototype = {
         let deferred = Promise.defer();
         PlacesUtils.asyncGetBookmarkIds(
           currentURI, ids => { deferred.resolve(ids.length > 0); });
         return deferred.promise;
       };
 
       if (yield promiseIsBookmarked(currentURI)) {
         // Tagging is only allowed for bookmarked URIs (but see 424160).
-        let unfiledGuid =
-          yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
         let createTxn = TransactionsHistory.getRawTransaction(
           PT.NewBookmark({ uri: currentURI
-                         , tags: aTags, parentGuid: unfiledGuid }));
+                         , tags: aTags
+                         , parentGuid: PlacesUtils.bookmarks.unfiledGuid }));
         yield createTxn.execute();
         onUndo.unshift(createTxn.undo.bind(createTxn));
         onRedo.push(createTxn.redo.bind(createTxn));
       }
       else {
         let currentTags = PlacesUtils.tagging.getTagsForURI(currentURI);
         let newTags = [t for (t of aTags) if (currentTags.indexOf(t) == -1)];
         PlacesUtils.tagging.tagURI(currentURI, newTags);
--- a/toolkit/components/places/PlacesUtils.jsm
+++ b/toolkit/components/places/PlacesUtils.jsm
@@ -1687,17 +1687,17 @@ this.PlacesUtils = {
        FROM descendants d
        LEFT JOIN moz_bookmarks b3 ON b3.id = d.parent
        LEFT JOIN moz_places h ON h.id = d.fk
        LEFT JOIN moz_favicons f ON f.id = h.favicon_id
        ORDER BY d.level, d.parent, d.position`;
 
 
     if (!aItemGuid)
-      aItemGuid = yield this.promiseItemGuid(PlacesUtils.placesRootId);
+      aItemGuid = this.bookmarks.rootGuid;
 
     let hasExcludeItemsCallback =
       aOptions.hasOwnProperty("excludeItemsCallback");
     let excludedParents = new Set();
     let shouldExcludeItem = (aItem, aParentGuid) => {
       let exclude = excludedParents.has(aParentGuid) ||
                     aOptions.excludeItemsCallback(aItem);
       if (exclude) {
--- a/toolkit/components/places/nsNavBookmarks.cpp
+++ b/toolkit/components/places/nsNavBookmarks.cpp
@@ -272,44 +272,45 @@ nsNavBookmarks::Init()
   return NS_OK;
 }
 
 nsresult
 nsNavBookmarks::ReadRoots()
 {
   nsCOMPtr<mozIStorageStatement> stmt;
   nsresult rv = mDB->MainConn()->CreateStatement(NS_LITERAL_CSTRING(
-    "SELECT root_name, folder_id FROM moz_bookmarks_roots"
+    "SELECT guid, id FROM moz_bookmarks WHERE guid IN ( "
+      "'root________', 'menu________', 'toolbar_____', "
+      "'tags________', 'unfiled_____' )"
   ), getter_AddRefs(stmt));
   NS_ENSURE_SUCCESS(rv, rv);
 
   bool hasResult;
   while (NS_SUCCEEDED(stmt->ExecuteStep(&hasResult)) && hasResult) {
-    nsAutoCString rootName;
-    rv = stmt->GetUTF8String(0, rootName);
+    nsAutoCString guid;
+    rv = stmt->GetUTF8String(0, guid);
     NS_ENSURE_SUCCESS(rv, rv);
-    int64_t rootId;
-    rv = stmt->GetInt64(1, &rootId);
+    int64_t id;
+    rv = stmt->GetInt64(1, &id);
     NS_ENSURE_SUCCESS(rv, rv);
-    NS_ABORT_IF_FALSE(rootId != 0, "Root id is 0, that is an invalid value.");
-
-    if (rootName.EqualsLiteral("places")) {
-      mRoot = rootId;
+
+    if (guid.EqualsLiteral("root________")) {
+      mRoot = id;
     }
-    else if (rootName.EqualsLiteral("menu")) {
-      mMenuRoot = rootId;
+    else if (guid.EqualsLiteral("menu________")) {
+      mMenuRoot = id;
     }
-    else if (rootName.EqualsLiteral("toolbar")) {
-      mToolbarRoot = rootId;
+    else if (guid.EqualsLiteral("toolbar_____")) {
+      mToolbarRoot = id;
     }
-    else if (rootName.EqualsLiteral("tags")) {
-      mTagsRoot = rootId;
+    else if (guid.EqualsLiteral("tags________")) {
+      mTagsRoot = id;
     }
-    else if (rootName.EqualsLiteral("unfiled")) {
-      mUnfiledRoot = rootId;
+    else if (guid.EqualsLiteral("unfiled_____")) {
+      mUnfiledRoot = id;
     }
   }
 
   if (!mRoot || !mMenuRoot || !mToolbarRoot || !mTagsRoot || !mUnfiledRoot)
     return NS_ERROR_FAILURE;
 
   return NS_OK;
 }
--- a/toolkit/components/places/tests/bookmarks/test_bookmarks_eraseEverything.js
+++ b/toolkit/components/places/tests/bookmarks/test_bookmarks_eraseEverything.js
@@ -3,55 +3,52 @@
 
 add_task(function* test_eraseEverything() {
   yield promiseAddVisits({ uri: NetUtil.newURI("http://example.com/") });
   yield promiseAddVisits({ uri: NetUtil.newURI("http://mozilla.org/") });
   let frecencyForExample = frecencyForUrl("http://example.com/");
   let frecencyForMozilla = frecencyForUrl("http://example.com/");
   Assert.ok(frecencyForExample > 0);
   Assert.ok(frecencyForMozilla > 0);
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
-  let unfiledFolder = yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledGuid,
+  let unfiledFolder = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                            type: PlacesUtils.bookmarks.TYPE_FOLDER });
   checkBookmarkObject(unfiledFolder);
-  let unfiledBookmark = yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledGuid,
+  let unfiledBookmark = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                              type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
                                                              url: "http://example.com/",
                                                              keyword: "kw1" });
   checkBookmarkObject(unfiledBookmark);
   let unfiledBookmarkInFolder =
     yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledFolder.guid,
                                          type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
                                          url: "http://mozilla.org/" });
   checkBookmarkObject(unfiledBookmarkInFolder);
   PlacesUtils.annotations.setItemAnnotation((yield PlacesUtils.promiseItemId(unfiledBookmarkInFolder.guid)),
                                             "testanno1", "testvalue1", 0, 0);
 
-  let menuGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.bookmarksMenuFolderId);
-  let menuFolder = yield PlacesUtils.bookmarks.insert({ parentGuid: menuGuid,
+  let menuFolder = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.menuGuid,
                                                         type: PlacesUtils.bookmarks.TYPE_FOLDER });
   checkBookmarkObject(menuFolder);
-  let menuBookmark = yield PlacesUtils.bookmarks.insert({ parentGuid: menuGuid,
+  let menuBookmark = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.menuGuid,
                                                           type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
                                                           url: "http://example.com/",
                                                           keyword: "kw2" });
   checkBookmarkObject(unfiledBookmark);
   let menuBookmarkInFolder =
     yield PlacesUtils.bookmarks.insert({ parentGuid: menuFolder.guid,
                                          type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
                                          url: "http://mozilla.org/" });
   checkBookmarkObject(menuBookmarkInFolder);
   PlacesUtils.annotations.setItemAnnotation((yield PlacesUtils.promiseItemId(menuBookmarkInFolder.guid)),
                                             "testanno1", "testvalue1", 0, 0);
 
-  let toolbarGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.toolbarFolderId);
-  let toolbarFolder = yield PlacesUtils.bookmarks.insert({ parentGuid: toolbarGuid,
+  let toolbarFolder = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.toolbarGuid,
                                                            type: PlacesUtils.bookmarks.TYPE_FOLDER });
   checkBookmarkObject(toolbarFolder);
-  let toolbarBookmark = yield PlacesUtils.bookmarks.insert({ parentGuid: toolbarGuid,
+  let toolbarBookmark = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.toolbarGuid,
                                                              type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
                                                              url: "http://example.com/",
                                                              keyword: "kw3" });
   checkBookmarkObject(toolbarBookmark);
   let toolbarBookmarkInFolder =
     yield PlacesUtils.bookmarks.insert({ parentGuid: toolbarFolder.guid,
                                          type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
                                          url: "http://mozilla.org/" });
@@ -77,23 +74,18 @@ add_task(function* test_eraseEverything(
   rows = yield conn.execute(`SELECT * FROM moz_anno_attributes`);
   Assert.equal(rows.length, 0);
 });
 
 add_task(function* test_eraseEverything_roots() {
   yield PlacesUtils.bookmarks.eraseEverything();
 
   // Ensure the roots have not been removed.
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
-  Assert.ok(yield PlacesUtils.bookmarks.fetch(unfiledGuid));
-  let toolbarGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.toolbarFolderId);
-  Assert.ok(yield PlacesUtils.bookmarks.fetch(toolbarGuid));
-  let menuGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.bookmarksMenuFolderId);
-  Assert.ok(yield PlacesUtils.bookmarks.fetch(menuGuid));
-  let tagsGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.tagsFolderId);
-  Assert.ok(yield PlacesUtils.bookmarks.fetch(tagsGuid));
-  let rootGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.placesRootId);
-  Assert.ok(yield PlacesUtils.bookmarks.fetch(rootGuid));
+  Assert.ok(yield PlacesUtils.bookmarks.fetch(PlacesUtils.bookmarks.unfiledGuid));
+  Assert.ok(yield PlacesUtils.bookmarks.fetch(PlacesUtils.bookmarks.toolbarGuid));
+  Assert.ok(yield PlacesUtils.bookmarks.fetch(PlacesUtils.bookmarks.menuGuid));
+  Assert.ok(yield PlacesUtils.bookmarks.fetch(PlacesUtils.bookmarks.tagsGuid));
+  Assert.ok(yield PlacesUtils.bookmarks.fetch(PlacesUtils.bookmarks.rootGuid));
 });
 
 function run_test() {
   run_next_test();
 }
--- a/toolkit/components/places/tests/bookmarks/test_bookmarks_fetch.js
+++ b/toolkit/components/places/tests/bookmarks/test_bookmarks_fetch.js
@@ -95,45 +95,43 @@ add_task(function* invalid_input_throws(
 add_task(function* fetch_nonexistent_guid() {
   let bm = yield PlacesUtils.bookmarks.fetch({ guid: "123456789012" },
                                                gAccumulator.callback);
   Assert.equal(bm, null);
   Assert.equal(gAccumulator.results.length, 0);
 });
 
 add_task(function* fetch_bookmark() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
-  let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledGuid,
+  let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                  type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
                                                  url: "http://example.com/",
                                                  title: "a bookmark" });
   checkBookmarkObject(bm1);
 
   let bm2 = yield PlacesUtils.bookmarks.fetch(bm1.guid,
                                               gAccumulator.callback);
   checkBookmarkObject(bm2);
   Assert.equal(gAccumulator.results.length, 1);
   checkBookmarkObject(gAccumulator.results[0]);
   Assert.deepEqual(gAccumulator.results[0], bm1);
 
   Assert.deepEqual(bm1, bm2);
-  Assert.equal(bm2.parentGuid, unfiledGuid);
+  Assert.equal(bm2.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
   Assert.equal(bm2.index, 0);
   Assert.deepEqual(bm2.dateAdded, bm2.lastModified);
   Assert.equal(bm2.type, PlacesUtils.bookmarks.TYPE_BOOKMARK);
   Assert.equal(bm2.url.href, "http://example.com/");
   Assert.equal(bm2.title, "a bookmark");
   Assert.ok(!("keyword" in bm2));
 
   yield PlacesUtils.bookmarks.remove(bm1.guid);
 });
 
 add_task(function* fetch_bookmar_empty_title() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
-  let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledGuid,
+  let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                  type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
                                                  url: "http://example.com/",
                                                  title: "" });
   checkBookmarkObject(bm1);
 
   let bm2 = yield PlacesUtils.bookmarks.fetch(bm1.guid);
   checkBookmarkObject(bm2);
 
@@ -141,66 +139,62 @@ add_task(function* fetch_bookmar_empty_t
   Assert.equal(bm2.index, 0);
   Assert.ok(!("title" in bm2));
   Assert.ok(!("keyword" in bm2));
 
   yield PlacesUtils.bookmarks.remove(bm1.guid);
 });
 
 add_task(function* fetch_folder() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
-  let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledGuid,
+  let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                  type: PlacesUtils.bookmarks.TYPE_FOLDER,
                                                  title: "a folder" });
   checkBookmarkObject(bm1);
 
   let bm2 = yield PlacesUtils.bookmarks.fetch(bm1.guid);
   checkBookmarkObject(bm2);
 
   Assert.deepEqual(bm1, bm2);
-  Assert.equal(bm2.parentGuid, unfiledGuid);
+  Assert.equal(bm2.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
   Assert.equal(bm2.index, 0);
   Assert.deepEqual(bm2.dateAdded, bm2.lastModified);
   Assert.equal(bm2.type, PlacesUtils.bookmarks.TYPE_FOLDER);
   Assert.equal(bm2.title, "a folder");
   Assert.ok(!("url" in bm2));
   Assert.ok(!("keyword" in bm2));
 
   yield PlacesUtils.bookmarks.remove(bm1.guid);
 });
 
 add_task(function* fetch_folder_empty_title() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
-  let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledGuid,
+  let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                  type: PlacesUtils.bookmarks.TYPE_FOLDER,
                                                  title: "" });
   checkBookmarkObject(bm1);
 
   let bm2 = yield PlacesUtils.bookmarks.fetch(bm1.guid);
   checkBookmarkObject(bm2);
 
   Assert.deepEqual(bm1, bm2);
   Assert.equal(bm2.index, 0);
   Assert.ok(!("title" in bm2));
 
   yield PlacesUtils.bookmarks.remove(bm1.guid);
 });
 
 add_task(function* fetch_separator() {
- 
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
-  let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledGuid,
+  let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                  type: PlacesUtils.bookmarks.TYPE_SEPARATOR });
   checkBookmarkObject(bm1);
 
   let bm2 = yield PlacesUtils.bookmarks.fetch(bm1.guid);
   checkBookmarkObject(bm2);
 
   Assert.deepEqual(bm1, bm2);
-  Assert.equal(bm2.parentGuid, unfiledGuid);
+  Assert.equal(bm2.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
   Assert.equal(bm2.index, 0);
   Assert.deepEqual(bm2.dateAdded, bm2.lastModified);
   Assert.equal(bm2.type, PlacesUtils.bookmarks.TYPE_SEPARATOR);
   Assert.ok(!("url" in bm2));
   Assert.ok(!("title" in bm2));
   Assert.ok(!("keyword" in bm2));
 
   yield PlacesUtils.bookmarks.remove(bm1.guid);  
@@ -210,81 +204,78 @@ add_task(function* fetch_byposition_none
   let bm = yield PlacesUtils.bookmarks.fetch({ parentGuid: "123456789012",
                                                index: 0 },
                                              gAccumulator.callback);
   Assert.equal(bm, null);
   Assert.equal(gAccumulator.results.length, 0);
 });
 
 add_task(function* fetch_byposition_nonexisting_index() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
-  let bm = yield PlacesUtils.bookmarks.fetch({ parentGuid: unfiledGuid,
+  let bm = yield PlacesUtils.bookmarks.fetch({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                index: 100 },
                                              gAccumulator.callback);
   Assert.equal(bm, null);
   Assert.equal(gAccumulator.results.length, 0);
 });
 
 add_task(function* fetch_byposition() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
-  let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledGuid,
+  let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                  type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
                                                  url: "http://example.com/",
                                                  title: "a bookmark" });
   checkBookmarkObject(bm1);
 
   let bm2 = yield PlacesUtils.bookmarks.fetch({ parentGuid: bm1.parentGuid,
                                                 index: bm1.index },
                                               gAccumulator.callback);
   checkBookmarkObject(bm2);
   Assert.equal(gAccumulator.results.length, 1);
   checkBookmarkObject(gAccumulator.results[0]);
   Assert.deepEqual(gAccumulator.results[0], bm1);
 
   Assert.deepEqual(bm1, bm2);
-  Assert.equal(bm2.parentGuid, unfiledGuid);
+  Assert.equal(bm2.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
   Assert.equal(bm2.index, 0);
   Assert.deepEqual(bm2.dateAdded, bm2.lastModified);
   Assert.equal(bm2.type, PlacesUtils.bookmarks.TYPE_BOOKMARK);
   Assert.equal(bm2.url.href, "http://example.com/");
   Assert.equal(bm2.title, "a bookmark");
   Assert.ok(!("keyword" in bm2));
 });
 
 add_task(function* fetch_byurl_nonexisting() {
   let bm = yield PlacesUtils.bookmarks.fetch({ url: "http://nonexisting.com/" },
                                              gAccumulator.callback);
   Assert.equal(bm, null);
   Assert.equal(gAccumulator.results.length, 0);
 });
 
 add_task(function* fetch_byurl() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
-  let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledGuid,
+  let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                  type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
                                                  url: "http://byurl.com/",
                                                  title: "a bookmark" });
   checkBookmarkObject(bm1);
 
   let bm2 = yield PlacesUtils.bookmarks.fetch({ url: bm1.url },
                                               gAccumulator.callback);
   checkBookmarkObject(bm2);
   Assert.equal(gAccumulator.results.length, 1);
   checkBookmarkObject(gAccumulator.results[0]);
   Assert.deepEqual(gAccumulator.results[0], bm1);
 
   Assert.deepEqual(bm1, bm2);
-  Assert.equal(bm2.parentGuid, unfiledGuid);
+  Assert.equal(bm2.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
   Assert.deepEqual(bm2.dateAdded, bm2.lastModified);
   Assert.equal(bm2.type, PlacesUtils.bookmarks.TYPE_BOOKMARK);
   Assert.equal(bm2.url.href, "http://byurl.com/");
   Assert.equal(bm2.title, "a bookmark");
   Assert.ok(!("keyword" in bm2));
 
-  let bm3 = yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledGuid,
+  let bm3 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                  type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
                                                  url: "http://byurl.com/",
                                                  title: "a bookmark" });
   let bm4 = yield PlacesUtils.bookmarks.fetch({ url: bm1.url },
                                               gAccumulator.callback);
   checkBookmarkObject(bm4);
   Assert.deepEqual(bm3, bm4);
   Assert.equal(gAccumulator.results.length, 2);
@@ -307,38 +298,37 @@ add_task(function* fetch_byurl() {
 add_task(function* fetch_bykeyword_nonexisting() {
   let bm = yield PlacesUtils.bookmarks.fetch({ keyword: "nonexisting" },
                                              gAccumulator.callback);
   Assert.equal(bm, null);
   Assert.equal(gAccumulator.results.length, 0);
 });
 
 add_task(function* fetch_bykeyword() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
-  let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledGuid,
+  let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                  type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
                                                  url: "http://bykeyword1.com/",
                                                  keyword: "bykeyword" });
   checkBookmarkObject(bm1);
 
   let bm2 = yield PlacesUtils.bookmarks.fetch({ keyword: "bykeyword" },
                                               gAccumulator.callback);
   checkBookmarkObject(bm2);
   Assert.equal(gAccumulator.results.length, 1);
   checkBookmarkObject(gAccumulator.results[0]);
   Assert.deepEqual(gAccumulator.results[0], bm1);
 
   Assert.deepEqual(bm1, bm2);
-  Assert.equal(bm2.parentGuid, unfiledGuid);
+  Assert.equal(bm2.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
   Assert.deepEqual(bm2.dateAdded, bm2.lastModified);
   Assert.equal(bm2.type, PlacesUtils.bookmarks.TYPE_BOOKMARK);
   Assert.equal(bm2.url.href, "http://bykeyword1.com/");
   Assert.equal(bm2.keyword, "bykeyword");
 
-  let bm3 = yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledGuid,
+  let bm3 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                  type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
                                                  url: "http://bykeyword2.com/",
                                                  keyword: "bykeyword" });
   let bm4 = yield PlacesUtils.bookmarks.fetch({ keyword: "bykeyword" },
                                               gAccumulator.callback);
   checkBookmarkObject(bm4);
   Assert.deepEqual(bm3, bm4);
   Assert.equal(gAccumulator.results.length, 2);
--- a/toolkit/components/places/tests/bookmarks/test_bookmarks_insert.js
+++ b/toolkit/components/places/tests/bookmarks/test_bookmarks_insert.js
@@ -110,115 +110,108 @@ add_task(function* invalid_properties_fo
                 /Invalid value for property 'keyword'/);
 });
 
 add_task(function* long_title_trim() {
   let longtitle = "a";
   for (let i = 0; i < 4096; i++) {
     longtitle += "a";
   }
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
-  let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledGuid,
+  let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                 type: PlacesUtils.bookmarks.TYPE_FOLDER,
                                                 title: longtitle });
   checkBookmarkObject(bm);
-  Assert.equal(bm.parentGuid, unfiledGuid);
+  Assert.equal(bm.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
   Assert.equal(bm.index, 0);
   Assert.equal(bm.dateAdded, bm.lastModified);
   Assert.equal(bm.type, PlacesUtils.bookmarks.TYPE_FOLDER);
   Assert.equal(bm.title.length, 4096, "title should have been trimmed");
   Assert.ok(!("url" in bm), "url should not be set");
   Assert.ok(!("keyword" in bm), "keyword should not be set");
 });
 
 add_task(function* create_separator() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
-  let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledGuid,
+  let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                 type: PlacesUtils.bookmarks.TYPE_SEPARATOR,
                                                 index: PlacesUtils.bookmarks.DEFAULT_INDEX });
   checkBookmarkObject(bm);
-  Assert.equal(bm.parentGuid, unfiledGuid);
+  Assert.equal(bm.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
   Assert.equal(bm.index, 1);
   Assert.equal(bm.dateAdded, bm.lastModified);
   Assert.equal(bm.type, PlacesUtils.bookmarks.TYPE_SEPARATOR);
   Assert.ok(!("title" in bm), "title should not be set");
 });
 
 add_task(function* create_separator_w_title_fail() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
   try {
-    yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledGuid,
+    yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                          type: PlacesUtils.bookmarks.TYPE_SEPARATOR,
                                          title: "a separator" });
     Assert.ok(false, "Trying to set title for a separator should reject");
   } catch (ex) {}
 });
 
 add_task(function* create_separator_invalid_parent_fail() {
   try {
     yield PlacesUtils.bookmarks.insert({ parentGuid: "123456789012",
                                          type: PlacesUtils.bookmarks.TYPE_SEPARATOR,
                                          title: "a separator" });
     Assert.ok(false, "Trying to create an item in a non existing parent reject");
   } catch (ex) {}
 });
 
 add_task(function* create_separator_given_guid() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
-  let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledGuid,
+  let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                 type: PlacesUtils.bookmarks.TYPE_SEPARATOR,
                                                 index: PlacesUtils.bookmarks.DEFAULT_INDEX,
                                                 guid: "123456789012" });
   checkBookmarkObject(bm);
   Assert.equal(bm.guid, "123456789012");
-  Assert.equal(bm.parentGuid, unfiledGuid);
+  Assert.equal(bm.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
   Assert.equal(bm.index, 2);
   Assert.equal(bm.dateAdded, bm.lastModified);
   Assert.equal(bm.type, PlacesUtils.bookmarks.TYPE_SEPARATOR);
   Assert.ok(!("title" in bm), "title should not be set");
 });
 
 add_task(function* create_item_given_guid_no_type_fail() {
   try {
     yield PlacesUtils.bookmarks.insert({ parentGuid: "123456789012" });
     Assert.ok(false, "Trying to create an item with a given guid but no type should reject");
   } catch (ex) {}
 });
 
 add_task(function* create_separator_big_index() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
-  let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledGuid,
+  let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                 type: PlacesUtils.bookmarks.TYPE_SEPARATOR,
                                                 index: 9999 });
   checkBookmarkObject(bm);
-  Assert.equal(bm.parentGuid, unfiledGuid);
+  Assert.equal(bm.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
   Assert.equal(bm.index, 3);
   Assert.equal(bm.dateAdded, bm.lastModified);
   Assert.equal(bm.type, PlacesUtils.bookmarks.TYPE_SEPARATOR);
   Assert.ok(!("title" in bm), "title should not be set");
 });
 
 add_task(function* create_separator_given_dateAdded() {
   let time = new Date();
   let past = new Date(time - 86400000);
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
-  let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledGuid,
+  let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                 type: PlacesUtils.bookmarks.TYPE_SEPARATOR,
                                                 dateAdded: past });
   checkBookmarkObject(bm);
   Assert.equal(bm.dateAdded, past);
   Assert.equal(bm.lastModified, past);
 });
 
 add_task(function* create_folder() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
-  let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledGuid,
+  let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                 type: PlacesUtils.bookmarks.TYPE_FOLDER });
   checkBookmarkObject(bm);
-  Assert.equal(bm.parentGuid, unfiledGuid);
+  Assert.equal(bm.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
   Assert.equal(bm.dateAdded, bm.lastModified);
   Assert.equal(bm.type, PlacesUtils.bookmarks.TYPE_FOLDER);
   Assert.ok(!("title" in bm), "title should not be set");
 
   // And then create a nested folder.
   let parentGuid = bm.guid;
   bm = yield PlacesUtils.bookmarks.insert({ parentGuid: parentGuid,
                                             type: PlacesUtils.bookmarks.TYPE_FOLDER,
@@ -226,18 +219,17 @@ add_task(function* create_folder() {
   checkBookmarkObject(bm);
   Assert.equal(bm.parentGuid, parentGuid);
   Assert.equal(bm.index, 0);
   Assert.equal(bm.type, PlacesUtils.bookmarks.TYPE_FOLDER);
   Assert.strictEqual(bm.title, "a folder");
 });
 
 add_task(function* create_bookmark() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
-  let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledGuid,
+  let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                 type: PlacesUtils.bookmarks.TYPE_FOLDER });
   let parentGuid = bm.guid;
 
   bm = yield PlacesUtils.bookmarks.insert({ parentGuid: parentGuid,
                                             type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
                                             url: "http://example.com/",
                                             title: "a bookmark" });
   checkBookmarkObject(bm);
@@ -273,18 +265,17 @@ add_task(function* create_bookmark() {
   Assert.equal(bm.parentGuid, parentGuid);
   Assert.equal(bm.index, 2);
   Assert.equal(bm.type, PlacesUtils.bookmarks.TYPE_BOOKMARK);
   Assert.equal(bm.url.href, "http://example.com/");
   Assert.ok(!("title" in bm), "title should not be set");
 });
 
 add_task(function* create_bookmark_frecency() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
-  let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledGuid,
+  let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                 type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
                                                 url: "http://example.com/",
                                                 title: "a bookmark" });
   checkBookmarkObject(bm);
 
   yield promiseAsyncUpdates();
   Assert.ok(frecencyForUrl(bm.url) > 0, "Check frecency has been updated")
 });
--- a/toolkit/components/places/tests/bookmarks/test_bookmarks_notifications.js
+++ b/toolkit/components/places/tests/bookmarks/test_bookmarks_notifications.js
@@ -1,116 +1,108 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 add_task(function* insert_separator_notification() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
   let observer = expectNotifications();
   let bm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_SEPARATOR,
-                                                parentGuid: unfiledGuid});
+                                                parentGuid: PlacesUtils.bookmarks.unfiledGuid});
   let itemId = yield PlacesUtils.promiseItemId(bm.guid);
   let parentId = yield PlacesUtils.promiseItemId(bm.parentGuid);
   observer.check([ { name: "onItemAdded",
                      arguments: [ itemId, parentId, bm.index, bm.type,
                                   null, null, bm.dateAdded,
                                   bm.guid, bm.parentGuid ] }
                  ]);
 });
 
 add_task(function* insert_folder_notification() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
   let observer = expectNotifications();
   let bm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_FOLDER,
-                                                parentGuid: unfiledGuid,
+                                                parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                 title: "a folder" });
   let itemId = yield PlacesUtils.promiseItemId(bm.guid);
   let parentId = yield PlacesUtils.promiseItemId(bm.parentGuid);
   observer.check([ { name: "onItemAdded",
                      arguments: [ itemId, parentId, bm.index, bm.type,
                                   null, bm.title, bm.dateAdded,
                                   bm.guid, bm.parentGuid ] }
                  ]);
 });
 
 add_task(function* insert_folder_notitle_notification() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
   let observer = expectNotifications();
   let bm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_FOLDER,
-                                                parentGuid: unfiledGuid });
+                                                parentGuid: PlacesUtils.bookmarks.unfiledGuid });
   let itemId = yield PlacesUtils.promiseItemId(bm.guid);
   let parentId = yield PlacesUtils.promiseItemId(bm.parentGuid);
   observer.check([ { name: "onItemAdded",
                      arguments: [ itemId, parentId, bm.index, bm.type,
                                   null, null, bm.dateAdded,
                                   bm.guid, bm.parentGuid ] }
                  ]);
 });
 
 add_task(function* insert_bookmark_notification() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
   let observer = expectNotifications();
   let bm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
-                                                parentGuid: unfiledGuid,
+                                                parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                 url: new URL("http://example.com/"),
                                                 title: "a bookmark" });
   let itemId = yield PlacesUtils.promiseItemId(bm.guid);
   let parentId = yield PlacesUtils.promiseItemId(bm.parentGuid);
   observer.check([ { name: "onItemAdded",
                      arguments: [ itemId, parentId, bm.index, bm.type,
                                   bm.url, bm.title, bm.dateAdded,
                                   bm.guid, bm.parentGuid ] }
                  ]);
 });
 
 add_task(function* insert_bookmark_notitle_notification() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
   let observer = expectNotifications();
   let bm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
-                                                parentGuid: unfiledGuid,
+                                                parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                 url: new URL("http://example.com/") });
   let itemId = yield PlacesUtils.promiseItemId(bm.guid);
   let parentId = yield PlacesUtils.promiseItemId(bm.parentGuid);
   observer.check([ { name: "onItemAdded",
                      arguments: [ itemId, parentId, bm.index, bm.type,
                                   bm.url, null, bm.dateAdded,
                                   bm.guid, bm.parentGuid ] }
                  ]);
 });
 
 add_task(function* insert_bookmark_keyword_notification() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
   let observer = expectNotifications();
   let bm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
-                                                parentGuid: unfiledGuid,
+                                                parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                 url: new URL("http://example.com/"),
                                                 keyword: "kw" });
   let itemId = yield PlacesUtils.promiseItemId(bm.guid);
   let parentId = yield PlacesUtils.promiseItemId(bm.parentGuid);
   observer.check([ { name: "onItemAdded",
                      arguments: [ itemId, parentId, bm.index, bm.type,
                                   bm.url, null, bm.dateAdded,
                                   bm.guid, bm.parentGuid ] },
                    { name: "onItemChanged",
                      arguments: [ itemId, "keyword", false, bm.keyword,
                                   bm.lastModified, bm.type, parentId,
                                   bm.guid, bm.parentGuid ] }
                  ]);
 });
 
 add_task(function* insert_bookmark_tag_notification() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
   let bm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
-                                                parentGuid: unfiledGuid,
+                                                parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                 url: new URL("http://tag.example.com/") });
   let itemId = yield PlacesUtils.promiseItemId(bm.guid);
   let parentId = yield PlacesUtils.promiseItemId(bm.parentGuid);
 
-  let tagsGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.tagsFolderId);
   let tagFolder = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_FOLDER,
-                                                       parentGuid: tagsGuid,
+                                                       parentGuid: PlacesUtils.bookmarks.tagsGuid,
                                                        title: "tag" });
   let observer = expectNotifications();
   let tag = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
                                                  parentGuid: tagFolder.guid,
                                                  url: new URL("http://tag.example.com/") });
   let tagId = yield PlacesUtils.promiseItemId(tag.guid);
   let tagParentId = yield PlacesUtils.promiseItemId(tag.parentGuid);
 
@@ -125,131 +117,123 @@ add_task(function* insert_bookmark_tag_n
                    { name: "onItemChanged",
                      arguments: [ itemId, "tags", false, "",
                                   bm.lastModified, bm.type, parentId,
                                   bm.guid, bm.parentGuid ] }
                  ]);
 });
 
 add_task(function* update_bookmark_lastModified() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
   let bm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
-                                                parentGuid: unfiledGuid,
+                                                parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                 url: new URL("http://lastmod.example.com/") });
   let observer = expectNotifications();
   bm = yield PlacesUtils.bookmarks.update({ guid: bm.guid,
                                             lastModified: new Date() });
   let itemId = yield PlacesUtils.promiseItemId(bm.guid);
   let parentId = yield PlacesUtils.promiseItemId(bm.parentGuid);
 
   observer.check([ { name: "onItemChanged",
                      arguments: [ itemId, "lastModified", false,
                                   `${bm.lastModified * 1000}`, bm.lastModified,
                                   bm.type, parentId, bm.guid, bm.parentGuid ] }
                  ]);
 });
 
 add_task(function* update_bookmark_title() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
   let bm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
-                                                parentGuid: unfiledGuid,
+                                                parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                 url: new URL("http://title.example.com/") });
   let observer = expectNotifications();
   bm = yield PlacesUtils.bookmarks.update({ guid: bm.guid,
                                             title: "new title" });
   let itemId = yield PlacesUtils.promiseItemId(bm.guid);
   let parentId = yield PlacesUtils.promiseItemId(bm.parentGuid);
 
   observer.check([ { name: "onItemChanged",
                      arguments: [ itemId, "title", false, bm.title,
                                   bm.lastModified, bm.type, parentId, bm.guid,
                                   bm.parentGuid ] }
                  ]);
 });
 
 add_task(function* update_bookmark_uri() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
   let bm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
-                                                parentGuid: unfiledGuid,
+                                                parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                 url: new URL("http://url.example.com/") });
   let observer = expectNotifications();
   bm = yield PlacesUtils.bookmarks.update({ guid: bm.guid,
                                             url: "http://mozilla.org/" });
   let itemId = yield PlacesUtils.promiseItemId(bm.guid);
   let parentId = yield PlacesUtils.promiseItemId(bm.parentGuid);
 
   observer.check([ { name: "onItemChanged",
                      arguments: [ itemId, "uri", false, bm.url.href,
                                   bm.lastModified, bm.type, parentId, bm.guid,
                                   bm.parentGuid ] }
                  ]);
 });
 
 add_task(function* update_bookmark_keyword() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
   let bm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
-                                                parentGuid: unfiledGuid,
+                                                parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                 url: new URL("http://keyword.example.com/") });
   let observer = expectNotifications();
   bm = yield PlacesUtils.bookmarks.update({ guid: bm.guid,
                                             keyword: "kw" });
   let itemId = yield PlacesUtils.promiseItemId(bm.guid);
   let parentId = yield PlacesUtils.promiseItemId(bm.parentGuid);
 
   observer.check([ { name: "onItemChanged",
                      arguments: [ itemId, "keyword", false, bm.keyword,
                                   bm.lastModified, bm.type, parentId, bm.guid,
                                   bm.parentGuid ] }
                  ]);
 });
 
 add_task(function* remove_bookmark() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
   let bm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
-                                                parentGuid: unfiledGuid,
+                                                parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                 url: new URL("http://remove.example.com/") });
   let itemId = yield PlacesUtils.promiseItemId(bm.guid);
   let parentId = yield PlacesUtils.promiseItemId(bm.parentGuid);
 
   let observer = expectNotifications();
   bm = yield PlacesUtils.bookmarks.remove(bm.guid);
   // TODO (Bug 653910): onItemAnnotationRemoved notified even if there were no
   // annotations.
   observer.check([ { name: "onItemRemoved",
                      arguments: [ itemId, parentId, bm.index, bm.type, bm.url,
                                   bm.guid, bm.parentGuid ] }
                  ]);
 });
 
 add_task(function* remove_folder() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
   let bm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_FOLDER,
-                                                parentGuid: unfiledGuid });
+                                                parentGuid: PlacesUtils.bookmarks.unfiledGuid });
   let itemId = yield PlacesUtils.promiseItemId(bm.guid);
   let parentId = yield PlacesUtils.promiseItemId(bm.parentGuid);
 
   let observer = expectNotifications();
   bm = yield PlacesUtils.bookmarks.remove(bm.guid);
   observer.check([ { name: "onItemRemoved",
                      arguments: [ itemId, parentId, bm.index, bm.type, null,
                                   bm.guid, bm.parentGuid ] }
                  ]);
 });
 
 add_task(function* remove_bookmark_tag_notification() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
   let bm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
-                                                parentGuid: unfiledGuid,
+                                                parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                 url: new URL("http://untag.example.com/") });
   let itemId = yield PlacesUtils.promiseItemId(bm.guid);
   let parentId = yield PlacesUtils.promiseItemId(bm.parentGuid);
 
-  let tagsGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.tagsFolderId);
   let tagFolder = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_FOLDER,
-                                                       parentGuid: tagsGuid,
+                                                       parentGuid: PlacesUtils.bookmarks.tagsGuid,
                                                        title: "tag" });
   let tag = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
                                                  parentGuid: tagFolder.guid,
                                                  url: new URL("http://untag.example.com/") });
   let tagId = yield PlacesUtils.promiseItemId(tag.guid);
   let tagParentId = yield PlacesUtils.promiseItemId(tag.parentGuid);
 
   let observer = expectNotifications();
@@ -264,43 +248,40 @@ add_task(function* remove_bookmark_tag_n
                                   bm.guid, bm.parentGuid ] }
                  ]);
 });
 
 add_task(function* eraseEverything_notification() {
   // Let's start from a clean situation.
   yield PlacesUtils.bookmarks.eraseEverything();
 
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
   let folder1 = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_FOLDER,
-                                                     parentGuid: unfiledGuid });
+                                                     parentGuid: PlacesUtils.bookmarks.unfiledGuid });
   let folder1Id = yield PlacesUtils.promiseItemId(folder1.guid);
   let folder1ParentId = yield PlacesUtils.promiseItemId(folder1.parentGuid);
 
   let bm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
                                                 parentGuid: folder1.guid,
                                                 url: new URL("http://example.com/") });
   let itemId = yield PlacesUtils.promiseItemId(bm.guid);
   let parentId = yield PlacesUtils.promiseItemId(bm.parentGuid);
 
   let folder2 = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_FOLDER,
-                                                     parentGuid: unfiledGuid });
+                                                     parentGuid: PlacesUtils.bookmarks.unfiledGuid });
   let folder2Id = yield PlacesUtils.promiseItemId(folder2.guid);
   let folder2ParentId = yield PlacesUtils.promiseItemId(folder2.parentGuid);
 
-  let toolbarGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.toolbarFolderId);
   let toolbarBm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
-                                                       parentGuid: toolbarGuid,
+                                                       parentGuid: PlacesUtils.bookmarks.toolbarGuid,
                                                        url: new URL("http://example.com/") });
   let toolbarBmId = yield PlacesUtils.promiseItemId(toolbarBm.guid);
   let toolbarBmParentId = yield PlacesUtils.promiseItemId(toolbarBm.parentGuid);
 
-  let menuGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.bookmarksMenuFolderId);
   let menuBm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
-                                                    parentGuid: menuGuid,
+                                                    parentGuid: PlacesUtils.bookmarks.menuGuid,
                                                     url: new URL("http://example.com/") });
   let menuBmId = yield PlacesUtils.promiseItemId(menuBm.guid);
   let menuBmParentId = yield PlacesUtils.promiseItemId(menuBm.parentGuid);
 
   let observer = expectNotifications();
   let removed = yield PlacesUtils.bookmarks.eraseEverything();
 
   observer.check([ { name: "onItemRemoved",
--- a/toolkit/components/places/tests/bookmarks/test_bookmarks_remove.js
+++ b/toolkit/components/places/tests/bookmarks/test_bookmarks_remove.js
@@ -39,58 +39,54 @@ add_task(function* remove_nonexistent_gu
     yield PlacesUtils.bookmarks.remove({ guid: "123456789012"});
     Assert.ok(false, "Should have thrown");
   } catch (ex) {
     Assert.ok(/No bookmarks found for the provided GUID/.test(ex));
   }
 });
 
 add_task(function* remove_roots_fail() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
   try {
-    yield PlacesUtils.bookmarks.remove(unfiledGuid);
+    yield PlacesUtils.bookmarks.remove(PlacesUtils.bookmarks.unfiledGuid);
     Assert.ok(false, "Should have thrown");
   } catch (ex) {
     Assert.ok(/It's not possible to remove Places root folders/.test(ex));
   }
 
-  let placesRootGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.placesRootId);
   try {
-    yield PlacesUtils.bookmarks.remove(placesRootGuid);
+    yield PlacesUtils.bookmarks.remove(PlacesUtils.bookmarks.rootGuid);
     Assert.ok(false, "Should have thrown");
   } catch (ex) {
     Assert.ok(/It's not possible to remove Places root folders/.test(ex));
   }
 });
 
 add_task(function* remove_bookmark() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
-  let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledGuid,
+  let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                  type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
                                                  url: "http://example.com/",
                                                  title: "a bookmark" });
   checkBookmarkObject(bm1);
 
   let bm2 = yield PlacesUtils.bookmarks.remove(bm1.guid);
   checkBookmarkObject(bm2);
 
   Assert.deepEqual(bm1, bm2);
-  Assert.equal(bm2.parentGuid, unfiledGuid);
+  Assert.equal(bm2.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
   Assert.equal(bm2.index, 0);
   Assert.deepEqual(bm2.dateAdded, bm2.lastModified);
   Assert.equal(bm2.type, PlacesUtils.bookmarks.TYPE_BOOKMARK);
   Assert.equal(bm2.url.href, "http://example.com/");
   Assert.equal(bm2.title, "a bookmark");
   Assert.ok(!("keyword" in bm2));
 });
 
 
 add_task(function* remove_bookmark_orphans() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
-  let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledGuid,
+  let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                  type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
                                                  url: "http://example.com/",
                                                  title: "a bookmark",
                                                  keyword: "test"});
   checkBookmarkObject(bm1);
   PlacesUtils.annotations.setItemAnnotation((yield PlacesUtils.promiseItemId(bm1.guid)),
                                             "testanno", "testvalue", 0, 0);
 
@@ -106,78 +102,74 @@ add_task(function* remove_bookmark_orpha
   Assert.equal(rows.length, 0);
   // removeItemAnnotations doesn't remove orphan annotations, cause it likely
   // relies on expiration to do so.
   //rows = yield conn.execute(`SELECT * FROM moz_anno_attributes`);
   //Assert.equal(rows.length, 0);
 });
 
 add_task(function* remove_bookmark_empty_title() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
-  let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledGuid,
+  let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                  type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
                                                  url: "http://example.com/",
                                                  title: "" });
   checkBookmarkObject(bm1);
 
   let bm2 = yield PlacesUtils.bookmarks.remove(bm1.guid);
   checkBookmarkObject(bm2);
 
   Assert.deepEqual(bm1, bm2);
   Assert.equal(bm2.index, 0);
   Assert.ok(!("title" in bm2));
   Assert.ok(!("keyword" in bm2));
 });
 
 add_task(function* remove_folder() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
-  let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledGuid,
+  let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                  type: PlacesUtils.bookmarks.TYPE_FOLDER,
                                                  title: "a folder" });
   checkBookmarkObject(bm1);
 
   let bm2 = yield PlacesUtils.bookmarks.remove(bm1.guid);
   checkBookmarkObject(bm2);
 
   Assert.deepEqual(bm1, bm2);
-  Assert.equal(bm2.parentGuid, unfiledGuid);
+  Assert.equal(bm2.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
   Assert.equal(bm2.index, 0);
   Assert.deepEqual(bm2.dateAdded, bm2.lastModified);
   Assert.equal(bm2.type, PlacesUtils.bookmarks.TYPE_FOLDER);
   Assert.equal(bm2.title, "a folder");
   Assert.ok(!("url" in bm2));
   Assert.ok(!("keyword" in bm2));
 });
 
 add_task(function* remove_folder_empty_title() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
-  let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledGuid,
+  let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                  type: PlacesUtils.bookmarks.TYPE_FOLDER,
                                                  title: "" });
   checkBookmarkObject(bm1);
 
   let bm2 = yield PlacesUtils.bookmarks.remove(bm1.guid);
   checkBookmarkObject(bm2);
 
   Assert.deepEqual(bm1, bm2);
   Assert.equal(bm2.index, 0);
   Assert.ok(!("title" in bm2));
 });
 
 add_task(function* remove_separator() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
-  let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledGuid,
+  let bm1 = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                  type: PlacesUtils.bookmarks.TYPE_SEPARATOR });
   checkBookmarkObject(bm1);
 
   let bm2 = yield PlacesUtils.bookmarks.remove(bm1.guid);
   checkBookmarkObject(bm2);
 
   Assert.deepEqual(bm1, bm2);
-  Assert.equal(bm2.parentGuid, unfiledGuid);
+  Assert.equal(bm2.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
   Assert.equal(bm2.index, 0);
   Assert.deepEqual(bm2.dateAdded, bm2.lastModified);
   Assert.equal(bm2.type, PlacesUtils.bookmarks.TYPE_SEPARATOR);
   Assert.ok(!("url" in bm2));
   Assert.ok(!("title" in bm2));
   Assert.ok(!("keyword" in bm2));
 });
 
--- a/toolkit/components/places/tests/bookmarks/test_bookmarks_update.js
+++ b/toolkit/components/places/tests/bookmarks/test_bookmarks_update.js
@@ -92,19 +92,18 @@ add_task(function* nonexisting_bookmark_
                                          title: "test" });
     Assert.ok(false, "Should have thrown");
   } catch (ex) {
     Assert.ok(/No bookmarks found for the provided GUID/.test(ex));
   }
 });
 
 add_task(function* invalid_properties_for_existing_bookmark() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
   let bm = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
-                                                parentGuid: unfiledGuid,
+                                                parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                 url: "http://example.com/" });
 
   try {
     yield PlacesUtils.bookmarks.update({ guid: bm.guid,
                                          type: PlacesUtils.bookmarks.TYPE_FOLDER });
     Assert.ok(false, "Should have thrown");
   } catch (ex) {
     Assert.ok(/The bookmark type cannot be changed/.test(ex));
@@ -140,34 +139,34 @@ add_task(function* invalid_properties_fo
     yield PlacesUtils.bookmarks.update({ guid: bm.guid,
                                          lastModified: past });
     Assert.ok(false, "Should have thrown");
   } catch (ex) {
     Assert.ok(/Invalid value for property 'lastModified'/.test(ex));
   }
 
   let folder = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_FOLDER,
-                                                    parentGuid: unfiledGuid });
+                                                    parentGuid: PlacesUtils.bookmarks.unfiledGuid });
   try {
     yield PlacesUtils.bookmarks.update({ guid: folder.guid,
                                          url: "http://example.com/" });
     Assert.ok(false, "Should have thrown");
   } catch (ex) {
     Assert.ok(/Invalid value for property 'url'/.test(ex));
   }
   try {
     yield PlacesUtils.bookmarks.update({ guid: folder.guid,
                                          keyword: "test" });
     Assert.ok(false, "Should have thrown");
   } catch (ex) {
     Assert.ok(/Invalid value for property 'keyword'/.test(ex));
   }
 
   let separator = yield PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_SEPARATOR,
-                                                       parentGuid: unfiledGuid });
+                                                       parentGuid: PlacesUtils.bookmarks.unfiledGuid });
   try {
     yield PlacesUtils.bookmarks.update({ guid: separator.guid,
                                          url: "http://example.com/" });
     Assert.ok(false, "Should have thrown");
   } catch (ex) {
     Assert.ok(/Invalid value for property 'url'/.test(ex));
   }
   try {
@@ -186,35 +185,33 @@ add_task(function* invalid_properties_fo
   }
 });
 
 add_task(function* long_title_trim() {
   let longtitle = "a";
   for (let i = 0; i < 4096; i++) {
     longtitle += "a";
   }
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
-  let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledGuid,
+  let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                 type: PlacesUtils.bookmarks.TYPE_FOLDER,
                                                 title: "title" });
   checkBookmarkObject(bm);
 
   bm = yield PlacesUtils.bookmarks.update({ guid: bm.guid,
                                             title: longtitle });
   let newTitle = bm.title;
   Assert.equal(newTitle.length, 4096, "title should have been trimmed");
 
   bm = yield PlacesUtils.bookmarks.fetch(bm.guid);
   Assert.equal(bm.title, newTitle);
 });
 
 add_task(function* update_lastModified() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
   let yesterday = new Date(Date.now() - 86400000);
-  let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledGuid,
+  let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                 type: PlacesUtils.bookmarks.TYPE_FOLDER,
                                                 title: "title",
                                                 dateAdded: yesterday });
   checkBookmarkObject(bm);
   Assert.deepEqual(bm.lastModified, yesterday);
 
   let time = new Date();
   bm = yield PlacesUtils.bookmarks.update({ guid: bm.guid,
@@ -237,18 +234,17 @@ add_task(function* update_lastModified()
                                             title: "" });
   Assert.ok(!("title" in bm));
 
   bm = yield PlacesUtils.bookmarks.fetch(bm.guid);
   Assert.ok(!("title" in bm));
 });
 
 add_task(function* update_keyword() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
-  let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledGuid,
+  let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                 type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
                                                 url: "http://example.com/",
                                                 title: "title",
                                                 keyword: "kw" });
   checkBookmarkObject(bm);
   let lastModified = bm.lastModified;
 
   bm = yield PlacesUtils.bookmarks.update({ guid: bm.guid,
@@ -272,18 +268,17 @@ add_task(function* update_keyword() {
   // Check orphan keyword has been removed from the database.
   let conn = yield PlacesUtils.promiseDBConnection();
   let rows = yield conn.executeCached(
     `SELECT id from moz_keywords WHERE keyword >= :keyword`, { keyword: "kw" });
   Assert.equal(rows.length, 0);
 });
 
 add_task(function* update_url() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
-  let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledGuid,
+  let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                 type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
                                                 url: "http://example.com/",
                                                 title: "title",
                                                 keyword: "kw" });
   checkBookmarkObject(bm);
   let lastModified = bm.lastModified;
   let frecency = frecencyForUrl(bm.url);
   Assert.ok(frecency > 0, "Check frecency has been updated");
@@ -298,18 +293,17 @@ add_task(function* update_url() {
   Assert.equal(bm.url.href, "http://mozilla.org/");
   Assert.ok(bm.lastModified >= lastModified);
 
   Assert.equal(frecencyForUrl("http://example.com/"), frecency, "Check frecency for example.com");
   Assert.equal(frecencyForUrl("http://mozilla.org/"), frecency, "Check frecency for mozilla.org");
 });
 
 add_task(function* update_index() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
-  let parent = yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledGuid,
+  let parent = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                     type: PlacesUtils.bookmarks.TYPE_FOLDER }) ;
   let f1 = yield PlacesUtils.bookmarks.insert({ parentGuid: parent.guid,
                                                 type: PlacesUtils.bookmarks.TYPE_FOLDER });
   Assert.equal(f1.index, 0);
   let f2 = yield PlacesUtils.bookmarks.insert({ parentGuid: parent.guid,
                                                 type: PlacesUtils.bookmarks.TYPE_FOLDER });
   Assert.equal(f2.index, 1);
   let f3 = yield PlacesUtils.bookmarks.insert({ parentGuid: parent.guid,
@@ -339,18 +333,17 @@ add_task(function* update_index() {
   f1 = yield PlacesUtils.bookmarks.fetch(f1.guid);
   Assert.equal(f1.index, 2);
 
   f2 = yield PlacesUtils.bookmarks.fetch(f2.guid);
   Assert.equal(f2.index, 1);
 });
 
 add_task(function* update_move_folder_into_descendant_throws() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
-  let parent = yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledGuid,
+  let parent = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                     type: PlacesUtils.bookmarks.TYPE_FOLDER }) ;
   let descendant = yield PlacesUtils.bookmarks.insert({ parentGuid: parent.guid,
                                                         type: PlacesUtils.bookmarks.TYPE_FOLDER });
 
   try {
     yield PlacesUtils.bookmarks.update({ guid: parent.guid,
                                          parentGuid: parent.guid,
                                          index: 0 });
@@ -365,18 +358,17 @@ add_task(function* update_move_folder_in
                                          index: 0 });
     Assert.ok(false, "Should have thrown");
   } catch (ex) {
     Assert.ok(/Cannot insert a folder into itself or one of its descendants/.test(ex));
   }
 });
 
 add_task(function* update_move() {
-  let unfiledGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.unfiledBookmarksFolderId);
-  let parent = yield PlacesUtils.bookmarks.insert({ parentGuid: unfiledGuid,
+  let parent = yield PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                     type: PlacesUtils.bookmarks.TYPE_FOLDER }) ;
   let bm = yield PlacesUtils.bookmarks.insert({ parentGuid: parent.guid,
                                                 url: "http://example.com/",
                                                 type: PlacesUtils.bookmarks.TYPE_BOOKMARK }) ;
   let descendant = yield PlacesUtils.bookmarks.insert({ parentGuid: parent.guid,
                                                         type: PlacesUtils.bookmarks.TYPE_FOLDER });
   Assert.equal(descendant.index, 1);
   let lastModified = bm.lastModified;
--- a/toolkit/components/places/tests/head_common.js
+++ b/toolkit/components/places/tests/head_common.js
@@ -1,14 +1,15 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-const CURRENT_SCHEMA_VERSION = 24;
+const CURRENT_SCHEMA_VERSION = 25;
+const FIRST_UPGRADABLE_SCHEMA_VERSION = 11;
 
 const NS_APP_USER_PROFILE_50_DIR = "ProfD";
 const NS_APP_PROFILE_DIR_STARTUP = "ProfDS";
 
 // Shortcuts to transitions type.
 const TRANSITION_LINK = Ci.nsINavHistoryService.TRANSITION_LINK;
 const TRANSITION_TYPED = Ci.nsINavHistoryService.TRANSITION_TYPED;
 const TRANSITION_BOOKMARK = Ci.nsINavHistoryService.TRANSITION_BOOKMARK;
@@ -38,16 +39,18 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 XPCOMUtils.defineLazyModuleGetter(this, "BookmarkHTMLUtils",
                                   "resource://gre/modules/BookmarkHTMLUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PlacesBackups",
                                   "resource://gre/modules/PlacesBackups.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PlacesTransactions",
                                   "resource://gre/modules/PlacesTransactions.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "OS",
                                   "resource://gre/modules/osfile.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Sqlite",
+                                  "resource://gre/modules/Sqlite.jsm");
 
 // This imports various other objects in addition to PlacesUtils.
 Cu.import("resource://gre/modules/PlacesUtils.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "SMALLPNG_DATA_URI", function() {
   return NetUtil.newURI(
          "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAA" +
          "AAAA6fptVAAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg==");
--- a/toolkit/components/places/tests/migration/head_migration.js
+++ b/toolkit/components/places/tests/migration/head_migration.js
@@ -1,40 +1,45 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-const Ci = Components.interfaces;
-const Cc = Components.classes;
-const Cr = Components.results;
-const Cu = Components.utils;
+"use strict"
+
+const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 
 // Import common head.
 let (commonFile = do_get_file("../head_common.js", false)) {
   let uri = Services.io.newFileURI(commonFile);
   Services.scriptloader.loadSubScript(uri.spec, this);
 }
 
 // Put any other stuff relative to this test folder below.
 
-const kDBName = "places.sqlite";
+const DB_FILENAME = "places.sqlite";
 
 /**
  * Sets the database to use for the given test.  This should be the very first
- * thing we do otherwise, this database will not be used!
+ * thing in the test, otherwise this database will not be used!
  *
  * @param aFileName
  *        The filename of the database to use.  This database must exist in
  *        toolkit/components/places/tests/migration!
+ * @return {Promise}
  */
-function setPlacesDatabase(aFileName)
-{
-  let file = do_get_file(aFileName);
+let setupPlacesDatabase = Task.async(function* (aFileName) {
+  let currentDir = yield OS.File.getCurrentDirectory();
+
+  let src = OS.Path.join(currentDir, aFileName);
+  Assert.ok((yield OS.File.exists(src)), "Database file found");
 
   // Ensure that our database doesn't already exist.
-  let (dbFile = gProfD.clone()) {
-    dbFile.append(kDBName);
-    do_check_false(dbFile.exists());
-  }
+  let dest = OS.Path.join(OS.Constants.Path.profileDir, DB_FILENAME);
+  Assert.ok(!(yield OS.File.exists(dest)), "Database file should not exist yet");
 
-  file.copyToFollowingLinks(gProfD, kDBName);
+  yield OS.File.copy(src, dest);
+});
+
+// This works provided all tests in this folder use add_task.
+function run_test() {
+  run_next_test();
 }
deleted file mode 100644
index 915b471ee21188a9134ab6bce6404f1ea2b9a606..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 810416564845b673f74c6c2587e803662c6edc99..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..bef27d5f594cdb2333c21298df93ff46a261a3bd
GIT binary patch
literal 1081344
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
z6#xJL0000000000000000000000000000000001he-r0To)C#fqS3<Js;aZ%u~?+C
z>iRnyzBe$M&s@G?UFVu<4MPK$tebmWp>n}1OO>NFvFMthE9lQBI+DG)BO7jA-<oY3
zYF^g5x@-1DlgbTemK#>bBISnZk;KAGW@}$EyEW)8H@s)xXufdfs`j?FmgQ|t!$b2X
zmOD7B+(A`5vLchqC)TBMsr=C`bFG~n3r9BQ=42W!n>C@_^5x~0l{N9k&dgvwvG%}(
z_s=WmZ%ee#Z0cRsy>-d(W!sj{8-Lh%6*aNuAfIUI-=0ZtA02PB<^FjC^V=Jiwr<a_
z$h0*rs4cgwE4Pf-L>CR_@|nKWjv%oll?{3_!{ugIuNrOMS--A%VUVBI)HCmr*NiJS
zZzwm9)kKyC>48MDzdO+}n9pQW$@GDV@7prk&#bO_-NDGRIdgWjc3x0Z{yfhswU5Q(
zD>6G$>2&h&u}9nPpEojpxM5)0s^*o=8(S}|F1MXlZX1uaCi6jImzM^~?sTd@IAY*^
zTe??V(zIwv!@!Jud&h-U<%yREjz;6r!j9!r{k@6yd@_6RL%MSJXyc}hL1uVG_o^KY
z8`dwVERS4Xbu1cR+n>u68y!3z<+1Db?;h=D+p^w)RoT_`%ZC?d>MF|3Pdd;%cJMsb
zU46}H!=~-S%T|u8ULJJz%zAaa+@S72gXqCw5*?XLx-*$Qtaaf?ZCf_DvGcNqb=kgI
zL-S+h)>99(jy&6XMbJNZc+>9<v~=dS4mWR_aY=Udz<JSf(~0G#g}bg)dEbqrvus_o
zZBB2peg2NFf#!+D%i)(I;jhA<hWCfxD!c^%000000000000000000000000000000
z000000DwPI<16E*MF;zPQt6<(vZf+_QZ%3J%~gz#7sB~WCf%9L#%p4Qa9_|r7^{uO
zPl*nslU+eBT3cvc8Gbbq{yO}5_@nSUg|`3z000000000000000000000000000000
z000000Px3beEhWNV1G|49duU~-{&)#bZ0UfuZf=&%_n<v6}9nGq66t<SCESqV|_vY
zU~FQs<?a`G<^TWy00000000000000000000000000000000000@FJ@%Cc9tcNdN!<
z00000000000000000000000000000000000z>92RG1>hhPXYh{000000000000000
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
z|KxEqBVT^<meU@t?b?_8$IVktdFHr@6Dv=PZU655pRKKrM`AS}{`B?N|7c45?(O@d
zkDfev&KD-^sQ%(--}k`Yk?O?m>poDk@b~=_8aAJOccS|X>l(jMb@t7*Kb^KaviH*u
z{<?M6#7Fl(`K8TuwR=AoJ)yd~zW%OgY~S$@$5ws3;l9t_aaVNK#7ELq>l0O<+4sJe
zo!WlV#aF!a&N<WTdWUc6J??d1{qDymT)z8?-I3U5BagiI7m3p@xb6e*-SfTsqF=mm
z_b+z;_LiG&`u#<(d&&NHzx|2R6T44-;B%MXG3kF+HZD#)-JJcvb=N%@p0#Rs?A^!x
z!@Ltte&v^Ly)o9b;LHCKiB|l1<*FM#b8+9u8y|j2*A0J`c=KJ~iqym_Cci7X=Hb2F
z7k>G=YrnLA|Cj#elq;jLn)giE{gvTgUw+;9*Dd<Zb+`WM&X=D5jmWRQ)b^*>j!W#W
zZ><>loA{}JdEM^H$`hx5zwzY46sCUt8<A*LWWqUbyW`faUpas5)A{-n<NumtIm5AZ
zEdO1PW$a&bEE^6xma`m7$MWC!SVsRf$FknBbS(cJk7e-~RquLbB)lmc4rlFpY}Y4u
z^%aT$000000000000000000000000000000000000011VrDD%X(JlG>K<<LNy1vYg
zOtyD=S9kyP!rN3jot)ku<m>u^?o_fa)z@3slgb7?nc=#g<n~lorhj@NxoAdx!^~;*
z^QvB8Pvss)^Jxw9=L{EK(+B!{E9b=rUvNjosZ=kj*fXxwve0m7Xy{;zLJxH_>g#9M
z^(DK5X@djPMn|7HtzlNftT}UM&zdoN#?0CE_4O4mxQ`h}^$~x;eKZ`_$E-phu@~G&
z{ZV~HCl){9-7oS90{{R30000000000000000000000000000000001h7um$Zt1{df
z3GWYY4L=mVz3>(Q000000000000000000000000000000000000091DO{t7WX0J*o
zyMkO@dtWk}Uzo{kE#zBIsE9|VrBmC3VxcaV$_H!Lw44w>G}sda-G$(3v3O*`K&gwC
z{(O+_Pp0eEG&L^X)V8v9;~CL-q^0vfpR2N&fgqbt6~^iga$VWfKt7e}uPscYGTa#n
ze-hpvel&bX;Vl3F000000000000000000000000000000000000Q|>#S$sisAf4<A
zaxMM&Alsiz*R5%4T)e4mW$VV+iScRCbZUFhm&|Uh%cb(c+BGc|hXs3rpt}%^pBZn7
zc4jhLi@{ad%s`OMr-EEvcaZDKrUvq<On>y``0VJa(nxjfg=+bQ2dY<2EKH+%S3@NH
zi!c*T*>&@-x9qyKPy_$~00000000000000000000000000000000000;1Bte>hY0i
zG;&5X8m+22u5wM#74+vjlD)Y|MLbejb^V<U-y0asXH=EyHk9g4I#4$~GWyTwgYJWE
z?%6k*pI2FG^U6}2iIpodx%|3RE|nj%^7@KW<;zQzt1GtT^8**u)%6Vb1VMLhdS7No
zDxFSF@5=Pm1^v_3w%7HfvO!N~xGtUA9&{d<MXv5($NRR7=Ii36jz`KJ$Den{TY_YF
zI@KTKrVsa}$LRNrSgGIR%KgR~A{EgitE8h7idFWMcOV{Z?Cwq+oNFSVN#wVra*3Wy
zx;w}gi@6{ugo3_AcPclKPL2fKiA;Ynl2~}KRYxY1?o4J6PUy<rqj_!NBOM>!9tnRJ
zJ`p}1{yh9i_)vIXcu#m&cxNFD000000000000000000000000000000000000001g
zG%DlKX!ZDFT2Wa{;}yj;7B8mJSVcS%tt}?wib+i|sV*i}#Uxr=Xg@w|iG;rkp9mih
z?+fn;|2}+oxG&6w|DzBF00000000000000000000000000000000000004j&=EV54
zXkVsldNQ3(?a1^^9~v5(K5ndF<ygUrv4Zijg0ZoJ(PFSSn>j2veym_^MLZI%DJIp$
zq^h<s_3`1&k?^<Sufl%{9|<1{?+fn<?+Wh>Z!d%a0000000000000000000000000
z0000000000007{RKxI4{jgBv+wWV}iF^$xe(&|!LRZ1&MX+<fGm(o}%jn)==86SQ+
z68<*)RrpWgBjH2gec`vmZ-jS*w-&+x00000000000000000000000000000000000
z008ixTU9(3ja*$>&ML}Tyqv|#S+p`9jds_T(s9K!Qd3H+OKDXxeP(=Zp{w!X-$laT
zg-?W!hd&R05<V2(AKn{&HN3eH1^@s60000000000000000000000000000000001h
z|C}botD=$0s_XCE-0|S}gN4@~Kd<&+VaetV<0|5jXiYJxE+$pQq_UV)6q9%{i4~J*
zZK2C}_^n9zc=%8u0{{R30000000000000000000000000000000001h|0*U`M606X
zBb8Ox-?_Qt!FZ`yTPnWx_<6BXaa^gmWb=l?g-9eG{!=9UZTPD~1^@s60000000000
z0000000000000000000000000{|!{eqtRHrm_}p8G!m^XMC0LiBjGQ@9~UwJ00000
z000000000000000000000000000000008)}WkS3v8mX+h{?5%E55^A`UVHq!*ulb*
z%^RY%g{qUoeUb1t;Xj8z3m*>e5AO-T8GbpuHT+a~V|YV&U3g8nzfb`H0000000000
z000000000000000000000000000902R98f!(VFOSrMx;isgzemCzkTc=!8;U5glL3
z<I&nu9*d4E<%OD66_G-Gaw&_|l(Xt`R$0y}%2~Xe#mZT<wlMbOaCanpGJGt2Bz!Qu
zH@qwSa(HX_sqn_|hVZ)Zns9%(uTTL100000000000000000000000000000000000
z0090SRaZo#(VF;#avmFB&ZD*EJTk77$79vyJX%%GBNIz`EM8O2W0T8y^tf^!nN-T7
z@yc=@t0?EucsY;6N_iv_tu4%9a(Hqi{O9oD@SgC?;b+1RhwlmZhkL?o*cEn!P2rsI
zoI(Wv0000000000000000000000000000000000000915np6?3iq=FbtFFJZ;d=we
zm5SBn;ywE&m5NoP#fhb2Wx4pa#Dr3@qFmfRZ+xj3A1&6Fim`I>>Q&=P#b~*>Z%ft0
zibz#-blAy<m12jK?%5YVq_lrt%^{_ITdEH!UAepR*;3v9-4%zGqP2y!j^BA%B)m6#
zUziCm46AqDyX(4L+jic%^DTui00000000000000000000000000000000000006+h
zgR|qSqXX$=S8zdoWFS~D=j>c2n_ti{>+HVd@R}eun9k=GG}PBjk0%dQ%Ld)4Y|xd@
zt;lo-3uct-&pW(&)t<VFy`v3!GU@IhyI^5k+wv8SYnHcfTG6y}?b!#SYgaC5X>D4(
z>EPAT3mt83tqU91oV{%@$c}Urr`B*_YBSCbhP%>(-9bw}=xga&mCOeH`K8HRV}E}p
zpUkH+{R`5m?Ll8MyY;LYOL~H!d+nN*!{;~J!|Foksh|+4F0OA&K0lDVpssFcXlQz0
zW=ATWPEOBcd+UP!X=~f-dJ3!V$qd)^2Sat^=f-o-v-+&*^~LwOe0H$Eu6A^oBbs$(
z`i^L}B}fm{#b(C0KELW+gSmXBFSR46i$DK1nZCZk{#1UXuA(8{`#jqewmO?k*G1>V
zw>`fWhpm6yIq~-AZkFuK4Cd=9YYQiHeApBT9}OP}zaHKcekgoLcvUzY_J->UVE_OC
z00000000000000000000000000000000000c>X5G&x&r}&_2I$M(2#qwxBIm3=FOs
z?(Xbq+BmCuaCm$%(7(3*vSfbanniOO7e|YMbZ2JU!eqnzt^G|ywWYxNwk6FAm#tng
zG_AX$7`Uvxb!n>YlHS=H7cH(T2D*Azt{xd$zA?YPZ)?05=v=yGV>Vd6ZfVQFs+wY8
zeRg)!K*zF%!Pb%9am7H#infN;+4h;MwqLTLx)_+-wQ+FH+<^_NyXViXtSwG|*JF|J
z(eQ!r>)}n|hr)M+SB1l2Z@4aO3TK6{3||sP3l#tW0000000000000000000000000
z00000000000QfIua{R35$o%1kfoZFnS2k~Kttkd_t(_eUM>gi>WEw7;SPX1iHn_3#
zvW9ipzF9-@a-er$Rd#j#^5Mmq%3@$(etW~x*6sNfnYO0!#lY6}t=YDr=4Gv`yJjC(
z40Nx!q-oKThJhLR_KxaeptF8m^THrMtEp$+CAGys`^=`^W!+ns3}3cw>4ajSb<wst
zy~+0ZJGus%qs2f=XKw3o^QIY>WLFQwih-u>!^>8VtX>{;_ROj%1vUnm;T7Ghb~J2Q
zUsVh&oVlvKt*vEwThs8+q+(!J*SzjvWZ9fKJ6b!(6$3MuZ&=s4W?IA0z$NP@*A_Qr
z_lx|Y000000000000000000000000000000000000002Mi>$Wrst&&#37-rf3m*v|
z4DSu^Dii?#000000000000000000000000000000000000N{^ObwxB9J+894luxRx
aD&-R^D@%EGMMXJ}$IE#vR?6ei=>G@nLw4o>
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..1d984bd72aea065da5c7cb537be1ef2a1f7e0583
GIT binary patch
literal 1114112
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
zM$6Xz+>$Lz+ZVUYt{m)O;$R15(a?%?HdlRqBAdt^*>cII^@~=emNqso?wU1y%wWqm
z4z?^Uk2bWXdvn!mhbFwaZa7~xb8|~mUvFRYKx+2vibKXLDUU3U=c*gKx2BU@hsWz!
zGTgEw+uvEYytyg9WlrPV(St2(2U|wV!}EKyxpXQq5U*a8$izF+{f9R1STbYl^wk?W
z6RT%+E~<OmsKMs-gUuu5p(XKTPj#%jy}G40m(C<&$)Sn2UNqdkC)t=8SYDrAvSvl=
z+2w=x^Q>a~NF=%<J&;HyV~37C+;(%_rsT?=H46roEr_=^oKrS9_F&s^I2z6`I+y6~
ztX`9gW%lp$JN9=nXX%`o>z1!xzOr-0vbm*$0}oC-5{|Cz&ZY~E_TS;bd8en{H{4CC
zw{=BV-}I)o`i|ALC4<dR7-}Bbf24*R<n!jG3)-7j*UwJIW@p|S9c)lL)F8ZnnCg~v
zI@ub_96H>MSJ$k{_H@i&x^#Z)s+n^lgRLhGwGJI<y&~S-duY?WJ8P1el>?pUuW9W`
zEjcSZ*mUe*)BF$TuvumoZ%y@euWyRan$tA4a5=aq6#ORmdGJ{9Q2r|b0000000000
z0000000000000000000000000008`%8dDlQCEVNHkx0hdOGlMNPYCB?o!OEx(R?_U
zPA6MqndqoUKAeho_eLth(UZbG$yi%F8?MN=E)BjB3Vs*-GWc=u-TYSo0000000000
z0000000000000000000000000008)NHYR#XxVO6_k&L&O7QW}w>11mx6CD*jA)JeK
zW=krfCxv^Gv9@?NT!^LO-Mx{qg_b*C<Cy~h000000000000000000000000000000
z000000KjXkqLA!-jVA#B00000000000000000000000000000000000006JCv4v#k
zYdi@600000000000000000000000000000000000004N6jm>|`)2l+;-#+lA{^NUl
zayxpypDzLc0000000000000000000000000000000KorKmyRkQ73#fg^QmPMH|26Y
z*|TeFQ|W<prgKVLd-s(5*F-WIo6;T6)u!U@iCAqS)mhsS+nQ)gcTdSDSFBpOcx=VV
z75SdVHZEDvoX?Lbd`6Y!(^G%_Vl1CM+qj^iW%ge^(ERtS=hs($`!6PcHFWd7uT_05
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
z!g-gx{_8WR)OPmY-Z}o#Z+!3bl^5^4WM?RHOK9J<zp6gv?CU;t?XG`*H2hC{cm8VU
zA8x<()<2zl>Ff4<?5bx^t=@U!<6pV>-f{n5X~Tl*7Zzteb=`G83?{DH8Tr`w|1<lz
z6W@H#9eX1S=ic|*P`KoMrK@iE@_DIk?|$-iZ8!W?^?M(DC^RZsa?D4=%}?%bKj*&d
zuDNH=o_qf8q|3sQQ6I0``L+JvU3}g5&!7MM>+X2__SaATX6QHfG`;<r(bYTamX~b%
zyXeUux^8D_>G4y(-*94n3X>lAW++@1syyR^_ukR<waFtN)xND8F4)@B+Sb;)F8R(0
z(SOq!o$8D_qyG=j=#t#R*4Ex-GiFX(weFo0BLAi{T7SqHo#u=>qyN6o(JkAybk@g{
z8<%h0_|6I8f72PQJLHT`bw-`hf7dhG9N)Nn+pJ8@yq-1F3rDJa$D2dJtwDb<eaF)~
zzPKZmF9HAn00000000000000000000000000000000000aHPhPT_=P$<#IjQvukTp
z>49{nb4pu#_muqCL^2th(jCv$rsD01SZyNJS=*7w#5>acwH>joiMDk2lzejT)Vlg<
zHFdMgUS&^%Jq+hH^>b$S=RZ?=x;sl}M|)p&M}?`B&o9|Ey4W(`u&=Lge~Ww%wNvZr
zX4Ix)?eUu4o|@s&r`6O?ub)11){N;hr_Px*y{@jV<W=`E^@u*Auey)=L;9GO?<4Z6
z`=~plk9?K7@Ywtfjs$myg2(a+000000000000000000000000000000000000002|
z8LNs!Lo-$-V{P$l?V409lbe@Lcjfc03E^m{v301hDwFPsXL5;rrS^EXEtBZUCDPp$
z`Sy|E?ojZvd;$Of000000000000000000000000000000000000Ds0#i#CQ^)9J2M
zEYr0rlkSOUa*24hwmqJ0%OrYoiF9}P#ORFhs${G!A6}EMmYX+JJu<e?!Oqus0RR91
z00000000000000000000000000000000000@ERMN|C9u!q2RBBcu=4J0ssI200000
z00000000000000000000000000002Me_wx5GA0xbhbDx>;j*%Ek>+??ygSzt>&%8q
zqM_2V>+j#Pcjs_EHCn7&U#vTJsBUuGymY!N70YzR+xNG*@#^9HtVprVn~QBKBP-I`
z-1&)YA~#~?WVo_WdDmd=Xt<%hy}EU%_iS}8U7g#M$X0ixlkM?Lp_q-w^PzaEx;>HY
zNyfIt+pE*vg-G?h{jFNk>11mxvwyUA^bhA_^UE&@>O;Z(!TW=Y@?QV|0000000000
z00000000000000000000000000N|CVDJePQoT^lMU}I}K-Ia=Ey0V89HYRfMRHC~*
z-an%{|6gsi<cxD)s(Mc>6YtIqHJDaiKPOUh#+sMwKN-vBQt9?YM<U*SV63U(k~12Q
zdx@r<y@~dXz1@i|z44(|^%eOgjS21!1%C{l4W0>p8T>4GB6u|TPVivx^?Vor00000
z0000000000000000000000000000000091Mlt#nh@-c<9q_mJmOA2WuT1dl@l4vMg
zQAkD?l2L`EypWU?l5j=7{g|LJ6#OxGHh3m@G`KhThu~wu<v})hM?MSy0000000000
z0000000000000000000000000006Jf@zI)aD&00EmP{rF(y1wZeSK3#j}$B&DOfU6
zFgj8&GEy*H2zF-DhXlur6s#zThQgx?NqHeDtH@7%OmJH$_(SlU;9r7$!4tuw!FPfO
zgRcj7=feO1000000000000000000000000000000000000Pts^G#U<v#}w0wVmi8z
zhDH_B@?u(6OiPPtNimHU(?~H5SLAyc6WkmM{t)~o_?KW`@I>%v@a^E6!M(v9`7i(g
z000000000000000000000000000000000000Q~1x7L9~MSC$TDC4*UXFpCUk;nHY0
z++I;kM;Fr2sA5`POv?)Ci(@MCU5yF;J{0^hcs6(@_+{|3;ECX|;E~`P!EO0400000
z0000000000000000000000000000000002|=TsRj3x`U}uD}1P4?Q?$e__wQy%qZl
zJGbu{T@nq2M-`ItLQ+;pN()IzA&C}}NFfPV<hzUp4~2qff+zAB000000000000000
z000000000000000000000002|S23<6ToxV^DlNPI{;NLpV6<4QC>HnZ+Z!nsM;D7b
zx9`bc2!*1-zl4H61i#5=000000000000000000000000000000000000002+-#}?J
z9F9Z_X*g0yL*a^iG#Y#_6#P2)X+8r000000000000000000000000000000000000
z0D%8mDx+oLP-)rq_h0p)2c!E7d-m;(>@V!xz9(FfuR1<>Unux}@UOuyf+vH=g6{<1
z3hoVV555?DF8FkCZSdjzWdHyG00000000000000000000000000000000000_>WXx
z5)Ow)g~t{1^6=PVUKXw_=B42=#k?e3QOu*^(ZxIx9#zcqHOopu`S|!^7AYUhN(Zx&
z!7MtMMFz8QMSjrn!R4Xgx!~zwU+}}=k>J7LzTl4FOTpgYhTyv3>R?a)G5`Po00000
z000000000000000000000000000000{D&wn35Ubw(J_O0q+&1+j~>iJql$SnTsD}8
zDvNm}T0WRZ#t-J<af5kiY%vc<O9%5v$zUFi4(6dqF%N~p75TBp2d9UEe+`}tz7yOR
zd^xx=_;~QXU}vx;Xbsi`3xXN>%K!iX00000000000000000000000000000000000
zkT<R*ToxV`DlNPI{w;fVjw=?+2a7jeJ+@dZ8!lEBi=~6b&2?jn#ggG-MX?wiEOsmz
zT`We1i=&Fg@L;j^qO!3ip|bGsu;ULYMGh+6cy;uk(&oDIgG%q{FFjC7PrI+=kW#oJ
zzq&EoH-&;ng6o3r;OwAm$9H#pd`EiwZQI|M4+8)I0000000000000000000000000
z0000000000{JT3nx;osGjJ3tj&TZ?7&z*UCHl4}Mt)G5+D%Rf|&-NyB*}3&~qozb-
zL)9|z_CzM$mdmb4x5wvB9jrh5(CTHoYD;zxH|R(w+vAzJ^O~BLt!QXowr1msg)7&d
zJ``QMa#7>*g$p+BzdC%OrKxH8yoTn}xAev{+gb`!s~?)$)YIerZOPvDcw;V}YV24Q
z%f!2LOJdoE?(TFhmP@3&=Oz<d<EdDtYvR;J9r1Yk+UCYX=QrHL>U`&kcs^2ISl^~x
zt|xnTZEas)-;`8(AdyVQrld2SwejwnwQFiS@~iGh_t$pE`)bF`j`qI7>h<+g>I#Ky
zF4NmxTQNM&VeQ(|sl(cBiYI$&Bh#W?udI4oZ#I`sB?jWP(O2Fkol5m~Cvw|rOX{PY
zudq#iuQRb^ZFp8R`^s7zx&folh^~3*cCprUZ?3kqB7Zi=1PepKQ^DiG1HrAqXM?{9
zt_b>r&fxrf7ytkO00000000000000000000000000000000000Ub$nU6T|%tTRYn~
zw=C`2T(iEU5J)a;+%UCeW8;F(w)Ch%psQ)|hP5^8yLw|ybIJ;VwuW45^MaNY7j!PV
zAY2HnZ)k1oKY#Q2>7Jf!q!3uwIB(|Cwk6YMb>w2Dg}|C*Lu`Fr$H3OvP1B==K=b_W
z%_|1BuIyept#@=Guz1nhnpC_owr<I~hB1Y}!hw~ud*g|Y`O6w(<%K|fXVaQ_iME-I
zU9;OND)Q4GAB01}Q^DiG1HrAqXM?{9t_b>r&fxrDVK6;-bMU(SWdHyG0000000000
z0000000000000000000000000{;NACIx)O$U0r8x;ie5sH}&+4F9foSx2F2K*Ehvy
z&1ni30zJvb%)s*c^pZ6zT1OQEsovHVU47G=+Uh%2mlgt>k}G@GEErg}Al}+gUI=t#
z`#bBFH#fz%%xSDB1e%vFXm46wKRX$lohc~<R?Xbp($v@6*F2D#J*E&?vT6OIRjH+o
z&5OHcRTcsZ6H}W9mTyee_cqKPR|w2mI%np(<*S#k>|C*|tPq&7b^7WJor%@6Iv3TA
zE(E5|XxZAITe4+o`{I_dg+NU*vvQ#G{57pTsU?wOU{$uKWB$^m^IKQVj8+u(VCQRm
z4*&oF00000000000000000000000000000000000;5Al}|C9tj3<b{xPY3(*UjP6A
z00000000000000000000000000000000000;J={ql5jXYE>cp=$3~*XyfP9g=FxEY
F{|Aou5pe(j
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..5183cde83de09c6f1fa200cfa8c21537cf201c8d
GIT binary patch
literal 1212416
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
zgEf19z4w~EEqhD$oVO=>@p~_B%4Y)r00000000000000000000000000000000000
z!2du))f1{hiF9p6d3iWoI%Qif*PA`3uCBkoe|mR%cdDx^F+H8>tV{OPu3KBTHI+$j
zO%K%dB>U?Yru%!k(ut1v;^EBrkM>;^Uz|xM;~SD&;`1}<{%kT+%v>?tPiH1QJ<-*b
z+MVv6Ug*B;xll>zb$4IYbi>ZIYi2DTXx^3GIln(ySrzIF6{Zt<(bH*|F}=Q!$mTMA
zJ#|Np(@`Ae%BvrmF}rzr=lrI&8NH2bJ1VL|*~5l8VwCoD_w$a@oo*jzl%YHCS+%31
zrFl;Cnk^SDU3gA;RcK8pR9;aYDi2L5{{Q07Dg1BQ=QW*~O=oiR8fKo^ofv3MX8XEw
z*?A51b2FPZ>=<01X<52`+0cTr>d^kg5v{kTyE>AYdGlATTDGFOb=lg@D;BL>cjid$
zx|NGtmM>bk`C#d2LEEZT%jY+@p1HFxnHg*=OrT+80yEA`4zzdmbtGGI$?le|s}q@I
zPws+5wz;P#olE3W>7IFAsa?tLL}tg78H=|jlO5|?TMnP}Xb)@hou`udob4+X%vnEU
z?XLBM13mLg^QY^GHDr<<`7LeFWmlv-lJjN^&t%Two%XD5?CD>yZNZicvn?x2szPf+
zwdMH}8VNoBy-I9J_vMbdH?hza_1Wa=?X4@<b<Aj4cwww6wByC~H+t{$Io*9dsodaE
zeMduAY}|A~?Y8>0y>06Uw_h0j!~5>b=F;7%-N~c+j^yW^OkFrDIhaiEYM9>^DePsT
z?}``O_qJqL?@`@`uINZ57H-*<Ubue!u8kYQRiVyeub~$`<NO)PB)Z1wc+1AN-j+<u
zg4z|^msaQBF45qQQ1EE*-FyT900000000000000000000000000000000000004iq
zj*pgw!r{_zI5HtrQhMFpS2f*G5_wsqEL2g*tSshTdG$jjk;&n*P<gntB3x0-8@ltJ
zNOhrueJ}9>000000000000000000000000000000000000002sC01Do_PxZD00000
z0000000000000000000000000000000001hmsoZF7YV)}3Leb|000000000000000
z000000000000000000000002+r{}mxEOdIfJH0#A)s>i@&UAK64(D?sqdD#A?$8yL
z`HGR?hoRt!d;kCd000000000000000000000000000000000000Dr0`MNbcRr+25i
zx)RgVna;?>=;;-s>GpJYb)m||p9=-w4&D=76x8qi<=)Tjy?F2I_lEa;ZO=RRykXC)
zF8)cr7ytkO0000000000000000000000000000000002^AMCZ0szTvVIGn#MEu9jL
zL_#H{*WH~7-8UM~oVl@eFu7`TPy422vnE!BD#GE4(~FhMBdy8yWKS;MmgvkL*=%-h
zZmzLw{ifx!m$c5SE;cJ~EH*0}Y1TCupPx?e=uTvIBs+@Dc0T?1Xx!S<+P=JP-TcIb
z^Jg|y4L6@sY+f2&k<RAg>r>fO?&x-l8&?j@@2{QFI%n6i#tFrC;a3;im6S!Bx1{@W
z@pZ#<-TB!AqjAHMTyE#U+U})`w(Xc*IoxP?uvl4SNir92>DiU;+BG`bCqFmZFx8%%
zyKG(G&g6<Uv(K#<-kZANjVxQxm(8WSQ@fM##i>kkYkFX~(Z}u??PSBUZRyo(2G`a$
zb~e1Oe0Yfs#m14c3zA*E@kCEYysa;n&ZH7u*~43Z?4E_Y8h5sI)UIrsyS?k2vf+F9
z+Tqrb{0<fWzx0QX{NYDNr`^=MY0I(;b`Gv=S+;XdX@2C2aK&)jXnwW1R8MDoZ7z{H
zxV@t-Km5qr4Qu8u%Pei!wtd;+*Oe4Ttq70IIl8VVn=Z6Dcvpw#oL<p8-1_>^!rba~
zdV9mb_Qt-I(__P}PZ*i=!80^kKOfikF5bR0y}V^hc6Q4-(PI6P?Ts89Bi@!ycWp^z
z4j=33$7l67^=(deE?L(!t9^E)*tUG?k!@Ebd-@J*m_NA9gA2EHY*>?9-?E^7YPis_
zyu5n2;gR#3Kc}^O?#||=+mefW@>N15!B<1UuY+F%4+Qt-F984m000000000000000
z00000000000000000000;E&aWlISbLeLY)KUCEA;@>ukQa4ylAjZKK=vvcWm*Oo*k
zS{}(~cPD%LA{F82Nfo_aiS}f+GT*o)xGNMq89W+19Nd?`1ONa4000000000000000
z0000000000000000001hKWY=AuMGF~Y)y3~J4y=IxpcZ~OCl33kDd_DB|5XQis(rd
zy<Lg+WVVpio$Tq0R2LfVdx<9w000000000000000000000000000000000000000l
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
zJ`(&>DEL`E000000000000000000000000000000000000001hKW3*!TPn7s(>uBo
znH{S$>E2`}mr7>qI+EG;OsY4RO81-?ofTf)m1xiBuFcoV%^#^9sV=nN_Y%(^00000
z00000000000000000000000000000000019V%7OyET{|xR|VUGS@{b90000000000
z00000000000000000000000000091%n;M%C3Wr0dmWRWor4u8q$@XMVt}W4-jYUHx
zrPtk^3EejuH$;n78;Vt{N2+!W&QGUzbSE-9k{u&Wc0T?1X#8i9Vw2O0O{yX*(%Ibl
zR5q0xukQA6RVZ8$8XB$~ZSLrZZyD)28_%WVxoxRzd~3R^Bbg~Av&m#WE7=|INM(Dw
z5`)Q(c)F*M6Q6&uRa-jUwIz`m9qangXk49Nc`RrM1$PDS2rkNB000000000000000
z000000000000000000000002Mi%}bkopo+acY62cE$Q@*?nGus_OQg}R4&<_>gh-h
z%!=p#tBc0YI`8?a_a-vQp4>=-#(2ZrNbIb&FVufmBAe?@cciwak{yS}nh}nj)pGpv
zH0|t5b!_hIN$u=Qj<jm1%r9v|@Rd;Tbns;G%iz)Ak>JO{1Hpa4zXo^ZvjG4A00000
z000000000000000000000000000000;Eza2G#oCQPzYlsg)kZ`gpp`0S`m)KqM>kQ
zA*d(><%OWE5R^uvp^D0U>j}ZqQ1JWUH^CFZ{lQm*PX+G_E)R0S=6p5)0000000000
z0000000000000000000000000008`fULLItcc<H@C%U>)yVKp%`}_N+SB#fgGG1nE
zyv*o$nUUk8wG~HZ7AkgT(ud_u7%#Ij77c~V3qe^SD6P!Td_wSzQ1Eo{Wbn)2(cqEb
z$H4=^cY}L_f6iwE00000000000000000000000000000000000006)rnOL+UJfRR&
z7J`acv^-p12+9gUX(1>n1hGO8Ed-Hhw7jA+-*Q55ODOnV@ay35;1|J9f(L`|2LBq|
z8QhW21^@s60000000000000000000000000000000001h|M^Ozk#OjWlHn*e97Ttt
zNJ%tOkuQse!yT2yup$;M50@8$vO-W=$b4=>WxksU!6!q()4`L$FM~&eM}i**4+P&0
z?h0<rX9EBL00000000000000000000000000000000000!2eKH(b90Jr1ZMGuWGts
z!okFqS3gvFFfnxJJr%KNC|q6$$_hbgAt)&Xu|g0n1d(VoR8g7lF&f+(3Vs><I3EE3
z000000000000000000000000000000000000KlJ&iLr2LctWV8^t!vRYPum>OjZ_?
zS6=;4q&lChs3<0f?!2cmUq2c=5el9Tp3Fx8000000000000000000000000000000
z00000008j6LrF9ojznY8ihLL?uc*vtMT75!g8vA9mX81c00000000000000000000
z0000000000000000N_tdRkSo5Dk;70?yH(^h#pK_dG$k)3DMGuVq)mddn)raBf<Tl
z;Q!_W000000000000000000000000000000000000002^6Ery%IlUruMR$64s;et8
zy*=GMITk)W+%cMw&U8j9^YtbL*Mx%K1-}aZJ@`rRK=7U5p5Pn7?ZM5#XM&Ff*9Qmk
z#Q*>R00000000000000000000000000000000000@X{!ag)7446N^z<bulWfDn=y}
ziczex7)2|JQKY;iR*|n#8ViNP(MiQ9QZ^iw3`eoyC^{TPO7c-fq%uF$q~Kkl;P=6=
zgU5nLf*%Io3%(WH8QdP+9DFADSa5xCZN3-)000000000000000000000000000000
z00000003SJWwCHLTo#=$97ifkW8sQ$Sw%i750{k}Q_<35Dq2;n6N#1$$B{|J(#XVO
zX{5R|RuK+IONvn>RuZeox6Ft6qFAiFyrMEc*red>Q1GkZC&71uuLm~;HwM=R?+Eq>
z*`Om>7c35D=ZgUV000000000000000000000000000000000000HA1MEL<8c50#W&
zcXuXq-^60FteD*S^yAgVWa((Ks+cSpPJZ^lgkmx_nyf4)qr=Hhey*aJj0`6~c29YA
ztfDkLoci!1rPZ;}NGd<-q{C8?L#h0j(J`sd9w-}=x;|8LD3xB(8>`BvDn?V4`L#{h
zlL`g*1qXt3aBfhx_rAT??(N-k>z*s~*#H0l000000000000000000000000000000
z00000|Mkv{t_k;cCEAnc<OX|_^P0}grZc&D4KvT|P7JgrvwdB;?7W8h^6AmUNVQC|
zBb7<E=dvr(9m#n!hU?Ecyn5+SU2OkogRSYVj$~%u{8g)#t!Qptws!N1MJv~xIg-0>
z<>Hp*ixzG^SUOtJwrbV#`OU3o?(9ou2HOf#YZ#f@j5Cu1?OlBx$(CHQyJhR@L?+pj
zyC9Km?&(SA61h~mXI@uoSF$^i*)e6t;;qSK$GX;*!{;~J!<u~OsboH<tgyaqxm<7d
zoVvRH{{HFR>D{TWuEg|orn4^DQ@d_$-PZi7x26Z`dXoKh6XrzwUS#!#8Pn?viEJ*@
z*Hc$HI?fU8+SA=fwA+^K>aB}3Mt8ip>g|2mT)I28J6RWf@om!G-F-c&++ba-KH6FF
z;@af*I+N(Cn;p%*xIqqIf5lnRwa?!!u_fJ?t1GF@AI%BD;!yBd@Idg*;O5{X!QTdN
z3kHL2!G?S`000000000000000000000000000000000000002|0gj7K3GZCHX4c|?
z=3UvH^ZO?hGI~}w_Vh2<wqVPJ*_P5m#`YBp=B%HwcGvpBfu6ELMn@{KaLcar!u9KS
zZH!EcPN~?kv8}fy)3Ts;#rCCz3L7_FP`j;uZExH9!R@g^#;P41EzNV9*KE0P>B5Ra
z#@x)N4Lb(cXIhqSUshhom@&I~dFTA5wi&&RYby&G_1Wa=?X4@<b<Aj4SW?VLrY@Y7
z989KnHO!Az=4U@Ch=hX2f(L?c1~&&E3H~;?JQxhN1sj6J!K~nn;P`wo0000000000
z00000000000000000000000000001g@{Ws638&hVbC<2_+nHRkW_D#EW5cp->D6ln
z*VZ<6HdGWc)^1occUfj>!?x|q7MB(>T6<dCm$$8(pSW=T%<4kM;>MK&^ZRROw9eVJ
ztg4W)a988bmX6w$ZF9GGl@~K|tJCT24FlU7`&O1ricYDRKc}^O?#||=+mefW3Kg0M
z7jEm=uqL;@WkG$UkTE+qH`my;e$(>VOIjxuGMaifZCQ4~&cT%}%XXF(GG_HR^=(de
zE?L(!t36uCm^pJ}>tJ%#=AQOV%O({v8kXd8I|tTwFI}{4$Am&geedG!OVi6+wq$3w
z#3~D0u<s?l1poj500000000000000000000000000000000000@Di)c|6;+9Lc#BX
zUj{$VUjP6A00000000000000000000000000000000000z@MbDSU4P>7>O0*>PWO0
OS4AQvv2aC2^#1{D=B^R|
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..f72930826141b1bef15e7a9d0310d73fb93e53ea
GIT binary patch
literal 1179648
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
z000000000000000000000000000000e}Z<_PO1qdGWAuJmEmyt)Xn*Pf9|w~hM}RM
z8R^W{RBvx$Mkd?cknF2pv$|nZDx2Jt8E)uH4mB*y4E6P95?%4dqnYs^?RbBDaW<KZ
zuT5@@w`4Ozxn#DKxootb?rdg8qPI7-HItrE?7rf~P+9r)4_tcnm6>#R%iNy&-1)O-
zuI;X_35|s6tEwtPuXs95vu8BUXeuUi`Rrg{!@eVRl?J-xmMh!y>l)MDZEY>HR`hPF
zstFD4HPAlebY{{oGfq0wd4O@UH@A&!$#tGLv}Wnzvs)INR#_8T846Vv#;FWVE&V^|
zPb>bf-OreNQZAFtpV2h?q;z6<RWdi&o6num)R<k>xN!EGwaW(=wyxhfrJ^>pb7Y^^
zn=-v!$?O>|D^{Ghta;UWt2>r0TE6C_vD`Jw7q>25w6J4$>3Bi=iWN&+npd4PFqq7a
zv==APG&X^mdr#n`<Zx&2U{`Wwp<*go$XV0Bq&b~lw0=%=cWP#NO{jUF`ILH@zjr6g
zTIaS5tX|icS(je4ysRd)I#gd-IAM{{OYd}IV`ebF-@e8|m#=Ic$Ys|qTfThG()H_O
zHKCqY*5CM@E99gH`%?Ll{rZlEF7I!jIk=!@Zbx%+cKiD1tM7X-m(QeATa)|s9SL3D
z(bLh`zI^7o`hg1*?UBNhR_eRzmG-?k+1tNgx1r0=UcYX5pu1<`lK#2#*M@6C-KAbb
zuXx7EzI-;(dw`C&EErg@Wu&Ek&OpbO+QQo*8r%~Ko(vu?L;wH)000000000000000
z00000000000000000000@JH+LXhkR-E)RzzlR{<X*FSLS)mN594vSQTs*0J_rMydS
zDdZg*t_W3z%d5gwrM&FTZIRky2RmNl1poj5000000000000000000000000000000
z00000z-z3!80>hBCjkHe000000000000000000000000000000000000I#vy!Y>ls
z7Ycq>2mk;800000000000000000000000000000000000;E&s}k@C=q;mWD$%+^$I
zZ(>F!+ugM}pYP9|*3d9CG&G|wTquuJ9x-0tnMsE(FBVi68b^X3hJvRH0RR9100000
z000000000000000000000000000000{HdA}Ju#flY)$p{CT3)^-I2-B6RXD4otboP
zvC2jN5DLB>d^p$;G;aUZ_J7!Z(e}4&4{!U*w)bs&>$W#s^pip{000000000000000
z00000000000000000000008jc*r`)$Lg7$2T(~SRpBjxsLS^OGKah;IjmIlipFc0R
zX0W|)aZ~r4$u*&>aJcHkQsv6Xs$^%fFCTADbm#VMmR*wWXd79-w7q-t+B0fP%_?V=
znpKQ7>m7-=WHLSJM7Af{HQFq+dA#{ZNB`P+^ZM4$9m==Otr=}TwbZ;kx-65+$InmY
zQu%$`g*GpoGk4LN)ZBG_vzk}WnpA2Req*U!Sw*yYV`eZPUo$$_uFst_9-o_A)zsCx
zVr~Dx{7v(!M;na}7ORLXN#^6NeOofUTgFD~`pky$xMyY8;Oes%E^S%5s`>P)(Y<LH
z-N=fw2XpyMI<++!U!2M&H)V!L8+~$j+`4t<qW1Q#p%wXM3*THhy2PeZ<4DCh$=?2W
zqOU97KA6vBQ;FWOIp1)_c-*pLRnN?}Web+JCt6Rd7`=z5j<${zcBu6KrQdtxkKQ=G
z-h6-G!1>+thC4F#$@%4lk*mU0qiv&w)#g)u-SO4=M0R|8ceniLjU#;nsU>qSOeW_p
znfK<h;;2>Ou{lTA^yM<eHoNcY=$tp6F}7VFd}yHS!nRFA%ja*&4GqkQjkZ2wY|gvS
z(0Khqy!iaY;>GjU4lQmzr|Yz6ss7mZMs|-8Z_i|UHzu-swJjWkj)jYJ=_Nz+XRcY=
zIxkXcTRCmtw#$-zgL^lOwar=6GPA#Hps~4sY45afv0-Ip?P$Y&=eM<GcxK1QoR!_P
z7vu|7LS?~yq2M>cFM>yd2Md<~00000000000000000000000000000000000008jE
zYEoJB_2I$3O{v~wS6O8&dPF#%=+4C^MGM*aOs02ZA{(uY6tdIFzQIUUIC^wde{Z5Q
znX4`|E(`7t1<wRe29F016)ph)000000000000000000000000000000000000N{_>
zr0DCzgMFJ)y~(b!;&ncg>D`#fMk}L7g!75+T&ya3bX9+EqBEH*W~GyTgOS=|!yT{j
z!~p;R00000000000000000000000000000000000;5AlV40gQ6lK=n!0000000000
z0000000000000000000000000fY(@UG1&1MPXYh{0000000000000000000000000
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
znQQ1u<~p;f{(LIacT{vvxUDzQS;$>osFiOSs~xE=w%_p@&mRB)000000000000000
z000000000000000000000A6FYg<mYF4h8QIHV1PG7XSbN00000000000000000000
z000000000000000{0}!RHYpSihmNldhs(<+M^+^}lYRO2M0YM04V9H&|3EU<HXb)c
zOI4dnRcptp_Kvh<GCk=;wkO#&-XyenJpQvtsmY0@CN+^|nOy$-R4$c2P~8i|HKA}-
zXy<6<XmeLreB)Txxp+Pk&u>oU;+rzPUCC@QnM)=MS;=&~E0yc-O^hVF;+ei;PP}Dz
ztM*K$cVi+uHdfa)caF!kg_XyGrciKy@ZMlU;Q{~v0000000000000000000000000
z00000000000A7juSnTA}>(ZI69UC*5o^&GHliMrNk;*62slKk{@SJ$zzlLb+<TGEY
zdVeCD?8}cem=$kY5Q&|<`sMoXP2}?FOjl}CD%rJXteN51$*qUKMAPoUR9DAfUus}5
zIo7JFy0D~4!M&m2x!{@LSHY9P6Ty#zM}voge+}+0WCH*I00000000000000000000
z000000000000000z#oyaXgFLksTjt}ieWTX3?tE4v??5lMML50Vo+5KDvLoyF({8l
zLsiv<){}yBL%|<{-v&<yj|BGxpAW7HE(`KOM<E*k0000000000000000000000000
z0000000000003U4*G22Y=}hO0L~n0uYbHHoXlQ6g)qyh04wM-?P-gT%nUTYz^;P?3
z7AtmVGkfJtI#6bHEE)<|7K4gnP+nb_`J~`$q2RgTnc!E!lfe_gkAp{phl2-$e=cML
z00000000000000000000000000000000000006)rnOL+cJgFE|7lW!;v@%>-3@VC2
zc`+y}2C-rgEe4Tjw6dzY&~j36dnovQ@SEV5!7qZJ1djy|2mcy;J-DZk4FCWD00000
z000000000000000000000000000000|NWImBjM2HWusASG>VQ!k+Nu{s!$dUhr6mv
zVO1<z8Llh_6~&;unEB$Q>Owb@g3pD5=YnT~Uj<JFPXs>>9t|E2?ho!LWCH*I00000
z000000000000000000000000000000z<*OU(eiMpto-^1F1`B7NxKu5+;V00?nL(H
zwyIb(6s{}=6~&;u7?c%*STTqegGe+Qs;VyZ7!4i_1-}Y@T!;Vw000000000000000
z000000000000000000000N_u?<XE^oJSkLGe*FWNUVUY>l&mf#FS+H)NNpimRaHu6
zZ*HqD)Q<*Fhl1yVX9^Jj00000000000000000000000000000000000008{YP!<h`
zBhgs2st`sitEvlG(crtG;6H+&6(Rrt00000000000000000000000000000000000
z0QeJA6D<#i%F3^Q;L@wFjP6cca?6#GNzwAEQX+eETXmu4l;EmR@cZD`!M_JT2_6l;
z6MQT9T5xx8TX0M8nc(BWb%kO800000000000000000000000000000000000004Mx
zl*htV;mXOSsG_zMmDiM_vPq>VR$YpsRi!9WSr)4*R4I>z!r|zYQWU8ejmk!&*k}|T
zjUr`*s47xj7-~xJfl%;=;5Wfj!4ts`gYO0p1YZyC4sHu>2|g2iJh-+{3;+NC00000
z000000000000000000000000000000uZ4<OI2^8sP8y9P)#b5pRk)(65LJdNDod$o
zc_|gGDb<NYD@NnUlu~JAa;Y>@TOO+lhofbsC=x4+RTWwm!a`9jR#{n9T^MXia7rln
zb?}qmJHc0jTZ5Z|YlHU&yMkQM6|4ys2lEQW000000000000000000000000000000
z000000000`GC3A54_AiD%CCPQ8EczdN>+>~YfH)U(PU_IO(|JcN_KtjoJpl*Y&7|q
z4b`P&bTs+N;i^(HGMc>MipttpRe5+c_0b#4Yh$6YRAHDYd!-^1QlZV!J*mQw6%$e)
ze5h<sYU3FjVl{<S)p)A9u(nCtJ{bxg3a$y#!GfS{`@e1f(DvSKzufjOg=_!-00000
z000000000000000000000000000000fd7V0imnXz_a-`%r{zcblV{95DVNFS&uE%`
zQaUlbDw!MX&F9W&YOFjq+B{aRR6c+2;_|o0c8-jdZ_4y`C9`L=tXOg0vgTFit?pR1
zX!)9x#&XvzU);KM(ZY`1rQ-$dD^@IRX<l{Gz+f^v(q5cN)7VUA?mg5=$>Gl4!LH=W
zLd8_FkW(=unh0;s=lgS~H8czj4b4brwx)V}6EiZ|?uKMv{hHMcn^M{2rp$0dUvj8n
z(rM9=S6IDi_Ke0EO~qs`pB?OLs2(3_pO&4O^gb;&Cwu!FBD11BudI6KU@o6Yr?w^=
zqOZJ7CY>JaOXWuzVvW)6s#n$~*_Y2IdK(r*hhEtr`|d#1$<fs>-7>K;Gnj8Et1g_Z
zNx|Y!@Ko?<@QvWM;8Vc|gUf>9pgUMw$OZra000000000000000000000000000000
z00000fLGy==+yAYmR#p~Lu-~UKD%W>)s*Pesx1o!7Hk=5sh=~@v87lcyQ*>F>@{nb
z4=!w7Us=rPZ=X51pk;1Hb8>cjteBBWcel*#sn4B1d*<3n#f*-gj>h)oGuPD*T$qR!
zGuHGkX-=mXt)J7}ovJ8iwCC3~rn}qPT4t^2tuAJ)Y#qpD*DhPWe9qGKWyOqTt#exj
zR<CQ!tV=H{FJ_#*e%<guchABl{d4C>stdE95=275Q^BLbH-g)OPX!+gE(?Z(?%@1j
zQ7}6=F*vMH3;+NC0000000000000000000000000000000002MpS&s2sa0EBhG%w+
z%vsqzdqMt?=+y8?-#}`~+zXS*xl87imohr~*Up>Qw|?$WzOA;Hk?-#tIKO+|a7U&-
zSy9Z$E=hN^jjUhV-o1J4<YLA^*M)7HhL+FYk{cQ*D`xbp>>6Bs_QIttOII~l7c)8*
zF3zQw49%apW@&4*n6YB@`SWsX2HX1<H+4@bW}KT_)zsCxVr~Dx{7sXJ8LeAqE^2S@
z8d{NGwy>(0vH1MN;>GjU4lQmzrz=*>SU6|yqBW_x>-uIjudXR(w5(XwGqY{kf~D<=
z*2-eWoHZ>o`@04joBNmcMyiWju;Vqp1poj5000000000000000000000000000000
z00000@EWTw{9?h6Lc#BYUj;ueTmS$700000000000000000000000000000000000
ez@MawSU4P>9Ep|U+DNn%*F+*^v2ayY^#22-A3Os9
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..30bf840b0fe831fcd744242e117c5eac9e3cc050
GIT binary patch
literal 1179648
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
z00000000000000000000000000Dq!()sCwPB{I{hDl5a`@=0C!d~fc|`uhI<{^{MB
zp;S7Zn4ZaY)+c+WtzTQ;k;*1JG6VHJ$^QC<nf{)1Cea>WJe(Q-$<7bN7iW{n_{QYs
z`21|9KbOpwGM5kc)0xdoPo&eSp-lJmV)qp<h04mWeK1@<ar5Bn{I=Hfd(U4ydwsIH
zCe#<2R#jCQdezgJF=Ki|F_Ft>`+DjR9H+fF%mdFK+qJD}!Lk(t^OtQJ+Pb#AswR}%
zZ<qr{Y0GrK>?qxtwnL2a<inGf%v-Zz=7oKmR;4anb!KHvXmu!5Ss0}<G^zCeoIkVp
zzji-+&S|+!Hh*^Gtkb#^18b7GzH~l!c4I@^`gGrtb*mGb)~#5zYeGeBXxHEYtvfR5
z_GI?#`72j0UEaKA>Dt!ii&m^ZZ6tU7ip4F<7A<VuTRK{>Zsp2l^PAV4wzV&r9b8wO
zK;y^+X6!$K(~<*i>Av>l>O#d-vXHZEUgO1!)~#OLbbecQMtM!B`GEP9dTH9flT8By
z&G`%0ZfI?ovuH(GO=xXsT4mvMMM5vX&xy^MzWhP^8Vg;S?p``${)%Z0n+LaUxG+`|
z+Vbl98@+FZobJA!RDSTFzN4WlSD(N1{FQ537B6jYOkEg#?S1#<@|o_`Q1YO@BcUsk
zsfMAZ^~q%`S~f0S7b!etrM|0PZQotVbnijkhOXSSqJLZOlJ4fFz6Bi{!!@DKQm>&`
zJ>z6gKAT7%qT?A|OO`KaZfRW5)ik%Z@Meex_k@D~6MVlA0RR91000000000000000
z0000000000000000002MAG4#P6`^prJX{$W7b+{i_Q7!d#IhqJ6``tPUUf0+f#;9y
zDmx-v5vmNAS5;P(vYvc+a&58o&ewVN00000000000000000000000000000000000
z0002+I;$=QJ74EX000000000000000000000000000000000000002M>#Vl$iv;(C
zf}a-x000000000000000000000000000000000000002^<91@CJalTfa#D9@D3wkp
zrf0I9?OpkNZ|=<c`u_g@>2={kd8G1~(ek!Tcj(GuL3N>VB=~VCc%~2l0000000000
z0000000000000000000000000006+BstM6k!`+#oR63oQp2>Db#z#-B8cnxlx@(J7
zF8yLCcp&&la8b~(<5xSrxZ~0tZ`~2z{<ZDz-~P7kCtUh?p%?%F000000000000000
z00000000000000000000_)qMN2{oZ`C>$<amX}Y8Mk1lI@@pUXe)xvbxNCW)W63~b
zQ*(Z>fA;vAP*pfwb!w?{Wn@jVE!mTguS<01O4T2J;r7vH%eyu-w$EzX(%#gt@$A}C
zv&xyJW)&mN(u48&naq~%M0QKEeZS^~c+rC7nw5z}V%g@F&2wson@=h=FOM$I<nr+i
zsaz_5aJwaaEt?iD=xdytpPQaJuGB94rc%4IifHrZOkX~}eq^p+=pBuFTRZ#O+s>QS
z(J{DnZuM}Z;lW}RktNA|yrpMbCcSNRw3{y*jhAoUI<$IoW7kmog7jHc!+TRdypa_P
z`f~Y9cWNjZU!2M&J2C?YHlDd;ZS#!Qc}v$WZkhX*%Hbt8mKsMY&P%3y<B6X3_`1G)
zCYws6N9O$5J)`mZhJ{_568%Hd&Re?t%!=WAc*bz+NMVOc|6lt3NB-0oN7uW#aZYFR
z!qm|0rdbV5<%N-}!d1g<qlMMxQ$3yWwfRJL@Ai(i{L~klx@NCUq%tk7vo>D*ma^ig
zRpF62N7wh{GQ~D~@9OZJAN=OXim$(K#;mSn`-;Y`xz0>(dThA$F(Y%{dxl2q7vkAl
z7j<t~xh#`fxnSd&(Ng`9?TzdmBfc(^NpDVM_aEzp+Xp+Fwk}zoTGF!i;)c1AQrpTY
z2ew_F?CIODVd3ER&Cblt^k>&JY|OV!2^SkyR@M$TJaB%44P7f&ue{*G1p~_)3ROa7
z!9AhiH^Gy^Bf<TJO8@`>00000000000000000000000000000000000_+vG$Ec(W9
zUr$FWoop|wj75(L=M$Z|*tlpRJD<s<Hz%^u%19x*JK570sR~DrtLjZB+LF2ILgTXF
z-cayt@Ko?v@KE6r000000000000000000000000000000000000002~sEv!hG2GYF
zkxD1q%Zk_eOeVcKk&RYHj|t}!ow-<5^th_tbfPVpD`s^kd-@`^#fCdy=ZOOV00000
z0000000000000000000000000000000Kn_4x)|(yohJbR00000000000000000000
z000000000000000006JE+G4Qtb)EzO00000000000000000000000000000000000
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
zMrVgtr4wz1+_i;T`S~NYBeli$J74Gd0{{R3000000000000000000000000000000
z0002M>#Vl$iv`u8-~&NdFuQO800000000000000000000000000000000000006*$
zaZ_UBLg8@e<jQckynK9QO|mW7lV6wU%*CRivhr&m_<s0?(YP^Ms@hnpT02rTJvcv;
z+0vcJZb`O}G<o=i+ehO+i<Fw2T53`gS)R$|H>7f@{GsYz9Igq4t3tbmD@U8#+vA%@
zy3WP(nRvb{m5X;|((TD?F_}vy3t7qTczY_>n@$WS+vAy@VorSi-d5`}ne^sFc66-k
z?;DM43oDNWjiKP);C;bGg$n=x000000000000000000000000000000000000C+W~
z#bT$QRo9&vYTca4Z0Sy9x8(Lqw5IaO?o>~Ea$t76@Lzp2cKSIlSG_lpP4?tR8qAD0
z&WprOU;9e^rxUq+ccwknkxI7j8*4^5c6!UvFVnQMFV)`K*OS`XmmF!;SY24sxZv(k
z@O<!W@T=gd;ECX;!6U&#!M_Ig7P0{V00000000000000000000000000000000000
z0N{^ESu`B37*`BqWyLTWD~6G1ELs(g#G;{abup+a29?F2q8OA%qoJzmLhEtC`Jvzs
z!Eb|Sf*%C;1UCmC3oZ}xL2Dr!0000000000000000000000000000000000000019
zqc=pSg}XCt(-Y}*YADk^y}!SIdexya%MO(pJ5*-$P??dVqtmJm%q&*y%x3n>8+WM8
z>R2=st}F%>#h|>pF!OQ2H$uVl!Lz}yf~SHff}aMD1m6qp5B{Z)4FCWD0000000000
z0000000000000000000000000e`I3Os_?jCP+bhFV$sTQWihBI2Ia+|tQf?KL9`e|
zqS4B#>O#wL!L6a-_rY(1Uj|PGj|Yzi-wXaV_-1fdAsYYy00000000000000000000
z0000000000000000RHnUk4D0wE6awX*l-jbjv{5zNL8UM8V<Ktm%^%8v@%>-3@VC2
zc`@^)an*%x#s&Wv3Z4(14Sp3o6+99AG<YQVUT|-4TOk_&00000000000000000000
z0000000000000000091zs)?3|LuKXHJ{Yc_IBqoY!1Kp;Rqsta`S9ebSTq!_ECv<D
zpu8BA6@yqYh!%rLG#aX^F7y};?hggO3VvFM000000000000000000000000000000
z000000002sPsaFIxI8>AR91fNgW>v#(NeOyn0(;*W4j`?g=AG#Df#5XldB8$qro$w
z;Q8R$LIeN+000000000000000000000000000000000000RJ_VMZ@7pG#0HYgwe{X
z>OxjDcsLaNd+_r@1ONa400000000000000000000000000000000000e`0E)<>63S
z`Lz#*>nBD>6AwIpY*%Dlw7ja6c=F-N)rFc9f~!Np?}J|l{}wzRJQ932xG(rdaA)x4
z;Pb&}g6o4lg<=2z000000000000000000000000000000000000C;_r$HG<N%JHSB
zqP7&3*Oa2Naiu6$U5cVrr6^Ka7ON^$DUXH1;pl`?6sZ`F%7&xZa1<SmB4vfBDpFk-
zYC`bAQ1FM~H^I}v6Ty#zhlB3~-wf^yz8ri$_)Ktpa802Y00000000000000000000
z000000000000000000194;8U+I9w4OHylT*%VXiHa79%isti|DmQvC3QYu<gsuPJ;
z49AfPrP9dwQfZ{NJXRGBN6Si4BvuxyDzq$wg`!xjva+hWFxZ4(awzz9@Obdu;OoIH
z!KZ_3g7*cxgIv%atPd6ka|^`)00000000000000000000000000000000000002-j
zJ{B$ySBA>UuYKVA;Ty)6k`<-o!!O)kTS}IXCTmK`vf<<xddHQLvEk&+msOXN(a~g8
zDH$0~es)h~ZLF$1Je>N}7t3p7p^;Q!)Cv2gBKuN>F{5KrU+AqEle+%CvVExszj;}#
zrjV){O;s1xHg5Z8Lcv49o*)yP6;$kaXvZ}>dbj`k_6G{t00000000000000000000
z00000000000000000030Nu3s59qvsh+LCAH2YZue&p9oZ$>z^)oON1vVqi@&*O$)c
z&Ted|JTcllQms_pw108=C9z$DBjp{LbbB&;_WYGAmo9H!vvh6i@<l7wpEi=ae#PRJ
zWs4TJ?kycHShsTJviZ$xPTSg-%nq(A&ZKc<CNuUQ>a^rQTe`13xw=p>l`P~`OphkQ
zUHN=(?#%l7{{H^y-I<|OI-QuF$#&K!d#0^lTi=n&COa|%^*zb{`f*LszE@d&#*FC=
z#Y8Tj?dz$p9v$a^c5RvN1KM>Z)4lbPnb9q;u6kQvE}!X64JGTNuf9#DySuL^l^?8+
zHAFkBUR|4HPd=MS*UydSUfm%3ufOW_=-QWWm)M-?%h#7x7f#i<U~wq;W$<Y5?cmnn
z#^A%j6~SQ86>KbI0{{R30000000000000000000000000000000002MYj8w#Qg~a_
zf@LcP<}cecv~_KDF(ci*bjJJ@(;7ApZrxB;%t)phhMLwVm#t{oxHMYKXj`A|Te5C-
zV$-@6t162bn+I3tx3!+%d;a3t>&F!{HVq6k=Pz8lp|xSoqViJ4ivDfAOS+qz`WAFV
ziW#fVUwZz^H7$#mwl}6?#f)Y18ZTb7ZuR1(^V_l&#f&BM)@+!0Vc(`zsS8(CO^8ma
zn$fjn`GV$_#sytXbE^xppAbYs!PCJb!MB1h2cHW5Hn=<(2s(oe!J=SRaB6ULp%?%F
z00000000000000000000000000000000000fIoRhL??v@JDavHS)N+bvi9PJ=!EE`
zs=<b?m8(}?aN&Z1<qgFOeX}!jGyT~$4IA@qkzz(~YiD13+j+A(ItI6nD`s>p&vYyq
zNNj4(5B5(eW^8Vp)7iW*H8i_vRzpQGV|~NIu1$&lp=swWU0zwtSl+dvv3*w4miDHG
zjpIuho3{?F-rU$V)V?5HUCdb0*RpBhg1*MN`MK$uV#cBc$u%nziNvzaEt_kL8BJZY
z*CtY#meyGtFD@@;%-*`Fd&A0QnbgV!8)L<cnM>9-&uE>ubnW7nxmCrC8MC^Q?JF9$
z<~lREvg+a%?0lVX0RR9100000000000000000000000000000000000yw0i%zgX~-
zQ1JWUSHUj|7XSbN00000000000000000000000000000000000@F%Gv77mBUM`ES8
RHWDqxHIYbJEL>F;{l9QYYHR=i
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..b519b97d27f505cf38126d321e5562e99fc5531d
GIT binary patch
literal 1179648
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
z00000000000000000000007|s(7}ef`baw8R9jOMjV5R9ER}|e7dJPLjEu}3$nVYO
za_PDGLSJ)cuxazA=H6@})0-b{9?Xn1FU^k(=JM&D)Uxr+)b|d&GqtRc$)vVscBGaR
z@*~Aep^~{~yq~^8er`IK%kIq&%q@4H?1@w*Z+qy5jrVU~yKKeY4I2uJavO`8+WN?F
zq^Y*HCi0@EGjIOfmU5z4Dhv-cA3M(YFxM7t?pV8WOMBObj@J1-TQ07tk8FrUYQkY^
zBC{(0>ios!f871jh36IXh0>+1^UoVdk8aEqhjXRkrL8T!9SioZZA~xVwx?y)!Rgfv
zk%ME$wC>I4dNPGem#ka2YEApbRhzojbgbQc-bC)^aD}TomUbO3oh;~Fw{G>4_KoN5
z9?lfTI?EGiotVJ9qbG1)X0$su+>_Z5R?KF?oE_=)>oOxNm$q&noi{I8A89{kK9yb;
zAKl5C+=hjVmTlX#wymvuT~&Q#bEK&z{N7`c7ue|Zj{I=xxQ$IjZd}{aw{6w@-p<x7
zD_3_W>LXn*vcvBDV5yMZF<i<V*K0g-<KpF`{bSv07It-RU-X7}ePrN8_BweUx`&IU
z{6Kc^@twyaHx^e8^z9lf?cCF{tgty&AL*`iUi+du-<in`9oKK<#;u$BHV%$%-`%vb
zzkOS@K9a3;8+q|_&V)OX&Yhs=T|08~Hnc3*x;(vfO+$Fc#)5x}1piMM0000000000
z00000000000000000000000000002MZ=O?Q)sfn0GFnp?sY>4V&<z{!ubL69j?_ex
zwKcVstZNH5H<W80c!_5U000000000000000000000000000000000000000lvAS|_
z;3b{}000000000000000000000000000000000000002I#2Ug+H27g8{2u@S00000
z0000000000000000000000000000000Dc>s7EMOZjnza3@_VznTzYQ4&=<L}E-Z)!
zKaPa|0{{R30000000000000000000000000000000002MZ;xs5b883kd$YM*dTzeZ
z*AQk+zxuBu!9ND?4Xz4W_Wxx6U+=$q|LgWg_uaqm9sAy}?^Rbn8WsZp0000000000
z00000000000000000000000000RKOB;q>}QG!l)5m&xR;cq|sFO5XNRF7ec4ykcxL
zJ<_s#@AfM?cQ2S$AE}K-YtOAzu8D2TbY})jsm^p?@z`cfO9wjIcWo@qD-_!<ZKyP>
zX{$7=o@kaEOD)Og`v=m6{!Gt!v*?V;=K0>1P1~2W=XZCn%Pp)QZ$7KiJQ-h;FP2hU
zvc+ua*mltweH~pb%U1OE^%WO%ww+RG7yX?|yQ=DV`;Po@DYbcguKgceJQ-h^$*kVm
z-M{IIWo>PX>c$(550<EoEzguvD+c%Eb9*L6>%VRNWW40c)oqIkWBFx$t6qOe?fBj_
zk8fo46~o0+ejvLylUkN7WP0<X<Be|FIT^PW=55)qySQuTa8LTRHRDTctu&5RUzy1b
zrP6~vsm|e2zK~7lCg%K}1C#OA?6S<xzLnj(cI+CtxO)6Myl}jAEZm{Wze|7g$dhe9
zxOn;M*Ke4=dO=~RY01dqWH@qdw0690JX~!lJJ^@nR7w{nx3~XYH&4bL*~M3^*)TGk
z+ufUeZB=>H+UUfb<C_PI`Er}X-|G0Bcb<Crc<XoE(XqPo^#cQAi<j;k?wXqzZ+-g2
zoDZL&$@*bDw5XJ8S$^fNrJddLE{<2~Pi$}O@EEDid_K1$T{x<3co6msEnd^#F}i2L
z+ErT@#VT!UW*^&jO=fWT=!S`>mM`t>-_|#<sxWWU@a$;0VNFfLc*A4ox1wc!e#`dW
zvFzx)v9L;{D)@XP_*wA7;Njqb@Dcz300000000000000000000000000000000000
z0DfJaQWbw?ba=2go6Gc6)g<DlM@#9xV&ar|m|e=}b34+7cug$K9>@$1$7-YTGi!%(
z>F!LiE^J&Cd^r+489W|55<C=M0ssI20000000000000000000000000000000002M
zueDR+uZ#{4_GWXLo~rV7DWA{nNEhNY@zbNFbYC%18$YvlD3|We6w6rynZe;$L%HFB
zmw4g;00000000000000000000000000000000000008h3t1AZwUgAjr0000000000
z0000000000000000000000000006*Ctf3qnc!?(g0000000000000000000000000
z00000000000000lv4-%I9QsmZ-?qJXjMfZaRT>Nv0000000000000000000000000
z000000002MZ>qPZlC_b8r{6ewc5>FvQfa7oadY!Pes8|eH@CZIaBg^+&E?W_2Q#JS
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
z@$S-w)jeA?9rJfA9J^*#{6BO~=N)xU+niJ9^gsEWUa@}b_KiJ-^oq>L$hOtj%!>Vo
z&S~pW=X9QP>YV;3pVP~BUNo?EWasAI*3EraF1cn_^gnb?TaG%Xt<I@)`k#DGFFBBF
z?<=j}*x%H$a`&e4$x80eMuN`<LGZf$&+Pwrm;e9(0000000000000000000000000
z0000000000;Qu=-5(iI@?ktstiWfIG59Ige3w?9Ddj{u*m)Tq{J$EouY97e+WYf*r
zfxhP6Y$4N|A8qbU@5y%O2j_;tW%F8E+nQPyCx6AB#(S8In_4egI2wND4h{BIU7k1?
zuk;jlG%_-BxQDRE=6NkG3z`SgJ(;HAp{B`B+L~JDx6WU<Xu-mTZ5Pd(pZJwKn0HhM
zZSh~ZgVv)um>0V&?4b5n>7eDP4q6++uO=4U7YV)<1^@s600000000000000000000
z000000000000000@N29w7LP1gpG$XVip`q_(uLBJe7--7`)5Yukrg{866*{3p-iEa
z4J-9zirt0mP$`=qtP9)6g1?Id{}KiO00000000000000000000000000000000000
z008joY-W5#?T&oDe;{4xUth=%WeTNirr6w*DRvjKL#1qf@QnC^==xl`JIvh_)+#NT
zs2yu4w?FU_&mRB)000000000000000000000000000000000000A6AZ;U^K)MS^z*
zJA(z`1poj500000000000000000000000000000000000zvX5pPKiXLk(o8oXfio1
zwlUM487y_C`-+Kpq$+vaL%GCLlW}XjQnj^GwPB)aZfr?D-#?Hp^k;e|n?z?!#=je@
zG&#4@q&~JLUo36O7PF-j)!h}Xk3?%D2gfVN+k1LaJ0`j=rb_u#X=k>W>dohRGKF%o
zn8}1$nSoSKwm6hak7asN`N48dYRTbNo%wujN4hXER{uNhn2a03l_!GMNbu$0?ZH*y
z1poj500000000000000000000000000000000000yckW1#QB#r4&?WC?a1f*2hxT9
z;!%mNY$-F49qh@BE=Yy{HOCX@U-o>}hth@2U}>U3TdMV<SmOLmFVuf7T`Udcd$PUR
zOwW<A=0y|duQ=^_n)VH6d%A`Pv%7~g6Rle7!X?!OUy1}z2Tuk+2_6p~3%(zGD|j&Y
zhcFWW00000000000000000000000000000000000004gdRK=swWL-H-RF%Vcq8!HJ
ziFj=^mWW59wdJ6u98{NsWIP_JtqU901znNg--DkAKMuYX+#h^AcwcaRPzo~v00000
z000000000000000000000000000000007`W$IIhQ(Y``{ZaSCC?#&O(9T^#!TX&+&
z+7o3~ohUPLqRjY-GGnL3n`)119*;z8%0YEGNY;gutPB1}BzQV_GWbdGc<@;8{ovu?
z>%jwICIA2c00000000000000000000000000000000000{CY~nYom4Lpf(Y&iPn^Z
z>T-}Q2UX=DQ4ZqeAQq3;)YgTK>VkVC!M_JT4}Ki{FnBchcJNT}55X71OaK4?00000
z000000000000000000000000000000`1O&D$D)xNtHz_mcoZLxVpZ{2ZCDnMMtkZi
zVQnH_6Rjx+)#V^r7j{q=+#Ly?4xS8t5<DI}7JNT=IQV+-<uDTf000000000000000
z00000000000000000000004eH)W?(2NLBK-hi=$-f8F84wS}8&6Y)s2rW{n4gJe0V
zDhG*j5HAO@csx>D7j_a0z8?vG5(WSO00000000000000000000000000000000000
z0Pve@S|XZ^)<vq4w>@;j#`|LpVY0TilDxKXb6r>=7CadVo(=;5000000000000000
z00000000000000000000008*yl8DzvWAS)RZC#j%1^*HW{w)ju000000000000000
z00000000000000000000007`OTYWqkjZ`IXd+3IZ_s33&Cu=K-YYR8mg@x0DcSnL>
z20sn{HFz|5ICwDlYVgJ2-r%m_lfhpE9}I2{iva)t0000000000000000000000000
z0000000000;H8mFL~Elp(<)JQLnTVqSE8y@Dp8`Y62)sPQLLsaQ5#lCCL+;je0n8{
zRgXti<56NfijPOJsxYdJ)rCV%58f3C{yq3v@I>%f@ZI1W!PkN>1@{Jb1)mK5BKTl%
zOIQp500000000000000000000000000000000000001wA>O?det&X2E9>?mEiD+%K
zx;BhzqSZB(R6JQp#p^3|V)5$nI5xdf8k<%rjWr|_wb5w2suIN#Rf*cLWf+D<i9}6J
zZCyCn^x%R>@YCSY;KASv!JWZJgIj{P2Zw@U&=YJ9mIaH#VgLXD000000000000000
z00000000000000000000sF;?BCZjcxs^o1C<q}U#t0b!@lMR(*ay%KGQC~?`Rg(Q5
zTzpC;nHW#rw!W^CjE^U8*;!jj#>SKHIZ)G(s7*%4Q}4Pt*^r1#q{3mQAC-ztNkwPG
zkEFsOtEZ&iaYxmW)Xq~cPt=F0+R0R1xVE}|k41t9gAWHo!RvzB{a@ezXZz>wpB`oc
z00000000000000000000000000000000000008_3IxoH<I+ROyXD%*{4P`D}cwRAI
zC|%k*|Ga_p=*CQOI9DoO+S*d{>UjG^wMzNoql=SoN*o-UDDTbZdNPGem#ka2YEApb
zRhzojbgbQc-bC)^waZql?pWG&xOB3hbKSbtOWHS{w|h8K80#$0q;+B@^Nt?syv%5K
zZn!72A*`6qggMo7<LT(mQfa7oadY#?$jID*{N8LXm!6w1^fhM&n>KH1?#&i5z4_7R
z!OTc=U30wqMONRL$qhBf=EnzKWc}{pVktk6-J5BSx5l%zFS1c)uvAFrnit21U*s_J
z=Fe>@CyJ%Q@L+RoQ@ra18g}QyA+kG$OPS`x1@X-<P&>UNKU`|AsteCXU9dG0JP|w`
zd?mOm`19b8gX@FQU}u;K0000000000000000000000000000000000000030XJ*7_
zMT;v3`gRSLcJ66eR)|lJ&#K+EBR6kD%Yv=T(@WQsEA)0O*t@nhy?ooAmQ^+7j2-Fq
z>oOxNm$q&nomXAX*uHkzioF{)6c*(+7VF9xTQ~J>930)gyJ=;Ad#s$Xwxw^|s`<U0
zty@;Et}17&$!%D;XxX++YunnoljV$#wJW!@cWvlso!_&iww$qe`Dp)G_nL)Wo!b{B
z>cYuR4`PwviQwVjE5TjCp9g;&Tpx@EJA<vkvS2~*n&7ms7ytkO000000000000000
z0000000000000000001h-*_|Pv!Z*37O&~=7~QjA?W(Qua>mf2Qm$qBmAjU9cF#+c
zGxEJHo3<}$&+qPDmuo0z^mTN#EL+jr*H>K7SzpfBnq8LJ*|)NL*N$ByHRX&IW25Pj
zmgRf5U(vaH`t<m$+7&JH^INv}j%7#Zjg>20naQl)+TFkDie+tWr<606uYUc8`KuQc
zhMJa)R97;VcJ^=U8(3ACw`n+5&gjT4zGBUWk>T9#-fXgxvAXm10|R4=m+l<ysw!tJ
zxpH;eqQY2yS>LMH*OfC`3-h*Y*j?PUbGRp6Th3@&I?&O+Yh!6%q1ZO9uDk^YUgEC+
z0000000000000000000000000000000000000019Vs+ss5qvKa{4)4S@PqII00000
z0000000000000000000000000000000001fBULA&(de{Tq7pa6;+42Q7OP4`Yir~G
EFRuU>Jpcdz
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..b35f958a662500d4347e750f8e6c07fb5b65b3dd
GIT binary patch
literal 1179648
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
z0000000000000000000000000000000C-)RNVf%J-5u$cmRKycwB=B(Hd?)<vvYiW
ze8oulc%fL#t|(WAI`gHDz5SgB3zhuA^0CgIRV%vck!r0nR_eSbUmPrt<TJH$X5(am
zp-Op0wpc72FORIKx73sino^IQdGzXF<*vOQxxS&}2Um_%Zf$7`?hb;MbW6|@EKN85
zWBOa_|Nr}KYi_8PE4ACYSKTm@J+?bv9V^zVw{>@I=-9DpxNB2!%h0yNr!H&0G&nUe
zzxu&)F_*90wtnZ%t=oHdZ|xu0-nV1#4O6LmcWm6et#8A?Ozw2Xo}D|lt?%7^!;!Ik
zWnxc#1l?03SUGnDH{_2E7RPe=yQ6}Ie3a6={cwI_EI+Yv?V3Y9skWeZ{(u_Itee})
zXl*>-J94;u*YKK+yPDd9y+KDywEpp^(uLPQd!Rg4>zu#3$>8C`dxpAl2MTNVkB;BF
zH`x{pyw(;6%cWYSaA2&KKd0G5@bHo0LTS^gLx(o@-`D%DL|ZWOTAQ8TD1&3wT6v^!
z{M^>#!NdL4{>qlM$JXDssdv@Bcv~>oXg&SfTR)U9j-JzS@bIoRt4HqHxF)w{?eYHm
zVr@a8(Qfc<j5;4JO18K_(?jL4HTm3;zOMd#wYKQ)iG}|!h&})S000000000000000
z000000000000000000000PqHJS*$r|iKWsl>7Xg~*qKMK4%+I;Col4_0000000000
z00000000000000000000000000002sB5SQ5PG00e0000000000000000000000000
z00000000000002MMb;L5W8qhW=mP)%00000000000000000000000000000000000
z0B;0W#8Sca@s?nue7sOBW>=IeL&3wXQARBMdJug80000000000000000000000000
z0000000000007{P<I=?S>5=mBLa~@#QLYTNMM;Yv_-GLRY4}s&{bARM7fyWi!~-YZ
zc_Q}UlMnvLgWvbyTOasJlnnp?00000000000000000000000000000000000{0H`q
z#fySi5Q{~psnpU$JRUTq9y{}%(@#!^-TTKX>sRM0<=nuL)t4>`(y>_j`bOcF`0o5*
zzEsQX$qrTLSF3C}diZE<S6_9@+AX)WHLA7rG^#aERVz+p)|bn}BiYJuJ~vtI#52=j
z|Nb@WkKR-5-F|Or+nPm_)t5G^rxM%C)mmm>p<1X-*E{~wbiM9cdF`F+_aEv%-f^Vo
zl19DQ+Zy$nniIVT%44<6-l?(P^tI`*v|+GTSX0}1D1UhC+SbWRlbt1-<D2re%;wV3
za`EVNZ%bRID{k%R>AG|4;r_05wc%USlWWsCxsc6wj#X>rk;3tOW@Dj}KUh9CS!qdT
zI_$e^peH-DasPqCd&a)EWpaw$jmq)nyYj`+OtzHE>=~<-D}`)vYRp&fnhf8zu2vj8
zynA2I-Nn(a{#%+Sui-l;YsaG%YW%<Sb9=t>(Dbm^-o3TF`@sIvU3(90Uzdt{PRG)d
zbraESYlYHKroWc0%q;KaC#PE&+R(l2*qswQckU=3`QD~_uj$y-m=k+T)pEVg%vGHn
z^U?CujGLZZ*R%4-_}0FC8;ZwvuSibTzH(~JGka*dd=&29zH4yc@V#SQ6UEK9BpT(X
zmN!1rM`lmCTs)Ai%<b#=OM7}Z?<@4|=!+J3<=S|oZp*Uyb+_kBV{<E>ezLl4-}w49
zD~}HMZ0=nat5<AkX`8G#e|+Vk&HMYtw%$BEwzDHD5;TRM3c_!MUk#rQKNp<>00000
z000000000000000000000000000000006-2)g?`dYhz=jgN0%~*VK|sTp6onhpNd-
z5>axkTrM8SRuV1oD0w7b8jGi6iL2A2#q40d+8R}E3jZhwUkslMzZ`xcIt2g#00000
z000000000000000000000000000000fY-H464%DYN(T$Ye6Fc}UMrW22eOq!OXA8{
zEjv_ArW04EM~m6Pe6^l5k}r+L+v*ihUgUuT000000000000000000000000000000
z00000006*6)>=QDyvTz900000000000000000000000000000000000004lCtgU`H
zd65SJ000000000000000000000000000000000000000NSzGjNs+EEV?>+vJV=ZI%
zN2dS)000000000000000000000000000000006*6ajM*u4o+Qp`YqR`mL96rMyt1U
zc8-*fmn%an26Lqq(P^Pr%&sWqYn>zcTp`<87#Zq3m_1q;ESILkj_#Y+9E-jyMoU8v
z?b@-at@WDLsOh%NcWu}mg_qU8Eve{u-9NmNje>2PH}vjV_d|m(?ObyIRU1=Z{OH72
zKmIG>*TV9bKJm)$eCu~df9fX(9{#--zp?m<=i<4(AGvYooqu)D-p~KuQ@5XZ`4i<}
z$+v!B@pYTp9{E7*%O|t<M=kGo=;q(}@Va~JliA$2W5b8n-+#I=k{!x-MxzOun!A4V
z(G@op4{zLBJKDGF=2dqOy?1FcnsMTxH&4wtn(+Ae_{>bBnRl-2>RR17lFj8i#zs4)
zC)?A}y{dcFnzgHYx_i1;^}LpeCWm^r_XfeQJh`^%2mdyTUtR0Fx7J@iSR2n)@<DH|
zd?26MTp#Q1d^R_6<kR`@4T9L8)mP`(pC5Snl~-<0EDbUzf8zZ&KmVnV4?X|)fB*6?
z|I#nL{G}iJ;je%Ep@%*lW?uRH-~H)_e&b7zkMDfTPsW1S?+2Aw%Li|+KJl3^eBq^!
zUy?ZUO3xi1YklAI@gvt<_V^uN|HZu@I{LexJJWSXaO$BC^bEZ-b<H<#fAcS1zTw9c
zUk?Xc+Wz_-%a;9Xd-9=2uMRG|W6@{3URvA}Jo(bcul;iC;QO*)xxfADR~EOmHC-D&
z`qW=O-rAK2;w``Qn~y#AH|>ef9esc7`KvBlb7s-;=1)HU=+mbsnlmRK`MH+$FP9c|
z-+#mBGPyJRde5Y8_?_0j>o^&l{>^7z+_tLi`S-u{#QmMEr++(kMRRjk*Joq#_g((w
z_^w~;{^H}G`fO}f+q1>gJ(<*Rz3<VtUekZ&9S^+a57w;c96I*#p~dg{!>4|A(YsGR
za59KL9z6TO=Q7vc^2pD9@YJ7wG4{!ioP6%&KY#pVAA9-s_q^%-Km9+xd0pn@RZsu+
zyFYd5e{1U9konf8%FjLW$TQ*6T_@u|z4(8xyW*<rpZLT_;(fP0`Hdi!{O?V>e&M(7
z7@7EiFTZK<7k()7UqAaNK}#Ze*-yoGfBAIo)+ZnNz!UF({}VrZ_4mi(EkDzK^3%s&
zeD@=NvG2}*dgK%DdhjjF|2X)^Cw9K;1L@4ku5HPQpG{ozV~?C{YI^gEzv#Ux8p5*A
z{BaOV1&eO{(NBG1_|wbJzfTW7`L&I^SMS(Txi?!HEDpbSY2x3sPgl;_rz`DK`}8}!
zPe0j`KRQv_zHh_L`wo|OzISQ--?UG==j_vN`_w-D4)4?7&1~MdWpsRO->Mz!_jJ8?
zY3$#$PrGLC)1I5{Q~UHgyib37-PZkm0|&PaZ(BFI?w<P2YC7?&LHLO<4BvU;U!zk1
z00000000000000000000000000000000000003SeHYZPA89P*~jaF~z>>Mc{FIR?E
z4CYEJqSHdLm|aoI*E&b?xk9$HFf!D6FnhExST0S69o;vtITn3ajFyI)?ns_WG+K%p
z8Xq5@X(4K{b7fc8>dujDF5fXW+A-ZoPe=Ev?p15nuI}mX>0Z^7{I(ldIj4b@iEq1s
z?l}!~$8V1sNPjyGbj@y{=jOI(LF3`?2jO2v2LJ#70000000000000000000000000
z0000000000cpYnxCxX?xirK+@wX=UDTdA!tmxrTpcu6b~Y(6j**;Ofz<}0;AR4A9P
z4ps`IwL-bn8r6@7pA5qP8yx@u000000000000000000000000000000000000O0j(
zNn&&QK)F0TlC2Eys+33bm0BTR?abw?gO$Q)txzsql~^6yRm=`Xsr^x@+WM)|@wR&X
zlNWjX000000000000000000000000000000000000001Rk+ntNWY`*nKN=niS4SrR
z00000000000000000000000000000000000006wfElXY!#A3mcmRKy6x-`B!KbSAo
z_GE{u$wbhUdhE=5PCq#vb|)G|yBkH@rivCP)|bn}BiYJuJ~v(E#52?3_rx1ju5VOX
z6yIL1*7g;uh1x=8562b-v2<{1vT&j|m&+WOYPy=Kl{2+Ng=*$txtPmW>d|UGA0_2S
zGPy!^w3wa9=Q8C|Jteb#rq-Tvxp*L3neMCYC#J);Xy(bVI|%<M{NeEa=mY=&00000
z0000000000000000000000000000000A7oZWb(#a+egaB2M(0W!z0<saCJ^(pis+?
z6iT`LvDKOAUuPnD<LwtJKANrMOSP#AJ(=#C<H;NQU#<OOwptr0=L!c4`P|vQR>qPy
zZoc9IRfon3xq-1#;mBBis#bSvG^KR-*&uv5d@+0>d@g)8{Oj<G;h#lG0000000000
z00000000000000000000000000002+y4943#hTLfW3s7!OeE{acp{ld$KuIE5NoL)
zn(K#DA`zrpqdMuZ7KHy2elz@f_?O|6;je~26Fw9r0RR9100000000000000000000
z00000000000002MzpFPVI$}eW@``M+SU6rDSus97z9PL)V$(v2$%PUV3nj*{NOYvn
zsh$X8E%ifl{g7&n#*+>|7lbc|FNQCK&xOy1e-l0(J{2Va00000000000000000000
z000000000000000006-2S~8K2rIU%4SWErTTtB4hho<@=SwAG|hj=2<l5UO4r^8PN
z;lG6648I<JHT+8Wbolx3vr!TN00000000000000000000000000000000000006xH
zq!RI1@Nm;)kemz>lR>;G5l=^XiC8R`P9|DnE%ifl{g7&ns;0v~3c{De7sD6A=fY>h
zzX_iXpNf(I00000000000000000000000000000000000007{1X;C5-3z|}ooq6=?
zAe~GEv6lLwxqe914^8z$vVKU^5Aj4INVi7yV&Mxx^Z@_>00000000000000000000
z000000000000000fH#n~WGt0V2TiHR&OCZ`&>E%0!k2^S0{{R3000000000000000
z00000000000000000000Z%BzmOS&}*W8psr(FXtk0000000000000000000000000
z00000000000Nzk8Nu<(2Q|hrZk6s<LM)Aer2ZHdQ!+!|>KKx4fbolx3v*90vXTpz#
zzaD-#{Q2;aC>sC(0000000000000000000000000000000000004|PHGM0|DT-pel
z+ZsV?Q6p%&q!A=r8$lx72;wbG$#hgCl?-CB#NtK}Z=MXACWGW;keCeOO;M1Jw?<tp
z4u3od|0VoJ_<Z<m_*dbdhkp|OVR$C|SorJVhr^!_KNw{L00000000000000000000
z000000000000000006+n(436LV$F$5Cc}7ZDj7@1n$uCx5^HX0#1g4SEU~CjCZ1@X
z4C9L%x$#RIx$(ACG98O0ni@eo*_2F2HKSvcl}xs@q+6rT7Kb+l;Xj052|pixI($6*
z<?w^y4~M72YM2Z6h8x4RQ8oYo0000000000000000000000000000000000005n{h
zjHO~NK~w6nGw(V5<fV;h^JMhIGi{A%YC5{85p9}`-t@Ig8qwr*w6zgUOh%Vv(v4_*
zGWxc4Ep5qkDmEFr@=&TR8BE7cKe>2LEIuoC{H4UK*iBz+o)v3)vgvH>XgQNy6vfih
zvDRpA=@aci`1$aEg`?p+!}N)#PW+b>?~IZF000000000000000000000000000000
z00000000Pr8xnWNMvK|O{4KSK(fn;|Zm5<kwcEN^-7u0pwmV-PE7q#Fb$7LVSE6^S
zSR;Sk-0al5lcy%8@(-4axqRie^*eWN-QK%<YyZIZz8!mSm`dHdW8>y+eH#X5a;G!)
z?A*C+eedoYj*R6i6MO0->7E+N%DG+LkUut99LweJjtUm?QA%@XVlZ~7RvWF}(%Csa
zKE7h4e7sOBW>=IeL!J3j$KL+VgM~`|VEI_*p?q<)GrlS@@*2wzj#X>rk;3tOXQDe%
zNWaEP`BJTtEq1O;jJ?KgdRDFIsz<7|%2=s0-H{l0m5PJqsEfjZv0A<}c~fHVtCY?j
zD38@Tn_8oboemEL;q&3s;b+2+g&zukGW@}CB1!@P0000000000000000000000000
z00000000000D$kf%MwdtM}`ZfO{)$a+Sq?zZ?c{+S{u*zjvOxEHN0kHs-AFo&rnzH
zKw<6v(eZnm7AKabhstAX^0^~@UH$uN^#c9X{>qlM$JXDssdrVPp0I1p>XCakuE}j#
zd%QnhPuS40W7Tlirs9^NZHHUx3BB77=O@PU6C2mAIn-QFSh;I&N3L(^_`#JUm2_(~
zw#8vQ2%it14nGrqEc{UTKf{N@W8qM^FYF6fhi?zBh_V3y00000000000000000000
z0000000000000000QgVuvc%F@tvGmi_r9LHi=$orE%k)zwteI4*Q`7`+_SkiUQeiO
zIePeLZC77)%i1lME>0{>mxng*?;G2C^YGZtj(UO8hQV54O>O6){Nb&a)Dwm_bZ<L$
z=fuvPJIY5=^@KgWoA(uZcJvKx+`lqWPw3yjX8qB7s=eFqEp2P7C+yz7YjEK3y<=Sy
z#m&ij!q$$St~<9L?(bSx8*Z&9^xZYklZ_fUaCpyHx}LDEXXTOct$q786p!t0swb?y
zduw_3f&Hbs_8!{aTu<n(mDk?6e*dBV;~hs9H4^rZRo1W0Rm!=6Ba2(>OK|ccUjhIC
z000000000000000000000000000000000000Jz9nqi-_&>mdB+@P+X2q7wiB00000
z0000000000000000000000000000000QgU-IT?$^E{!J}VOu=W2p7fUP03g~o%sJ1
C$PrQi
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..ef5e1def9b7f5a5c6495a5c3ac5eb76cb6a6038b
GIT binary patch
literal 1179648
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
zb5Ah}0{{R3000000000000000000000000000000006-Eony_dZNc4}J5tTfu~_4>
z=6#jQc=?*n&dJHim1D(2xqLpevRE4J%oaL!@9Z4Om9itnsm?-fbYCSuUCoy(rHMl4
z#(F_|TfHE?v09MspD3iaXGXK5rQ*s=KA$^O99voKxZ%a1q49xdJBrOCYljYPzHw;X
zExFC3LoIDVG3ZF8nu9aVWYIaCI?8Zuko4pCmCC(?ckJJj>sx=*&HGbrLHN>xjF*ac
zWrr%|xzSdyUD=iCeyPDO{Lq7U6-u}C_2$-X=-ajL+UB-kM-VhegEa@sQni1W{+jB)
z|9;)t%ge=5<+|>xE+5NG^=Hcy`AYe^?yl(@#|}>IDQ)Q8GTeLY+@^DaW7DTLA1UUC
zv!&}c^!44kwWt5qoda8Yx9z@sCc1mu#?4!LZyJ~@oh{ha*SBRuPygiyCbFgJUDX+M
z&&*)e$uqb-J2jM_7|!m9D(13LWdGJx2M<LnTHigkdv#-5&~xg9YTc|qxtHAS1H)@a
zyEd&K>fgJ)p)J@QbTmf?EFLvF^8w2Y7AGpFZEiAnXJ%+BJ2BY5Ds$`2rQON4VBqEU
zI8-cDO1Z&_O7^sF6Tv(C`*yCM-oO3euCXoa-;!tx#$Il>v*%)HqFgDC<qn<RdpvmO
zZ9|9lPWSH{-n#0*{@dbh!BDOD)XVREUp7B}TF1dV$BNswcJG?Jdeg{6<&IcekgN3@
zd>6CMMw^n!FVOY&)wivi*pM68*u8zKEqXpA!jA{x{|o;*N&o-=000000000000000
z00000000000000000000;FauEiKZYHYm7C=TZ4wi2cGRHHaDCXZwgY?SW7LGe*C_M
zb7M_GbF4AdoT`N`{Lq7K)z(MP^6UWs00000000000000000000000000000000000
z0N^ZZsa}qr<w*bl000000000000000000000000000000000000Ki$+7X8G+uLaTn
z000000000000000000000000000000000000002+gW&vFV{lo#IT$M*%H{K!mBrF%
z@XnT~AQnCoME?T-000000000000000000000000000000000000KgB9a}t-O#)^k>
z`Fv(&u{7Eig_hp)U=aRg_)FoPVb_sok34wfo+CecBzE`{hkxeqn-9P4o~NQ>00000
z000000000000000000000000000000007{7*qfFv31UGk7Tq>BE=$DYK||vM&*Z<o
zZ#M1Nk<I41*7WVn?mf8XoFzdj7E4`LtK1y#&kkh^mGrL6Xt`efV~^L<r=IVrtlPAD
zXlvij1BD&ewbhz6udX#~nrW7wPH!j{_m5>t`?JIKX75;EPd{+;mg#b4Z|}kW!Ak%B
zwM**Fm(`j#CbkyKmGo`7a;`GlZpS<7Y2|}^)~(%psCV1oy7C?4t6OXBVy~~YYiLUJ
z3>GIU>D~3YzV(Ui_4I2`+_Gz8eOG0&YyBN}UA3;I-l#rUvMIhPTS;#&94zJ!&W!ff
z_uOAkKYV3j$A-P*>&Huby0`4THdWu7&iY0+-8fOM6vuLhvgwVvQg);`Rc};!q@Mox
z&AF{xdM0|iZtTkEZuybs`VzZqjpI!>XY=FfOkp^^Yobyt<udvDoc~)cU2nbf=*9zu
zT^sHixp~v(y}4_e>Yw48>aF9^4%Pl$`jbX}%l`GV>)u<sWlbeNxjj30aO3*MXyjBZ
zRd1V!R$IvxM$<bhnbPd`zWJVS)YGqS-#0nfQJk0>xnsJ2^hX-1qo!grb586ol#A6i
zbDwH$&fj=(uzn`?ESs7rjO6m!;eo1^$$IMxX68J5hGy$m(@GQ@m~l;_R)1!D<8x!A
zcNL5I!A$9-v7!S}sfTNA*TrjXo0p&3c5AjUadN|N?;DF^vx6>=RU0-px78b-I=@n}
zSedOFRS6oxj|bs5!>@%;hM$RU0RR910000000000000000000000000000000002s
zm8!KN@!Hr#VI-H&4mUI>6BooPnbC5xH4%j?#bSOiQ%W?)qwrX^FcDA15*Me&^O>P+
zxg~1c5Pm8Mp9{YpemQ(1x&;6L00000000000000000000000000000000000fLFBE
z#A{;{g^^r7JKRvcuM~^<!AvR9oVXxX$&8khsl>&p@qA_|Tds!2vW1CwTeacQvpjJC
z0000000000000000000000000000000000000214TB?_$XL%9;000000000000000
z00000000000000000000003~7wN)=i&+;Sy000000000000000000000000000000
z00000007`DYm0swDuv+io<kp;YM!_=x&;6L000000000000000000000000000000
z007R4W5tG4aO{HP7hcl1Y+t1^UcRQYbF6r%SQ=e9G+bC2-RAQ7%*sNx(m9qL&Sg4t
zW22oTnS;5ZVqrGz=)QXGRP?iQyfAw2_HCQmT3*u<b=|i4=9~JX^xW!Cb7OS9<X>LQ
zM9G%TH}&jV|5HQH_g#ADMH?Ic=E3Q&J^X?28)5MakG%K?-}%GwU;4#?cYf@-Z!Uf8
z>+#{<pShy%#=pCL_h&!$x$BR-@JKPZ^gBPX^pZ_&_rELl<)fK9qn@|jd-d<WfBl~7
zVm9|~yXpNK?mV6w%Zz3_quB%vO<j+6+;iu?Ej_p2b?fHI(G8n#d;79vwBp3Qubx?P
zwBX6f$+?wAEAL#@)wQN`EHj+#m>BPvUF_<P?yI`5TDxv-*ZNg!y4Ss&g(gRPw)O<U
z2R^Z`;V1to%3oaR-Ba0F9H~rZO4*=ixHy<iZ?4X@KbskzKJdxxj|4&Nud2H<_4&aU
zUVQQT#IhiL^cU{C`spt`Jo@xM|MLsK^}hGL@P(iI>1Q6k_ufy2=@&oy)xUi2?|$K-
z$-WDJF&4!BC@966-+guYu}?qo#PbigCLVop^$j0sdB@Z71Ft#vp&Oq0&E4-k_=lf)
zwCjf8*uC#sJ^G`Kulcv@U;Ufs-SqQ`XTqW8w!eSV^5x%dPu}~Ui-U7-Sn_z+^GjC;
zpLqV^*M7NW=pC7-?rgvK#iea+4X=$K{M_F@)Y6p*;?3{-y$2rnQhVYv2k(nLebKpV
zA6;^&>5m_J&y&Zeo6<+`|Fz}~FBFz^-+B3G(!-D5*7IoN<$uuf)sCaV@!$L6b6c)z
zd-}fTAG@=&<@iTq=QlNVbv+)7zvH|w$G87Z_uoA9@yBCVwS6Vucze3>_uuiJ*S%)v
z1vlJt;h(Hs**QA(@aWPX`_s?;_L94g-g7jFKNNiB-Cs|?_L}>D?cK*d|2MHe{@~HC
zAN|(DANj}&*Z<h7?)&Bc^>3G?k6!fTNALdlIsc=f=ce>`HkE$u{`<ceF57-I{>w}M
zeEs<sUG~@`AB^{2_la)?vE=`3*!~;8f5X`HPki}RL%;D;>Hq%tUj)sG<hj2T>;Llc
z;cGu}|GOT$@4m-=_2Re1;?2L(e)N-5&)t3hU*C4)zu*7JTMl2i;?IJAeXQ>-?@FbQ
zc5O*c|7zkjKX?DphK5(K{Og{JqA4u@^q&Q>#$d@6Kl|}V_J4B4qUZEu8{XF3zhhG|
zJAQEI`0W#ww=YZlr_SlB`RBB2wR7s6{uiIq9XH&%_pa52-BY(^_7sNRzAXNqI;Y+9
z&goTGcRQ!f>3{J#eZy3tZ`+#D!EIy3q1&&1`?A=7>YR4XKc{QfIH%6(f9*N#`MF2N
zN7oFOH*daq$H6_l)sxk5<hO(HkuVH@^vJiPTL1t60000000000000000000000000
z0000000000UKutgk6jSkSE-Dbuj%X@D;_GAMpq6E7gk2MxqLpevXHHGj%9~)na<qU
zXy-`gU~Z^bm`yvnuU<P9{j3}>j5gemJeH{S6m>K?IXTxu)MMwWuC6tmW0~P>$HaKY
zY$vNby07ZKYVEqUUF%n^>0X!ot~*#Yzk{yTiSN3D?s*+tb#-_A`ly4{chf=F{0`Qv
zX^S>A9{y1f{%v#t00000000000000000000000000000000000004kju=aQ&ShGE!
z8OoMBcaCLBl?}z>{wUplX)F<J9-PT+FBQkLrAjWUG@LCDm2%^iT(Qs+wU38?9EATE
zT>t<800000000000000000000000000000000000;Favs#OBmsvABOMQ`*11R2<Ki
zD!FXAb2wWbD&@v2xnkj>#G2Uld}b($?u=?xHq6wHw^iF8J<Ib4000000000000000
z00000000000000000000004lqtS$OUhAlz(v*EsQO>_eQ00000000000000000000
z0000000000000000KgBp<;m6{77H$Ij>Q@q&x!YEhq8sruFPmTnFtyhA9yDJ)bq1x
zccNCcyH>SrrfPnAL$SDjEK}N_9iDCS-aBX0ACA|WTvltcB)+v+uH2R@=PD=aRz5hJ
z-W6LC#8SbrdgVmV@Njx?rt5OLQcPF&<;v-iVtzPVs%FdCY!u3lrH6Cn@qA`FJDe^S
zs*&`DxmLT1#r$BVG&9!TPu?(_wnZyXhTTE<sqm-6JEI!_00000000000000000000
z000000000000000004M7I+DpNu5BMH9vT=d7Wa>3O8d(vWd?GU>{zZaoSj;ej{fUR
zB(J#sOx4FTrEH-x(_nSF`|5b|ik&aje?C*Lj1`A-Bf0GGiLqA2l2>d#{|rq>Cvw9B
z6NTJ?iR?_P?v`jtt>I%q_(J$x_-y#~@GIe$!Y9Kg!aol`6@>u+000000000000000
z000000000000000000000N@p*ArXr;v{tXlhUztutX|`ZWFi%dClf)erFuzKFU{3U
zQ}xoANCc^tsC8?2OA!7?_;2Ae;opXz2!A{LmGIuM5)MRR00000000000000000000
z0000000000000000002^F1<R@5gRQPS7!40+@a#w%E`&em8}Z}TNVnY778{j6ihA@
zOe_?PpP%SRoz^@N#G0#@rs}1!C7O9__$NX5Lik+xZ20x?E8&;IC&SN$p9%kO6b1kQ
z00000000000000000000000000000000000fLEAgA{A?`URtV`R5H;VYp!0Js+Y#<
zrJ;IBRxgR_C7wt$r&^+xt>H(5@LS<G!*7IN3!e(V5PmNF^YBl@KZ?Qt0000000000
z0000000000000000000000000008j4uQ3si1@COAC&_w}s3-A;L_8IhC1SDRmfAIy
zOf<)utCyzgrLh`(v9%@YrZxOf5WWyT7d{()J^V`erSQq{bK$4Lhodk60000000000
z0000000000000000000000000004ZCT9Rmt1r3c4Jlj!hZk@}dAHT0<E_30B9!w<@
zL9DrYX{ufttCxoAC0V^Bs+V{o5u{q89uwhbg7De!OHl#<00000000000000000000
z000000000000000007@N&Pm1^W353$;{(rj6q^&ZY)dVhe*C_8Ta-<uYS{}v^k7R=
zKM_6?gfE28MF{`^000000000000000000000000000000000000Q_KRNW^0CL^6?z
zu8HPUOB70kpAW)+4gWDp000000000000000000000000000000000000002s`^=I=
zV=QQBeBjxRVsm0HlYacZcx$3DRm)uXp$A){noGlX1>v{Ce+mCNd@6i0{A~Dm_$T3`
z;YY#`hwl%6J-k0E1^@s60000000000000000000000000000000001hv!gK?OU0Vc
zsU=NqwWM)LEoo@2CCQdrl1SB(cymKC6;)|W2C-OTX)TF2)su#LlB_3*dJ=Dll2p7U
z8ft0y^FjC@;Wxvl!>@#Y7k)nci||jwN5hYV9}eFi{(AWCs2BhM000000000000000
z000000000000000000000M3S{WGohIO0?F~cuQk4mWnl{qNF+2)LhFY8f&@4l3Ja3
zqN$$7m)1(-=hRB$ZH>uPES6}fCGliKG8MIqu2E4k+1#9Ji3VF5UKxb{5<V4vHvDAx
zQ21NnyThLjkB8-OINTj>4A(`)000000000000000000000000000000000000000`
zb51hW7;6q18XtHj|J3v6)Ur+W><4act7RMO*~$l()Upk=>|4L~L~AXZtY<%bWlJra
zsAqrt=2R^kuV;52ZEj1Z8e_HGo4>lfu`L<Q<nrI%xAdf3d|qzHI}#^yZ+&8W(}~=k
zWm64vxo^BU_;_+jluOO#TB5bJ9=<;aKO6p^a5CHwzUs(d9l8I=;NgEb{P8FZ00000
z000000000000000000000000000000008hk<MPCg*myoOl)a`hJ)XU8?d9cSsd8QS
zRhN%truwtxiF~DeU3XXW8xlP;)oSJIPcCk}J9%t+rhKHBAI_Gp+tAl{>(-wBTXzm@
z?cKKf@|o!FZ5ual>Ah)Su5`9wS6|<j4L$vrADGCNrgv3m(mgYiRVNR1d3I_jKQWx$
z5mn4(qe#<ri7>XWQW-B_)7d#WIk|GIcqo_8XI2(Vqn+cW;$7LHO1X0+SIUkQr#e@!
zUD=iCu4c=X(nO&%wI)$qwDoMGLT+?lB|m+lRm-)ByBBShEp+VOxp>>w&cx8mY`ZU;
zAMcD`l^A=O^@k?PmEu_LP_{GCoyetLW}|GOQp)5zI}!sgG0adgs+k*{sAM~nS0;A9
zMD5IAaiY@M&=Q@o)^KAGek1%s_-Elq!}o>182)599qtQnkHP=|000000000000000
z000000000000000000000PtNnH?b@>edE}{sXe6)y<3KRo2!9Rxp(l6{d;nK>u<Wb
zr5YG3Zrj?uYx3$%BNLT)HL!o{s)L7a>FZtJJ+`~48n~-ain6(N8~S$bOH~88+Xsf%
zj&^NYKh(dsu^JdzJ9KFCjYI2h$!#8Otp+kfQ`w2Z{#BV<Z!R@d1Gfzw+B@C9Z+Ppf
z1N#%zK!4xP_0#*eAKW#zWqopKVp(eY>f6>$Y{(64?A|`r63u>T7!Sgy!zaT}haU;w
z8~*R`-f$`$4Q~s3!!_X>!}FtJ000000000000000000000000000000000000002K
z@12`i7Mm!H<nr0!fvSdTpi(U62Q#HwAW;isM#}>;l1mfIQl(<CG8?E?DD2p<cYOVL
zX;1f-y)D(iShg@RTOnQz<hE|<ndt4hu`8duB~=aVn;h&YPE3v5G2K7fSPkqg-Lj^V
zpWL1uJh-u`8rZXL?cPJZ+XmN_?-*ZF4Q!b%XZH3U>>sT3?{BLHZrL@lzN<3Xwf>H~
zu4=6YHXbPK+Hlv%&6_sw%{5m8J(YEvRu66M+j*d{<D6=sV@Ecd>sr&dGrRZT(w6EL
z96ie)0RR9100000000000000000000000000000000000oMkQ1Pcr=bApBPNZ1~ma
z1^@s600000000000000000000000000000000000zArT;W3kvd@nkJ+izjO7l6br!
J8B3)S{~wTd`QQKm
rename from toolkit/components/places/tests/migration/places_v6_no_frecency.sqlite
rename to toolkit/components/places/tests/migration/places_v6.sqlite
deleted file mode 100644
index 6e823996bf5b1abc70a3f3e52d1b8b2e0770bbd1..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
new file mode 100644
--- /dev/null
+++ b/toolkit/components/places/tests/migration/test_current_from_downgraded.js
@@ -0,0 +1,19 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+add_task(function* setup() {
+  yield setupPlacesDatabase(`places_v${CURRENT_SCHEMA_VERSION}.sqlite`);
+  // Downgrade the schema version to the first supported one.
+  let path = OS.Path.join(OS.Constants.Path.profileDir, DB_FILENAME);
+  let db = yield Sqlite.openConnection({ path: path });
+  yield db.setSchemaVersion(FIRST_UPGRADABLE_SCHEMA_VERSION);
+  yield db.close();
+});
+
+add_task(function* database_is_valid() {
+  Assert.equal(PlacesUtils.history.databaseStatus,
+               PlacesUtils.history.DATABASE_STATUS_UPGRADED);
+
+  let db = yield PlacesUtils.promiseDBConnection();
+  Assert.equal((yield db.getSchemaVersion()), CURRENT_SCHEMA_VERSION);
+});
deleted file mode 100644
--- a/toolkit/components/places/tests/migration/test_current_from_v10_migrated_from_v14.js
+++ /dev/null
@@ -1,132 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * This file tests migration invariants from a database with schema version 14
- * that was then downgraded to a database with a schema version 10.  Places
- * should then migrate this database to one with the current schema version.
- */
-
-////////////////////////////////////////////////////////////////////////////////
-//// Test Functions
-
-function test_initial_state()
-{
-  // Mostly sanity checks our starting DB to make sure it's setup as we expect
-  // it to be.
-  let dbFile = gProfD.clone();
-  dbFile.append(kDBName);
-  let db = Services.storage.openUnsharedDatabase(dbFile);
-
-  let stmt = db.createStatement("PRAGMA journal_mode");
-  do_check_true(stmt.executeStep());
-  // WAL journal mode should have been unset this database when it was migrated
-  // down to v10.
-  do_check_neq(stmt.getString(0).toLowerCase(), "wal");
-  stmt.finalize();
-
-  do_check_true(db.indexExists("moz_bookmarks_guid_uniqueindex"));
-  do_check_true(db.indexExists("moz_places_guid_uniqueindex"));
-
-  // There should be a non-zero amount of bookmarks without a guid.
-  stmt = db.createStatement(
-    `SELECT COUNT(1)
-     FROM moz_bookmarks
-     WHERE guid IS NULL`
-  );
-  do_check_true(stmt.executeStep());
-  do_check_neq(stmt.getInt32(0), 0);
-  stmt.finalize();
-
-  // There should be a non-zero amount of places without a guid.
-  stmt = db.createStatement(
-    `SELECT COUNT(1)
-     FROM moz_places
-     WHERE guid IS NULL`
-  );
-  do_check_true(stmt.executeStep());
-  do_check_neq(stmt.getInt32(0), 0);
-  stmt.finalize();
-
-  // Check our schema version to make sure it is actually at 10.
-  do_check_eq(db.schemaVersion, 10);
-
-  db.close();
-  run_next_test();
-}
-
-function test_bookmark_guids_non_null()
-{
-  // First, sanity check that we have a non-zero amount of bookmarks.  If
-  // migration failed, we would have zero.
-  let stmt = DBConn().createStatement(
-    `SELECT COUNT(1)
-     FROM moz_bookmarks`
-  );
-  do_check_true(stmt.executeStep());
-  do_check_neq(stmt.getInt32(0), 0);
-  stmt.finalize();
-
-  // Now, make sure we have no NULL guid entries.
-  stmt = DBConn().createStatement(
-    `SELECT guid
-     FROM moz_bookmarks
-     WHERE guid IS NULL`
-  );
-  do_check_false(stmt.executeStep());
-  stmt.finalize();
-  run_next_test();
-}
-
-function test_place_guids_non_null()
-{
-  // First, sanity check that we have a non-zero amount of places.  If migration
-  // failed, we would have zero.
-  let stmt = DBConn().createStatement(
-    `SELECT COUNT(1)
-     FROM moz_places`
-  );
-  do_check_true(stmt.executeStep());
-  do_check_neq(stmt.getInt32(0), 0);
-  stmt.finalize();
-
-  // Now, make sure we have no NULL guid entry.
-  stmt = DBConn().createStatement(
-    `SELECT guid
-     FROM moz_places
-     WHERE guid IS NULL`
-  );
-  do_check_false(stmt.executeStep());
-  stmt.finalize();
-  run_next_test();
-}
-
-function test_final_state()
-{
-  // We open a new database mostly so that we can check that the settings were
-  // actually saved.
-  let dbFile = gProfD.clone();
-  dbFile.append(kDBName);
-  let db = Services.storage.openUnsharedDatabase(dbFile);
-
-  do_check_eq(db.schemaVersion, CURRENT_SCHEMA_VERSION);
-
-  db.close();
-  run_next_test();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//// Test Runner
-
-[
-  test_initial_state,
-  test_bookmark_guids_non_null,
-  test_place_guids_non_null,
-  test_final_state,
-].forEach(add_test);
-
-function run_test()
-{
-  setPlacesDatabase("places_v10_from_v14.sqlite");
-  run_next_test();
-}
rename from toolkit/components/places/tests/migration/test_current_from_v10.js
rename to toolkit/components/places/tests/migration/test_current_from_v16.js
--- a/toolkit/components/places/tests/migration/test_current_from_v10.js
+++ b/toolkit/components/places/tests/migration/test_current_from_v16.js
@@ -1,368 +1,48 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-/**
- * This file tests migration invariants from schema version 10 to the current
- * schema version.
- */
-
-////////////////////////////////////////////////////////////////////////////////
-//// Constants
-
-const kGuidAnnotationName = "sync/guid";
-const kExpectedAnnotations = 5;
-const kExpectedValidGuids = 2;
-
-////////////////////////////////////////////////////////////////////////////////
-//// Globals
-
-// Set in test_initial_state to the value in the database.
-var gItemGuid = [];
-var gItemId = [];
-var gPlaceGuid = [];
-var gPlaceId = [];
-
-////////////////////////////////////////////////////////////////////////////////
-//// Helpers
-
-/**
- * Determines if a guid is valid or not.
- *
- * @return true if it is a valid guid, false otherwise.
- */
-function isValidGuid(aGuid)
-{
-  return /^[a-zA-Z0-9\-_]{12}$/.test(aGuid);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//// Test Functions
-
-function test_initial_state()
-{
-  // Mostly sanity checks our starting DB to make sure it's setup as we expect
-  // it to be.
-  let dbFile = gProfD.clone();
-  dbFile.append(kDBName);
-  let db = Services.storage.openUnsharedDatabase(dbFile);
-
-  let stmt = db.createStatement("PRAGMA journal_mode");
-  do_check_true(stmt.executeStep());
-  // WAL journal mode should not be set on this database.
-  do_check_neq(stmt.getString(0).toLowerCase(), "wal");
-  stmt.finalize();
-
-  do_check_false(db.indexExists("moz_bookmarks_guid_uniqueindex"));
-  do_check_false(db.indexExists("moz_places_guid_uniqueindex"));
+add_task(function* setup() {
+  yield setupPlacesDatabase("places_v16.sqlite");
+});
 
-  // There should be five item annotations for a bookmark guid.
-  stmt = db.createStatement(
-    `SELECT content AS guid, item_id
-     FROM moz_items_annos
-     WHERE anno_attribute_id = (
-       SELECT id
-       FROM moz_anno_attributes
-       WHERE name = :attr_name
-     )`
-  );
-  stmt.params.attr_name = kGuidAnnotationName;
-  while (stmt.executeStep()) {
-    gItemGuid.push(stmt.row.guid);
-    gItemId.push(stmt.row.item_id)
-  }
-  do_check_eq(gItemGuid.length, gItemId.length);
-  do_check_eq(gItemGuid.length, kExpectedAnnotations);
-  stmt.finalize();
-
-  // There should be five item annotations for a place guid.
-  stmt = db.createStatement(
-    `SELECT content AS guid, place_id
-     FROM moz_annos
-     WHERE anno_attribute_id = (
-       SELECT id
-       FROM moz_anno_attributes
-       WHERE name = :attr_name
-     )`
-  );
-  stmt.params.attr_name = kGuidAnnotationName;
-  while (stmt.executeStep()) {
-    gPlaceGuid.push(stmt.row.guid);
-    gPlaceId.push(stmt.row.place_id)
-  }
-  do_check_eq(gPlaceGuid.length, gPlaceId.length);
-  do_check_eq(gPlaceGuid.length, kExpectedAnnotations);
-  stmt.finalize();
-
-  // Check our schema version to make sure it is actually at 10.
-  do_check_eq(db.schemaVersion, 10);
-
-  db.close();
-  run_next_test();
-}
-
-function test_moz_bookmarks_guid_exists()
-{
-  // This will throw if the column does not exist
-  let stmt = DBConn().createStatement(
-    `SELECT guid
-     FROM moz_bookmarks`
-  );
-  stmt.finalize();
-
-  run_next_test();
-}
-
-function test_bookmark_guids_non_null()
-{
-  // First, sanity check that we have a non-zero amount of bookmarks.
-  let stmt = DBConn().createStatement(
-    `SELECT COUNT(1)
-     FROM moz_bookmarks`
-  );
-  do_check_true(stmt.executeStep());
-  do_check_neq(stmt.getInt32(0), 0);
-  stmt.finalize();
-
-  // Now, make sure we have no NULL guid entry.
-  stmt = DBConn().createStatement(
-    `SELECT guid
-     FROM moz_bookmarks
-     WHERE guid IS NULL`
-  );
-  do_check_false(stmt.executeStep());
-  stmt.finalize();
-  run_next_test();
-}
+add_task(function* database_is_valid() {
+  Assert.equal(PlacesUtils.history.databaseStatus,
+               PlacesUtils.history.DATABASE_STATUS_UPGRADED);
 
-function test_bookmark_guid_annotation_imported()
-{
-  // Make sure we have the imported guid; not a newly generated one.
-  let stmt = DBConn().createStatement(
-    `SELECT id
-     FROM moz_bookmarks
-     WHERE guid = :guid
-     AND id = :item_id`
-  );
-  let validGuids = 0;
-  let seenGuids = [];
-  for (let i = 0; i < gItemGuid.length; i++) {
-    let guid = gItemGuid[i];
-    stmt.params.guid = guid;
-    stmt.params.item_id = gItemId[i];
-
-    // Check that it is a valid guid that we expect, and that it is not a
-    // duplicate (which would violate the unique constraint).
-    let valid = isValidGuid(guid) && seenGuids.indexOf(guid) == -1;
-    seenGuids.push(guid);
-
-    if (valid) {
-      validGuids++;
-      do_check_true(stmt.executeStep());
-    }
-    else {
-      do_check_false(stmt.executeStep());
-    }
-    stmt.reset();
-  }
-  do_check_eq(validGuids, kExpectedValidGuids);
-  stmt.finalize();
-
-  run_next_test();
-}
+  let db = yield PlacesUtils.promiseDBConnection();
+  Assert.equal((yield db.getSchemaVersion()), CURRENT_SCHEMA_VERSION);
+});
 
-function test_bookmark_guid_annotation_removed()
-{
-  let stmt = DBConn().createStatement(
-    `SELECT COUNT(1)
-     FROM moz_items_annos
-     WHERE anno_attribute_id = (
-       SELECT id
-       FROM moz_anno_attributes
-       WHERE name = :attr_name
-     )`
-  );
-  stmt.params.attr_name = kGuidAnnotationName;
-  do_check_true(stmt.executeStep());
-  do_check_eq(stmt.getInt32(0), 0);
-  stmt.finalize();
-
-  run_next_test();
-}
-
-function test_moz_places_guid_exists()
-{
-  // This will throw if the column does not exist
-  let stmt = DBConn().createStatement(
-    `SELECT guid
-     FROM moz_places`
-  );
-  stmt.finalize();
-
-  run_next_test();
-}
-
-function test_place_guids_non_null()
-{
-  // First, sanity check that we have a non-zero amount of places.
-  let stmt = DBConn().createStatement(
-    `SELECT COUNT(1)
-     FROM moz_places`
-  );
-  do_check_true(stmt.executeStep());
-  do_check_neq(stmt.getInt32(0), 0);
-  stmt.finalize();
+add_task(function* test_moz_hosts() {
+  let db = yield PlacesUtils.promiseDBConnection();
 
-  // Now, make sure we have no NULL guid entry.
-  stmt = DBConn().createStatement(
-    `SELECT guid
-     FROM moz_places
-     WHERE guid IS NULL`
-  );
-  do_check_false(stmt.executeStep());
-  stmt.finalize();
-  run_next_test();
-}
-
-function test_place_guid_annotation_imported()
-{
-  // Make sure we have the imported guid; not a newly generated one.
-  let stmt = DBConn().createStatement(
-    `SELECT id
-     FROM moz_places
-     WHERE guid = :guid
-     AND id = :item_id`
-  );
-  let validGuids = 0;
-  let seenGuids = [];
-  for (let i = 0; i < gPlaceGuid.length; i++) {
-    let guid = gPlaceGuid[i];
-    stmt.params.guid = guid;
-    stmt.params.item_id = gPlaceId[i];
-
-    // Check that it is a valid guid that we expect, and that it is not a
-    // duplicate (which would violate the unique constraint).
-    let valid = isValidGuid(guid) && seenGuids.indexOf(guid) == -1;
-    seenGuids.push(guid);
+  // This will throw if the column does not exist.
+  yield db.execute("SELECT host, frecency, typed, prefix FROM moz_hosts");
 
-    if (valid) {
-      validGuids++;
-      do_check_true(stmt.executeStep());
-    }
-    else {
-      do_check_false(stmt.executeStep());
-    }
-    stmt.reset();
-  }
-  do_check_eq(validGuids, kExpectedValidGuids);
-  stmt.finalize();
-
-  run_next_test();
-}
+  // moz_hosts is populated asynchronously, so we need to wait.
+  yield promiseAsyncUpdates();
 
-function test_place_guid_annotation_removed()
-{
-  let stmt = DBConn().createStatement(
-    `SELECT COUNT(1)
-     FROM moz_annos
-     WHERE anno_attribute_id = (
-       SELECT id
-       FROM moz_anno_attributes
-       WHERE name = :attr_name
-     )`
-  );
-  stmt.params.attr_name = kGuidAnnotationName;
-  do_check_true(stmt.executeStep());
-  do_check_eq(stmt.getInt32(0), 0);
-  stmt.finalize();
-
-  run_next_test();
-}
-
-function test_moz_hosts()
-{
-  // This will throw if the column does not exist
-  let stmt = DBConn().createStatement(
-    `SELECT host, frecency, typed, prefix
-     FROM moz_hosts`
-  );
-  stmt.finalize();
-
-  // moz_hosts is populated asynchronously, so query asynchronously to serialize
-  // to that.
   // check the number of entries in moz_hosts equals the number of
   // unique rev_host in moz_places
-  stmt = DBConn().createAsyncStatement(
+  let rows = yield db.execute(
     `SELECT (SELECT COUNT(host) FROM moz_hosts),
             (SELECT COUNT(DISTINCT rev_host)
              FROM moz_places
-             WHERE LENGTH(rev_host) > 1)`);
-  try {
-    stmt.executeAsync({
-      handleResult: function (aResult) {
-        this._hasResults = true;
-        let row = aResult.getNextRow();
-        let mozHostsCount = row.getResultByIndex(0);
-        let mozPlacesCount = row.getResultByIndex(1);
-        do_check_true(mozPlacesCount > 0);
-        do_check_eq(mozPlacesCount, mozHostsCount);
-      },
-      handleError: function () {},
-      handleCompletion: function (aReason) {
-        do_check_eq(aReason, Ci.mozIStorageStatementCallback.REASON_FINISHED);
-        do_check_true(this._hasResults);
-        run_next_test();
-      }
-    });
-  }
-  finally {
-    stmt.finalize();
-  }
-}
+             WHERE LENGTH(rev_host) > 1)
+    `);
 
-function test_final_state()
-{
-  // We open a new database mostly so that we can check that the settings were
-  // actually saved.
-  let dbFile = gProfD.clone();
-  dbFile.append(kDBName);
-  let db = Services.storage.openUnsharedDatabase(dbFile);
+  Assert.equal(rows.length, 1);
+  let mozHostsCount = rows[0].getResultByIndex(0);
+  let mozPlacesCount = rows[0].getResultByIndex(1);
 
-  let (stmt = db.createStatement("PRAGMA journal_mode")) {
-    do_check_true(stmt.executeStep());
-    // WAL journal mode should be set on this database.
-    do_check_eq(stmt.getString(0).toLowerCase(), "wal");
-    stmt.finalize();
-  }
-
-  do_check_true(db.indexExists("moz_bookmarks_guid_uniqueindex"));
-  do_check_true(db.indexExists("moz_places_guid_uniqueindex"));
-  do_check_true(db.indexExists("moz_favicons_guid_uniqueindex"));
-
-  do_check_eq(db.schemaVersion, CURRENT_SCHEMA_VERSION);
-
-  db.close();
-  run_next_test();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//// Test Runner
+  Assert.ok(mozPlacesCount > 0, "There is some url in the database");
+  Assert.equal(mozPlacesCount, mozHostsCount, "moz_hosts has the expected number of entries");
+});
 
-[
-  test_initial_state,
-  test_moz_bookmarks_guid_exists,
-  test_bookmark_guids_non_null,
-  test_bookmark_guid_annotation_imported,
-  test_bookmark_guid_annotation_removed,
-  test_moz_places_guid_exists,
-  test_place_guids_non_null,
-  test_place_guid_annotation_imported,
-  test_place_guid_annotation_removed,
-  test_moz_hosts,
-  test_final_state,
-].forEach(add_test);
-
-function run_test()
-{
-  setPlacesDatabase("places_v10.sqlite");
-  run_next_test();
-}
+add_task(function* test_journal() {
+  let db = yield PlacesUtils.promiseDBConnection();
+  let rows = yield db.execute("PRAGMA journal_mode");
+  Assert.equal(rows.length, 1);
+  // WAL journal mode should be set on this database.
+  Assert.equal(rows[0].getResultByIndex(0), "wal");
+});
--- a/toolkit/components/places/tests/migration/test_current_from_v19.js
+++ b/toolkit/components/places/tests/migration/test_current_from_v19.js
@@ -1,62 +1,42 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-/**
- * This file tests migration invariants from schema version 19 to the current
- * schema version.
- */
+const ANNO_LEGACYGUID = "placesInternal/GUID";
 
-////////////////////////////////////////////////////////////////////////////////
-//// Globals
-
-const kGuidAnnotationName = "placesInternal/GUID";
-
-function getTotalGuidAnnotationsCount(aStorageConnection) {
-  stmt = aStorageConnection.createStatement(
+let getTotalGuidAnnotationsCount = Task.async(function* (db) {
+  let rows = yield db.execute(
     `SELECT count(*)
      FROM moz_items_annos a
      JOIN moz_anno_attributes b ON a.anno_attribute_id = b.id
-     WHERE b.name = :attr_name`
-  );
-  try {
-    stmt.params.attr_name = kGuidAnnotationName;
-    do_check_true(stmt.executeStep());
-    return stmt.getInt32(0);
-  } finally {
-    stmt.finalize();
-  }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//// Tests
+     WHERE b.name = :attr_name
+    `, { attr_name: ANNO_LEGACYGUID });
+  return rows[0].getResultByIndex(0);
+});
 
-function run_test()
-{
-  setPlacesDatabase("places_v19.sqlite");
-  run_next_test();
-}
-
-add_test(function test_initial_state()
-{
-  let dbFile = gProfD.clone();
-  dbFile.append(kDBName);
-  let db = Services.storage.openUnsharedDatabase(dbFile);
-
-  // There should be an obsolete bookmark GUID annotation.
-  do_check_eq(getTotalGuidAnnotationsCount(db), 1);
-
-  // Check our schema version to make sure it is actually at 19.
-  do_check_eq(db.schemaVersion, 19);
-
-  db.close();
-  run_next_test();
+add_task(function* setup() {
+  yield setupPlacesDatabase("places_v19.sqlite");
 });
 
-add_test(function test_bookmark_guid_annotation_removed()
-{
+add_task(function* initial_state() {
+  let path = OS.Path.join(OS.Constants.Path.profileDir, DB_FILENAME);
+  let db = yield Sqlite.openConnection({ path: path });
+
+  Assert.equal((yield getTotalGuidAnnotationsCount(db)), 1,
+               "There should be 1 obsolete guid annotation");
+  yield db.close();
+});
 
-  // There should be no obsolete bookmark GUID annotation anymore.
-  do_check_eq(getTotalGuidAnnotationsCount(DBConn()), 0);
+add_task(function* database_is_valid() {
+  Assert.equal(PlacesUtils.history.databaseStatus,
+               PlacesUtils.history.DATABASE_STATUS_UPGRADED);
 
-  run_next_test();
+  let db = yield PlacesUtils.promiseDBConnection();
+  Assert.equal((yield db.getSchemaVersion()), CURRENT_SCHEMA_VERSION);
 });
+
+add_task(function test_bookmark_guid_annotation_removed()
+{
+  let db = yield PlacesUtils.promiseDBConnection();
+  Assert.equal((yield getTotalGuidAnnotationsCount(db)), 0,
+               "There should be no more obsolete GUID annotations.");
+});
new file mode 100644
--- /dev/null
+++ b/toolkit/components/places/tests/migration/test_current_from_v24.js
@@ -0,0 +1,35 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+add_task(function* setup() {
+  yield setupPlacesDatabase("places_v24.sqlite");
+});
+
+add_task(function* database_is_valid() {
+  Assert.equal(PlacesUtils.history.databaseStatus,
+               PlacesUtils.history.DATABASE_STATUS_UPGRADED);
+
+  let db = yield PlacesUtils.promiseDBConnection();
+  Assert.equal((yield db.getSchemaVersion()), CURRENT_SCHEMA_VERSION);
+});
+
+add_task(function test_bookmark_guid_annotation_removed()
+{
+  yield PlacesUtils.bookmarks.eraseEverything();
+
+  let db = yield PlacesUtils.promiseDBConnection();
+  let m = new Map([
+    [PlacesUtils.placesRootId, PlacesUtils.bookmarks.rootGuid],
+    [PlacesUtils.bookmarksMenuFolderId, PlacesUtils.bookmarks.menuGuid],
+    [PlacesUtils.toolbarFolderId, PlacesUtils.bookmarks.toolbarGuid],
+    [PlacesUtils.unfiledBookmarksFolderId, PlacesUtils.bookmarks.unfiledGuid],
+    [PlacesUtils.tagsFolderId, PlacesUtils.bookmarks.tagsGuid]
+  ]);
+
+  let rows = yield db.execute(`SELECT id, guid FROM moz_bookmarks`);
+  for (let row of rows) {
+    let id = row.getResultByName("id");
+    let guid = row.getResultByName("guid");
+    Assert.equal(m.get(id), guid, "The root folder has the correct GUID");
+  }
+});
rename from toolkit/components/places/tests/migration/test_database_from_v6_no_frecency.js
rename to toolkit/components/places/tests/migration/test_current_from_v6.js
--- a/toolkit/components/places/tests/migration/test_database_from_v6_no_frecency.js
+++ b/toolkit/components/places/tests/migration/test_current_from_v6.js
@@ -1,31 +1,38 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
  * This file tests migration from a preliminary schema version 6 that
  * lacks frecency column and moz_inputhistory table.
  */
 
-add_test(function database_is_valid() {
-  do_check_eq(PlacesUtils.history.databaseStatus,
-              PlacesUtils.history.DATABASE_STATUS_UPGRADED);
-  // This throws if frecency column does not exist.
-  stmt = DBConn().createStatement("SELECT frecency from moz_places");
-  stmt.finalize();
-  // Check moz_inputhistory is in place.
-  do_check_true(DBConn().tableExists("moz_inputhistory"));
-  run_next_test();
+add_task(function* setup() {
+  yield setupPlacesDatabase("places_v6.sqlite");
+});
+
+add_task(function* corrupt_database_not_exists() {
+  let corruptPath = OS.Path.join(OS.Constants.Path.profileDir,
+                                 "places.sqlite.corrupt");
+  Assert.ok(!(yield OS.File.exists(corruptPath)), "Corrupt file should not exist");
 });
 
-add_test(function corrupt_database_not_exists() {
-  let dbFile = gProfD.clone();
-  dbFile.append("places.sqlite.corrupt");
-  do_check_false(dbFile.exists());
-  run_next_test();
+add_task(function* database_is_valid() {
+  Assert.equal(PlacesUtils.history.databaseStatus,
+               PlacesUtils.history.DATABASE_STATUS_CORRUPT);
+
+  let db = yield PlacesUtils.promiseDBConnection();
+  Assert.equal((yield db.getSchemaVersion()), CURRENT_SCHEMA_VERSION);
 });
 
-function run_test()
-{
-  setPlacesDatabase("places_v6_no_frecency.sqlite");
-  run_next_test();
-}
+add_task(function* check_columns() {
+  // Check the database has been replaced, these would throw otherwise.
+  let db = yield PlacesUtils.promiseDBConnection();
+  yield db.execute("SELECT frecency from moz_places");
+  yield db.execute("SELECT 1 from moz_inputhistory");
+});
+
+add_task(function* corrupt_database_exists() {
+  let corruptPath = OS.Path.join(OS.Constants.Path.profileDir,
+                                 "places.sqlite.corrupt");
+  Assert.ok((yield OS.File.exists(corruptPath)), "Corrupt file should exist");
+});
deleted file mode 100644
--- a/toolkit/components/places/tests/migration/test_database_from_alpha.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * This file tests migration replaces the database if schema version < 6.
- */
-
-add_test(function corrupt_database_not_exists() {
-  let dbFile = gProfD.clone();
-  dbFile.append("places.sqlite.corrupt");
-  do_check_false(dbFile.exists());
-  run_next_test();
-});
-
-add_test(function database_is_valid() {
-  do_check_eq(PlacesUtils.history.databaseStatus,
-              PlacesUtils.history.DATABASE_STATUS_CORRUPT);
-  do_check_eq(DBConn().schemaVersion, CURRENT_SCHEMA_VERSION);
-  run_next_test();
-});
-
-add_test(function corrupt_database_exists() {
-  let dbFile = gProfD.clone();
-  dbFile.append("places.sqlite.corrupt");
-  do_check_true(dbFile.exists());
-  run_next_test();
-});
-
-function run_test()
-{
-  setPlacesDatabase("places_alpha.sqlite");
-  run_next_test();
-}
-
deleted file mode 100644
--- a/toolkit/components/places/tests/migration/test_database_from_v6_no_indices.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * This file tests migration from a preliminary schema version 6 that
- * lacks important indices.  The database should be replaced.
- */
-
-add_test(function corrupt_database_not_exists() {
-  let dbFile = gProfD.clone();
-  dbFile.append("places.sqlite.corrupt");
-  do_check_false(dbFile.exists());
-  run_next_test();
-});
-
-add_test(function database_is_valid() {
-  do_check_eq(PlacesUtils.history.databaseStatus,
-              PlacesUtils.history.DATABASE_STATUS_CORRUPT);
-  do_check_eq(DBConn().schemaVersion, CURRENT_SCHEMA_VERSION);
-  run_next_test();
-});
-
-add_test(function corrupt_database_exists() {
-  let dbFile = gProfD.clone();
-  dbFile.append("places.sqlite.corrupt");
-  do_check_true(dbFile.exists());
-  run_next_test();
-});
-
-function run_test()
-{
-  setPlacesDatabase("places_v6_no_indices.sqlite");
-  run_next_test();
-}
--- a/toolkit/components/places/tests/migration/xpcshell.ini
+++ b/toolkit/components/places/tests/migration/xpcshell.ini
@@ -1,18 +1,22 @@
 [DEFAULT]
 head = head_migration.js
 tail =
-skip-if = toolkit == 'android' || toolkit == 'gonk'
+
 support-files =
-  places_alpha.sqlite
+  places_v6.sqlite
   places_v10.sqlite
-  places_v10_from_v14.sqlite
+  places_v11.sqlite
+  places_v16.sqlite
+  places_v17.sqlite
   places_v19.sqlite
-  places_v6_no_frecency.sqlite
-  places_v6_no_indices.sqlite
+  places_v21.sqlite
+  places_v22.sqlite
+  places_v23.sqlite
+  places_v24.sqlite
+  places_v25.sqlite
 
-[test_current_from_v10.js]
-[test_current_from_v10_migrated_from_v14.js]
+[test_current_from_downgraded.js]
+[test_current_from_v6.js]
+[test_current_from_v16.js]
 [test_current_from_v19.js]
-[test_database_from_alpha.js]
-[test_database_from_v6_no_frecency.js]
-[test_database_from_v6_no_indices.js]
+[test_current_from_v24.js]
--- a/toolkit/components/places/tests/unit/test_promiseBookmarksTree.js
+++ b/toolkit/components/places/tests/unit/test_promiseBookmarksTree.js
@@ -205,58 +205,53 @@ function* test_promiseBookmarksTreeAgain
   let itemId = aItemGuid ?
     yield PlacesUtils.promiseItemId(aItemGuid) : PlacesUtils.placesRootId;
   let node = PlacesUtils.getFolderContents(itemId).root;
   return yield test_promiseBookmarksTreeForEachNode(node, aOptions, aExcludedGuids);
 }
 
 add_task(function* () {
   // Add some bookmarks to cover various use cases.
-  let toolbarGuid =
-    yield PlacesUtils.promiseItemGuid(PlacesUtils.toolbarFolderId);
-  let menuGuid =
-    yield PlacesUtils.promiseItemGuid(PlacesUtils.bookmarksMenuFolderId);
-  yield new_bookmark({ parentGuid: toolbarGuid });
-  yield new_folder({ parentGuid: menuGuid
+  yield new_bookmark({ parentGuid: PlacesUtils.bookmarks.toolbarGuid });
+  yield new_folder({ parentGuid: PlacesUtils.bookmarks.menuGuid
                    , annotations: [{ name: "TestAnnoA", value: "TestVal"
                                    , name: "TestAnnoB", value: 0 }]});
   yield PlacesTransactions.transact(
-    PlacesTransactions.NewSeparator({ parentGuid: menuGuid }));
-  let folderGuid = yield new_folder({ parentGuid: menuGuid });
+    PlacesTransactions.NewSeparator({ parentGuid: PlacesUtils.bookmarks.menuGuid }));
+  let folderGuid = yield new_folder({ parentGuid: PlacesUtils.bookmarks.menuGuid });
   yield new_bookmark({ title: null
                      , parentGuid: folderGuid
                      , keyword: "test_keyword"
                      , tags: ["TestTagA", "TestTagB"]
                      , annotations: [{ name: "TestAnnoA", value: "TestVal2"}]});
   let urlWithCharsetAndFavicon = uri("http://charset.and.favicon");
   yield new_bookmark({ parentGuid: folderGuid, uri: urlWithCharsetAndFavicon });
   yield PlacesUtils.setCharsetForURI(urlWithCharsetAndFavicon, "UTF-8");
   yield promiseSetIconForPage(urlWithCharsetAndFavicon, SMALLPNG_DATA_URI);
   // Test the default places root without specifying it.
   yield test_promiseBookmarksTreeAgainstResult();
 
   // Do specify it
-  let rootGuid = yield PlacesUtils.promiseItemGuid(PlacesUtils.placesRootId);
-  yield test_promiseBookmarksTreeAgainstResult(rootGuid);
+  yield test_promiseBookmarksTreeAgainstResult(PlacesUtils.bookmarks.rootGuid);
 
   // Exclude the bookmarks menu.
   // The calllback should be four times - once for the toolbar, once for
   // the bookmark we inserted under, and once for the menu (and not
   // at all for any of its descendants) and once for the unsorted bookmarks
   // folder.  However, promiseBookmarksTree is called multiple times, so
   // rather than counting the calls, we count the number of unique items
   // passed in.
   let guidsPassedToExcludeCallback = new Set();
   let placesRootWithoutTheMenu =
-  yield test_promiseBookmarksTreeAgainstResult(rootGuid, {
+  yield test_promiseBookmarksTreeAgainstResult(PlacesUtils.bookmarks.rootGuid, {
     excludeItemsCallback: aItem =>  {
       guidsPassedToExcludeCallback.add(aItem.guid);
       return aItem.root == "bookmarksMenuFolder";
     },
     includeItemIds: true
-  }, [menuGuid]);
+  }, [PlacesUtils.bookmarks.menuGuid]);
   do_check_eq(guidsPassedToExcludeCallback.size, 4);
   do_check_eq(placesRootWithoutTheMenu.children.length, 2);
 });
 
 function run_test() {
   run_next_test();
 }
new file mode 100644
--- /dev/null
+++ b/toolkit/modules/PromiseUtils.jsm
@@ -0,0 +1,54 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict"
+
+this.EXPORTED_SYMBOLS = ["PromiseUtils"];
+
+Components.utils.import("resource://gre/modules/Timer.jsm");
+
+this.PromiseUtils = {
+  /*
+   * A simple timeout mechanism.
+   *
+   * Example:
+   * resolveOrTimeout(myModule.shutdown(), 1000, new Error("The module took too long to shutdown"));
+   *
+   * @param {Promise} promise The Promise that should resolve/reject quickly.
+   * @param {number} delay A delay after which to stop waiting for `promise`, in milliseconds.
+   * @param {function} rejection If `promise` hasn't resolved/rejected after `delay`,
+   * a value used to construct the rejection.
+   *
+   * @return {Promise} A promise that behaves as `promise`, if `promise` is
+   * resolved/rejected within `delay` ms, or rejects with `rejection()` otherwise.
+   */
+  resolveOrTimeout : function(promise, delay, rejection)  {
+    // throw a TypeError if <promise> is not a Promise object
+    if (!(promise instanceof Promise)) {
+      throw new TypeError("first argument <promise> must be a Promise object");
+    }
+
+    // throw a TypeError if <delay> is not a number
+    if (typeof delay != "number" || delay < 0) {
+      throw new TypeError("second argument <delay> must be a positive number");
+    }
+
+    // throws a TypeError if <rejection> is not a function
+    if (rejection && typeof rejection != "function") {
+      throw new TypeError("third optional argument <rejection> must be a function");
+    }
+
+    return new Promise((resolve, reject) => {
+      promise.then(resolve, reject);
+      let id = setTimeout(() => {
+        try {
+          rejection ? reject(rejection()) : reject(new Error("Promise Timeout"));
+        } catch(ex) {
+          reject(ex);
+        }
+        clearTimeout(id);
+      }, delay);
+    });
+  }
+}
\ No newline at end of file
--- a/toolkit/modules/moz.build
+++ b/toolkit/modules/moz.build
@@ -31,16 +31,17 @@ EXTRA_JS_MODULES += [
     'NewTabUtils.jsm',
     'PageMenu.jsm',
     'PermissionsUtils.jsm',
     'PopupNotifications.jsm',
     'Preferences.jsm',
     'PrivateBrowsingUtils.jsm',
     'Promise-backend.js',
     'Promise.jsm',
+    'PromiseUtils.jsm',
     'PropertyListUtils.jsm',
     'RemoteController.jsm',
     'RemoteFinder.jsm',
     'RemoteSecurityUI.jsm',
     'RemoteWebNavigation.jsm',
     'RemoteWebProgress.jsm',
     'SelectContentHelper.jsm',
     'SelectParentHelper.jsm',
new file mode 100644
--- /dev/null
+++ b/toolkit/modules/tests/xpcshell/test_PromiseUtils.js
@@ -0,0 +1,78 @@
+  /* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+Components.utils.import("resource://gre/modules/PromiseUtils.jsm");
+Components.utils.import("resource://gre/modules/Timer.jsm");
+
+// Tests for PromiseUtils.jsm
+function run_test() {
+  run_next_test();
+}
+
+/* Tests for the case when arguments to resolveOrTimeout
+ * are not of correct type */
+add_task(function* test_wrong_arguments() {
+  let p = new Promise((resolve, reject) => {});
+  // for the first argument
+  Assert.throws(() => PromiseUtils.resolveOrTimeout("string", 200), /first argument <promise> must be a Promise object/,
+                "TypeError thrown because first argument is not a Promsie object");
+  // for second argument
+  Assert.throws(() => PromiseUtils.resolveOrTimeout(p, "string"), /second argument <delay> must be a positive number/,
+                "TypeError thrown because second argument is not a positive number");
+  // for the third argument
+  Assert.throws(() => PromiseUtils.resolveOrTimeout(p, 200, "string"), /third optional argument <rejection> must be a function/,
+                "TypeError thrown because thrird argument is not a function");
+});
+
+/* Tests for the case when the optional third argument is not provided
+ * In that case the returned promise rejects with a default Error */
+add_task(function* test_optional_third_argument() {
+  let p = new Promise((resolve, reject) => {});
+  yield Assert.rejects(PromiseUtils.resolveOrTimeout(p, 200), /Promise Timeout/, "Promise rejects with a default Error");
+});
+
+/* Test for the case when the passed promise resolves quickly
+ * In that case the returned promise also resolves with the same value */
+add_task(function* test_resolve_quickly() {
+  let p = new Promise((resolve, reject) => setTimeout(() => resolve("Promise is resolved"), 20));
+  let result = yield PromiseUtils.resolveOrTimeout(p, 200);
+  Assert.equal(result, "Promise is resolved", "Promise resolves quickly");
+});
+
+/* Test for the case when the passed promise rejects quickly
+ * In that case the returned promise also rejects with the same value */
+add_task(function* test_reject_quickly() {
+  let p = new Promise((resolve, reject) => setTimeout(() => reject("Promise is rejected"), 20));
+  yield Assert.rejects(PromiseUtils.resolveOrTimeout(p, 200), /Promise is rejected/, "Promise rejects quickly");
+});
+
+/* Tests for the case when the passed promise doesn't settle
+ * and rejection returns string/object/undefined */
+add_task(function* test_rejection_function() {
+  let p = new Promise((resolve, reject) => {});
+  // for rejection returning string
+  yield Assert.rejects(PromiseUtils.resolveOrTimeout(p, 200, () => {
+    return "Rejection returned a string";
+  }), /Rejection returned a string/, "Rejection returned a string");
+
+  // for rejection returning object
+  yield Assert.rejects(PromiseUtils.resolveOrTimeout(p, 200, () => {
+    return {Name:"Promise"};
+  }), Object, "Rejection returned an object");
+
+  // for rejection returning undefined
+  yield Assert.rejects(PromiseUtils.resolveOrTimeout(p, 200, () => {
+    return;
+  }), undefined, "Rejection returned undefined");
+});
+
+/* Tests for the case when the passed promise doesn't settles
+ * and rejection throws an error */
+add_task(function* test_rejection_throw_error() {
+  let p = new Promise((resolve, reject) => {});
+  yield Assert.rejects(PromiseUtils.resolveOrTimeout(p, 200, () => {
+    throw new Error("Rejection threw an Error");
+  }), /Rejection threw an Error/, "Rejection threw an error");
+});
\ No newline at end of file
--- a/toolkit/modules/tests/xpcshell/xpcshell.ini
+++ b/toolkit/modules/tests/xpcshell/xpcshell.ini
@@ -16,16 +16,17 @@ support-files =
 # GMPInstallManager is not shipped on Android
 skip-if = os == 'android'
 [test_Http.js]
 [test_Log.js]
 [test_NewTabUtils.js]
 [test_PermissionsUtils.js]
 [test_Preferences.js]
 [test_Promise.js]
+[test_PromiseUtils.js]
 [test_propertyListsUtils.js]
 [test_readCertPrefs.js]
 [test_Services.js]
 [test_sqlite.js]
 [test_sqlite_shutdown.js]
 [test_task.js]
 [test_TelemetryTimestamps.js]
 [test_timer.js]