backing out test patch for bug 384370
authordietrich@mozilla.com
Tue, 04 Mar 2008 12:04:14 -0800
changeset 12563 4bc773c63aa95789a0ee516fade1ddd9f2ef06c2
parent 12562 ce87f83a217e4db30224c363026b5009539ecd42
child 12564 4fc6e0ba78331ef31de027ec66e3f684495b8491
push idunknown
push userunknown
push dateunknown
bugs384370
milestone1.9b5pre
backing out test patch for bug 384370
browser/app/profile/firefox.js
browser/base/content/browser-menubar.inc
browser/base/content/browser-places.js
browser/base/content/browser.js
browser/base/content/nsContextMenu.js
browser/components/nsBrowserGlue.js
browser/components/places/content/bookmarkProperties.js
browser/components/places/content/bookmarksPanel.js
browser/components/places/content/controller.js
browser/components/places/content/editBookmarkOverlay.js
browser/components/places/content/history-panel.js
browser/components/places/content/menu.xml
browser/components/places/content/moveBookmarks.js
browser/components/places/content/places.js
browser/components/places/content/places.xul
browser/components/places/content/placesOverlay.xul
browser/components/places/content/sidebarUtils.js
browser/components/places/content/toolbar.xml
browser/components/places/content/tree.xml
browser/components/places/content/treeView.js
browser/components/places/content/utils.js
browser/components/places/src/Makefile.in
browser/components/places/src/nsPlacesImportExportService.cpp
browser/components/places/src/nsPlacesTransactionsService.js
browser/components/places/tests/unit/head_bookmarks.js
browser/components/places/tests/unit/test_384370.js
browser/components/places/tests/unit/test_398914.js
browser/components/places/tests/unit/test_bookmarks_html.js
browser/components/sidebar/src/nsSidebar.js
toolkit/components/places/src/Makefile.in
toolkit/components/places/src/nsTaggingService.js
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -315,20 +315,19 @@ pref("browser.tabs.closeButtons", 1);
 // true   return to the tab that opened this tab (its owner)
 // false  return to the adjacent tab (old default)
 pref("browser.tabs.selectOwnerOnClose", true);
 
 // Default bookmark sorting
 pref("browser.bookmarks.sort.direction", "descending");
 pref("browser.bookmarks.sort.resource", "rdf:http://home.netscape.com/NC-rdf#Name");
 
-// By default, do not export HTML at shutdown.
-// If true, at shutdown the bookmarks in your menu and toolbar will
-// be exported as HTML to the bookmarks.html file.
-pref("browser.bookmarks.autoExportHTML",          false);
+// By default, do not overwrite bookmarks.html in the profile directory
+// See bug #381216 for details
+pref("browser.bookmarks.overwrite",               false);
 
 // Scripts & Windows prefs
 pref("dom.disable_open_during_load",              true);
 #ifdef DEBUG
 pref("javascript.options.showInConsole",          true);
 pref("general.warnOnAboutConfig",                 false);
 #else
 pref("javascript.options.showInConsole",          false);
--- a/browser/base/content/browser-menubar.inc
+++ b/browser/base/content/browser-menubar.inc
@@ -324,17 +324,17 @@
                 <menuitem hidden="true" id="documentDirection-swap" 
                           label="&bidiSwitchPageDirectionItem.label;"
                           accesskey="&bidiSwitchPageDirectionItem.accesskey;"
                           oncommand="SwitchDocumentDirection(window.content)"/>
               </menupopup>
             </menu>
 
             <menu id="history-menu"
-                  oncommand="var url = event.target.getAttribute('statustext'); if (url) { PlacesUIUtils.markPageAsTyped(url); openUILink(url, event, false, true); }"
+                  oncommand="var url = event.target.getAttribute('statustext'); if (url) { PlacesUtils.markPageAsTyped(url); openUILink(url, event, false, true); }"
                   onclick="checkForMiddleClick(this, event);"
                   label="&historyMenu.label;"
                   accesskey="&historyMenu.accesskey;">
               <menupopup id="goPopup"
                          type="places"
                          onpopupshowing="HistoryMenu.onPopupShowing(this);"
                          place="place:type=0&amp;sort=4&amp;maxResults=10">
                 <menuitem label="&backCmd.label;"
--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -100,17 +100,17 @@ var StarUI = {
       case "popuphidden":
         if (aEvent.originalTarget == this.panel) {
           if (!this._element("editBookmarkPanelContent").hidden)
             gEditItemOverlay.uninitPanel(true);
           this._restoreCommandsState();
           this._itemId = -1;
           this._uri = null;
           if (this._batching) {
-            PlacesUIUtils.ptm.endBatch();
+            PlacesUtils.ptm.endBatch();
             this._batching = false;
           }
         }
         break;
       case "keypress":
         if (aEvent.keyCode == KeyEvent.DOM_VK_ESCAPE) {
           // In edit mode, the ESC key is mapped to the cancel button
           if (!this._element("editBookmarkPanelContent").hidden)
@@ -183,21 +183,21 @@ var StarUI = {
     this._itemId = aItemId !== undefined ? aItemId : this._itemId;
     this.beginBatch();
 
     // XXXmano hack: We push a no-op transaction on the stack so it's always
     // safe for the Cancel button to call undoTransaction after endBatch.
     // Otherwise, if no changes were done in the edit-item panel, the last
     // transaction on the undo stack may be the initial createItem transaction,
     // or worse, the batched editing of some other item.
-    PlacesUIUtils.ptm.doTransaction({ doTransaction: function() { },
-                                      undoTransaction: function() { },
-                                      redoTransaction: function() { },
-                                      isTransient: false,
-                                      merge: function() { return false; } });
+    PlacesUtils.ptm.doTransaction({ doTransaction: function() { },
+                                    undoTransaction: function() { },
+                                    redoTransaction: function() { },
+                                    isTransient: false,
+                                    merge: function() { return false; } });
 
     if (this.panel.state == "closed") {
       // Consume dismiss clicks, see bug 400924
       this.panel.popupBoxObject
           .setConsumeRollupEvent(Ci.nsIPopupBoxObject.ROLLUP_CONSUME);
       this.panel.openPopup(aAnchorElement, aPosition, -1, -1);
     }
     else {
@@ -266,29 +266,29 @@ var StarUI = {
   },
 
   editButtonCommand: function SU_editButtonCommand() {
     this.showEditBookmarkPopup();
   },
 
   cancelButtonOnCommand: function SU_cancelButtonOnCommand() {
     this.endBatch();
-    PlacesUIUtils.ptm.undoTransaction();
+    PlacesUtils.ptm.undoTransaction();
     this.panel.hidePopup();
   },
 
   removeBookmarkButtonCommand: function SU_removeBookmarkButtonCommand() {
 #ifdef ADVANCED_STARRING_UI
     // In minimal mode ("page bookmarked" notification), the bookmark
     // is removed and the panel is hidden immediately. In full edit mode,
     // a "Bookmark Removed" notification along with an Undo button is
     // shown
     if (this._batching) {
-      PlacesUIUtils.ptm.endBatch();
-      PlacesUIUtils.ptm.beginBatch(); // allow undo from within the notification
+      PlacesUtils.ptm.endBatch();
+      PlacesUtils.ptm.beginBatch(); // allow undo from within the notification
       var bundle = this._element("bundle_browser");
 
       // "Bookmark Removed" title (the description field is already empty in
       // this mode)
       this._element("editBookmarkPanelTitle").value =
         bundle.getString("editBookmarkPanel.bookmarkedRemovedTitle");
       // hide the edit fields, the buttons below to and the remove bookmark
       // button. Show the undo-remove-bookmark button.
@@ -303,47 +303,47 @@ var StarUI = {
 
     // cache its uri so we can get the new itemId in the case of undo
     this._uri = PlacesUtils.bookmarks.getBookmarkURI(this._itemId);
 
     // remove all bookmarks for the bookmark's url, this also removes
     // the tags for the url
     var itemIds = PlacesUtils.getBookmarksForURI(this._uri);
     for (var i=0; i < itemIds.length; i++) {
-      var txn = PlacesUIUtils.ptm.removeItem(itemIds[i]);
-      PlacesUIUtils.ptm.doTransaction(txn);
+      var txn = PlacesUtils.ptm.removeItem(itemIds[i]);
+      PlacesUtils.ptm.doTransaction(txn);
     }
 
 #ifdef ADVANCED_STARRING_UI
     // hidePopup resets our itemId, thus we call it only after removing
     // the bookmark
     if (!this._batching)
 #endif
       this.panel.hidePopup();
   },
 
   undoRemoveBookmarkCommand: function SU_undoRemoveBookmarkCommand() {
     // restore the bookmark by undoing the last transaction and go back
     // to the edit state
     this.endBatch();
-    PlacesUIUtils.ptm.undoTransaction();
+    PlacesUtils.ptm.undoTransaction();
     this._itemId = PlacesUtils.getMostRecentBookmarkForURI(this._uri);
     this.showEditBookmarkPopup();
   },
 
   beginBatch: function SU_beginBatch() {
     if (!this._batching) {
-      PlacesUIUtils.ptm.beginBatch();
+      PlacesUtils.ptm.beginBatch();
       this._batching = true;
     }
   },
 
   endBatch: function SU_endBatch() {
     if (this._batching) {
-      PlacesUIUtils.ptm.endBatch();
+      PlacesUtils.ptm.endBatch();
       this._batching = false;
     }
   }
 }
 
 var PlacesCommandHook = {
   /**
    * Adds a bookmark to the page loaded in the given browser.
@@ -367,33 +367,33 @@ var PlacesCommandHook = {
       // no DOMWindow (?) but information about the loaded document
       // may still be obtained from the webNavigation.
       var webNav = aBrowser.webNavigation;
       var url = webNav.currentURI;
       var title;
       var description;
       try {
         title = webNav.document.title || url.spec;
-        description = PlacesUIUtils.getDescriptionFromDocument(webNav.document);
+        description = PlacesUtils.getDescriptionFromDocument(webNav.document);
       }
       catch (e) { }
 
       if (aShowEditUI) {
         // If we bookmark the page here (i.e. page was not "starred" already)
         // but open right into the "edit" state, start batching here, so
         // "Cancel" in that state removes the bookmark.
         StarUI.beginBatch();
       }
 
       var parent = aParent != undefined ?
                    aParent : PlacesUtils.unfiledBookmarksFolderId;
       var descAnno = { name: DESCRIPTION_ANNO, value: description };
-      var txn = PlacesUIUtils.ptm.createItem(uri, parent, -1,
-                                             title, null, [descAnno]);
-      PlacesUIUtils.ptm.doTransaction(txn);
+      var txn = PlacesUtils.ptm.createItem(uri, parent, -1,
+                                           title, null, [descAnno]);
+      PlacesUtils.ptm.doTransaction(txn);
       itemId = PlacesUtils.getMostRecentBookmarkForURI(uri);
     }
 
     // dock the panel to the star icon when possible, otherwise dock
     // it to the content area
     if (aBrowser.contentWindow == window.content) {
       var starIcon = aBrowser.ownerDocument.getElementById("star-button");
       if (starIcon && isElementVisible(starIcon)) {
@@ -427,18 +427,18 @@ var PlacesCommandHook = {
    * @param aTitle
    *        The link text
    */
   bookmarkLink: function PCH_bookmarkLink(aParent, aURL, aTitle) {
     var linkURI = makeURI(aURL);
     var itemId = PlacesUtils.getMostRecentBookmarkForURI(linkURI);
     if (itemId == -1) {
       StarUI.beginBatch();
-      var txn = PlacesUIUtils.ptm.createItem(linkURI, aParent, -1, aTitle);
-      PlacesUIUtils.ptm.doTransaction(txn);
+      var txn = PlacesUtils.ptm.createItem(linkURI, aParent, -1, aTitle);
+      PlacesUtils.ptm.doTransaction(txn);
       itemId = PlacesUtils.getMostRecentBookmarkForURI(linkURI);
     }
 
     StarUI.showEditBookmarkPopup(itemId, getBrowser(), "overlap");
   },
 
   /**
    * This function returns a list of nsIURI objects characterizing the
@@ -469,17 +469,17 @@ var PlacesCommandHook = {
   },
 
   /**
    * Adds a folder with bookmarks to all of the currently open tabs in this 
    * window.
    */
   bookmarkCurrentPages: function PCH_bookmarkCurrentPages() {
     var tabURIs = this._getUniqueTabInfo();
-    PlacesUIUtils.showMinimalAddMultiBookmarkUI(tabURIs);
+    PlacesUtils.showMinimalAddMultiBookmarkUI(tabURIs);
   },
 
   
   /**
    * Adds a Live Bookmark to a feed associated with the current page. 
    * @param     url
    *            The nsIURI of the page the feed was attached to
    * @title     title
@@ -495,22 +495,22 @@ var PlacesCommandHook = {
     
     var doc = gBrowser.contentDocument;
     var title = (arguments.length > 1) ? feedTitle : doc.title;
  
     var description;
     if (arguments.length > 2)
       description = feedSubtitle;
     else
-      description = PlacesUIUtils.getDescriptionFromDocument(doc);
+      description = PlacesUtils.getDescriptionFromDocument(doc);
 
     var toolbarIP =
       new InsertionPoint(PlacesUtils.bookmarks.toolbarFolder, -1);
-    PlacesUIUtils.showMinimalAddLivemarkUI(feedURI, gBrowser.currentURI,
-                                           title, description, toolbarIP, true);
+    PlacesUtils.showMinimalAddLivemarkUI(feedURI, gBrowser.currentURI,
+                                         title, description, toolbarIP, true);
   },
 
   /**
    * Opens the Places Organizer. 
    * @param   aLeftPaneRoot
    *          The query to select in the organizer window - options
    *          are: History, AllBookmarks, BookmarksMenu, BookmarksToolbar,
    *          UnfiledBookmarks and Tags.
@@ -576,17 +576,17 @@ var BookmarksEventHandler = {
    *        DOMEvent for the click
    */
   onClick: function BT_onClick(aEvent) {
     // Only handle middle-clicks.
     if (aEvent.button != 1)
       return;
 
     var target = aEvent.originalTarget;
-    var view = PlacesUIUtils.getViewForNode(target);
+    var view = PlacesUtils.getViewForNode(target);
     if (target.node && PlacesUtils.nodeIsFolder(target.node)) {
       // Don't open the root folder in tabs when the empty area on the toolbar
       // is middle-clicked or when a non-bookmark item except for Open in Tabs)
       // in a bookmarks menupopup is middle-clicked.
       if (target.localName == "menu" || target.localName == "toolbarbutton")
         PlacesUtils.openContainerNodeInTabs(target.node, aEvent);
     }
     else
@@ -620,17 +620,17 @@ var BookmarksEventHandler = {
    * Menus and submenus from the folder buttons bubble up to this handler.
    * Opens the item.
    * @param aEvent 
    *        DOMEvent for the command
    */
   onCommand: function BM_onCommand(aEvent) {
     var target = aEvent.originalTarget;
     if (target.node)
-      PlacesUIUtils.openNodeWithEvent(target.node, aEvent);
+      PlacesUtils.openNodeWithEvent(target.node, aEvent);
   },
 
   /**
    * Handler for popupshowing event for an item in bookmarks toolbar or menu.
    * If the item isn't the main bookmarks menu, add an "Open All in Tabs"
    * menuitem to the bottom of the popup.
    * @param event 
    *        DOMEvent for popupshowing
@@ -680,26 +680,26 @@ var BookmarksEventHandler = {
               "openUILink(this.getAttribute('siteURI'), event);");
           // If a user middle-clicks this item we serve the oncommand event
           // We are using checkForMiddleClick because of Bug 246720
           // Note: stopPropagation is needed to avoid serving middle-click 
           // with BT_onClick that would open all items in tabs
           openHomePage.setAttribute("onclick",
               "checkForMiddleClick(this, event); event.stopPropagation();");
           openHomePage.setAttribute("label",
-              PlacesUIUtils.getFormattedString("menuOpenLivemarkOrigin.label",
+              PlacesUtils.getFormattedString("menuOpenLivemarkOrigin.label",
               [target.parentNode.getAttribute("label")]));
           target.appendChild(openHomePage);
         }
 
         if (hasMultipleEntries) {
           var openInTabs = document.createElement("menuitem");
           openInTabs.setAttribute("openInTabs", "true");
           openInTabs.setAttribute("oncommand",
-                                  "PlacesUIUtils.openContainerNodeInTabs(this.parentNode._resultNode, event);");
+                                  "PlacesUtils.openContainerNodeInTabs(this.parentNode._resultNode, event);");
           openInTabs.setAttribute("label",
                      gNavigatorBundle.getString("menuOpenAllInTabs.label"));
           target.appendChild(openInTabs);
         }
       }
     }
   },
 
@@ -750,17 +750,17 @@ var BookmarksMenuDropHandler = {
   /**
    * Advertises the set of data types that can be dropped on the Bookmarks
    * Menu
    * @returns a FlavourSet object per nsDragAndDrop parlance.
    */
   getSupportedFlavours: function BMDH_getSupportedFlavours() {
     var flavorSet = new FlavourSet();
     var view = document.getElementById("bookmarksMenuPopup");
-    var types = PlacesUIUtils.GENERIC_VIEW_DROP_TYPES
+    var types = PlacesUtils.GENERIC_VIEW_DROP_TYPES
     for (var i = 0; i < types.length; ++i)
       flavorSet.appendFlavour(types[i]);
     return flavorSet;
   }, 
 
   /**
    * Determine whether or not the user can drop on the Bookmarks Menu.
    * @param   event
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -2544,17 +2544,17 @@ function openHomeDialog(aURL)
 }
 
 var bookmarksButtonObserver = {
   onDrop: function (aEvent, aXferData, aDragSession)
   {
     var split = aXferData.data.split("\n");
     var url = split[0];
     if (url != aXferData.data)  // do nothing if it's not a valid URL
-      PlacesUIUtils.showMinimalAddBookmarkUI(makeURI(url), split[1]);
+      PlacesUtils.showMinimalAddBookmarkUI(makeURI(url), split[1]);
   },
 
   onDragOver: function (aEvent, aFlavour, aDragSession)
   {
     var statusTextFld = document.getElementById("statusbar-display");
     statusTextFld.label = gNavigatorBundle.getString("droponbookmarksbutton");
     aDragSession.dragAction = Components.interfaces.nsIDragService.DRAGDROP_ACTION_LINK;
   },
@@ -3014,17 +3014,17 @@ function addToUrlbarHistory(aUrlToAdd)
 {
   if (!aUrlToAdd)
      return;
   if (aUrlToAdd.search(/[\x00-\x1F]/) != -1) // don't store bad URLs
      return;
 
    try {
      if (aUrlToAdd.indexOf(" ") == -1) {
-       PlacesUIUtils.markPageAsTyped(aUrlToAdd);
+       PlacesUtils.markPageAsTyped(aUrlToAdd);
      }
    }
    catch(ex) {
    }
 }
 
 function toJavaScriptConsole()
 {
@@ -4425,19 +4425,19 @@ function asyncOpenWebPanel(event)
          loadURI(url, null, postData.value, false);
          event.preventDefault();
          return false;
        }
        else if (linkNode.getAttribute("rel") == "sidebar") {
          // This is the Opera convention for a special link that - when clicked - allows
          // you to add a sidebar panel.  We support the Opera convention here.  The link's
          // title attribute contains the title that should be used for the sidebar panel.
-         PlacesUIUtils.showMinimalAddBookmarkUI(makeURI(wrapper.href),
-                                                wrapper.getAttribute("title"),
-                                                null, null, true, true);
+         PlacesUtils.showMinimalAddBookmarkUI(makeURI(wrapper.href),
+                                              wrapper.getAttribute("title"),
+                                              null, null, true, true);
          event.preventDefault();
          return false;
        }
        else if (target == "_search") {
          // Used in WinIE as a way of transiently loading pages in a sidebar.  We
          // mimic that WinIE functionality here and also load the page transiently.
 
          // DISALLOW_INHERIT_PRINCIPAL is used here in order to also
@@ -5391,19 +5391,19 @@ function AddKeywordForSearchField()
 
   var postData;
 
   if (isURLEncoded)
     postData = formData.join("&");
   else
     spec += "?" + formData.join("&");
 
-  var description = PlacesUIUtils.getDescriptionFromDocument(node.ownerDocument);
-  PlacesUIUtils.showMinimalAddBookmarkUI(makeURI(spec), "", description, null,
-                                         null, null, "", postData);
+  var description = PlacesUtils.getDescriptionFromDocument(node.ownerDocument);
+  PlacesUtils.showMinimalAddBookmarkUI(makeURI(spec), "", description, null,
+                                       null, null, "", postData);
 }
 
 function SwitchDocumentDirection(aWindow) {
   aWindow.document.dir = (aWindow.document.dir == "ltr" ? "rtl" : "ltr");
   for (var run = 0; run < aWindow.frames.length; run++)
     SwitchDocumentDirection(aWindow.frames[run]);
 }
 
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -1186,23 +1186,23 @@ nsContextMenu.prototype = {
 
   addBookmarkForFrame: function CM_addBookmarkForFrame() {
     var doc = this.target.ownerDocument;
     var uri = doc.documentURIObject;
 
     var itemId = PlacesUtils.getMostRecentBookmarkForURI(uri);
     if (itemId == -1) {
       var title = doc.title;
-      var description = PlacesUIUtils.getDescriptionFromDocument(doc);
+      var description = PlacesUtils.getDescriptionFromDocument(doc);
 
       var descAnno = { name: DESCRIPTION_ANNO, value: description };
-      var txn = PlacesUIUtils.ptm.createItem(uri, 
+      var txn = PlacesUtils.ptm.createItem(uri, 
                                            PlacesUtils.bookmarksMenuFolderId,
                                            -1, title, null, [descAnno]);
-      PlacesUIUtils.ptm.doTransaction(txn);
+      PlacesUtils.ptm.doTransaction(txn);
       itemId = PlacesUtils.getMostRecentBookmarkForURI(uri);
       StarUI.beginBatch();
     }
 
     window.top.StarUI.showEditBookmarkPopup(itemId, this.browser, "overlap");
   },
 
   savePageAs: function CM_savePageAs() {
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -40,23 +40,16 @@
 const Ci = Components.interfaces;
 const Cc = Components.classes;
 const Cr = Components.results;
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource:///modules/distribution.js");
 
-// Check to see if bookmarks need backing up once per
-// day on 1 hour idle.
-const BOOKMARKS_ARCHIVE_IDLE_TIME = 60 * 60;
-
-// Backup bookmarks once every 24 hours.
-const BOOKMARKS_ARCHIVE_INTERVAL = 86400 * 1000;
-
 // Factory object
 const BrowserGlueServiceFactory = {
   _instance: null,
   createInstance: function (outer, iid) 
   {
     if (outer != null)
       throw Components.results.NS_ERROR_NO_AGGREGATION;
     return this._instance == null ?
@@ -105,33 +98,25 @@ BrowserGlue.prototype = {
         break;
       case "quit-application-requested":
         this._onQuitRequest(subject, data);
         break;
       case "quit-application-granted":
         if (this._saveSession) {
           this._setPrefToSaveSession();
         }
-        this._shutdownPlaces();
-        this.idleService.removeIdleObserver(this, BOOKMARKS_ARCHIVE_IDLE_TIME);
         break;
       case "session-save":
         this._setPrefToSaveSession();
         subject.QueryInterface(Ci.nsISupportsPRBool);
         subject.data = true;
         break;
-      case "idle":
-        if (this.idleService.idleTime > BOOKMARKS_ARCHIVE_IDLE_TIME * 1000) {
-          // Back up bookmarks.
-          this._archiveBookmarks();
-        }
-        break;
     }
-  }, 
-
+  }
+, 
   // initialization (called on application startup) 
   _init: function() 
   {
     // observer registration
     const osvr = Cc['@mozilla.org/observer-service;1'].
                  getService(Ci.nsIObserverService);
     osvr.addObserver(this, "quit-application", false);
     osvr.addObserver(this, "xpcom-shutdown", false);
@@ -334,89 +319,87 @@ BrowserGlue.prototype = {
     if(typeof(Sanitizer) != "function") { // we should dynamically load the script
       Cc["@mozilla.org/moz/jssubscript-loader;1"].
       getService(Ci.mozIJSSubScriptLoader).
       loadSubScript("chrome://browser/content/sanitize.js", null);
     }
     return Sanitizer;
   },
 
-  _idleService: null,
-  get idleService() {
-    if (!this._idleService)
-      this._idleService = Cc["@mozilla.org/widget/idleservice;1"].
-                          getService(Ci.nsIIdleService);
-    return this._idleService;
-  },
-
   /**
    * Initialize Places
    * - imports the bookmarks html file if bookmarks datastore is empty
    */
   _initPlaces: function bg__initPlaces() {
     // we need to instantiate the history service before we check the 
     // the browser.places.importBookmarksHTML pref, as 
     // nsNavHistory::ForceMigrateBookmarksDB() will set that pref
     // if we need to force a migration (due to a schema change)
     var histsvc = Cc["@mozilla.org/browser/nav-history-service;1"].
                   getService(Ci.nsINavHistoryService);
 
-    var prefBranch = Cc["@mozilla.org/preferences-service;1"].
-                     getService(Ci.nsIPrefBranch);
-
     var importBookmarks = false;
     try {
+      var prefBranch = Cc["@mozilla.org/preferences-service;1"].
+                       getService(Ci.nsIPrefBranch);
       importBookmarks = prefBranch.getBoolPref("browser.places.importBookmarksHTML");
     } catch(ex) {}
 
     /**
      * These prefs are set by the backend services upon creation (or recreation)
      * of the Places db:
      * - browser.places.importBookmarksHTML
      *   Set to false by the history service to indicate we need to re-import.
      * - browser.places.createdSmartBookmarks
      *   Set during HTML import to indicate that the queries were created.
      */
     if (!importBookmarks) {
       // Call it here for Fx3 profiles created before the Places folder
       // has been added, otherwise it's called during import.
       this.ensurePlacesDefaultQueriesInitialized();
+      return;
     }
-    else {
-      // ensurePlacesDefaultQueriesInitialized() is called by import.
-      prefBranch.setBoolPref("browser.places.createdSmartBookmarks", false);
+
+    // ensurePlacesDefaultQueriesInitialized() is called by import.
+    prefBranch.setBoolPref("browser.places.createdSmartBookmarks", false);
+
+    var dirService = Cc["@mozilla.org/file/directory_service;1"].
+                     getService(Ci.nsIProperties);
+
+    var bookmarksFile = dirService.get("BMarks", Ci.nsILocalFile);
 
-      // get latest backup
-      Cu.import("resource://gre/modules/utils.js");
-      var bookmarksFile = PlacesUtils.getMostRecentBackup();
-
-      if (bookmarksFile && bookmarksFile.leafName.match("\.json$")) {
-        // restore a JSON backup
-        PlacesUtils.restoreBookmarksFromJSONFile(bookmarksFile);
+    if (bookmarksFile.exists()) {
+      // import the file
+      try {
+        var importer = 
+          Cc["@mozilla.org/browser/places/import-export-service;1"].
+          getService(Ci.nsIPlacesImportExportService);
+        importer.importHTMLFromFile(bookmarksFile, true);
+      } catch(ex) {
+      } finally {
+        prefBranch.setBoolPref("browser.places.importBookmarksHTML", false);
       }
-      else {
-        // if there's no json backup use bookmarks.html
-        var dirService = Cc["@mozilla.org/file/directory_service;1"].
-                         getService(Ci.nsIProperties);
-        var bookmarksFile = dirService.get("BMarks", Ci.nsILocalFile);
 
-        // import the file
-        try {
-          var importer = Cc["@mozilla.org/browser/places/import-export-service;1"].
-                         getService(Ci.nsIPlacesImportExportService);
-          importer.importHTMLFromFile(bookmarksFile, true /* overwrite existing */);
-        } finally {
-          prefBranch.setBoolPref("browser.places.importBookmarksHTML", false);
+      // only back up pre-places bookmarks.html if we plan on overwriting it
+      if (prefBranch.getBoolPref("browser.bookmarks.overwrite")) {
+        // backup pre-places bookmarks.html
+        // XXXtodo remove this before betas, after import/export is solid
+        var profDir = dirService.get("ProfD", Ci.nsILocalFile);
+        var bookmarksBackup = profDir.clone();
+        bookmarksBackup.append("bookmarks.preplaces.html");
+        if (!bookmarksBackup.exists()) {
+          // save old bookmarks.html file as bookmarks.preplaces.html
+          try {
+            bookmarksFile.copyTo(profDir, "bookmarks.preplaces.html");
+          } catch(ex) {
+            dump("nsBrowserGlue::_initPlaces(): copy of bookmarks.html to bookmarks.preplaces.html failed: " + ex + "\n");
+          }
         }
       }
     }
-
-    // Initialize bookmark archiving on idle.
-    // Once a day, either on idle or shutdown, bookmarks are backed up.
-    this.idleService.addIdleObserver(this, BOOKMARKS_ARCHIVE_IDLE_TIME);
   },
 
   /**
    * Places shut-down tasks
    * - back up and archive bookmarks
    */
   _shutdownPlaces: function bg__shutdownPlaces() {
     // backup bookmarks to bookmarks.html
--- a/browser/components/places/content/bookmarkProperties.js
+++ b/browser/components/places/content/bookmarkProperties.js
@@ -562,18 +562,18 @@ var BookmarkPropertiesPanel = {
     if (this._itemType != BOOKMARK_ITEM || !this._bookmarkURI) {
       namePicker.selectedItem = userEnteredNameField;
       return;
     }
 
     var itemToSelect = userEnteredNameField;
     try {
       this._microsummaries =
-        PlacesUIUtils.microsummaries.getMicrosummaries(this._bookmarkURI,
-                                                       this._bookmarkId);
+        PlacesUtils.microsummaries.getMicrosummaries(this._bookmarkURI,
+                                                     this._bookmarkId);
     }
     catch(ex) {
       // getMicrosummaries will throw an exception if the page to which the URI
       // refers isn't HTML or XML (the only two content types the service knows
       // how to summarize).
       this._microsummaries = null;
     }
     if (this._microsummaries) {
@@ -585,18 +585,18 @@ var BookmarkPropertiesPanel = {
 
         var menupopup = namePicker.menupopup;
         while (enumerator.hasMoreElements()) {
           var microsummary = enumerator.getNext()
                                        .QueryInterface(Ci.nsIMicrosummary);
           var menuItem = this._createMicrosummaryMenuItem(microsummary);
 
           if (this._action == ACTION_EDIT &&
-              PlacesUIUtils.microsummaries
-                           .isMicrosummary(this._bookmarkId, microsummary))
+              PlacesUtils.microsummaries
+                         .isMicrosummary(this._bookmarkId, microsummary))
             itemToSelect = menuItem;
 
           menupopup.appendChild(menuItem);
         }
       }
 
       this._microsummaries.addObserver(this);
     }
@@ -708,29 +708,29 @@ var BookmarkPropertiesPanel = {
    *        the ID of the textbox element whose contents we'll test
    *
    * @returns true if the textbox contains a valid URI string, false otherwise
    */
   _containsValidURI: function BPP__containsValidURI(aTextboxID) {
     try {
       var value = this._element(aTextboxID).value;
       if (value) {
-        var uri = PlacesUIUtils.createFixedURI(value);
+        var uri = PlacesUtils.createFixedURI(value);
         return true;
       }
     } catch (e) { }
     return false;
   },
 
   /**
    * Get an edit title transaction for the item edit/added in the dialog
    */
   _getEditTitleTransaction:
   function BPP__getEditTitleTransaction(aItemId, aNewTitle) {
-    return PlacesUIUtils.ptm.editItemTitle(aItemId, aNewTitle);
+    return PlacesUtils.ptm.editItemTitle(aItemId, aNewTitle);
   },
 
   /**
    * XXXmano todo:
    *  1. Make setAnnotationsForURI unset a given annotation if the value field
    *     is not set.
    *  2. Replace PlacesEditItemDescriptionTransaction and
    *     PlacesSetLoadInSidebarTransaction transaction with a generic
@@ -808,87 +808,87 @@ var BookmarkPropertiesPanel = {
     // title
     var newTitle = this._element("userEnteredName").label;
     if (newTitle != this._itemTitle)
       transactions.push(this._getEditTitleTransaction(itemId, newTitle));
 
     // description
     var description = this._element("descriptionTextfield").value;
     if (description != this._itemDescription) {
-      transactions.push(PlacesUIUtils.ptm.
+      transactions.push(PlacesUtils.ptm.
                         editItemDescription(itemId, description,
                         this._itemType != BOOKMARK_ITEM));
     }
 
     if (this._itemType == BOOKMARK_ITEM) {
       // location
-      var url = PlacesUIUtils.createFixedURI(this._element("editURLBar").value);
+      var url = PlacesUtils.createFixedURI(this._element("editURLBar").value);
       if (!this._bookmarkURI.equals(url))
-        transactions.push(PlacesUIUtils.ptm.editBookmarkURI(itemId, url));
+        transactions.push(PlacesUtils.ptm.editBookmarkURI(itemId, url));
 
       // keyword transactions
       var newKeyword = this._element("keywordTextfield").value;
       if (newKeyword != this._bookmarkKeyword) {
-        transactions.push(PlacesUIUtils.ptm.
+        transactions.push(PlacesUtils.ptm.
                           editBookmarkKeyword(itemId, newKeyword));
       }
 
       // microsummaries
       var namePicker = this._element("namePicker");
       var newMicrosummary = namePicker.selectedItem.microsummary;
 
       // Only add a microsummary update to the transaction if the
       // microsummary has actually changed, i.e. the user selected no
       // microsummary, but the bookmark previously had one, or the user
       // selected a microsummary which is not the one the bookmark previously
       // had.
       if ((newMicrosummary == null &&
-           PlacesUIUtils.microsummaries.hasMicrosummary(itemId)) ||
+           PlacesUtils.microsummaries.hasMicrosummary(itemId)) ||
           (newMicrosummary != null &&
-           !PlacesUIUtils.microsummaries
-                         .isMicrosummary(itemId, newMicrosummary))) {
+           !PlacesUtils.microsummaries
+                       .isMicrosummary(itemId, newMicrosummary))) {
         transactions.push(
-          PlacesUIUtils.ptm.editBookmarkMicrosummary(itemId, newMicrosummary));
+          PlacesUtils.ptm.editBookmarkMicrosummary(itemId, newMicrosummary));
       }
 
       // load in sidebar
       var loadInSidebarChecked = this._element("loadInSidebarCheckbox").checked;
       if (loadInSidebarChecked != this._loadBookmarkInSidebar) {
         transactions.push(
-          PlacesUIUtils.ptm.setLoadInSidebar(itemId, loadInSidebarChecked));
+          PlacesUtils.ptm.setLoadInSidebar(itemId, loadInSidebarChecked));
       }
     }
     else if (this._itemType == LIVEMARK_CONTAINER) {
       var feedURIString = this._element("feedLocationTextfield").value;
-      var feedURI = PlacesUIUtils.createFixedURI(feedURIString);
+      var feedURI = PlacesUtils.createFixedURI(feedURIString);
       if (!this._feedURI.equals(feedURI)) {
         transactions.push(
-          PlacesUIUtils.ptm.editLivemarkFeedURI(this._folderId, feedURI));
+          PlacesUtils.ptm.editLivemarkFeedURI(this._folderId, feedURI));
       }
 
       // Site Location is empty, we can set its URI to null
       var newSiteURIString = this._element("feedSiteLocationTextfield").value;
       var newSiteURI = null;
       if (newSiteURIString)
-        newSiteURI = PlacesUIUtils.createFixedURI(newSiteURIString);
+        newSiteURI = PlacesUtils.createFixedURI(newSiteURIString);
 
       if ((!newSiteURI && this._siteURI)  ||
           (newSiteURI && (!this._siteURI || !this._siteURI.equals(newSiteURI)))) {
         transactions.push(
-          PlacesUIUtils.ptm.editLivemarkSiteURI(this._folderId, newSiteURI));
+          PlacesUtils.ptm.editLivemarkSiteURI(this._folderId, newSiteURI));
       }
     }
 
     // If we have any changes to perform, do them via the
     // transaction manager passed by the opener so they can be undone.
     if (transactions.length > 0) {
       window.arguments[0].performed = true;
       var aggregate =
-        PlacesUIUtils.ptm.aggregateTransactions(this._getDialogTitle(), transactions);
-      PlacesUIUtils.ptm.doTransaction(aggregate);
+        PlacesUtils.ptm.aggregateTransactions(this._getDialogTitle(), transactions);
+      PlacesUtils.ptm.doTransaction(aggregate);
     }
   },
 
   /**
    * [New Item Mode] Get the insertion point details for the new item, given
    * dialog state and opening arguments.
    *
    * The container-identifier and insertion-index are returned separately in
@@ -907,58 +907,58 @@ var BookmarkPropertiesPanel = {
   },
 
   /**
    * Returns a transaction for creating a new bookmark item representing the
    * various fields and opening arguments of the dialog.
    */
   _getCreateNewBookmarkTransaction:
   function BPP__getCreateNewBookmarkTransaction(aContainer, aIndex) {
-    var uri = PlacesUIUtils.createFixedURI(this._element("editURLBar").value);
+    var uri = PlacesUtils.createFixedURI(this._element("editURLBar").value);
     var title = this._element("userEnteredName").label;
     var keyword = this._element("keywordTextfield").value;
     var annotations = [];
     var description = this._element("descriptionTextfield").value;
     if (description)
       annotations.push(this._getDescriptionAnnotation(description));
 
     var loadInSidebar = this._element("loadInSidebarCheckbox").checked;
     if (loadInSidebar)
       annotations.push(this._getLoadInSidebarAnnotation(true));
 
     var childTransactions = [];
     var microsummary = this._element("namePicker").selectedItem.microsummary;
     if (microsummary) {
       childTransactions.push(
-        PlacesUIUtils.ptm.editBookmarkMicrosummary(-1, microsummary));
+        PlacesUtils.ptm.editBookmarkMicrosummary(-1, microsummary));
     }
 
     if (this._postData) {
       childTransactions.push(
-        PlacesUIUtils.ptm.editBookmarkPostData(-1, this._postData));
+        PlacesUtils.ptm.editBookmarkPostData(-1, this._postData));
     }
 
-    var transactions = [PlacesUIUtils.ptm.createItem(uri, aContainer, aIndex,
-                                                     title, keyword,
-                                                     annotations,
-                                                     childTransactions)];
+    var transactions = [PlacesUtils.ptm.createItem(uri, aContainer, aIndex,
+                                                   title, keyword,
+                                                   annotations,
+                                                   childTransactions)];
 
-    return PlacesUIUtils.ptm.aggregateTransactions(this._getDialogTitle(), transactions);
+    return PlacesUtils.ptm.aggregateTransactions(this._getDialogTitle(), transactions);
   },
 
   /**
    * Returns a childItems-transactions array representing the URIList with
    * which the dialog has been opened.
    */
   _getTransactionsForURIList: function BPP__getTransactionsForURIList() {
     var transactions = [];
     for (var i = 0; i < this._URIList.length; ++i) {
       var uri = this._URIList[i];
       var title = this._getURITitleFromHistory(uri);
-      transactions.push(PlacesUIUtils.ptm.createItem(uri, -1, -1, title));
+      transactions.push(PlacesUtils.ptm.createItem(uri, -1, -1, title));
     }
     return transactions; 
   },
 
   /**
    * Returns a transaction for creating a new folder item representing the
    * various fields and opening arguments of the dialog.
    */
@@ -968,37 +968,37 @@ var BookmarkPropertiesPanel = {
     var annotations = [];
     var childItemsTransactions;
     if (this._URIList)
       childItemsTransactions = this._getTransactionsForURIList();
     var description = this._element("descriptionTextfield").value;
     if (description)
       annotations.push(this._getDescriptionAnnotation(description));
 
-    return PlacesUIUtils.ptm.createFolder(folderName, aContainer, aIndex,
-                                          annotations, childItemsTransactions);
+    return PlacesUtils.ptm.createFolder(folderName, aContainer, aIndex,
+                                        annotations, childItemsTransactions);
   },
 
   /**
    * Returns a transaction for creating a new live-bookmark item representing
    * the various fields and opening arguments of the dialog.
    */
   _getCreateNewLivemarkTransaction:
   function BPP__getCreateNewLivemarkTransaction(aContainer, aIndex) {
     var feedURIString = this._element("feedLocationTextfield").value;
-    var feedURI = PlacesUIUtils.createFixedURI(feedURIString);
+    var feedURI = PlacesUtils.createFixedURI(feedURIString);
 
     var siteURIString = this._element("feedSiteLocationTextfield").value;
     var siteURI = null;
     if (siteURIString)
-      siteURI = PlacesUIUtils.createFixedURI(siteURIString);
+      siteURI = PlacesUtils.createFixedURI(siteURIString);
 
     var name = this._element("namePicker").value;
-    return PlacesUIUtils.ptm.createLivemark(feedURI, siteURI, name,
-                                            aContainer, aIndex);
+    return PlacesUtils.ptm.createLivemark(feedURI, siteURI, name,
+                                          aContainer, aIndex);
   },
 
   /**
    * Dialog-accept code-path for creating a new item (any type)
    */
   _createNewItem: function BPP__getCreateItemTransaction() {
     var [container, index] = this._getInsertionPointDetails();
     var createTxn;
@@ -1013,17 +1013,17 @@ var BookmarkPropertiesPanel = {
     // list
     if (container != PlacesUtils.toolbarFolderId &&
         container != PlacesUtils.bookmarksMenuFolderId)
       this._markFolderAsRecentlyUsed(container);
 
     // perfrom our transaction do via the transaction manager passed by the
     // opener so it can be undone.
     window.arguments[0].performed = true;
-    PlacesUIUtils.ptm.doTransaction(createTxn);
+    PlacesUtils.ptm.doTransaction(createTxn);
   },
 
   onNamePickerInput: function BPP_onNamePickerInput() {
     this._element("userEnteredName").label = this._element("namePicker").value;
   },
 
   toggleTreeVisibility: function BPP_toggleTreeVisibility() {
     var expander = this._element("expander");
@@ -1044,17 +1044,17 @@ var BookmarkPropertiesPanel = {
                             expander.getAttribute("tooltiptextup"));
       document.documentElement.buttons = "accept,cancel,extra2";
 
       this._folderTree.collapsed = false;
 
       if (!this._folderTree.place) {
         const FOLDER_TREE_PLACE_URI =
           "place:excludeItems=1&excludeQueries=1&excludeReadOnlyFolders=1&folder=" +
-          PlacesUIUtils.allBookmarksFolderId;
+          PlacesUtils.allBookmarksFolderId;
         this._folderTree.place = FOLDER_TREE_PLACE_URI;
       }
 
       var currentFolder = this._getFolderIdFromMenuList();
       this._folderTree.selectItems([currentFolder]);
       this._folderTree.focus();
 
       resizeTo(window.outerWidth, window.outerHeight + this._folderTreeHeight);
--- a/browser/components/places/content/bookmarksPanel.js
+++ b/browser/components/places/content/bookmarksPanel.js
@@ -32,17 +32,17 @@
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
 function init() {
   document.getElementById("bookmarks-view").place =
-    "place:queryType=1&folder=" + window.top.PlacesUIUtils.allBookmarksFolderId;
+    "place:queryType=1&folder=" + window.top.PlacesUtils.allBookmarksFolderId;
   document.getElementById("search-box").focus();
 }
 
 function searchBookmarks(aSearchString) {
   var tree = document.getElementById('bookmarks-view');
   if (!aSearchString)
     tree.place = tree.place;
   else
--- a/browser/components/places/content/controller.js
+++ b/browser/components/places/content/controller.js
@@ -98,19 +98,19 @@ PlacesController.prototype = {
   /**
    * The places view.
    */
   _view: null,
 
   isCommandEnabled: function PC_isCommandEnabled(aCommand) {
     switch (aCommand) {
     case "cmd_undo":
-      return PlacesUIUtils.ptm.numberOfUndoItems > 0;
+      return PlacesUtils.ptm.numberOfUndoItems > 0;
     case "cmd_redo":
-      return PlacesUIUtils.ptm.numberOfRedoItems > 0;
+      return PlacesUtils.ptm.numberOfRedoItems > 0;
     case "cmd_cut":
     case "cmd_delete":
       return this._hasRemovableSelection(false);
     case "placesCmd_moveBookmarks":
       return this._hasRemovableSelection(true);
     case "cmd_copy":
       return this._view.hasSelection;
     case "cmd_paste":
@@ -147,17 +147,17 @@ PlacesController.prototype = {
             (PlacesUtils.nodeIsBookmark(selectedNode) &&
             !PlacesUtils.nodeIsLivemarkItem(selectedNode)))
           return true;
       }
       return false;
     case "placesCmd_reloadMicrosummary":
       var selectedNode = this._view.selectedNode;
       return selectedNode && PlacesUtils.nodeIsBookmark(selectedNode) &&
-             PlacesUIUtils.microsummaries.hasMicrosummary(selectedNode.itemId);
+             PlacesUtils.microsummaries.hasMicrosummary(selectedNode.itemId);
     case "placesCmd_reload":
       // Livemark containers
       var selectedNode = this._view.selectedNode;
       return selectedNode && PlacesUtils.nodeIsLivemarkContainer(selectedNode);
     case "placesCmd_sortBy:name":
       var selectedNode = this._view.selectedNode;
       return selectedNode &&
              PlacesUtils.nodeIsFolder(selectedNode) &&
@@ -187,20 +187,20 @@ PlacesController.prototype = {
     // filters out other commands that we do _not_ support (see 329587).
     const CMD_PREFIX = "placesCmd_";
     return (aCommand.substr(0, CMD_PREFIX.length) == CMD_PREFIX);
   },
 
   doCommand: function PC_doCommand(aCommand) {
     switch (aCommand) {
     case "cmd_undo":
-      PlacesUIUtils.ptm.undoTransaction();
+      PlacesUtils.ptm.undoTransaction();
       break;
     case "cmd_redo":
-      PlacesUIUtils.ptm.redoTransaction();
+      PlacesUtils.ptm.redoTransaction();
       break;
     case "cmd_cut":
       this.cut();
       break;
     case "cmd_copy":
       this.copy();
       break;
     case "cmd_paste":
@@ -208,23 +208,23 @@ PlacesController.prototype = {
       break;
     case "cmd_delete":
       this.remove("Remove Selection");
       break;
     case "cmd_selectAll":
       this.selectAll();
       break;
     case "placesCmd_open":
-      PlacesUIUtils.openNodeIn(this._view.selectedNode, "current");
+      PlacesUtils.openNodeIn(this._view.selectedNode, "current");
       break;
     case "placesCmd_open:window":
-      PlacesUIUtils.openNodeIn(this._view.selectedNode, "window");
+      PlacesUtils.openNodeIn(this._view.selectedNode, "window");
       break;
     case "placesCmd_open:tab":
-      PlacesUIUtils.openNodeIn(this._view.selectedNode, "tab");
+      PlacesUtils.openNodeIn(this._view.selectedNode, "tab");
       break;
     case "placesCmd_new:folder":
       this.newItem("folder");
       break;
     case "placesCmd_new:bookmark":
       this.newItem("bookmark");
       break;
     case "placesCmd_new:livemark":
@@ -332,18 +332,18 @@ PlacesController.prototype = {
    * @returns true if: - clipboard data is of a TYPE_X_MOZ_PLACE_* flavor,
                        - clipboard data is of type TEXT_UNICODE and
                          is a valid URI.
    */
   _isClipboardDataPasteable: function PC__isClipboardDataPasteable() {
     // if the clipboard contains TYPE_X_MOZ_PLACE_* data, it is definitely
     // pasteable, with no need to unwrap all the nodes.
 
-    var flavors = PlacesUIUtils.placesFlavors;
-    var clipboard = PlacesUIUtils.clipboard;
+    var flavors = PlacesUtils.placesFlavors;
+    var clipboard = PlacesUtils.clipboard;
     var hasPlacesData =
       clipboard.hasDataMatchingFlavors(flavors, flavors.length,
                                        Ci.nsIClipboard.kGlobalClipboard);
     if (hasPlacesData)
       return this._view.insertionPoint != null;
 
     // if the clipboard doesn't have TYPE_X_MOZ_PLACE_* data, we also allow
     // pasting of valid "text/unicode" and "text/x-moz-url" data
@@ -437,17 +437,17 @@ PlacesController.prototype = {
           break;
         case Ci.nsINavHistoryResultNode.RESULT_TYPE_URI:
         case Ci.nsINavHistoryResultNode.RESULT_TYPE_VISIT:
         case Ci.nsINavHistoryResultNode.RESULT_TYPE_FULL_VISIT:
           nodeData["link"] = true;
           uri = PlacesUtils._uri(node.uri);
           if (PlacesUtils.nodeIsBookmark(node)) {
             nodeData["bookmark"] = true;
-            var mss = PlacesUIUtils.microsummaries;
+            var mss = PlacesUtils.microsummaries;
             if (mss.hasMicrosummary(node.itemId))
               nodeData["microsummary"] = true;
             else if (node.parent &&
                      PlacesUtils.nodeIsLivemarkContainer(node.parent))
               nodeData["livemarkChild"] = true;
           }
           break;
       }
@@ -623,19 +623,19 @@ PlacesController.prototype = {
    */
   showBookmarkPropertiesForSelection: 
   function PC_showBookmarkPropertiesForSelection() {
     var node = this._view.selectedNode;
     if (!node)
       return;
 
     if (PlacesUtils.nodeIsFolder(node))
-      PlacesUIUtils.showFolderProperties(node.itemId);
+      PlacesUtils.showFolderProperties(node.itemId);
     else if (PlacesUtils.nodeIsBookmark(node))
-      PlacesUIUtils.showBookmarkProperties(node.itemId);
+      PlacesUtils.showBookmarkProperties(node.itemId);
   },
 
   /**
    * This method can be run on a URI parameter to ensure that it didn't
    * receive a string instead of an nsIURI object.
    */
   _assertURINotString: function PC__assertURINotString(value) {
     NS_ASSERT((typeof(value) == "object") && !(value instanceof String), 
@@ -651,17 +651,17 @@ PlacesController.prototype = {
       PlacesUtils.livemarks.reloadLivemarkFolder(selectedNode.itemId);
   },
 
   /**
    * Reload the microsummary associated with the selection
    */
   reloadSelectedMicrosummary: function PC_reloadSelectedMicrosummary() {
     var selectedNode = this._view.selectedNode;
-    var mss = PlacesUIUtils.microsummaries;
+    var mss = PlacesUtils.microsummaries;
     if (mss.hasMicrosummary(selectedNode.itemId))
       mss.refreshMicrosummary(selectedNode.itemId);
   },
 
   /**
    * Gives the user a chance to cancel loading lots of tabs at once
    */
   _confirmOpenTabs: function(numTabsToOpen) {
@@ -683,24 +683,24 @@ PlacesController.prototype = {
         var strings = document.getElementById("placeBundle");
         const BRANDING_BUNDLE_URI = "chrome://branding/locale/brand.properties";
         var brandShortName = Cc["@mozilla.org/intl/stringbundle;1"].
                              getService(Ci.nsIStringBundleService).
                              createBundle(BRANDING_BUNDLE_URI).
                              GetStringFromName("brandShortName");
        
         var buttonPressed = promptService.confirmEx(window,
-          PlacesUIUtils.getString("tabs.openWarningTitle"),
-          PlacesUIUtils.getFormattedString(messageKey, 
+          PlacesUtils.getString("tabs.openWarningTitle"),
+          PlacesUtils.getFormattedString(messageKey, 
             [numTabsToOpen, brandShortName]),
           (promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_0)
           + (promptService.BUTTON_TITLE_CANCEL * promptService.BUTTON_POS_1),
-          PlacesUIUtils.getString(openKey),
+          PlacesUtils.getString(openKey),
           null, null,
-          PlacesUIUtils.getFormattedString("tabs.openWarningPromptMeBranded",
+          PlacesUtils.getFormattedString("tabs.openWarningPromptMeBranded",
             [brandShortName]),
           warnOnOpen);
 
          reallyOpen = (buttonPressed == 0);
          // don't set the pref unless they press OK and it's false
          if (reallyOpen && !warnOnOpen.value)
            pref.setBoolPref(kWarnOnOpenPref, false);
       }
@@ -709,39 +709,39 @@ PlacesController.prototype = {
   },
 
   /**
    * Opens the links in the selected folder, or the selected links in new tabs. 
    */
   openSelectionInTabs: function PC_openLinksInTabs(aEvent) {
     var node = this._view.selectedNode;
     if (node && PlacesUtils.nodeIsContainer(node))
-      PlacesUIUtils.openContainerNodeInTabs(this._view.selectedNode, aEvent);
+      PlacesUtils.openContainerNodeInTabs(this._view.selectedNode, aEvent);
     else
-      PlacesUIUtils.openURINodesInTabs(this._view.getSelectionNodes(), aEvent);
+      PlacesUtils.openURINodesInTabs(this._view.getSelectionNodes(), aEvent);
   },
 
   /**
    * Shows the Add Bookmark UI for the current insertion point.
    *
    * @param aType
    *        the type of the new item (bookmark/livemark/folder)
    */
   newItem: function PC_newItem(aType) {
     var ip = this._view.insertionPoint;
     if (!ip)
       throw Cr.NS_ERROR_NOT_AVAILABLE;
 
     var performed = false;
     if (aType == "bookmark")
-      performed = PlacesUIUtils.showAddBookmarkUI(null, null, null, ip);
+      performed = PlacesUtils.showAddBookmarkUI(null, null, null, ip);
     else if (aType == "livemark")
-      performed = PlacesUIUtils.showAddLivemarkUI(null, null, null, null, ip);
+      performed = PlacesUtils.showAddLivemarkUI(null, null, null, null, ip);
     else // folder
-      performed = PlacesUIUtils.showAddFolderUI(null, ip);
+      performed = PlacesUtils.showAddFolderUI(null, ip);
 
     if (performed) {
       // select the new item
       var insertedNodeId = PlacesUtils.bookmarks
                                       .getIdForItemAt(ip.itemId, ip.index);
       this._view.selectItems([insertedNodeId], ip.itemId);
     }
   },
@@ -752,34 +752,34 @@ PlacesController.prototype = {
    * of the folder. 
    */
   newFolder: function PC_newFolder() {
     var ip = this._view.insertionPoint;
     if (!ip)
       throw Cr.NS_ERROR_NOT_AVAILABLE;
 
     var performed = false;
-    performed = PlacesUIUtils.showAddFolderUI(null, ip);
+    performed = PlacesUtils.showAddFolderUI(null, ip);
     if (performed) {
       // select the new item
       var insertedNodeId = PlacesUtils.bookmarks
                                       .getIdForItemAt(ip.itemId, ip.index);
       this._view.selectItems([insertedNodeId]);
     }
   },
 
   /**
    * Create a new Bookmark separator somewhere.
    */
   newSeparator: function PC_newSeparator() {
     var ip = this._view.insertionPoint;
     if (!ip)
       throw Cr.NS_ERROR_NOT_AVAILABLE;
-    var txn = PlacesUIUtils.ptm.createSeparator(ip.itemId, ip.index);
-    PlacesUIUtils.ptm.doTransaction(txn);
+    var txn = PlacesUtils.ptm.createSeparator(ip.itemId, ip.index);
+    PlacesUtils.ptm.doTransaction(txn);
     // select the new item
     var insertedNodeId = PlacesUtils.bookmarks
                                     .getIdForItemAt(ip.itemId, ip.index);
     this._view.selectItems([insertedNodeId]);
   },
 
   /**
    * Opens a dialog for moving the selected nodes.
@@ -790,18 +790,18 @@ PlacesController.prototype = {
                       this._view.getSelectionNodes());
   },
 
   /**
    * Sort the selected folder by name
    */
   sortFolderByName: function PC_sortFolderByName() {
     var itemId = PlacesUtils.getConcreteItemId(this._view.selectedNode);
-    var txn = PlacesUIUtils.ptm.sortFolderByName(itemId);
-    PlacesUIUtils.ptm.doTransaction(txn);
+    var txn = PlacesUtils.ptm.sortFolderByName(itemId);
+    PlacesUtils.ptm.doTransaction(txn);
   },
 
   /**
    * Walk the list of folders we're removing in this delete operation, and
    * see if the selected node specified is already implicitly being removed 
    * because it is a child of that folder. 
    * @param   node
    *          Node to check for containment. 
@@ -851,35 +851,35 @@ PlacesController.prototype = {
     for (var i = 0; i < range.length; ++i) {
       var node = range[i];
       if (this._shouldSkipNode(node, removedFolders))
         continue;
 
       if (PlacesUtils.nodeIsFolder(node))
         removedFolders.push(node);
 
-      transactions.push(PlacesUIUtils.ptm.removeItem(node.itemId));
+      transactions.push(PlacesUtils.ptm.removeItem(node.itemId));
     }
   },
 
   /**
    * Removes the set of selected ranges from bookmarks.
    * @param   txnName
    *          See |remove|.
    */
   _removeRowsFromBookmarks: function PC__removeRowsFromBookmarks(txnName) {
     var ranges = this._view.getRemovableSelectionRanges();
     var transactions = [];
     // Delete the selected rows. Do this by walking the selection backward, so
     // that when undo is performed they are re-inserted in the correct order.
     for (var i = ranges.length - 1; i >= 0 ; --i)
       this._removeRange(ranges[i], transactions);
     if (transactions.length > 0) {
-      var txn = PlacesUIUtils.ptm.aggregateTransactions(txnName, transactions);
-      PlacesUIUtils.ptm.doTransaction(txn);
+      var txn = PlacesUtils.ptm.aggregateTransactions(txnName, transactions);
+      PlacesUtils.ptm.doTransaction(txn);
     }
   },
 
   /**
    * Removes the set of selected ranges from history.
    */
   _removeRowsFromHistory: function PC__removeRowsFromHistory() {
     // Other containers are history queries, just delete from history
@@ -992,17 +992,17 @@ PlacesController.prototype = {
       }
 
       var dataSet = new TransferDataSet();
       for (var i = 0; i < nodes.length; ++i) {
         var node = nodes[i];
 
         var data = new TransferData();
         function addData(type, overrideURI) {
-          data.addDataForFlavour(type, PlacesUIUtils._wrapString(
+          data.addDataForFlavour(type, PlacesUtils._wrapString(
                                  PlacesUtils.wrapNode(node, type, overrideURI)));
         }
 
         function addURIData(overrideURI) {
           addData(PlacesUtils.TYPE_X_MOZ_URL, overrideURI);
           addData(PlacesUtils.TYPE_UNICODE, overrideURI);
           addData(PlacesUtils.TYPE_HTML, overrideURI);
         }
@@ -1070,31 +1070,31 @@ PlacesController.prototype = {
         }
 
         // all items wrapped as TYPE_X_MOZ_PLACE
         placeString += generateChunk(PlacesUtils.TYPE_X_MOZ_PLACE);
       }
 
       function addData(type, data) {
         xferable.addDataFlavor(type);
-        xferable.setTransferData(type, PlacesUIUtils._wrapString(data), data.length * 2);
+        xferable.setTransferData(type, PlacesUtils._wrapString(data), data.length * 2);
       }
       // This order is _important_! It controls how this and other applications 
       // select data to be inserted based on type.
       if (placeString)
         addData(PlacesUtils.TYPE_X_MOZ_PLACE, placeString);
       if (mozURLString)
         addData(PlacesUtils.TYPE_X_MOZ_URL, mozURLString);
       if (unicodeString)
         addData(PlacesUtils.TYPE_UNICODE, unicodeString);
       if (htmlString)
         addData(PlacesUtils.TYPE_HTML, htmlString);
 
       if (placeString || unicodeString || htmlString || mozURLString) {
-        PlacesUIUtils.clipboard.setData(xferable, null, Ci.nsIClipboard.kGlobalClipboard);
+        PlacesUtils.clipboard.setData(xferable, null, Ci.nsIClipboard.kGlobalClipboard);
       }
     }
     finally {
       if (oldViewer)
         result.viewer = oldViewer;
     }
   },
 
@@ -1111,17 +1111,16 @@ PlacesController.prototype = {
    */
   paste: function PC_paste() {
     // Strategy:
     // 
     // There can be data of various types (folder, separator, link) on the 
     // clipboard. We need to get all of that data and build edit transactions
     // for them. This means asking the clipboard once for each type and 
     // aggregating the results. 
-    dump("PASTING\n");
 
     /**
      * Constructs a transferable that can receive data of specific types.
      * @param   types
      *          The types of data the transferable can hold, in order of
      *          preference.
      * @returns The transferable.
      */
@@ -1129,17 +1128,17 @@ PlacesController.prototype = {
       var xferable = 
           Cc["@mozilla.org/widget/transferable;1"].
           createInstance(Ci.nsITransferable);
       for (var i = 0; i < types.length; ++i) 
         xferable.addDataFlavor(types[i]);
       return xferable;
     }
 
-    var clipboard = PlacesUIUtils.clipboard;
+    var clipboard = PlacesUtils.clipboard;
 
     var ip = this._view.insertionPoint;
     if (!ip)
       throw Cr.NS_ERROR_NOT_AVAILABLE;
 
     /**
      * Gets a list of transactions to perform the paste of specific types.
      * @param   types
@@ -1157,19 +1156,19 @@ PlacesController.prototype = {
         var items = PlacesUtils.unwrapNodes(data, type.value);
         var transactions = [];
         var index = ip.index;
         for (var i = 0; i < items.length; ++i) {
           // adjusted to make sure that items are given the correct index -
           // transactions insert differently if index == -1
           if (ip.index > -1)
             index = ip.index + i;
-          transactions.push(PlacesUIUtils.makeTransaction(items[i], type.value,
-                                                          ip.itemId, index,
-                                                          true));
+          transactions.push(PlacesUtils.makeTransaction(items[i], type.value, 
+                                                        ip.itemId, index,
+                                                        true));
         }
         return transactions;
       }
       catch (e) {
         // getAnyTransferData will throw if there is no data of the specified
         // type on the clipboard. 
         // unwrapNodes will throw if the data that is present is malformed in
         // some way. 
@@ -1178,18 +1177,18 @@ PlacesController.prototype = {
       return [];
     }
 
     // Get transactions to paste any folders, separators or links that might
     // be on the clipboard, aggregate them and execute them. 
     var transactions = getTransactions([PlacesUtils.TYPE_X_MOZ_PLACE,
                                         PlacesUtils.TYPE_X_MOZ_URL, 
                                         PlacesUtils.TYPE_UNICODE]);
-    var txn = PlacesUIUtils.ptm.aggregateTransactions("Paste", transactions);
-    PlacesUIUtils.ptm.doTransaction(txn);
+    var txn = PlacesUtils.ptm.aggregateTransactions("Paste", transactions);
+    PlacesUtils.ptm.doTransaction(txn);
 
     // select the pasted items, they should be consecutive
     var insertedNodeIds = [];
     for (var i = 0; i < transactions.length; ++i)
       insertedNodeIds.push(PlacesUtils.bookmarks
                                       .getIdForItemAt(ip.itemId, ip.index + i));
     if (insertedNodeIds.length > 0)
       this._view.selectItems(insertedNodeIds);
@@ -1239,17 +1238,17 @@ var PlacesControllerDragHelper = {
 
   /**
    * Determines whether or not the data currently being dragged can be dropped
    * on a places view.
    */
   canDrop: function PCDH_canDrop() {
     var session = this.getSession();
     if (session) {
-      var types = PlacesUIUtils.GENERIC_VIEW_DROP_TYPES;
+      var types = PlacesUtils.GENERIC_VIEW_DROP_TYPES;
       for (var i = 0; i < types.length; ++i) {
         if (session.isDataFlavorSupported(types[i]))
           return true;
       }
     }
     return false;
   },
 
@@ -1259,17 +1258,17 @@ var PlacesControllerDragHelper = {
    * @param   session
    *          The active drag session
    * @returns An object implementing nsITransferable that can receive data
    *          dropped onto a view. 
    */
   _initTransferable: function PCDH__initTransferable(session) {
     var xferable = Cc["@mozilla.org/widget/transferable;1"].
                    createInstance(Ci.nsITransferable);
-    var types = PlacesUIUtils.GENERIC_VIEW_DROP_TYPES;
+    var types = PlacesUtils.GENERIC_VIEW_DROP_TYPES;
     for (var i = 0; i < types.length; ++i) {
       if (session.isDataFlavorSupported(types[i]))
         xferable.addDataFlavor(types[i]);
     }
     return xferable;
   },
 
   /**
@@ -1302,23 +1301,23 @@ var PlacesControllerDragHelper = {
       // drag multiple elts upward: need to increment index or each successive
       // elt will be inserted at the same index, each above the previous.
       if ((index != -1) && ((index < unwrapped.index) ||
                            (unwrapped.folder && (index < unwrapped.folder.index)))) {
         index = index + movedCount;
         movedCount++;
       }
 
-      transactions.push(PlacesUIUtils.makeTransaction(unwrapped,
+      transactions.push(PlacesUtils.makeTransaction(unwrapped,
                         flavor.value, insertionPoint.itemId,
                         index, copy));
     }
 
-    var txn = PlacesUIUtils.ptm.aggregateTransactions("DropItems", transactions);
-    PlacesUIUtils.ptm.doTransaction(txn);
+    var txn = PlacesUtils.ptm.aggregateTransactions("DropItems", transactions);
+    PlacesUtils.ptm.doTransaction(txn);
   }
 };
 
 function goUpdatePlacesCommands() {
   var placesController;
   try {
     // Or any other command...
     placesController = top.document.commandDispatcher
--- a/browser/components/places/content/editBookmarkOverlay.js
+++ b/browser/components/places/content/editBookmarkOverlay.js
@@ -140,17 +140,17 @@ var gEditItemOverlay = {
     // folder picker
     this._initFolderMenuList(container);
 
     // name picker
     this._initNamePicker();
 
     // description field
     this._initTextField("descriptionField", 
-                        PlacesUIUtils.getItemDescription(this._itemId));
+                        PlacesUtils.getItemDescription(this._itemId));
     
     this._showHideRows();
 
     // observe changes
     if (!this._observersAdded) {
       PlacesUtils.bookmarks.addObserver(this, false);
       window.addEventListener("unload", this, false);
       this._observersAdded = true;
@@ -319,18 +319,18 @@ var gEditItemOverlay = {
       this._microsummaries.removeObserver(this);
       this._microsummaries = null;
     }
 
     var itemToSelect = userEnteredNameField;
     try {
       if (this._itemType == Ci.nsINavBookmarksService.TYPE_BOOKMARK &&
           !this._readOnly)
-        this._microsummaries = PlacesUIUtils.microsummaries
-                                            .getMicrosummaries(this._uri, -1);
+        this._microsummaries = PlacesUtils.microsummaries
+                                          .getMicrosummaries(this._uri, -1);
     }
     catch(ex) {
       // getMicrosummaries will throw an exception in at least two cases:
       // 1. the bookmarked URI contains a scheme that the service won't
       //    download for security reasons (currently it only handles http,
       //    https, and file);
       // 2. the page to which the URI refers isn't HTML or XML (the only two
       //    content types the service knows how to summarize).
@@ -341,18 +341,18 @@ var gEditItemOverlay = {
 
       if (enumerator.hasMoreElements()) {
         // Show the drop marker if there are microsummaries
         droppable = true;
         while (enumerator.hasMoreElements()) {
           var microsummary = enumerator.getNext()
                                        .QueryInterface(Ci.nsIMicrosummary);
           var menuItem = this._createMicrosummaryMenuItem(microsummary);
-          if (PlacesUIUtils.microsummaries
-                           .isMicrosummary(this._itemId, microsummary))
+          if (PlacesUtils.microsummaries
+                         .isMicrosummary(this._itemId, microsummary))
             itemToSelect = menuItem;
 
           menupopup.appendChild(menuItem);
         }
       }
 
       this._microsummaries.addObserver(this);
     }
@@ -444,43 +444,43 @@ var gEditItemOverlay = {
           tagsToRemove.push(currentTags[i]);
       }
       for (i = 0; i < tags.length; i++) {
         if (currentTags.indexOf(tags[i]) == -1)
           tagsToAdd.push(tags[i]);
       }
 
       if (tagsToAdd.length > 0) {
-        var tagTxn = PlacesUIUtils.ptm.tagURI(this._uri, tagsToAdd);
-        PlacesUIUtils.ptm.doTransaction(tagTxn);
+        var tagTxn = PlacesUtils.ptm.tagURI(this._uri, tagsToAdd);
+        PlacesUtils.ptm.doTransaction(tagTxn);
       }
       if (tagsToRemove.length > 0) {
-        var untagTxn = PlacesUIUtils.ptm.untagURI(this._uri, tagsToRemove);
-        PlacesUIUtils.ptm.doTransaction(untagTxn);
+        var untagTxn = PlacesUtils.ptm.untagURI(this._uri, tagsToRemove);
+        PlacesUtils.ptm.doTransaction(untagTxn);
       }
     }
   },
 
   onNamePickerInput: function EIO_onNamePickerInput() {
     var title = this._element("namePicker").value;
     this._element("userEnteredName").label = title;
   },
 
   onNamePickerChange: function EIO_onNamePickerChange() {
     if (this._itemId == -1)
       return;
 
     var namePicker = this._element("namePicker")
     var txns = [];
-    const ptm = PlacesUIUtils.ptm;
+    const ptm = PlacesUtils.ptm;
 
     // Here we update either the item title or its cached static title
     var newTitle = this._element("userEnteredName").label;
     if (this._getItemStaticTitle() != newTitle) {
-      if (PlacesUIUtils.microsummaries.hasMicrosummary(this._itemId)) {
+      if (PlacesUtils.microsummaries.hasMicrosummary(this._itemId)) {
         // Note: this implicitly also takes care of the microsummary->static
         // title case, the removeMicorosummary method in the service will set
         // the item-title to the value of this annotation.
         //
         // XXXmano: use a transaction
         PlacesUtils.setAnnotationsForItem(this._itemId,
                                           [{name: STATIC_TITLE_ANNO,
                                             value: newTitle}]);
@@ -491,91 +491,91 @@ var gEditItemOverlay = {
 
     var newMicrosummary = namePicker.selectedItem.microsummary;
 
     // Only add a microsummary update to the transaction if the microsummary
     // has actually changed, i.e. the user selected no microsummary, but the
     // bookmark previously had one, or the user selected a microsummary which
     // is not the one the bookmark previously had
     if ((newMicrosummary == null &&
-         PlacesUIUtils.microsummaries.hasMicrosummary(this._itemId)) ||
+         PlacesUtils.microsummaries.hasMicrosummary(this._itemId)) ||
         (newMicrosummary != null &&
-         !PlacesUIUtils.microsummaries
-                       .isMicrosummary(this._itemId, newMicrosummary))) {
+         !PlacesUtils.microsummaries
+                     .isMicrosummary(this._itemId, newMicrosummary))) {
       txns.push(ptm.editBookmarkMicrosummary(this._itemId, newMicrosummary));
     }
 
     var aggregate = ptm.aggregateTransactions("Edit Item Title", txns);
     ptm.doTransaction(aggregate);
   },
 
   onDescriptionFieldBlur: function EIO_onDescriptionFieldInput() {
     var description = this._element("descriptionField").value;
     if (description != PlacesUtils.getItemDescription(this._itemId)) {
-      var txn = PlacesUIUtils.ptm
-                             .editItemDescription(this._itemId, description);
-      PlacesUIUtils.ptm.doTransaction(txn);
+      var txn = PlacesUtils.ptm
+                           .editItemDescription(this._itemId, description);
+      PlacesUtils.ptm.doTransaction(txn);
     }
   },
 
   onLocationFieldBlur: function EIO_onLocationFieldBlur() {
     var uri;
     try {
-      uri = PlacesUIUtils.createFixedURI(this._element("locationField").value);
+      uri = PlacesUtils.createFixedURI(this._element("locationField").value);
     }
     catch(ex) { return; }
 
     if (!this._uri.equals(uri)) {
-      var txn = PlacesUIUtils.ptm.editBookmarkURI(this._itemId, uri);
-      PlacesUIUtils.ptm.doTransaction(txn);
+      var txn = PlacesUtils.ptm.editBookmarkURI(this._itemId, uri);
+      PlacesUtils.ptm.doTransaction(txn);
     }
   },
 
   onKeywordFieldBlur: function EIO_onKeywordFieldBlur() {
     var keyword = this._element("keywordField").value;
     if (keyword != PlacesUtils.bookmarks.getKeywordForBookmark(this._itemId)) {
-      var txn = PlacesUIUtils.ptm.editBookmarkKeyword(this._itemId, keyword);
-      PlacesUIUtils.ptm.doTransaction(txn);
+      var txn = PlacesUtils.ptm.editBookmarkKeyword(this._itemId, keyword);
+      PlacesUtils.ptm.doTransaction(txn);
     }
   },
 
   onFeedLocationFieldBlur: function EIO_onFeedLocationFieldBlur() {
     var uri;
     try {
-      uri = PlacesUIUtils.createFixedURI(this._element("feedLocationField").value);
+      uri = PlacesUtils.createFixedURI(this._element("feedLocationField").value);
     }
     catch(ex) { return; }
 
     var currentFeedURI = PlacesUtils.livemarks.getFeedURI(this._itemId);
     if (!currentFeedURI.equals(uri)) {
-      var txn = PlacesUIUtils.ptm.editLivemarkFeedURI(this._itemId, uri);
-      PlacesUIUtils.ptm.doTransaction(txn);
+      var txn = PlacesUtils.ptm.editLivemarkFeedURI(this._itemId, uri);
+      PlacesUtils.ptm.doTransaction(txn);
     }
   },
 
   onSiteLocationFieldBlur: function EIO_onSiteLocationFieldBlur() {
     var uri = null;
     try {
-      uri = PlacesUIUtils.createFixedURI(this._element("siteLocationField").value);
+      uri = PlacesUtils.createFixedURI(this._element("siteLocationField").value);
     }
     catch(ex) {  }
 
     var currentSiteURI = PlacesUtils.livemarks.getSiteURI(this._itemId);
     if (!uri || !currentSiteURI.equals(uri)) {
-      var txn = PlacesUIUtils.ptm.editLivemarkSiteURI(this._itemId, uri);
-      PlacesUIUtils.ptm.doTransaction(txn);
+      var txn = PlacesUtils.ptm.editLivemarkSiteURI(this._itemId, uri);
+      PlacesUtils.ptm.doTransaction(txn);
     }
   },
 
   onLoadInSidebarCheckboxCommand:
   function EIO_onLoadInSidebarCheckboxCommand() {
     var loadInSidebarChecked = this._element("loadInSidebarCheckbox").checked;
-    var txn = PlacesUIUtils.ptm.setLoadInSidebar(this._itemId,
-                                                 loadInSidebarChecked);
-    PlacesUIUtils.ptm.doTransaction(txn);
+    var txn = PlacesUtils.ptm.setLoadInSidebar(this._itemId,
+                                               loadInSidebarChecked);
+    PlacesUtils.ptm.doTransaction(txn);
   },
 
   toggleFolderTreeVisibility: function EIO_toggleFolderTreeVisibility() {
     var expander = this._element("foldersExpander");
     if (!this._folderTree.collapsed) {
       expander.className = "expander-down";
       expander.setAttribute("tooltiptext",
                             expander.getAttribute("tooltiptextdown"));
@@ -586,17 +586,17 @@ var gEditItemOverlay = {
     else {
       expander.className = "expander-up"
       expander.setAttribute("tooltiptext",
                             expander.getAttribute("tooltiptextup"));
       this._folderTree.collapsed = false;
       if (!this._folderTree.place) {
         const FOLDER_TREE_PLACE_URI =
           "place:excludeItems=1&excludeQueries=1&excludeReadOnlyFolders=1&folder=" +
-          window.top.PlacesUIUtils.allBookmarksFolderId;
+          window.top.PlacesUtils.allBookmarksFolderId;
         this._folderTree.place = FOLDER_TREE_PLACE_URI;
       }
 
       this._element("chooseFolderSeparator").hidden =
         this._element("chooseFolderMenuItem").hidden = true;
       var currentFolder = this._getFolderIdFromMenuList();
       this._folderTree.selectItems([currentFolder]);
       this._folderTree.focus();
@@ -646,18 +646,18 @@ var gEditItemOverlay = {
       // menulist right away
       setTimeout(function(self) self.toggleFolderTreeVisibility(), 100, this);
       return;
     }
 
     // Move the item
     var container = this._getFolderIdFromMenuList();
     if (PlacesUtils.bookmarks.getFolderIdForItem(this._itemId) != container) {
-      var txn = PlacesUIUtils.ptm.moveItem(this._itemId, container, -1);
-      PlacesUIUtils.ptm.doTransaction(txn);
+      var txn = PlacesUtils.ptm.moveItem(this._itemId, container, -1);
+      PlacesUtils.ptm.doTransaction(txn);
 
       // Mark the containing folder as recently-used if it isn't in the
       // static list
       if (container != PlacesUtils.unfiledBookmarksFolderId &&
           container != PlacesUtils.toolbarFolderId &&
           container != PlacesUtils.bookmarksMenuFolderId)
         this._markFolderAsRecentlyUsed(container);
     }
--- a/browser/components/places/content/history-panel.js
+++ b/browser/components/places/content/history-panel.js
@@ -99,17 +99,17 @@ function GroupBy(groupingType)
 
 function historyAddBookmarks()
 { 
   // no need to check gHistoryTree.view.selection.count
   // node will be null if there is a multiple selection 
   // or if the selected item is not a URI node
   var node = gHistoryTree.selectedNode;
   if (node && PlacesUtils.nodeIsURI(node))
-    PlacesUIUtils.showMinimalAddBookmarkUI(PlacesUtils._uri(node.uri), node.title);
+    PlacesUtils.showMinimalAddBookmarkUI(PlacesUtils._uri(node.uri), node.title);
 }
 
 function searchHistory(aInput)
 {
   var query = PlacesUtils.history.getNewQuery();
   var options = PlacesUtils.history.getNewQueryOptions();
 
   const NHQO = Ci.nsINavHistoryQueryOptions;
--- a/browser/components/places/content/menu.xml
+++ b/browser/components/places/content/menu.xml
@@ -210,17 +210,17 @@
           PlacesControllerDragHelper.onDrop(dropPoint.ip);
         ]]></body>
       </method>
 
       <!-- This returns the FavourSet accepted by this popup -->
       <method name="getSupportedFlavours">
         <body><![CDATA[
           var flavourSet = new FlavourSet();
-          var acceptedDropFlavours = PlacesUIUtils.GENERIC_VIEW_DROP_TYPES;
+          var acceptedDropFlavours = PlacesUtils.GENERIC_VIEW_DROP_TYPES;
           acceptedDropFlavours.forEach(flavourSet.appendFlavour, flavourSet);
           return flavourSet;
         ]]></body>
       </method>
 
       <!-- Check if we should hide the drop indicator for the target -->
       <method name="_hideDropIndicator">
         <parameter name="aEvent"/>
@@ -596,17 +596,17 @@
       </method>
 
       <method name="insertNewItem">
         <parameter name="aChild"/>
         <parameter name="aParentPopup"/>
         <parameter name="aBefore"/>
         <body><![CDATA[
           var element =
-            PlacesUIUtils.createMenuItemForNode(aChild, this._containerNodesMap);
+            PlacesUtils.createMenuItemForNode(aChild, this._containerNodesMap);
 
           if (aBefore)
             aParentPopup.insertBefore(element, aBefore);
           else {
             // Add the new element to the menu.  If there is static content at
             // the end of the menu, add the element before that.  Otherwise,
             // just add to the end.
             if (aParentPopup._endMarker != -1)
@@ -621,17 +621,17 @@
       <method name="_showEmptyMenuItem">
         <parameter name="aPopup"/>
         <body><![CDATA[
           if (aPopup._emptyMenuItem) {
             aPopup._emptyMenuItem.hidden = false;
             return;
           }
 
-          var label = PlacesUIUtils.getString("bookmarksMenuEmptyFolder");
+          var label = PlacesUtils.getString("bookmarksMenuEmptyFolder");
           aPopup._emptyMenuItem = document.createElement("menuitem");
           aPopup._emptyMenuItem.setAttribute("label", label);
           aPopup._emptyMenuItem.setAttribute("disabled", true);
           aPopup.appendChild(aPopup._emptyMenuItem);
         ]]></body>
       </method>
 
       <method name="_rebuild">
--- a/browser/components/places/content/moveBookmarks.js
+++ b/browser/components/places/content/moveBookmarks.js
@@ -47,38 +47,38 @@ var gMoveBookmarksDialog = {
     return this._foldersTree;
   },
 
   init: function() {
     this._nodes = window.arguments[0];
 
     this.foldersTree.place =
       "place:excludeItems=1&excludeQueries=1&excludeReadOnlyFolders=1&folder=" +
-      PlacesUIUtils.allBookmarksFolderId;
+      PlacesUtils.allBookmarksFolderId;
   },
 
   onOK: function MBD_onOK(aEvent) {
     var selectedNode = this.foldersTree.selectedNode;
     NS_ASSERT(selectedNode,
               "selectedNode must be set in a single-selection tree with initial selection set");
     var selectedFolderID = PlacesUtils.getConcreteItemId(selectedNode);
 
     var transactions = [];
     for (var i=0; i < this._nodes.length; i++) {
       // Nothing to do if the node is already under the selected folder
       if (this._nodes[i].parent.itemId == selectedFolderID)
         continue;
 
       transactions.push(new
-        PlacesUIUtils.ptm.moveItem(this._nodes[i].itemId, selectedFolderID, -1));
+        PlacesUtils.ptm.moveItem(this._nodes[i].itemId, selectedFolderID, -1));
     }
 
     if (transactions.length != 0) {
-      var txn = PlacesUIUtils.ptm.aggregateTransactions("Move Items", transactions);
-      PlacesUIUtils.ptm.doTransaction(txn);
+      var txn = PlacesUtils.ptm.aggregateTransactions("Move Items", transactions);
+      PlacesUtils.ptm.doTransaction(txn);
     }
   },
 
   newFolder: function MBD_newFolder() {
     // The command is disabled when the tree is not focused
     this.foldersTree.focus();
     goDoCommand("placesCmd_new:folder");
   }
--- a/browser/components/places/content/places.js
+++ b/browser/components/places/content/places.js
@@ -38,22 +38,22 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 var PlacesOrganizer = {
   _places: null,
   _content: null,
 
   _initFolderTree: function() {
-    var leftPaneRoot = PlacesUIUtils.leftPaneFolderId;
+    var leftPaneRoot = PlacesUtils.leftPaneFolderId;
     this._places.place = "place:excludeItems=1&expandQueries=0&folder=" + leftPaneRoot;
   },
 
   selectLeftPaneQuery: function PO_selectLeftPaneQuery(aQueryName) {
-    var itemId = PlacesUIUtils.leftPaneQueries[aQueryName];
+    var itemId = PlacesUtils.leftPaneQueries[aQueryName];
     this._places.selectItems([itemId]);
     // Forcefully expand all-bookmarks
     if (aQueryName == "AllBookmarks")
       asContainer(this._places.selectedNode).containerOpen = true;
   },
 
   init: function PO_init() {
     this._places = document.getElementById("placesList");
@@ -213,17 +213,17 @@ var PlacesOrganizer = {
       var searchFilter = document.getElementById("searchFilter");
       searchFilter.reset();
     }
 
     // Update the "Find in <current collection>" command and the gray text in
     // the search box in the toolbar if the active collection is the current
     // collection.
     var findCommand = document.getElementById("OrganizerCommand_find:current");
-    var findLabel = PlacesUIUtils.getFormattedString("findInPrefix", [node.title]);
+    var findLabel = PlacesUtils.getFormattedString("findInPrefix", [node.title]);
     findCommand.setAttribute("label", findLabel);
     if (PlacesSearchBox.filterCollection == "collection")
       PlacesSearchBox.updateCollectionTitle(node.title);
   },
 
   /**
    * Handle clicks on the tree. If the user middle clicks on a URL, load that
    * URL according to rules. Single clicks or modified clicks do not result in
@@ -234,17 +234,17 @@ var PlacesOrganizer = {
   onTreeClick: function PO_onTreeClick(aEvent) {
     if (aEvent.target.localName != "treechildren")
       return;
 
     var currentView = aEvent.currentTarget;
     var selectedNode = currentView.selectedNode;
     if (selectedNode && aEvent.button == 1) {
       if (PlacesUtils.nodeIsURI(selectedNode))
-        PlacesUIUtils.openNodeWithEvent(selectedNode, aEvent);
+        PlacesUtils.openNodeWithEvent(selectedNode, aEvent);
       else if (PlacesUtils.nodeIsContainer(selectedNode)) {
         // The command execution function will take care of seeing the
         // selection is a folder/container and loading its contents in
         // tabs for us.
         PlacesUtils.openContainerNodeInTabs(selectedNode);
       }
     }
   },
@@ -252,17 +252,17 @@ var PlacesOrganizer = {
   openFlatContainer: function PO_openFlatContainerFlatContainer(aContainer) {
     if (aContainer.itemId != -1)
       this._places.selectItems([aContainer.itemId]);
     else if (PlacesUtils.nodeIsQuery(aContainer))
       this._places.selectPlaceURI(aContainer.uri);
   },
 
   openSelectedNode: function PU_openSelectedNode(aEvent) {
-    PlacesUIUtils.openNodeWithEvent(this._content.selectedNode, aEvent);
+    PlacesUtils.openNodeWithEvent(this._content.selectedNode, aEvent);
   },
 
   /**
    * Returns the options associated with the query currently loaded in the
    * main places pane.
    */
   getCurrentOptions: function PO_getCurrentOptions() {
     return asQuery(this._content.getResult().root).queryOptions;
@@ -293,17 +293,17 @@ var PlacesOrganizer = {
   },
 
   /**
    * Open a file-picker and import the selected file into the bookmarks store
    */
   importFromFile: function PO_importFromFile() {
     var fp = Cc["@mozilla.org/filepicker;1"].
              createInstance(Ci.nsIFilePicker);
-    fp.init(window, PlacesUIUtils.getString("SelectImport"),
+    fp.init(window, PlacesUtils.getString("SelectImport"),
             Ci.nsIFilePicker.modeOpen);
     fp.appendFilters(Ci.nsIFilePicker.filterHTML | Ci.nsIFilePicker.filterAll);
     if (fp.show() != Ci.nsIFilePicker.returnCancel) {
       if (fp.file) {
         var importer = Cc["@mozilla.org/browser/places/import-export-service;1"].
                        getService(Ci.nsIPlacesImportExportService);
         var file = fp.file.QueryInterface(Ci.nsILocalFile);
         importer.importHTMLFromFile(file, false);
@@ -312,17 +312,17 @@ var PlacesOrganizer = {
   },
 
   /**
    * Allows simple exporting of bookmarks.
    */
   exportBookmarks: function PO_exportBookmarks() {
     var fp = Cc["@mozilla.org/filepicker;1"].
              createInstance(Ci.nsIFilePicker);
-    fp.init(window, PlacesUIUtils.getString("EnterExport"),
+    fp.init(window, PlacesUtils.getString("EnterExport"),
             Ci.nsIFilePicker.modeSave);
     fp.appendFilters(Ci.nsIFilePicker.filterHTML);
     fp.defaultString = "bookmarks.html";
     if (fp.show() != Ci.nsIFilePicker.returnCancel) {
       var exporter = Cc["@mozilla.org/browser/places/import-export-service;1"].
                      getService(Ci.nsIPlacesImportExportService);
       exporter.exportHTMLToFile(fp.file);
     }
@@ -347,34 +347,34 @@ var PlacesOrganizer = {
     if (!bookmarksBackupDir.exists())
       return; // no backup files
 
     // get list of files
     var fileList = [];
     var files = bookmarksBackupDir.directoryEntries;
     while (files.hasMoreElements()) {
       var f = files.getNext().QueryInterface(Ci.nsIFile);
-      if (!f.isHidden() && f.leafName.match(/^bookmarks-.+(html|json)?$/))
+      if (!f.isHidden() && f.leafName.match(/\.html?$/))
         fileList.push(f);
     }
 
     fileList.sort(function PO_fileList_compare(a, b) {
-      return b.lastModifiedTime - a.lastModifiedTime;
-    });
+        return b.lastModifiedTime - a.lastModifiedTime;
+      });
 
     if (fileList.length == 0)
       return;
 
     // populate menu
     for (var i = 0; i < fileList.length; i++) {
       var m = restorePopup.insertBefore
         (document.createElement("menuitem"),
          document.getElementById("restoreFromFile"));
       var dateStr = fileList[i].leafName.replace("bookmarks-", "").
-        replace(/\.(html|json)$/, "");
+        replace(".html", "");
       if (!dateStr.length)
         dateStr = fileList[i].leafName;
       m.setAttribute("label", dateStr);
       m.setAttribute("value", fileList[i].leafName);
       m.setAttribute("oncommand",
                      "PlacesOrganizer.onRestoreMenuItemClick(this);");
     }
     restorePopup.insertBefore(document.createElement("menuseparator"),
@@ -387,82 +387,82 @@ var PlacesOrganizer = {
   onRestoreMenuItemClick: function PO_onRestoreMenuItemClick(aMenuItem) {
     var dirSvc = Cc["@mozilla.org/file/directory_service;1"].
                  getService(Ci.nsIProperties);
     var bookmarksFile = dirSvc.get("ProfD", Ci.nsIFile);
     bookmarksFile.append("bookmarkbackups");
     bookmarksFile.append(aMenuItem.getAttribute("value"));
     if (!bookmarksFile.exists())
       return;
-    this.restoreBookmarksFromFile(bookmarksFile);
-  },
 
-  /**
-   * Called when 'Choose File...' is selected from the restore menu.
-   * Prompts for a file and restores bookmarks to those in the file.
-   */
-  onRestoreBookmarksFromFile: function PO_onRestoreBookmarksFromFile() {
-    var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
-    fp.init(window, PlacesUIUtils.getString("bookmarksRestoreTitle"),
-            Ci.nsIFilePicker.modeOpen);
+    var prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"].
+                  getService(Ci.nsIPromptService);
+    if (!prompts.confirm(null,
+                         PlacesUtils.getString("bookmarksRestoreAlertTitle"),
+                         PlacesUtils.getString("bookmarksRestoreAlert")))
+      return;
 
-    var dirSvc = Cc["@mozilla.org/file/directory_service;1"].
-                 getService(Ci.nsIProperties);
-    var backupsDir = dirSvc.get("Desk", Ci.nsILocalFile);
-    fp.displayDirectory = backupsDir;
-
-    if (fp.show() != Ci.nsIFilePicker.returnCancel)
-      PlacesUtils.restoreBookmarksFromFile(fp.file);
+    var ieSvc = Cc["@mozilla.org/browser/places/import-export-service;1"].
+                getService(Ci.nsIPlacesImportExportService);
+    ieSvc.importHTMLFromFile(bookmarksFile, true);
   },
 
   /**
-   * Restores bookmarks from an HTML or JSON file.
-   */
-  restoreBookmarksFromFile: function PO_restoreBookmarksFromFile(aFile) {
-    var prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"].
-                  getService(Ci.nsIPromptService);
-    if (!prompts.confirm(null,
-                         PlacesUIUtils.getString("bookmarksRestoreAlertTitle"),
-                         PlacesUIUtils.getString("bookmarksRestoreAlert")))
-      return;
-
-    if (aFile.leafName.match("\.json$")) {
-      // restore a JSON backup
-      PlacesUtils.restoreBookmarksFromJSONFile(aFile);
-    }
-    else {
-      var importer = Cc["@mozilla.org/browser/places/import-export-service;1"].
-                     getService(Ci.nsIPlacesImportExportService);
-      importer.importHTMLFromFile(aFile, true /* overwrite existing */);
-    }
-  },
-
-  /**
-   * Backup bookmarks to desktop, auto-generate a filename with a date.
-   * The file is a JSON serialization of bookmarks, tags and any annotations
-   * of those items.
+   * Backup bookmarks to desktop, auto-generate a filename with a date
    */
   backupBookmarks: function PO_backupBookmarks() {
     var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
-    fp.init(window, PlacesUIUtils.getString("bookmarksBackupTitle"),
+    fp.init(window, PlacesUtils.getString("bookmarksBackupTitle"),
             Ci.nsIFilePicker.modeSave);
+    fp.appendFilters(Ci.nsIFilePicker.filterHTML);
 
     var dirSvc = Cc["@mozilla.org/file/directory_service;1"].
                  getService(Ci.nsIProperties);
     var backupsDir = dirSvc.get("Desk", Ci.nsILocalFile);
     fp.displayDirectory = backupsDir;
 
     // Use YYYY-MM-DD (ISO 8601) as it doesn't contain illegal characters
     // and makes the alphabetical order of multiple backup files more useful.
     var date = (new Date).toLocaleFormat("%Y-%m-%d");
     fp.defaultString = PlacesUtils.getFormattedString("bookmarksBackupFilename",
-                                                        [date]);
+                                                      [date]);
+
+    if (fp.show() != Ci.nsIFilePicker.returnCancel) {
+      var ieSvc = Cc["@mozilla.org/browser/places/import-export-service;1"].
+                  getService(Ci.nsIPlacesImportExportService);
+      ieSvc.exportHTMLToFile(fp.file);
+    }
+  },
 
-    if (fp.show() != Ci.nsIFilePicker.returnCancel)
-      PlacesUtils.backupBookmarksToFile(fp.file);
+  /**
+   * Called when 'Choose File...' is selected from the Revert menupopup
+   * Prompts for a file and reverts bookmarks to those in the file
+   */
+  restoreFromFile: function PO_restoreFromFile() {
+    var prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"].
+                  getService(Ci.nsIPromptService);
+    if (!prompts.confirm(null, PlacesUtils.getString("bookmarksRestoreAlertTitle"),
+                         PlacesUtils.getString("bookmarksRestoreAlert")))
+      return;
+
+    var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
+    fp.init(window, PlacesUtils.getString("bookmarksRestoreTitle"),
+            Ci.nsIFilePicker.modeOpen);
+    fp.appendFilters(Ci.nsIFilePicker.filterHTML);
+
+    var dirSvc = Cc["@mozilla.org/file/directory_service;1"].
+                 getService(Ci.nsIProperties);
+    var backupsDir = dirSvc.get("Desk", Ci.nsILocalFile);
+    fp.displayDirectory = backupsDir;
+
+    if (fp.show() != Ci.nsIFilePicker.returnCancel) {
+      var ieSvc = Cc["@mozilla.org/browser/places/import-export-service;1"].
+                  getService(Ci.nsIPlacesImportExportService);
+      ieSvc.importHTMLFromFile(fp.file, true);
+    }
   },
 
   _paneDisabled: false,
   _setDetailsFieldsDisabledState:
   function PO__setDetailsFieldsDisabledState(aDisabled) {
     if (aDisabled) {
       document.getElementById("paneElementsBroadcaster")
               .setAttribute("disabled", "true");
@@ -543,26 +543,26 @@ var PlacesOrganizer = {
     }
     else {
       detailsDeck.selectedIndex = 0;
       var selectItemDesc = document.getElementById("selectItemDescription");
       var itemsCountLabel = document.getElementById("itemsCountText");
       var rowCount = this._content.treeBoxObject.view.rowCount;
       if (rowCount == 0) {
         selectItemDesc.hidden = true;
-        itemsCountLabel.value = PlacesUIUtils.getString("detailsPane.noItems");
+        itemsCountLabel.value = PlacesUtils.getString("detailsPane.noItems");
       }
       else {
         selectItemDesc.hidden = false;
         if (rowCount == 1)
-          itemsCountLabel.value = PlacesUIUtils.getString("detailsPane.oneItem");
+          itemsCountLabel.value = PlacesUtils.getString("detailsPane.oneItem");
         else {
           itemsCountLabel.value =
-            PlacesUIUtils.getFormattedString("detailsPane.multipleItems",
-                                             [rowCount]);
+            PlacesUtils.getFormattedString("detailsPane.multipleItems",
+                                           [rowCount]);
         }
       }
     }
 
     // Nothing to do if the pane was already disabled
     if (!this._paneDisabled) {
       gEditItemOverlay.uninitPanel();
       this._setDetailsFieldsDisabledState(true);
@@ -637,36 +637,36 @@ var PlacesOrganizer = {
                                                              options);
     var placeURI = Cc["@mozilla.org/network/io-service;1"].
                    getService(Ci.nsIIOService).
                    newURI(placeSpec, null, null);
 
     // Prompt the user for a name for the query.
     // XXX - using prompt service for now; will need to make
     // a real dialog and localize when we're sure this is the UI we want.
-    var title = PlacesUIUtils.getString("saveSearch.title");
-    var inputLabel = PlacesUIUtils.getString("saveSearch.inputLabel");
-    var defaultText = PlacesUIUtils.getString("saveSearch.defaultText");
+    var title = PlacesUtils.getString("saveSearch.title");
+    var inputLabel = PlacesUtils.getString("saveSearch.inputLabel");
+    var defaultText = PlacesUtils.getString("saveSearch.defaultText");
 
     var prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"].
                   getService(Ci.nsIPromptService);
     var check = {value: false};
     var input = {value: defaultText};
     var save = prompts.prompt(null, title, inputLabel, input, null, check);
 
     // Don't add the query if the user cancels or clears the seach name.
     if (!save || input.value == "")
      return;
 
     // Add the place: uri as a bookmark under the bookmarks root.
-    var txn = PlacesUIUtils.ptm.createItem(placeURI,
-                                           PlacesUtils.bookmarksMenuFolderId,
-                                           PlacesUtils.bookmarks.DEFAULT_INDEX,
-                                           input.value);
-    PlacesUIUtils.ptm.doTransaction(txn);
+    var txn = PlacesUtils.ptm.createItem(placeURI,
+                                         PlacesUtils.bookmarksMenuFolderId,
+                                         PlacesUtils.bookmarks.DEFAULT_INDEX,
+                                         input.value);
+    PlacesUtils.ptm.doTransaction(txn);
 
     // select and load the new query
     this._places.selectPlaceURI(placeSpec);
   }
 };
 
 /**
  * A set of utilities relating to search within Bookmarks and History.
@@ -769,18 +769,18 @@ var PlacesSearchBox = {
   /**
    * Updates the display with the title of the current collection.
    * @param   title
    *          The title of the current collection.
    */
   updateCollectionTitle: function PSB_updateCollectionTitle(title) {
     this.searchFilter.emptyText =
       title ?
-      PlacesUIUtils.getFormattedString("searchCurrentDefault", [title]) :
-      PlacesUIUtils.getString("searchBookmarks");
+      PlacesUtils.getFormattedString("searchCurrentDefault", [title]) :
+      PlacesUtils.getString("searchBookmarks");
   },
 
   /**
    * Gets/sets the active collection from the dropdown menu.
    */
   get filterCollection() {
     return this.searchFilter.getAttribute("collection");
   },
@@ -1328,17 +1328,17 @@ var PlacesQueryBuilder = {
       case "scopeBarHistory":
         PlacesSearchBox.filterCollection = "history";
         folders = [];
         break;
       case "scopeBarFolder":
         var selectedFolder = PlacesOrganizer._places.selectedNode.itemId;
         // note "all bookmarks" isn't the concrete parent of the top-level
         // bookmark folders
-        if (selectedFolder != PlacesUIUtils.allBookmarksFolderId) {
+        if (selectedFolder != PlacesUtils.allBookmarksFolderId) {
           PlacesSearchBox.filterCollection = "collection";
           folders.push(PlacesOrganizer._places.selectedNode.itemId);
           break;
         }
       default: // all bookmarks
         PlacesSearchBox.filterCollection = "bookmarks";
         folders.push(PlacesUtils.bookmarksMenuFolderId,
                      PlacesUtils.toolbarFolderId,
@@ -1440,18 +1440,18 @@ var ViewMenu = {
       menuitem.column = column;
       var label = column.getAttribute("label");
       if (propertyPrefix) {
         var menuitemPrefix = propertyPrefix;
         // for string properties, use "name" as the id, instead of "title"
         // see bug #386287 for details
         var columnId = column.getAttribute("anonid");
         menuitemPrefix += columnId == "title" ? "name" : columnId;
-        label = PlacesUIUtils.getString(menuitemPrefix + ".label");
-        var accesskey = PlacesUIUtils.getString(menuitemPrefix + ".accesskey");
+        label = PlacesUtils.getString(menuitemPrefix + ".label");
+        var accesskey = PlacesUtils.getString(menuitemPrefix + ".accesskey");
         menuitem.setAttribute("accesskey", accesskey);
       }
       menuitem.setAttribute("label", label);
       if (type == "radio") {
         menuitem.setAttribute("type", "radio");
         menuitem.setAttribute("name", "columns");
         // This column is the sort key. Its item is checked.
         if (column.getAttribute("sortDirection") != "") {
--- a/browser/components/places/content/places.xul
+++ b/browser/components/places/content/places.xul
@@ -102,17 +102,17 @@
              oncommand="PlacesSearchBox.findCurrent();"/>
     <command id="OrganizerCommand_export"
              oncommand="PlacesOrganizer.exportBookmarks();"/>
     <command id="OrganizerCommand_import"
              oncommand="PlacesOrganizer.importBookmarks();"/>
     <command id="OrganizerCommand_backup"
              oncommand="PlacesOrganizer.backupBookmarks();"/>
     <command id="OrganizerCommand_restoreFromFile"
-             oncommand="PlacesOrganizer.onRestoreBookmarksFromFile();"/>
+             oncommand="PlacesOrganizer.restoreFromFile();"/>
     <command id="OrganizerCommand_search:save"
              oncommand="PlacesOrganizer.saveSearch();"/>
     <command id="OrganizerCommand_search:moreCriteria"
              oncommand="PlacesQueryBuilder.addRow();"/>
     <command id="OrganizerCommand:Back"
              oncommand="PlacesOrganizer.back();"/>
     <command id="OrganizerCommand:Forward"
              oncommand="PlacesOrganizer.forward();"/>
--- a/browser/components/places/content/placesOverlay.xul
+++ b/browser/components/places/content/placesOverlay.xul
@@ -89,17 +89,17 @@
              oncommand="goDoCommand('placesCmd_reloadMicrosummary');"/>
     <command id="placesCmd_sortBy:name"
              oncommand="goDoCommand('placesCmd_sortBy:name');"/>
     <command id="placesCmd_moveBookmarks"
              oncommand="goDoCommand('placesCmd_moveBookmarks');"/>
   </commandset>
 
   <popup id="placesContext"
-         onpopupshowing="this._view = PlacesUIUtils.getViewForNode(document.popupNode);
+         onpopupshowing="this._view = PlacesUtils.getViewForNode(document.popupNode);
                          return this._view.buildContextMenu(this);"
          onpopuphiding="this._view.destroyContextMenu();">
     <menuitem id="placesContext_open"
               command="placesCmd_open"
               label="&cmd.open.label;"
               accesskey="&cmd.open.accesskey;"
               default="true"
               selectiontype="single"
@@ -112,25 +112,25 @@
               selection="link"/>
     <menuitem id="placesContext_open:newtab"
               command="placesCmd_open:tab"
               label="&cmd.open_tab.label;"
               accesskey="&cmd.open_tab.accesskey;"
               selectiontype="single"
               selection="link"/>
     <menuitem id="placesContext_openContainer:tabs"
-              oncommand="var view = PlacesUIUtils.getViewForNode(document.popupNode);
+              oncommand="var view = PlacesUtils.getViewForNode(document.popupNode);
                          view.controller.openSelectionInTabs(event);"
               onclick="checkForMiddleClick(this, event);"
               label="&cmd.open_all_in_tabs.label;"
               accesskey="&cmd.open_all_in_tabs.accesskey;"
               selectiontype="single"
               selection="folder|host|query"/>
     <menuitem id="placesContext_openLinks:tabs"
-              oncommand="var view = PlacesUIUtils.getViewForNode(document.popupNode);
+              oncommand="var view = PlacesUtils.getViewForNode(document.popupNode);
                          view.controller.openSelectionInTabs(event);"
               onclick="checkForMiddleClick(this, event);"
               label="&cmd.open_all_in_tabs.label;"
               accesskey="&cmd.open_all_in_tabs.accesskey;"
               selectiontype="multiple"
               selection="link"/>
     <menuseparator id="placesContext_openSeparator"/>
     <menuitem id="placesContext_new:bookmark"
--- a/browser/components/places/content/sidebarUtils.js
+++ b/browser/components/places/content/sidebarUtils.js
@@ -62,23 +62,23 @@ var SidebarUtils = {
     }
     if (!mouseInGutter && 
         aEvent.originalTarget.localName == "treechildren" && 
         (aEvent.button == 0 || aEvent.button == 1)) {
       // Clear all other selection since we're loading a link now. We must
       // do this *before* attempting to load the link since openURL uses
       // selection as an indication of which link to load. 
       tbo.view.selection.select(row.value);
-      PlacesUIUtils.openNodeWithEvent(aTree.selectedNode, aEvent);
+      PlacesUtils.openNodeWithEvent(aTree.selectedNode, aEvent);
     }
   },
 
   handleTreeKeyPress: function SU_handleTreeKeyPress(aEvent) {
     if (aEvent.keyCode == KeyEvent.DOM_VK_RETURN)
-      PlacesUIUtils.openNodeWithEvent(aEvent.target.selectedNode, aEvent);
+      PlacesUtils.openNodeWithEvent(aEvent.target.selectedNode, aEvent);
   },
 
   /**
    * The following function displays the URL of a node that is being
    * hovered over.
    */
   handleTreeMouseMove: function SU_handleTreeMouseMove(aEvent) {
     if (aEvent.target.localName != "treechildren")
--- a/browser/components/places/content/toolbar.xml
+++ b/browser/components/places/content/toolbar.xml
@@ -897,17 +897,17 @@
           // Close any folder being hovered over
           if (this._overFolder.node)
             this._overFolder.closeTimer = this._setTimer(this._overFolder.hoverTime);
           PlacesControllerDragHelper.currentDropTarget = null;
         },
 
         getSupportedFlavours: function TBV_DO_getSupportedFlavours() {
           var flavorSet = new FlavourSet();
-          var types = PlacesUIUtils.GENERIC_VIEW_DROP_TYPES;
+          var types = PlacesUtils.GENERIC_VIEW_DROP_TYPES;
           for (var i = 0; i < types.length; ++i)
             flavorSet.appendFlavour(types[i]);
           return flavorSet;
         }
       })]]></field>
 
       <method name="checkForMenuEvent">
         <parameter name="event"/>
@@ -956,31 +956,31 @@
       <method name="_showEmptyMenuItem">
         <parameter name="aPopup"/>
         <body><![CDATA[
           if (aPopup._emptyMenuItem) {
             aPopup._emptyMenuItem.hidden = false;
             return;
           }
 
-          var label = PlacesUIUtils.getString("bookmarksMenuEmptyFolder");
+          var label = PlacesUtils.getString("bookmarksMenuEmptyFolder");
           aPopup._emptyMenuItem = document.createElement("menuitem");
           aPopup._emptyMenuItem.setAttribute("label", label);
           aPopup._emptyMenuItem.setAttribute("disabled", true);
           aPopup.appendChild(aPopup._emptyMenuItem);
         ]]></body>
       </method>
 
       <method name="insertNewItemToPopup">
         <parameter name="aChild"/>
         <parameter name="aParentPopup"/>
         <parameter name="aBefore"/>
         <body><![CDATA[
           var element =
-            PlacesUIUtils.createMenuItemForNode(aChild, this._containerNodesMap);
+            PlacesUtils.createMenuItemForNode(aChild, this._containerNodesMap);
           if (aBefore)
             aParentPopup.insertBefore(element, aBefore);
           else
             aParentPopup.appendChild(element);
         ]]></body>
       </method>
 
       <method name="_containerPopupShowing">
--- a/browser/components/places/content/tree.xml
+++ b/browser/components/places/content/tree.xml
@@ -706,17 +706,17 @@
           }
         ]]></body>
       </method>
 
       <!-- nsDragAndDrop -->
       <method name="getSupportedFlavours">
         <body><![CDATA[
           var flavorSet = new FlavourSet();
-          var types = PlacesUIUtils.GENERIC_VIEW_DROP_TYPES;
+          var types = PlacesUtils.GENERIC_VIEW_DROP_TYPES;
           for (var i = 0; i < types.length; ++i)
             flavorSet.appendFlavour(types[i]);
           return flavorSet;
         ]]></body>
       </method>
 
       <method name="buildContextMenu">
         <parameter name="aPopup"/>
--- a/browser/components/places/content/treeView.js
+++ b/browser/components/places/content/treeView.js
@@ -187,18 +187,18 @@ PlacesTreeView.prototype = {
    * It is used to compute each node's viewIndex.
    */
   _buildVisibleSection:
   function PTV__buildVisibleSection(aContainer, aVisible, aToOpen, aVisibleStartIndex)
   {
     if (!aContainer.containerOpen)
       return;  // nothing to do
 
-    const openLiteral = PlacesUIUtils.RDF.GetResource("http://home.netscape.com/NC-rdf#open");
-    const trueLiteral = PlacesUIUtils.RDF.GetLiteral("true");
+    const openLiteral = PlacesUtils.RDF.GetResource("http://home.netscape.com/NC-rdf#open");
+    const trueLiteral = PlacesUtils.RDF.GetLiteral("true");
 
     var cc = aContainer.childCount;
     for (var i=0; i < cc; i++) {
       var curChild = aContainer.getChild(i);
       var curChildType = curChild.type;
 
       // don't display separators when sorted
       if (curChildType == Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR) {
@@ -214,18 +214,18 @@ PlacesTreeView.prototype = {
       aVisible.push({ node: curChild, properties: null });
 
       // recursively do containers
       if (!this._flatList && PlacesUtils.containerTypes.indexOf(curChildType) != -1) {
         asContainer(curChild);
 
         var resource = this._getResourceForNode(curChild);
         var isopen = resource != null &&
-                     PlacesUIUtils.localStore.HasAssertion(resource, openLiteral,
-                                                           trueLiteral, true);
+                     PlacesUtils.localStore.HasAssertion(resource, openLiteral,
+                                                         trueLiteral, true);
         if (isopen != curChild.containerOpen)
           aToOpen.push(curChild);
         else if (curChild.containerOpen && curChild.childCount > 0)
           this._buildVisibleSection(curChild, aVisible, aToOpen, aVisibleStartIndex);
       }
     }
   },
 
@@ -827,17 +827,17 @@ PlacesTreeView.prototype = {
               "Node's visible index and array out of sync");
     return viewIndex;
   },
 
   _getResourceForNode: function PTV_getResourceForNode(aNode)
   {
     var uri = aNode.uri;
     NS_ASSERT(uri, "if there is no uri, we can't persist the open state");
-    return uri ? PlacesUIUtils.RDF.GetResource(uri) : null;
+    return uri ? PlacesUtils.RDF.GetResource(uri) : null;
   },
 
   // nsITreeView
   get rowCount() {
     return this._visibleElements.length;
   },
 
   get selection() {
@@ -1124,17 +1124,17 @@ PlacesTreeView.prototype = {
     switch (columnType) {
       case this.COLUMN_TYPE_TITLE:
         // normally, this is just the title, but we don't want empty items in
         // the tree view so return a special string if the title is empty.
         // Do it here so that callers can still get at the 0 length title
         // if they go through the "result" API.
         if (PlacesUtils.nodeIsSeparator(node))
           return "";
-        return node.title || PlacesUIUtils.getString("noTitle");
+        return node.title || PlacesUtils.getString("noTitle");
       case this.COLUMN_TYPE_TAGS:
         return node.tags;
       case this.COLUMN_TYPE_URI:
         if (PlacesUtils.nodeIsURI(node))
           return node.uri;
         return "";
       case this.COLUMN_TYPE_DATE:
         if (node.time == 0 || !PlacesUtils.nodeIsURI(node)) {
@@ -1198,23 +1198,23 @@ PlacesTreeView.prototype = {
 
     if (this._flatList && this._openContainerCallback) {
       this._openContainerCallback(node);
       return;
     }
 
     var resource = this._getResourceForNode(node);
     if (resource) {
-      const openLiteral = PlacesUIUtils.RDF.GetResource("http://home.netscape.com/NC-rdf#open");
-      const trueLiteral = PlacesUIUtils.RDF.GetLiteral("true");
+      const openLiteral = PlacesUtils.RDF.GetResource("http://home.netscape.com/NC-rdf#open");
+      const trueLiteral = PlacesUtils.RDF.GetLiteral("true");
 
       if (node.containerOpen)
-        PlacesUIUtils.localStore.Unassert(resource, openLiteral, trueLiteral);
+        PlacesUtils.localStore.Unassert(resource, openLiteral, trueLiteral);
       else
-        PlacesUIUtils.localStore.Assert(resource, openLiteral, trueLiteral, true);
+        PlacesUtils.localStore.Assert(resource, openLiteral, trueLiteral, true);
     }
 
     node.containerOpen = !node.containerOpen;
   },
 
   cycleHeader: function PTV_cycleHeader(aColumn) {
     if (!this._result)
       throw Cr.NS_ERROR_UNEXPECTED;
--- a/browser/components/places/content/utils.js
+++ b/browser/components/places/content/utils.js
@@ -18,17 +18,16 @@
  * Portions created by the Initial Developer are Copyright (C) 2005
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   Ben Goodger <beng@google.com>
  *   Myk Melez <myk@mozilla.org>
  *   Asaf Romano <mano@mozilla.com>
  *   Sungjoon Steve Won <stevewon@gmail.com>
- *   Dietrich Ayala <dietrich@mozilla.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -42,65 +41,133 @@
 function LOG(str) {
   dump("*** " + str + "\n");
 }
 
 var Ci = Components.interfaces;
 var Cc = Components.classes;
 var Cr = Components.results;
 
-#include ../../../../toolkit/content/debug.js
-#include ../../../../toolkit/components/places/src/utils.js
+Components.utils.import("resource://gre/modules/JSON.jsm");
 
 const LOAD_IN_SIDEBAR_ANNO = "bookmarkProperties/loadInSidebar";
 const DESCRIPTION_ANNO = "bookmarkProperties/description";
+const POST_DATA_ANNO = "bookmarkProperties/POSTData";
+const LMANNO_FEEDURI = "livemark/feedURI";
+const LMANNO_SITEURI = "livemark/siteURI";
 const ORGANIZER_FOLDER_ANNO = "PlacesOrganizer/OrganizerFolder";
 const ORGANIZER_QUERY_ANNO = "PlacesOrganizer/OrganizerQuery";
 
-/*
-XXX PULLED IN BY TOOLKIT UTILS.JS
-
-const LMANNO_FEEDURI = "livemark/feedURI";
-const LMANNO_SITEURI = "livemark/siteURI";
-
 #ifdef XP_MACOSX
 // On Mac OSX, the transferable system converts "\r\n" to "\n\n", where we
 // really just want "\n".
 const NEWLINE= "\n";
 #else
 // On other platforms, the transferable system converts "\r\n" to "\n".
 const NEWLINE = "\r\n";
 #endif
-*/
 
 function QI_node(aNode, aIID) {
   var result = null;
   try {
     result = aNode.QueryInterface(aIID);
   }
   catch (e) {
   }
   NS_ASSERT(result, "Node QI Failed");
   return result;
 }
 function asVisit(aNode)    { return QI_node(aNode, Ci.nsINavHistoryVisitResultNode);    }
 function asFullVisit(aNode){ return QI_node(aNode, Ci.nsINavHistoryFullVisitResultNode);}
 function asContainer(aNode){ return QI_node(aNode, Ci.nsINavHistoryContainerResultNode);}
 function asQuery(aNode)    { return QI_node(aNode, Ci.nsINavHistoryQueryResultNode);    }
 
-var PlacesUIUtils = {
+var PlacesUtils = {
+  // Place entries that are containers, e.g. bookmark folders or queries.
+  TYPE_X_MOZ_PLACE_CONTAINER: "text/x-moz-place-container",
+  // Place entries that are bookmark separators.
+  TYPE_X_MOZ_PLACE_SEPARATOR: "text/x-moz-place-separator",
+  // Place entries that are not containers or separators
+  TYPE_X_MOZ_PLACE: "text/x-moz-place",
+  // Place entries in shortcut url format (url\ntitle)
+  TYPE_X_MOZ_URL: "text/x-moz-url",
+  // Place entries formatted as HTML anchors
+  TYPE_HTML: "text/html",
+  // Place entries as raw URL text
+  TYPE_UNICODE: "text/unicode",
+
+  /**
+   * The Bookmarks Service.
+   */
+  get bookmarks() {
+    delete this.bookmarks;
+    return this.bookmarks = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
+                            getService(Ci.nsINavBookmarksService);
+  },
+
+  /**
+   * The Nav History Service.
+   */
+  get history() {
+    delete this.history;
+    return this.history = Cc["@mozilla.org/browser/nav-history-service;1"].
+                          getService(Ci.nsINavHistoryService);
+  },
+
+  get globalHistory() {
+    delete this.globalHistory;
+    return this.globalHistory = Cc["@mozilla.org/browser/global-history;2"].
+                                getService(Ci.nsIBrowserHistory);
+  },
+
+  /**
+   * The Live Bookmark Service.
+   */
+  get livemarks() {
+    delete this.livemarks;
+    return this.livemarks = Cc["@mozilla.org/browser/livemark-service;2"].
+                            getService(Ci.nsILivemarkService);
+  },
+
+  /**
+   * The Annotations Service.
+   */
+  get annotations() {
+    delete this.annotations;
+    return this.annotations = Cc["@mozilla.org/browser/annotation-service;1"].
+                              getService(Ci.nsIAnnotationService);
+  },
+
+  /**
+   * The Favicons Service
+   */
+  get favicons() {
+    delete this.favicons;
+    return this.favicons = Cc["@mozilla.org/browser/favicon-service;1"].
+                           getService(Ci.nsIFaviconService);
+  },
+
   /**
    * The Microsummary Service
    */
   get microsummaries() {
     delete this.microsummaries;
     return this.microsummaries = Cc["@mozilla.org/microsummary/service;1"].
                                  getService(Ci.nsIMicrosummaryService);
   },
 
+  /**
+   * The Places Tagging Service
+   */
+  get tagging() {
+    delete this.tagging;
+    return this.tagging = Cc["@mozilla.org/browser/tagging-service;1"].
+                          getService(Ci.nsITaggingService);
+  },
+
   get RDF() {
     delete this.RDF;
     return this.RDF = Cc["@mozilla.org/rdf/rdf-service;1"].
                       getService(Ci.nsIRDFService);
   },
 
   get localStore() {
     delete this.localStore;
@@ -121,16 +188,29 @@ var PlacesUIUtils = {
 
   get URIFixup() {
     delete this.URIFixup;
     return this.URIFixup = Cc["@mozilla.org/docshell/urifixup;1"].
                            getService(Ci.nsIURIFixup);
   },
 
   /**
+   * Makes a URI from a spec.
+   * @param   aSpec
+   *          The string spec of the URI
+   * @returns A URI object for the spec.
+   */
+  _uri: function PU__uri(aSpec) {
+    NS_ASSERT(aSpec, "empty URL spec");
+    return Cc["@mozilla.org/network/io-service;1"].
+           getService(Ci.nsIIOService).
+           newURI(aSpec, null, null);
+  },
+
+  /**
    * Makes a URI from a spec, and do fixup
    * @param   aSpec
    *          The string spec of the URI
    * @returns A URI object for the spec.
    */
   createFixedURI: function PU_createFixedURI(aSpec) {
     return this.URIFixup.createFixupURI(aSpec, 0);
   },
@@ -164,28 +244,438 @@ var PlacesUIUtils = {
     return this._bundle.formatStringFromName(key, params, params.length);
   },
 
   getString: function PU_getString(key) {
     return this._bundle.GetStringFromName(key);
   },
 
   /**
+   * Determines whether or not a ResultNode is a Bookmark folder.
+   * @param   aNode
+   *          A result node
+   * @returns true if the node is a Bookmark folder, false otherwise
+   */
+  nodeIsFolder: function PU_nodeIsFolder(aNode) {
+    NS_ASSERT(aNode, "null node");
+    return (aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER ||
+            aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER_SHORTCUT);
+  },
+
+  /**
+   * Determines whether or not a ResultNode represents a bookmarked URI.
+   * @param   aNode
+   *          A result node
+   * @returns true if the node represents a bookmarked URI, false otherwise
+   */
+  nodeIsBookmark: function PU_nodeIsBookmark(aNode) {
+    NS_ASSERT(aNode, "null node");
+    return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_URI &&
+           aNode.itemId != -1;
+  },
+
+  /**
+   * Determines whether or not a ResultNode is a Bookmark separator.
+   * @param   aNode
+   *          A result node
+   * @returns true if the node is a Bookmark separator, false otherwise
+   */
+  nodeIsSeparator: function PU_nodeIsSeparator(aNode) {
+    NS_ASSERT(aNode, "null node");
+
+    return (aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR);
+  },
+
+  /**
+   * Determines whether or not a ResultNode is a visit item.
+   * @param   aNode
+   *          A result node
+   * @returns true if the node is a visit item, false otherwise
+   */
+  nodeIsVisit: function PU_nodeIsVisit(aNode) {
+    NS_ASSERT(aNode, "null node");
+
+    const NHRN = Ci.nsINavHistoryResultNode;
+    var type = aNode.type;
+    return type == NHRN.RESULT_TYPE_VISIT ||
+           type == NHRN.RESULT_TYPE_FULL_VISIT;
+  },
+
+  /**
+   * Determines whether or not a ResultNode is a URL item.
+   * @param   aNode
+   *          A result node
+   * @returns true if the node is a URL item, false otherwise
+   */
+  uriTypes: [Ci.nsINavHistoryResultNode.RESULT_TYPE_URI,
+             Ci.nsINavHistoryResultNode.RESULT_TYPE_VISIT,
+             Ci.nsINavHistoryResultNode.RESULT_TYPE_FULL_VISIT],
+  nodeIsURI: function PU_nodeIsURI(aNode) {
+    NS_ASSERT(aNode, "null node");
+    return this.uriTypes.indexOf(aNode.type) != -1;
+  },
+
+  /**
+   * Determines whether or not a ResultNode is a Query item.
+   * @param   aNode
+   *          A result node
+   * @returns true if the node is a Query item, false otherwise
+   */
+  nodeIsQuery: function PU_nodeIsQuery(aNode) {
+    NS_ASSERT(aNode, "null node");
+    return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY;
+  },
+
+  /**
+   * Determines if a node is read only (children cannot be inserted, sometimes
+   * they cannot be removed depending on the circumstance)
+   * @param   aNode
+   *          A result node
+   * @returns true if the node is readonly, false otherwise
+   */
+  nodeIsReadOnly: function PU_nodeIsReadOnly(aNode) {
+    NS_ASSERT(aNode, "null node");
+
+    if (this.nodeIsFolder(aNode))
+      return this.bookmarks.getFolderReadonly(asQuery(aNode).folderItemId);
+    if (this.nodeIsQuery(aNode))
+      return asQuery(aNode).childrenReadOnly;
+    return false;
+  },
+
+  /**
+   * Determines whether or not a ResultNode is a host container.
+   * @param   aNode
+   *          A result node
+   * @returns true if the node is a host container, false otherwise
+   */
+  nodeIsHost: function PU_nodeIsHost(aNode) {
+    NS_ASSERT(aNode, "null node");
+    return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY &&
+           aNode.parent &&
+           asQuery(aNode.parent).queryOptions.resultType ==
+             Ci.nsINavHistoryQueryOptions.RESULTS_AS_SITE_QUERY;
+  },
+
+  /**
+   * Determines whether or not a ResultNode is a day container.
+   * @param   node
+   *          A NavHistoryResultNode
+   * @returns true if the node is a day container, false otherwise
+   */
+  nodeIsDay: function PU_nodeIsDay(aNode) {
+    NS_ASSERT(aNode, "null node");
+    var resultType;
+    return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY &&
+           aNode.parent &&
+           ((resultType = asQuery(aNode.parent).queryOptions.resultType) ==
+               Ci.nsINavHistoryQueryOptions.RESULTS_AS_DATE_QUERY ||
+             resultType == Ci.nsINavHistoryQueryOptions.RESULTS_AS_DATE_SITE_QUERY);
+  },
+
+  /**
+   * Determines whether or not a ResultNode is a container.
+   * @param   aNode
+   *          A result node
+   * @returns true if the node is a container item, false otherwise
+   */
+  containerTypes: [Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER,
+                   Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER_SHORTCUT,
+                   Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY,
+                   Ci.nsINavHistoryResultNode.RESULT_TYPE_DYNAMIC_CONTAINER],
+  nodeIsContainer: function PU_nodeIsContainer(aNode) {
+    NS_ASSERT(aNode, "null node");
+    return this.containerTypes.indexOf(aNode.type) != -1;
+  },
+
+  /**
+   * Determines whether or not a result-node is a dynamic-container item.
+   * The dynamic container result node type is for dynamically created
+   * containers (e.g. for the file browser service where you get your folders
+   * in bookmark menus).
+   * @param   aNode
+   *          A result node
+   * @returns true if the node is a dynamic container item, false otherwise
+   */
+  nodeIsDynamicContainer: function PU_nodeIsDynamicContainer(aNode) {
+    NS_ASSERT(aNode, "null node");
+    if (aNode.type == NHRN.RESULT_TYPE_DYNAMIC_CONTAINER)
+      return true;
+    return false;
+  },
+
+ /**
+  * Determines whether a result node is a remote container registered by the
+  * livemark service.
+  * @param aNode
+  *        A result Node
+  * @returns true if the node is a livemark container item
+  */
+  nodeIsLivemarkContainer: function PU_nodeIsLivemarkContainer(aNode) {
+    // Use the annotations service directly to avoid instantiating
+    // the Livemark service on startup. (bug 398300)
+    return this.nodeIsFolder(aNode) &&
+           this.annotations.itemHasAnnotation(aNode.itemId, LMANNO_FEEDURI);
+  },
+
+ /**
+  * Determines whether a result node is a live-bookmark item
+  * @param aNode
+  *        A result node
+  * @returns true if the node is a livemark container item
+  */
+  nodeIsLivemarkItem: function PU_nodeIsLivemarkItem(aNode) {
+    return aNode.parent && this.nodeIsLivemarkContainer(aNode.parent);
+  },
+
+  /**
+   * Determines whether or not a node is a readonly folder.
+   * @param   aNode
+   *          The node to test.
+   * @returns true if the node is a readonly folder.
+  */
+  isReadonlyFolder: function(aNode) {
+    NS_ASSERT(aNode, "null node");
+
+    return this.nodeIsFolder(aNode) &&
+           this.bookmarks.getFolderReadonly(asQuery(aNode).folderItemId);
+  },
+
+  /**
+   * Gets the concrete item-id for the given node. Generally, this is just
+   * node.itemId, but for folder-shortcuts that's node.folderItemId.
+   */
+  getConcreteItemId: function PU_getConcreteItemId(aNode) {
+    if (aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER_SHORTCUT)
+      return asQuery(aNode).folderItemId;
+    return aNode.itemId;
+  },
+
+  /**
+   * Gets the index of a node within its parent container
+   * @param   aNode
+   *          The node to look up
+   * @returns The index of the node within its parent container, or -1 if the
+   *          node was not found or the node specified has no parent.
+   */
+  getIndexOfNode: function PU_getIndexOfNode(aNode) {
+    NS_ASSERT(aNode, "null node");
+
+    var parent = aNode.parent;
+    if (!parent)
+      return -1;
+    var wasOpen = parent.containerOpen;
+    var result, oldViewer;
+    if (!wasOpen) {
+      result = parent.parentResult;
+      oldViewer = result.viewer;
+      result.viewer = null;
+      parent.containerOpen = true;
+    }
+    var cc = parent.childCount;
+    for (var i = 0; i < cc && parent.getChild(i) != aNode; ++i);
+    if (!wasOpen) {
+      parent.containerOpen = false;
+      result.viewer = oldViewer;
+    }
+    return i < cc ? i : -1;
+  },
+
+  /**
+   * String-wraps a result node according to the rules of the specified
+   * content type.
+   * @param   aNode
+   *          The Result node to wrap (serialize)
+   * @param   aType
+   *          The content type to serialize as
+   * @param   [optional] aOverrideURI
+   *          Used instead of the node's URI if provided.
+   *          This is useful for wrapping a container as TYPE_X_MOZ_URL,
+   *          TYPE_HTML or TYPE_UNICODE.
+   * @returns A string serialization of the node
+   */
+  wrapNode: function PU_wrapNode(aNode, aType, aOverrideURI) {
+    var self = this;
+
+    // when wrapping a node, we want all the items, even if the original
+    // query options are excluding them.
+    // this can happen when copying from the left hand pane of the bookmarks
+    // organizer
+    function convertNode(cNode) {
+      try {
+        if (self.nodeIsFolder(cNode) && cNode.queryOptions.excludeItems)
+          return self.getFolderContents(cNode.itemId, false, true).root;
+      }
+      catch (e) {
+      }
+      return cNode;
+    }
+
+    switch (aType) {
+      case this.TYPE_X_MOZ_PLACE:
+      case this.TYPE_X_MOZ_PLACE_SEPARATOR:
+      case this.TYPE_X_MOZ_PLACE_CONTAINER:
+        function gatherDataPlace(bNode) {
+          var nodeId = 0;
+          if (bNode.itemId != -1)
+            nodeId = bNode.itemId;
+          var nodeUri = bNode.uri
+          var nodeTitle = bNode.title;
+          var nodeParentId = 0;
+          if (bNode.parent && self.nodeIsFolder(bNode.parent))
+            nodeParentId = bNode.parent.itemId;
+          var nodeIndex = self.getIndexOfNode(bNode);
+          var nodeKeyword = self.bookmarks.getKeywordForBookmark(bNode.itemId);
+          var nodeAnnos = self.getAnnotationsForItem(bNode.itemId);
+          var nodeType = "";
+          if (self.nodeIsContainer(bNode))
+            nodeType = self.TYPE_X_MOZ_PLACE_CONTAINER;
+          else if (self.nodeIsURI(bNode)) // a bookmark or a history visit
+            nodeType = self.TYPE_X_MOZ_PLACE;
+          else if (self.nodeIsSeparator(bNode))
+            nodeType = self.TYPE_X_MOZ_PLACE_SEPARATOR;
+
+          var node = { id: nodeId,
+                       uri: nodeUri,
+                       title: nodeTitle,
+                       parent: nodeParentId,
+                       index: nodeIndex,
+                       keyword: nodeKeyword,
+                       annos: nodeAnnos,
+                       type: nodeType };
+
+          // Recurse down children if the node is a folder
+          if (self.nodeIsContainer(bNode)) {
+            asContainer(bNode);
+            if (self.nodeIsLivemarkContainer(bNode)) {
+              // just save the livemark info, reinstantiate on other end
+              var feedURI = self.livemarks.getFeedURI(bNode.itemId).spec;
+              var siteURI = self.livemarks.getSiteURI(bNode.itemId).spec;
+              node.uri = { feed: feedURI,
+                           site: siteURI };
+            }
+            else { // bookmark folders + history containers
+              var wasOpen = bNode.containerOpen;
+              if (!wasOpen)
+                bNode.containerOpen = true;
+              var childNodes = [];
+              var cc = bNode.childCount;
+              for (var i = 0; i < cc; ++i) {
+                var childObj = gatherDataPlace(bNode.getChild(i));
+                if (childObj != null)
+                  childNodes.push(childObj);
+              }
+              var parent = node;
+              node = { folder: parent,
+                       children: childNodes,
+                       type: self.TYPE_X_MOZ_PLACE_CONTAINER };
+              bNode.containerOpen = wasOpen;
+            }
+          }
+          return node;
+        }
+        return JSON.toString(gatherDataPlace(convertNode(aNode)));
+
+      case this.TYPE_X_MOZ_URL:
+        function gatherDataUrl(bNode) {
+          if (self.nodeIsLivemarkContainer(bNode)) {
+            var siteURI = self.livemarks.getSiteURI(bNode.itemId).spec;
+            return siteURI + NEWLINE + bNode.title;
+          }
+          if (self.nodeIsURI(bNode))
+            return (aOverrideURI || bNode.uri) + NEWLINE + bNode.title;
+          // ignore containers and separators - items without valid URIs
+          return "";
+        }
+        return gatherDataUrl(convertNode(aNode));
+
+      case this.TYPE_HTML:
+        function gatherDataHtml(bNode) {
+          function htmlEscape(s) {
+            s = s.replace(/&/g, "&amp;");
+            s = s.replace(/>/g, "&gt;");
+            s = s.replace(/</g, "&lt;");
+            s = s.replace(/"/g, "&quot;");
+            s = s.replace(/'/g, "&apos;");
+            return s;
+          }
+          // escape out potential HTML in the title
+          var escapedTitle = htmlEscape(bNode.title);
+          if (self.nodeIsLivemarkContainer(bNode)) {
+            var siteURI = self.livemarks.getSiteURI(bNode.itemId).spec;
+            return "<A HREF=\"" + siteURI + "\">" + escapedTitle + "</A>" + NEWLINE;
+          }
+          if (self.nodeIsContainer(bNode)) {
+            asContainer(bNode);
+            var wasOpen = bNode.containerOpen;
+            if (!wasOpen)
+              bNode.containerOpen = true;
+
+            var childString = "<DL><DT>" + escapedTitle + "</DT>" + NEWLINE;
+            var cc = bNode.childCount;
+            for (var i = 0; i < cc; ++i)
+              childString += "<DD>"
+                             + NEWLINE
+                             + gatherDataHtml(bNode.getChild(i))
+                             + "</DD>"
+                             + NEWLINE;
+            bNode.containerOpen = wasOpen;
+            return childString + "</DL>" + NEWLINE;
+          }
+          if (self.nodeIsURI(bNode))
+            return "<A HREF=\"" + bNode.uri + "\">" + escapedTitle + "</A>" + NEWLINE;
+          if (self.nodeIsSeparator(bNode))
+            return "<HR>" + NEWLINE;
+          return "";
+        }
+        return gatherDataHtml(convertNode(aNode));
+    }
+    // case this.TYPE_UNICODE:
+    function gatherDataText(bNode) {
+      if (self.nodeIsLivemarkContainer(bNode))
+        return self.livemarks.getSiteURI(bNode.itemId).spec;
+      if (self.nodeIsContainer(bNode)) {
+        asContainer(bNode);
+        var wasOpen = bNode.containerOpen;
+        if (!wasOpen)
+          bNode.containerOpen = true;
+
+        var childString = bNode.title + NEWLINE;
+        var cc = bNode.childCount;
+        for (var i = 0; i < cc; ++i) {
+          var child = bNode.getChild(i);
+          var suffix = i < (cc - 1) ? NEWLINE : "";
+          childString += gatherDataText(child) + suffix;
+        }
+        bNode.containerOpen = wasOpen;
+        return childString;
+      }
+      if (self.nodeIsURI(bNode))
+        return (aOverrideURI || bNode.uri);
+      if (self.nodeIsSeparator(bNode))
+        return "--------------------";
+      return "";
+    }
+
+    return gatherDataText(convertNode(aNode));
+  },
+
+  /**
    * Get a transaction for copying a uri item from one container to another
    * as a bookmark.
    * @param   aURI
    *          The URI of the item being copied
    * @param   aContainer
    *          The container being copied into
    * @param   aIndex
    *          The index within the container the item is copied to
    * @returns A nsITransaction object that performs the copy.
    */
   _getURIItemCopyTransaction: function (aData, aContainer, aIndex) {
-    return this.ptm.createItem(PlacesUtils._uri(aData.uri), aContainer, aIndex,
+    return this.ptm.createItem(this._uri(aData.uri), aContainer, aIndex,
                                aData.title, "");
   },
 
   /**
    * Get a transaction for copying a bookmark item from one container to
    * another.
    * @param   aID
    *          The identifier of the bookmark item being copied
@@ -196,24 +686,25 @@ var PlacesUIUtils = {
    * @param   [optional] aExcludeAnnotations
    *          Optional, array of annotations (listed by their names) to exclude
    *          when copying the item.
    * @returns A nsITransaction object that performs the copy.
    */
   _getBookmarkItemCopyTransaction:
   function PU__getBookmarkItemCopyTransaction(aData, aContainer, aIndex,
                                               aExcludeAnnotations) {
-    var itemURL = PlacesUtils._uri(aData.uri);
+    var itemURL = this._uri(aData.uri);
     var itemTitle = aData.title;
-    var keyword = aData.keyword || null;
-    var annos = aData.annos || [];
+    var keyword = aData.keyword;
+    var annos = aData.annos;
     if (aExcludeAnnotations) {
-      annos = annos.filter(function(aValue, aIndex, aArray) {
-        return aExcludeAnnotations.indexOf(aValue.name) == -1;
-      });
+      annos =
+        annos.filter(function(aValue, aIndex, aArray) {
+                       return aExcludeAnnotations.indexOf(aValue.name) == -1;
+                    });
     }
     var childTxns = [];
     if (aData.dateAdded)
       childTxns.push(this.ptm.editItemDateAdded(null, aData.dateAdded));
     if (aData.lastModified)
       childTxns.push(this.ptm.editItemLastModified(null, aData.lastModified));
 
     return this.ptm.createItem(itemURL, aContainer, aIndex, itemTitle, keyword,
@@ -243,87 +734,113 @@ var PlacesUIUtils = {
         var txn = null;
         var node = aChildren[i];
 
         // adjusted to make sure that items are given the correct index -
         // transactions insert differently if index == -1
         if (aIndex > -1)
           index = aIndex + i;
 
-        if (node.type == PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER) {
-          if (node.livemark && node.annos) // node is a livemark
-            txn = self._getLivemarkCopyTransaction(node, aContainer, index);
-          else {
-            var folderItemsTransactions = [];
-            if (node.dateAdded)
-              folderItemsTransactions.push(self.ptm.editItemDateAdded(null, node.dateAdded));
-            if (node.lastModified)
-              folderItemsTransactions.push(self.ptm.editItemLastModified(null, node.lastModified));
-            var annos = node.annos || [];
-            txn = self.ptm.createFolder(node.title, -1, index, annos,
+        if (node.type == self.TYPE_X_MOZ_PLACE_CONTAINER) {
+          if (node.folder) {
+            var title = node.folder.title;
+            var annos = node.folder.annos;
+            var folderItemsTransactions =
+              getChildItemsTransactions(node.children);
+            txn = self.ptm.createFolder(title, -1, index, annos,
                                         folderItemsTransactions);
           }
+          else { // node is a livemark
+            var feedURI = self._uri(node.uri.feed);
+            var siteURI = self._uri(node.uri.site);
+            txn = self.ptm.createLivemark(feedURI, siteURI, node.title,
+                                          aContainer, index, node.annos);
+          }
         }
-        else if (node.type == PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR)
+        else if (node.type == self.TYPE_X_MOZ_PLACE_SEPARATOR)
           txn = self.ptm.createSeparator(-1, index);
-        else if (node.type == PlacesUtils.TYPE_X_MOZ_PLACE)
+        else if (node.type == self.TYPE_X_MOZ_PLACE)
           txn = self._getBookmarkItemCopyTransaction(node, -1, index);
 
         NS_ASSERT(txn, "Unexpected item under a bookmarks folder");
         if (txn)
           childItemsTransactions.push(txn);
       }
       return childItemsTransactions;
     }
 
-    // tag folders use tag transactions
-    if (aContainer == PlacesUtils.bookmarks.tagsFolder) {
-      var txns = [];
-      if (aData.children) {
-        aData.children.forEach(function(aChild) {
-          txns.push(this.ptm.tagURI(PlacesUtils._uri(aChild.uri), [aData.title]));
-        }, this);
-      }
-      return this.ptm.aggregateTransactions("addTags", txns);
-    }
-    else if (aData.livemark && aData.annos) {
-      // Place is a Livemark Container
-      return this._getLivemarkCopyTransaction(aData, aContainer, aIndex);
-    }
-    else {
-      var childItems = getChildItemsTransactions(aData.children);
-      if (aData.dateAdded)
-        childItems.push(this.ptm.editItemDateAdded(null, aData.dateAdded));
-      if (aData.lastModified)
-        childItems.push(this.ptm.editItemLastModified(null, aData.lastModified));
-
-      var annos = aData.annos || [];
-      return this.ptm.createFolder(aData.title, aContainer, aIndex, annos, childItems);
-    }
+    var title = aData.folder.title;
+    var annos = aData.folder.annos;
+    var childItems = getChildItemsTransactions(aData.children);
+    if (aData.folder.dateAdded)
+      childItems.push(this.ptm.editItemDateAdded(null, aData.folder.dateAdded));
+    if (aData.folder.lastModified)
+      childItems.push(this.ptm.editItemLastModified(null, aData.folder.lastModified));
+    return this.ptm.createFolder(title, aContainer, aIndex, annos, childItems);
   },
 
-  _getLivemarkCopyTransaction:
-  function PU__getLivemarkCopyTransaction(aData, aContainer, aIndex) {
-    NS_ASSERT(aData.livemark && aData.annos, "node is not a livemark");
-    // Place is a Livemark Container
-    var feedURI = null;
-    var siteURI = null;
-    aData.annos = aData.annos.filter(function(aAnno) {
-      if (aAnno.name == LMANNO_FEEDURI) {
-        feedURI = this._uri(aAnno.value);
-        return false;
-      }
-      else if (aAnno.name == LMANNO_SITEURI) {
-        siteURI = this._uri(aAnno.value);
-        return false;
-      }
-      return true;
-    }, this);
-    return this.ptm.createLivemark(feedURI, siteURI, aData.title, aContainer,
-                                   aIndex, aData.annos);
+  /**
+   * Unwraps data from the Clipboard or the current Drag Session.
+   * @param   blob
+   *          A blob (string) of data, in some format we potentially know how
+   *          to parse.
+   * @param   type
+   *          The content type of the blob.
+   * @returns An array of objects representing each item contained by the source.
+   */
+  unwrapNodes: function PU_unwrapNodes(blob, type) {
+    // We split on "\n"  because the transferable system converts "\r\n" to "\n"
+    var nodes = [];
+    switch(type) {
+      case this.TYPE_X_MOZ_PLACE:
+      case this.TYPE_X_MOZ_PLACE_SEPARATOR:
+      case this.TYPE_X_MOZ_PLACE_CONTAINER:
+        nodes = JSON.fromString("[" + blob + "]");
+        break;
+      case this.TYPE_X_MOZ_URL:
+        var parts = blob.split("\n");
+        // data in this type has 2 parts per entry, so if there are fewer
+        // than 2 parts left, the blob is malformed and we should stop
+        // but drag and drop of files from the shell has parts.length = 1
+        if (parts.length != 1 && parts.length % 2)
+          break;
+        for (var i = 0; i < parts.length; i=i+2) {
+          var uriString = parts[i];
+          var titleString = "";
+          if (parts.length > i+1)
+            titleString = parts[i+1];
+          else {
+            // for drag and drop of files, try to use the leafName as title
+            try {
+              titleString = this._uri(uriString).QueryInterface(Ci.nsIURL)
+                              .fileName;
+            }
+            catch (e) {}
+          }
+          // note:  this._uri() will throw if uriString is not a valid URI
+          if (this._uri(uriString)) {
+            nodes.push({ uri: uriString,
+                         title: titleString ? titleString : uriString });
+          }
+        }
+        break;
+      case this.TYPE_UNICODE:
+        var parts = blob.split("\n");
+        for (var i = 0; i < parts.length; i++) {
+          var uriString = parts[i];
+          // note: this._uri() will throw if uriString is not a valid URI
+          if (uriString != "" && this._uri(uriString))
+            nodes.push({ uri: uriString, title: uriString });
+        }
+        break;
+      default:
+        LOG("Cannot unwrap data of type " + type);
+        throw Cr.NS_ERROR_INVALID_ARG;
+    }
+    return nodes;
   },
 
   /**
    * Constructs a Transaction for the drop or paste of a blob of data into
    * a container.
    * @param   data
    *          The unwrapped data blob of dropped or pasted data.
    * @param   type
@@ -335,52 +852,91 @@ var PlacesUIUtils = {
    * @param   copy
    *          The drag action was copy, so don't move folders or links.
    * @returns An object implementing nsITransaction that can perform
    *          the move/insert.
    */
   makeTransaction: function PU_makeTransaction(data, type, container,
                                                index, copy) {
     switch (data.type) {
-      case PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER:
+    case this.TYPE_X_MOZ_PLACE_CONTAINER:
+      if (data.folder) {
+        // Place is a folder.
         if (copy)
           return this._getFolderCopyTransaction(data, container, index);
-        else { // Move the item
-          var id = data.folder ? data.folder.id : data.id;
-          return this.ptm.moveItem(id, container, index);
-        }
-        break;
-      case PlacesUtils.TYPE_X_MOZ_PLACE:
-        if (data.id <= 0) // non-bookmark item
-          return this._getURIItemCopyTransaction(data, container, index);
-  
-        if (copy) {
-          // Copying a child of a live-bookmark by itself should result
-          // as a new normal bookmark item (bug 376731)
-          var copyBookmarkAnno =
-            this._getBookmarkItemCopyTransaction(data, container, index,
-                                                 ["livemark/bookmarkFeedURI"]);
-          return copyBookmarkAnno;
-        }
-        else
-          return this.ptm.moveItem(data.id, container, index);
-        break;
-      case PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR:
+      }
+      else if (copy) {
+        // Place is a Livemark Container, should be reinstantiated
+        var feedURI = this._uri(data.uri.feed);
+        var siteURI = this._uri(data.uri.site);
+        return this.ptm.createLivemark(feedURI, siteURI, data.title, container,
+                                       index, data.annos);
+      }
+      break;
+    case this.TYPE_X_MOZ_PLACE:
+      if (data.id <= 0)
+        return this._getURIItemCopyTransaction(data, container, index);
+
+      if (copy) {
+        // Copying a child of a live-bookmark by itself should result
+        // as a new normal bookmark item (bug 376731)
+        var copyBookmarkAnno =
+          this._getBookmarkItemCopyTransaction(data, container, index,
+                                               ["livemark/bookmarkFeedURI"]);
+        return copyBookmarkAnno;
+      }
+      break;
+    case this.TYPE_X_MOZ_PLACE_SEPARATOR:
+      if (copy) {
         // There is no data in a separator, so copying it just amounts to
         // inserting a new separator.
         return this.ptm.createSeparator(container, index);
-        break;
-      default:
-        if (type == PlacesUtils.TYPE_X_MOZ_URL || type == PlacesUtils.TYPE_UNICODE) {
-          var title = (type == PlacesUtils.TYPE_X_MOZ_URL) ? data.title : data.uri;
-          return this.ptm.createItem(PlacesUtils._uri(data.uri), container, index,
-                                     title);
-        }
+      }
+      break;
+    default:
+      if (type == this.TYPE_X_MOZ_URL || type == this.TYPE_UNICODE) {
+        var title = (type == this.TYPE_X_MOZ_URL) ? data.title : data.uri;
+        return this.ptm.createItem(this._uri(data.uri), container, index,
+                                   title);
+      }
+      return null;
     }
-    return null;
+    if (data.id <= 0)
+      return null;
+
+    // Move the item otherwise
+    var id = data.folder ? data.folder.id : data.id;
+    return this.ptm.moveItem(id, container, index);
+  },
+
+  /**
+   * Generates a nsINavHistoryResult for the contents of a folder.
+   * @param   folderId
+   *          The folder to open
+   * @param   [optional] excludeItems
+   *          True to hide all items (individual bookmarks). This is used on
+   *          the left places pane so you just get a folder hierarchy.
+   * @param   [optional] expandQueries
+   *          True to make query items expand as new containers. For managing,
+   *          you want this to be false, for menus and such, you want this to
+   *          be true.
+   * @returns A nsINavHistoryResult containing the contents of the
+   *          folder. The result.root is guaranteed to be open.
+   */
+  getFolderContents:
+  function PU_getFolderContents(aFolderId, aExcludeItems, aExpandQueries) {
+    var query = this.history.getNewQuery();
+    query.setFolders([aFolderId], 1);
+    var options = this.history.getNewQueryOptions();
+    options.excludeItems = aExcludeItems;
+    options.expandQueries = aExpandQueries;
+
+    var result = this.history.executeQuery(query, options);
+    result.root.containerOpen = true;
+    return result;
   },
 
   /**
    * Methods to show the bookmarkProperties dialog in its various modes.
    *
    * The showMinimalAdd* methods open the dialog by its alternative URI. Thus
    * they persist the dialog dimensions separately from the showAdd* methods.
    * Note these variants also do not return the dialog "performed" state since
@@ -746,42 +1302,41 @@ var PlacesUIUtils = {
    * By calling this before we visit a URL, we will use TRANSITION_TYPED
    * as the transition for the visit to that URL (if we don't have a referrer).
    * This is used when visiting pages from the history menu, history sidebar,
    * url bar, url autocomplete results, and history searches from the places
    * organizer.  If we don't call this, we'll treat those visits as
    * TRANSITION_LINK.
    */
   markPageAsTyped: function PU_markPageAsTyped(aURL) {
-    PlacesUtils.history.QueryInterface(Ci.nsIBrowserHistory)
-               .markPageAsTyped(this.createFixedURI(aURL));
+    this.globalHistory.markPageAsTyped(this.createFixedURI(aURL));
   },
 
   /**
    * By calling this before we visit a URL, we will use TRANSITION_BOOKMARK
    * as the transition for the visit to that URL (if we don't have a referrer).
    * This is used when visiting pages from the bookmarks menu, 
    * personal toolbar, and bookmarks from within the places organizer.
    * If we don't call this, we'll treat those visits as TRANSITION_LINK.
    */
   markPageAsFollowedBookmark: function PU_markPageAsFollowedBookmark(aURL) {
-    PlacesUtils.history.markPageAsFollowedBookmark(this.createFixedURI(aURL));
+    this.history.markPageAsFollowedBookmark(this.createFixedURI(aURL));
   },
 
   /**
    * Allows opening of javascript/data URI only if the given node is
    * bookmarked (see bug 224521).
    * @param aURINode
    *        a URI node
    * @return true if it's safe to open the node in the browser, false otherwise.
    *
    */
   checkURLSecurity: function PU_checkURLSecurity(aURINode) {
-    if (!PlacesUtils.nodeIsBookmark(aURINode)) {
-      var uri = PlacesUtils._uri(aURINode.uri);
+    if (!this.nodeIsBookmark(aURINode)) {
+      var uri = this._uri(aURINode.uri);
       if (uri.schemeIs("javascript") || uri.schemeIs("data")) {
         const BRANDING_BUNDLE_URI = "chrome://branding/locale/brand.properties";
         var brandShortName = Cc["@mozilla.org/intl/stringbundle;1"].
                              getService(Ci.nsIStringBundleService).
                              createBundle(BRANDING_BUNDLE_URI).
                              GetStringFromName("brandShortName");
         var promptService = Cc["@mozilla.org/embedcomp/prompt-service;1"].
                             getService(Ci.nsIPromptService);
@@ -790,16 +1345,147 @@ var PlacesUIUtils = {
         promptService.alert(window, brandShortName, errorStr);
         return false;
       }
     }
     return true;
   },
 
   /**
+   * Fetch all annotations for a URI, including all properties of each
+   * annotation which would be required to recreate it.
+   * @param aURI
+   *        The URI for which annotations are to be retrieved.
+   * @return Array of objects, each containing the following properties:
+   *         name, flags, expires, mimeType, type, value
+   */
+  getAnnotationsForURI: function PU_getAnnotationsForURI(aURI) {
+    var annosvc = this.annotations;
+    var annos = [], val = null;
+    var annoNames = annosvc.getPageAnnotationNames(aURI, {});
+    for (var i = 0; i < annoNames.length; i++) {
+      var flags = {}, exp = {}, mimeType = {}, storageType = {};
+      annosvc.getPageAnnotationInfo(aURI, annoNames[i], flags, exp, mimeType, storageType);
+      if (storageType.value == annosvc.TYPE_BINARY) {
+        var data = {}, length = {}, mimeType = {};
+        annosvc.getPageAnnotationBinary(aURI, annoNames[i], data, length, mimeType);
+        val = data.value;
+      }
+      else
+        val = annosvc.getPageAnnotation(aURI, annoNames[i]);
+
+      annos.push({name: annoNames[i],
+                  flags: flags.value,
+                  expires: exp.value,
+                  mimeType: mimeType.value,
+                  type: storageType.value,
+                  value: val});
+    }
+    return annos;
+  },
+
+  /**
+   * Fetch all annotations for an item, including all properties of each
+   * annotation which would be required to recreate it.
+   * @param aItemId
+   *        The identifier of the itme for which annotations are to be
+   *        retrieved.
+   * @return Array of objects, each containing the following properties:
+   *         name, flags, expires, mimeType, type, value
+   */
+  getAnnotationsForItem: function PU_getAnnotationsForItem(aItemId) {
+    var annosvc = this.annotations;
+    var annos = [], val = null;
+    var annoNames = annosvc.getItemAnnotationNames(aItemId, {});
+    for (var i = 0; i < annoNames.length; i++) {
+      var flags = {}, exp = {}, mimeType = {}, storageType = {};
+      annosvc.getItemAnnotationInfo(aItemId, annoNames[i], flags, exp, mimeType, storageType);
+      if (storageType.value == annosvc.TYPE_BINARY) {
+        var data = {}, length = {}, mimeType = {};
+        annosvc.geItemAnnotationBinary(aItemId, annoNames[i], data, length, mimeType);
+        val = data.value;
+      }
+      else
+        val = annosvc.getItemAnnotation(aItemId, annoNames[i]);
+
+      annos.push({name: annoNames[i],
+                  flags: flags.value,
+                  expires: exp.value,
+                  mimeType: mimeType.value,
+                  type: storageType.value,
+                  value: val});
+    }
+    return annos;
+  },
+
+  /**
+   * Annotate a URI with a batch of annotations.
+   * @param aURI
+   *        The URI for which annotations are to be set.
+   * @param aAnnotations
+   *        Array of objects, each containing the following properties:
+   *        name, flags, expires, type, mimeType (only used for binary
+   *        annotations) value.
+   */
+  setAnnotationsForURI: function PU_setAnnotationsForURI(aURI, aAnnos) {
+    var annosvc = this.annotations;
+    aAnnos.forEach(function(anno) {
+      var flags = ("flags" in anno) ? anno.flags : 0;
+      var expires = ("expires" in anno) ?
+        anno.expires : Ci.nsIAnnotationService.EXPIRE_NEVER;
+      if (anno.type == annosvc.TYPE_BINARY) {
+        annosvc.setPageAnnotationBinary(aURI, anno.name, anno.value,
+                                        anno.value.length, anno.mimeType,
+                                        flags, expires);
+      }
+      else
+        annosvc.setPageAnnotation(aURI, anno.name, anno.value, flags, expires);
+    });
+  },
+
+  /**
+   * Annotate an item with a batch of annotations.
+   * @param aItemId
+   *        The identifier of the item for which annotations are to be set
+   * @param aAnnotations
+   *        Array of objects, each containing the following properties:
+   *        name, flags, expires, type, mimeType (only used for binary
+   *        annotations) value.
+   */
+  setAnnotationsForItem: function PU_setAnnotationsForItem(aItemId, aAnnos) {
+    var annosvc = this.annotations;
+    aAnnos.forEach(function(anno) {
+      var flags = ("flags" in anno) ? anno.flags : 0;
+      var expires = ("expires" in anno) ?
+        anno.expires : Ci.nsIAnnotationService.EXPIRE_NEVER;
+      if (anno.type == annosvc.TYPE_BINARY) {
+        annosvc.setItemAnnotationBinary(aItemId, anno.name, anno.value,
+                                        anno.value.length, anno.mimeType,
+                                        flags, expires);
+      }
+      else {
+        annosvc.setItemAnnotation(aItemId, anno.name, anno.value, flags,
+                                  expires);
+      }
+    });
+  },
+
+  /**
+   * Helper for getting a serialized Places query for a particular folder.
+   * @param aFolderId The folder id to get a query for.
+   * @return string serialized place URI
+   */
+  getQueryStringForFolder: function PU_getQueryStringForFolder(aFolderId) {
+    var options = this.history.getNewQueryOptions();
+    var query = this.history.getNewQuery();
+    query.setFolders([aFolderId], 1);
+    return this.history.queriesToQueryString([query], 1, options);
+  },
+
+  /**
    * Get the description associated with a document, as specified in a <META>
    * element.
    * @param   doc
    *          A DOM Document to get a description for
    * @returns A description string if a META element was discovered with a
    *          "description" or "httpequiv" attribute, empty string otherwise.
    */
   getDescriptionFromDocument: function PU_getDescriptionFromDocument(doc) {
@@ -808,29 +1494,210 @@ var PlacesUIUtils = {
       if (metaElements[i].name.toLowerCase() == "description" ||
           metaElements[i].httpEquiv.toLowerCase() == "description") {
         return metaElements[i].content;
       }
     }
     return "";
   },
 
+  // identifier getters for special folders
+  get placesRootId() {
+    delete this.placesRootId;
+    return this.placesRootId = this.bookmarks.placesRoot;
+  },
+
+  get bookmarksMenuFolderId() {
+    delete this.bookmarksMenuFolderId;
+    return this.bookmarksMenuFolderId = this.bookmarks.bookmarksMenuFolder;
+  },
+
+  get toolbarFolderId() {
+    delete this.toolbarFolderId;
+    return this.toolbarFolderId = this.bookmarks.toolbarFolder;
+  },
+
+  get tagsFolderId() {
+    delete this.tagsFolderId;
+    return this.tagsFolderId = this.bookmarks.tagsFolder;
+  },
+
+  get unfiledBookmarksFolderId() {
+    delete this.unfiledBookmarksFolderId;
+    return this.unfiledBookmarksFolderId = this.bookmarks.unfiledBookmarksFolder;
+  },
+
+  /**
+   * Set the POST data associated with a bookmark, if any.
+   * Used by POST keywords.
+   *   @param aBookmarkId
+   *   @returns string of POST data
+   */
+  setPostDataForBookmark: function PU_setPostDataForBookmark(aBookmarkId, aPostData) {
+    const annos = this.annotations;
+    if (aPostData)
+      annos.setItemAnnotation(aBookmarkId, POST_DATA_ANNO, aPostData, 
+                              0, Ci.nsIAnnotationService.EXPIRE_NEVER);
+    else if (annos.itemHasAnnotation(aBookmarkId, POST_DATA_ANNO))
+      annos.removeItemAnnotation(aBookmarkId, POST_DATA_ANNO);
+  },
+
+  /**
+   * Get the POST data associated with a bookmark, if any.
+   * @param aBookmarkId
+   * @returns string of POST data if set for aBookmarkId. null otherwise.
+   */
+  getPostDataForBookmark: function PU_getPostDataForBookmark(aBookmarkId) {
+    const annos = this.annotations;
+    if (annos.itemHasAnnotation(aBookmarkId, POST_DATA_ANNO))
+      return annos.getItemAnnotation(aBookmarkId, POST_DATA_ANNO);
+
+    return null;
+  },
+
+  /**
+   * Get the URI (and any associated POST data) for a given keyword.
+   * @param aKeyword string keyword
+   * @returns an array containing a string URL and a string of POST data
+   */
+  getURLAndPostDataForKeyword: function PU_getURLAndPostDataForKeyword(aKeyword) {
+    var url = null, postdata = null;
+    try {
+      var uri = this.bookmarks.getURIForKeyword(aKeyword);
+      if (uri) {
+        url = uri.spec;
+        var bookmarks = this.bookmarks.getBookmarkIdsForURI(uri, {});
+        for (let i = 0; i < bookmarks.length; i++) {
+          var bookmark = bookmarks[i];
+          var kw = this.bookmarks.getKeywordForBookmark(bookmark);
+          if (kw == aKeyword) {
+            postdata = this.getPostDataForBookmark(bookmark);
+            break;
+          }
+        }
+      }
+    } catch(ex) {}
+    return [url, postdata];
+  },
+
   /**
    * Retrieve the description of an item
    * @param aItemId
    *        item identifier
    * @returns the description of the given item, or an empty string if it is
    * not set.
    */
   getItemDescription: function PU_getItemDescription(aItemId) {
-    if (PlacesUtils.annotations.itemHasAnnotation(aItemId, DESCRIPTION_ANNO))
-      return PlacesUtils.annotations.getItemAnnotation(aItemId, DESCRIPTION_ANNO);
+    if (this.annotations.itemHasAnnotation(aItemId, DESCRIPTION_ANNO))
+      return this.annotations.getItemAnnotation(aItemId, DESCRIPTION_ANNO);
     return "";
   },
 
+
+  /**
+   * Get all bookmarks for a URL, excluding items under tag or livemark
+   * containers.
+   */
+  getBookmarksForURI:
+  function PU_getBookmarksForURI(aURI) {
+    var bmkIds = this.bookmarks.getBookmarkIdsForURI(aURI, {});
+
+    // filter the ids list
+    return bmkIds.filter(function(aID) {
+      var parent = this.bookmarks.getFolderIdForItem(aID);
+      // Livemark child
+      if (this.annotations.itemHasAnnotation(parent, LMANNO_FEEDURI))
+        return false;
+      var grandparent = this.bookmarks.getFolderIdForItem(parent);
+      // item under a tag container
+      if (grandparent == this.tagsFolderId)
+        return false;
+      return true;
+    }, this);
+  },
+
+  /**
+   * Get the most recently added/modified bookmark for a URL, excluding items
+   * under tag or livemark containers. -1 is returned if no item is found.
+   */
+  getMostRecentBookmarkForURI:
+  function PU_getMostRecentBookmarkForURI(aURI) {
+    var bmkIds = this.bookmarks.getBookmarkIdsForURI(aURI, {});
+    for (var i = 0; i < bmkIds.length; i++) {
+      // Find the first folder which isn't a tag container
+      var bk = bmkIds[i];
+      var parent = this.bookmarks.getFolderIdForItem(bk);
+      if (parent == this.unfiledBookmarksFolderId)
+        return bk;
+
+      var grandparent = this.bookmarks.getFolderIdForItem(parent);
+      if (grandparent != this.tagsFolderId &&
+          !this.annotations.itemHasAnnotation(parent, LMANNO_FEEDURI))
+        return bk;
+    }
+    return -1;
+  },
+
+  getMostRecentFolderForFeedURI:
+  function PU_getMostRecentFolderForFeedURI(aURI) {
+    var feedSpec = aURI.spec
+    var annosvc = this.annotations;
+    var livemarks = annosvc.getItemsWithAnnotation(LMANNO_FEEDURI, {});
+    for (var i = 0; i < livemarks.length; i++) {
+      if (annosvc.getItemAnnotation(livemarks[i], LMANNO_FEEDURI) == feedSpec)
+        return livemarks[i];
+    }
+    return -1;
+  },
+
+  getURLsForContainerNode: function PU_getURLsForContainerNode(aNode) {
+    let urls = [];
+    if (this.nodeIsFolder(aNode) && asQuery(aNode).queryOptions.excludeItems) {
+      // grab manually
+      let contents = this.getFolderContents(aNode.itemId, false, false).root;
+      for (let i = 0; i < contents.childCount; ++i) {
+        let child = contents.getChild(i);
+        if (this.nodeIsURI(child))
+          urls.push({uri: child.uri, isBookmark: this.nodeIsBookmark(child)});
+      }
+    }
+    else {
+      let result, oldViewer, wasOpen;
+      try {
+        let wasOpen = aNode.containerOpen;
+        result = aNode.parentResult;
+        oldViewer = result.viewer;
+        if (!wasOpen) {
+          result.viewer = null;
+          aNode.containerOpen = true;
+        }
+        for (let i = 0; i < aNode.childCount; ++i) {
+          // Include visible url nodes only
+          let child = aNode.getChild(i);
+          if (this.nodeIsURI(child)) {
+            // If the node contents is visible, add the uri
+            if ((wasOpen && oldViewer && child.viewIndex != -1) ||
+                urls.indexOf(child.uri) == -1) {
+              urls.push({ uri: child.uri,
+                          isBookmark: this.nodeIsBookmark(child) });
+            }
+          }
+        }
+        if (!wasOpen)
+          aNode.containerOpen = false;
+      }
+      finally {
+        if (!wasOpen)
+          result.viewer = oldViewer;
+      }
+    }
+
+    return urls;
+  },
+
   /**
    * Gives the user a chance to cancel loading lots of tabs at once
    */
   _confirmOpenInTabs: function PU__confirmOpenInTabs(numTabsToOpen) {
     var pref = Cc["@mozilla.org/preferences-service;1"].
                getService(Ci.nsIPrefBranch);
 
     const kWarnOnOpenPref = "browser.tabs.warnOnOpen";
@@ -895,29 +1762,29 @@ var PlacesUIUtils = {
 
     var loadInBackground = where == "tabshifted" ? true : false;
     var replaceCurrentTab = where == "tab" ? false : true;
     browserWindow.getBrowser().loadTabs(urls, loadInBackground,
                                         replaceCurrentTab);
   },
 
   openContainerNodeInTabs: function PU_openContainerInTabs(aNode, aEvent) {
-    var urlsToOpen = PlacesUtils.getURLsForContainerNode(aNode);
+    var urlsToOpen = this.getURLsForContainerNode(aNode);
     if (!this._confirmOpenInTabs(urlsToOpen.length))
       return;
 
     this._openTabset(urlsToOpen, aEvent);
   },
 
   openURINodesInTabs: function PU_openURINodesInTabs(aNodes, aEvent) {
     var urlsToOpen = [];
     for (var i=0; i < aNodes.length; i++) {
       // skip over separators and folders
-      if (PlacesUtils.nodeIsURI(aNodes[i]))
-        urlsToOpen.push({uri: aNodes[i].uri, isBookmark: PlacesUtils.nodeIsBookmark(aNodes[i])});
+      if (this.nodeIsURI(aNodes[i]))
+        urlsToOpen.push({uri: aNodes[i].uri, isBookmark: this.nodeIsBookmark(aNodes[i])});
     }
     this._openTabset(urlsToOpen, aEvent);
   },
 
   /**
    * Loads the node's URL in the appropriate tab or window or as a web
    * panel given the user's preference specified by modifier keys tracked by a
    * DOM mouse/key event.
@@ -933,23 +1800,23 @@ var PlacesUIUtils = {
   
   /**
    * Loads the node's URL in the appropriate tab or window or as a
    * web panel.
    * see also openUILinkIn
    */
   openNodeIn: function PU_openNodeIn(aNode, aWhere) {
     if (aNode && PlacesUtils.nodeIsURI(aNode) &&
-        this.checkURLSecurity(aNode)) {
+        PlacesUtils.checkURLSecurity(aNode)) {
       var isBookmark = PlacesUtils.nodeIsBookmark(aNode);
 
       if (isBookmark)
-        this.markPageAsFollowedBookmark(aNode.uri);
+        PlacesUtils.markPageAsFollowedBookmark(aNode.uri);
       else
-        this.markPageAsTyped(aNode.uri);
+        PlacesUtils.markPageAsTyped(aNode.uri);
 
       // Check whether the node is a bookmark which should be opened as
       // a web panel
       if (aWhere == "current" && isBookmark) {
         if (PlacesUtils.annotations
                        .itemHasAnnotation(aNode.itemId, LOAD_IN_SIDEBAR_ANNO)) {
           var w = getTopWin();
           if (w) {
@@ -971,32 +1838,32 @@ var PlacesUIUtils = {
     if (type == Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR)
       element = document.createElement("menuseparator");
     else {
       var iconURI = aNode.icon;
       var iconURISpec = "";
       if (iconURI)
         iconURISpec = iconURI.spec;
 
-      if (PlacesUtils.uriTypes.indexOf(type) != -1) {
+      if (this.uriTypes.indexOf(type) != -1) {
         element = document.createElement("menuitem");
         element.setAttribute("statustext", aNode.uri);
         element.className = "menuitem-iconic bookmark-item";
       }
-      else if (PlacesUtils.containerTypes.indexOf(type) != -1) {
+      else if (this.containerTypes.indexOf(type) != -1) {
         element = document.createElement("menu");
         element.setAttribute("container", "true");
 
         if (aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY)
           element.setAttribute("query", "true");
         else if (aNode.itemId != -1) {
-          if (PlacesUtils.nodeIsLivemarkContainer(aNode))
+          if (this.nodeIsLivemarkContainer(aNode))
             element.setAttribute("livemark", "true");
-          else if (PlacesUtils.bookmarks.
-                               getFolderIdForItem(aNode.itemId) == PlacesUtils.tagsFolderId)
+          else if (this.bookmarks
+                     .getFolderIdForItem(aNode.itemId) == this.tagsFolderId)
             element.setAttribute("tagContainer", "true");
         }
 
         var popup = document.createElement("menupopup");
         popup.setAttribute("placespopup", "true");
         popup._resultNode = asContainer(aNode);
 #ifndef XP_MACOSX
         // no context menu on mac
@@ -1025,112 +1892,110 @@ var PlacesUIUtils = {
     this.leftPaneFolderId;
     return this.leftPaneQueries;
   },
 
   // get the folder id for the organizer left-pane folder
   get leftPaneFolderId() {
     var leftPaneRoot = -1;
     var allBookmarksId;
-    var items = PlacesUtils.annotations.getItemsWithAnnotation(ORGANIZER_FOLDER_ANNO, {});
+    var items = this.annotations.getItemsWithAnnotation(ORGANIZER_FOLDER_ANNO, {});
     if (items.length != 0 && items[0] != -1)
       leftPaneRoot = items[0];
     if (leftPaneRoot != -1) {
       // Build the leftPaneQueries Map
       delete this.leftPaneQueries;
       this.leftPaneQueries = {};
-      var items = PlacesUtils.annotations.
-                              getItemsWithAnnotation(ORGANIZER_QUERY_ANNO, { });
+      var items = this.annotations.getItemsWithAnnotation(ORGANIZER_QUERY_ANNO, { });
       for (var i=0; i < items.length; i++) {
-        var queryName = PlacesUtils.annotations.
-                                    getItemAnnotation(items[i], ORGANIZER_QUERY_ANNO);
+        var queryName = this.annotations
+                            .getItemAnnotation(items[i], ORGANIZER_QUERY_ANNO);
         this.leftPaneQueries[queryName] = items[i];
       }
       delete this.leftPaneFolderId;
       return this.leftPaneFolderId = leftPaneRoot;
     }
 
     var self = this;
-    const EXPIRE_NEVER = PlacesUtils.annotations.EXPIRE_NEVER;
+    const EXPIRE_NEVER = this.annotations.EXPIRE_NEVER;
     var callback = {
       runBatched: function(aUserData) {
         delete self.leftPaneQueries;
         self.leftPaneQueries = { };
 
         // Left Pane Root Folder
-        leftPaneRoot =
-          PlacesUtils.bookmarks.createFolder(PlacesUtils.placesRootId, "", -1);
+        leftPaneRoot = self.bookmarks.createFolder(self.placesRootId, "", -1);
 
         // History Query
-        let uri = PlacesUtils._uri("place:sort=4&");
+        let uri = self._uri("place:sort=4&");
         let title = self.getString("OrganizerQueryHistory");
-        let itemId = PlacesUtils.bookmarks.insertBookmark(leftPaneRoot, uri, -1, title);
-        PlacesUtils.annotations.setItemAnnotation(itemId, ORGANIZER_QUERY_ANNO,
-                                                  "History", 0, EXPIRE_NEVER);
+        let itemId = self.bookmarks.insertBookmark(leftPaneRoot, uri, -1, title);
+        self.annotations.setItemAnnotation(itemId, ORGANIZER_QUERY_ANNO,
+                                           "History", 0, EXPIRE_NEVER);
         self.leftPaneQueries["History"] = itemId;
 
         // XXX: Downloads
 
         // Tags Query
-        uri = PlacesUtils._uri("place:folder=" + PlacesUtils.tagsFolderId);
-        itemId = PlacesUtils.bookmarks.insertBookmark(leftPaneRoot, uri, -1, null);
-        PlacesUtils.annotations.setItemAnnotation(itemId, ORGANIZER_QUERY_ANNO,
-                                                  "Tags", 0, EXPIRE_NEVER);
+        uri = self._uri("place:folder=" + self.tagsFolderId);
+        itemId = self.bookmarks.insertBookmark(leftPaneRoot, uri, -1, null);
+        self.annotations.setItemAnnotation(itemId, ORGANIZER_QUERY_ANNO,
+                                           "Tags", 0, EXPIRE_NEVER);
         self.leftPaneQueries["Tags"] = itemId;
 
         // All Bookmarks Folder
         title = self.getString("OrganizerQueryAllBookmarks");
-        itemId = PlacesUtils.bookmarks.createFolder(leftPaneRoot, title, -1);
+        itemId = self.bookmarks.createFolder(leftPaneRoot, title, -1);
         allBookmarksId = itemId;
-        PlacesUtils.annotations.setItemAnnotation(itemId, ORGANIZER_QUERY_ANNO,
-                                                  "AllBookmarks", 0, EXPIRE_NEVER);
+        self.annotations.setItemAnnotation(itemId, ORGANIZER_QUERY_ANNO,
+                                           "AllBookmarks", 0, EXPIRE_NEVER);
         self.leftPaneQueries["AllBookmarks"] = itemId;
 
         // All Bookmarks->Bookmarks Toolbar Query
-        uri = PlacesUtils._uri("place:folder=" + PlacesUtils.toolbarFolderId);
-        itemId = PlacesUtils.bookmarks.insertBookmark(allBookmarksId, uri, -1, null);
-        PlacesUtils.annotations.setItemAnnotation(itemId, ORGANIZER_QUERY_ANNO,
-                                                  "BookmarksToolbar", 0, EXPIRE_NEVER);
+        uri = self._uri("place:folder=" + self.toolbarFolderId);
+        itemId = self.bookmarks.insertBookmark(allBookmarksId, uri, -1, null);
+        self.annotations.setItemAnnotation(itemId, ORGANIZER_QUERY_ANNO,
+                                           "BookmarksToolbar", 0, EXPIRE_NEVER);
         self.leftPaneQueries["BookmarksToolbar"] = itemId;
 
         // All Bookmarks->Bookmarks Menu Query
-        uri = PlacesUtils._uri("place:folder=" + PlacesUtils.bookmarksMenuFolderId);
-        itemId = PlacesUtils.bookmarks.insertBookmark(allBookmarksId, uri, -1, null);
-        PlacesUtils.annotations.setItemAnnotation(itemId, ORGANIZER_QUERY_ANNO,
-                                                  "BookmarksMenu", 0, EXPIRE_NEVER);
+        uri = self._uri("place:folder=" + self.bookmarksMenuFolderId);
+        itemId = self.bookmarks.insertBookmark(allBookmarksId, uri, -1, null);
+        self.annotations.setItemAnnotation(itemId, ORGANIZER_QUERY_ANNO,
+                                           "BookmarksMenu", 0, EXPIRE_NEVER);
         self.leftPaneQueries["BookmarksMenu"] = itemId;
 
         // All Bookmarks->Unfiled bookmarks
-        uri = PlacesUtils._uri("place:folder=" + PlacesUtils.unfiledBookmarksFolderId);
-        itemId = PlacesUtils.bookmarks.insertBookmark(allBookmarksId, uri, -1, null);
-        PlacesUtils.annotations.setItemAnnotation(itemId, ORGANIZER_QUERY_ANNO,
-                                                  "UnfiledBookmarks", 0,
-                                                  EXPIRE_NEVER);
+        uri = self._uri("place:folder=" + self.unfiledBookmarksFolderId);
+        itemId = self.bookmarks.insertBookmark(allBookmarksId, uri, -1, null);
+        self.annotations.setItemAnnotation(itemId, ORGANIZER_QUERY_ANNO,
+                                           "UnfiledBookmarks", 0,
+                                           EXPIRE_NEVER);
         self.leftPaneQueries["UnfiledBookmarks"] = itemId;
 
         // disallow manipulating this folder within the organizer UI
-        PlacesUtils.bookmarks.setFolderReadonly(leftPaneRoot, true);
+        self.bookmarks.setFolderReadonly(leftPaneRoot, true);
       }
     };
-    PlacesUtils.bookmarks.runInBatchMode(callback, null);
-    PlacesUtils.annotations.setItemAnnotation(leftPaneRoot, ORGANIZER_FOLDER_ANNO,
-                                              true, 0, EXPIRE_NEVER);
+    this.bookmarks.runInBatchMode(callback, null);
+    this.annotations.setItemAnnotation(leftPaneRoot, ORGANIZER_FOLDER_ANNO,
+                                       true, 0, EXPIRE_NEVER);
     delete this.leftPaneFolderId;
     return this.leftPaneFolderId = leftPaneRoot;
   },
 
   get allBookmarksFolderId() {
     // ensure the left-pane root is initialized;
     this.leftPaneFolderId;
     delete this.allBookmarksFolderId;
     return this.allBookmarksFolderId = this.leftPaneQueries["AllBookmarks"];
   }
 };
 
-PlacesUIUtils.placesFlavors = [PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER,
-                               PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR,
-                               PlacesUtils.TYPE_X_MOZ_PLACE];
+PlacesUtils.placesFlavors = [PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER,
+                             PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR,
+                             PlacesUtils.TYPE_X_MOZ_PLACE];
 
-PlacesUIUtils.GENERIC_VIEW_DROP_TYPES = [PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER,
-                                         PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR,
-                                         PlacesUtils.TYPE_X_MOZ_PLACE,
-                                         PlacesUtils.TYPE_X_MOZ_URL,
-                                         PlacesUtils.TYPE_UNICODE];
+PlacesUtils.GENERIC_VIEW_DROP_TYPES = [PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER,
+                                       PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR,
+                                       PlacesUtils.TYPE_X_MOZ_PLACE,
+                                       PlacesUtils.TYPE_X_MOZ_URL,
+                                       PlacesUtils.TYPE_UNICODE];
--- a/browser/components/places/src/Makefile.in
+++ b/browser/components/places/src/Makefile.in
@@ -62,13 +62,11 @@ REQUIRES	= \
 		  places \
 		  microsummaries \
 		  $(NULL)
 
 CPPSRCS = nsPlacesImportExportService.cpp
 
 EXTRA_COMPONENTS = nsPlacesTransactionsService.js
 
-EXTRA_PP_COMPONENTS = nsPlacesTransactionsService.js
-
 include $(topsrcdir)/config/rules.mk
 
 XPIDL_FLAGS += -I$(topsrcdir)/browser/components
--- a/browser/components/places/src/nsPlacesImportExportService.cpp
+++ b/browser/components/places/src/nsPlacesImportExportService.cpp
@@ -376,20 +376,20 @@ protected:
   // If set, we will move root items to from their existing position
   // in the hierarchy, to where we find them in the bookmarks file
   // being imported. This should be set when we are loading 
   // the default places html file, and should be unset when doing
   // normal imports so that root folders will not get moved when
   // importing bookmarks.html files.
   PRBool mAllowRootChanges;
 
-  // If set, this is an import of initial bookmarks.html content,
+  // if set, this is an import of initial bookmarks.html content,
   // so we don't want to kick off HTTP traffic
   // and we want the imported personal toolbar folder
-  // to be set as the personal toolbar folder. (If not set
+  // to be set as the personal toolbar folder.  (if not set
   // we will treat it as a normal folder.)
   PRBool mIsImportDefaults;
 
   // If a folder was specified to import into, then ignore flags to put
   // bookmarks in the bookmarks menu or toolbar and keep them inside
   // the folder.
   PRBool mFolderSpecified;
 
@@ -2435,64 +2435,86 @@ nsPlacesImportExportService::ExportHTMLT
   NS_ENSURE_SUCCESS(rv, rv);
   rv = safeStream->Finish();
 #ifdef DEBUG_EXPORT
   printf("\nTotal time in seconds: %lld\n", (PR_Now() - startTime)/1000000);
 #endif
   return rv;
 }
 
+#define BROWSER_BOOKMARKS_OVERWRITE_PREF    "browser.bookmarks.overwrite"
 #define BROWSER_BOOKMARKS_MAX_BACKUPS_PREF  "browser.bookmarks.max_backups"
+#define POSTPLACES_BOOKMARKS_FILE           "bookmarks.postplaces.html"
 
 NS_IMETHODIMP
 nsPlacesImportExportService::BackupBookmarksFile()
 {
   nsresult rv = EnsureServiceState();
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // get bookmarks file
   nsCOMPtr<nsIFile> bookmarksFileDir;
   rv = NS_GetSpecialDirectory(NS_APP_BOOKMARKS_50_FILE,
                               getter_AddRefs(bookmarksFileDir));
 
+  PRBool overwriteBookmarks;
+  rv = prefs->GetBoolPref(BROWSER_BOOKMARKS_OVERWRITE_PREF, &overwriteBookmarks);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  if (!overwriteBookmarks) {
+    rv = bookmarksFileDir->SetLeafName(NS_LITERAL_STRING(POSTPLACES_BOOKMARKS_FILE));
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
   NS_ENSURE_SUCCESS(rv, rv);
   nsCOMPtr<nsILocalFile> bookmarksFile(do_QueryInterface(bookmarksFileDir));
 
   // create if it doesn't exist
   PRBool exists;
   rv = bookmarksFile->Exists(&exists);
   if (NS_FAILED(rv)) {
     rv = bookmarksFile->Create(nsIFile::NORMAL_FILE_TYPE, 0600);
     NS_ASSERTION(rv, "Unable to create bookmarks.html!");
     return rv;
   }
 
   // export bookmarks.html
   rv = ExportHTMLToFile(bookmarksFile);
   NS_ENSURE_SUCCESS(rv, rv);
 
+  // archive if needed
+  PRInt32 numberOfBackups;
+  rv = prefs->GetIntPref(BROWSER_BOOKMARKS_MAX_BACKUPS_PREF, &numberOfBackups);
+  if (NS_FAILED(rv))
+    numberOfBackups = 5;
+
+  if (numberOfBackups > 0) {
+    rv = ArchiveBookmarksFile(numberOfBackups, PR_FALSE);
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
   return NS_OK;
 }
 
 /**
  *  ArchiveBookmarksFile()
  *
  *  Creates a dated backup once a day in <profile>/bookmarkbackups
  *
  *  PRInt32 numberOfBackups - the maximum number of backups to keep
  *
  *  PRBool forceArchive - forces creating an archive even if one was 
  *                        already created that day (overwrites)
  */
 nsresult
 nsPlacesImportExportService::ArchiveBookmarksFile(PRInt32 numberOfBackups,
-                                                  PRBool forceArchive)
+                                         PRBool forceArchive)
 {
   nsCOMPtr<nsIFile> bookmarksBackupDir;
   nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
                                        getter_AddRefs(bookmarksBackupDir));
   NS_ENSURE_SUCCESS(rv, rv);
   
   nsDependentCString dirName("bookmarkbackups");
   rv = bookmarksBackupDir->AppendNative(dirName);
@@ -2503,27 +2525,29 @@ nsPlacesImportExportService::ArchiveBook
   if (NS_FAILED(rv) || !exists) {
     rv = bookmarksBackupDir->Create(nsIFile::DIRECTORY_TYPE, 0700);
     
     // if there's no backup folder, there's no backup, fail
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   // construct the new leafname
-  PRTime now64 = PR_Now();
+  PRTime          now64 = PR_Now();
   PRExplodedTime  nowInfo;
   PR_ExplodeTime(now64, PR_LocalTimeParameters, &nowInfo);
   PR_NormalizeTime(&nowInfo, PR_LocalTimeParameters);
 
   char timeString[128];
 
   // Use YYYY-MM-DD (ISO 8601) as it doesn't contain illegal characters
   // and makes the alphabetical order of multiple backup files more useful.
   PR_FormatTime(timeString, 128, "bookmarks-%Y-%m-%d.html", &nowInfo);
 
+  //nsCAutoString backupFilenameCString(timeString);
+  //nsAutoString backupFilenameString = NS_ConvertUTF8toUTF16(backupFilenameCString);
   nsAutoString backupFilenameString = NS_ConvertUTF8toUTF16((timeString));
 
   nsCOMPtr<nsIFile> backupFile;
   if (forceArchive) {
     // if we have a backup from today, nuke it
     nsCOMPtr<nsIFile> currentBackup;
     rv = bookmarksBackupDir->Clone(getter_AddRefs(currentBackup));
     NS_ENSURE_SUCCESS(rv, rv);
@@ -2580,14 +2604,26 @@ nsPlacesImportExportService::ArchiveBook
       return NS_OK;
   }
 
   nsCOMPtr<nsIFile> bookmarksFile;
   rv = NS_GetSpecialDirectory(NS_APP_BOOKMARKS_50_FILE,
                               getter_AddRefs(bookmarksFile));
   NS_ENSURE_SUCCESS(rv, rv);
 
+  nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  PRBool overwriteBookmarks;
+  rv = prefs->GetBoolPref(BROWSER_BOOKMARKS_OVERWRITE_PREF, &overwriteBookmarks);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  if (!overwriteBookmarks) {
+    rv = bookmarksFile->SetLeafName(NS_LITERAL_STRING(POSTPLACES_BOOKMARKS_FILE));
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+  
   rv = bookmarksFile->CopyTo(bookmarksBackupDir, backupFilenameString);
   // at least dump something out in case this fails in a debug build
   NS_ENSURE_SUCCESS(rv, rv);
 
   return rv;
 }
--- a/browser/components/places/src/nsPlacesTransactionsService.js
+++ b/browser/components/places/src/nsPlacesTransactionsService.js
@@ -32,35 +32,35 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-let Ci = Components.interfaces;
-let Cc = Components.classes;
-let Cr = Components.results;
-
 const loadInSidebarAnno = "bookmarkProperties/loadInSidebar";
 const descriptionAnno = "bookmarkProperties/description";
 const CLASS_ID = Components.ID("c0844a84-5a12-4808-80a8-809cb002bb4f");
 const CONTRACT_ID = "@mozilla.org/browser/placesTransactionsService;1";
 
+var loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"].
+             getService(Components.interfaces.mozIJSSubScriptLoader);
+loader.loadSubScript("chrome://global/content/debug.js");
+loader.loadSubScript("chrome://browser/content/places/utils.js");
+
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 // The minimum amount of transactions we should tell our observers to begin
 // batching (rather than letting them do incremental drawing).
 const MIN_TRANSACTIONS_FOR_BATCH = 5;  
 
 function placesTransactionsService() {
   this.mTransactionManager = Cc["@mozilla.org/transactionmanager;1"].
                              createInstance(Ci.nsITransactionManager);
-  Components.utils.import("resource://gre/modules/utils.js");
 }
 
 placesTransactionsService.prototype = {
   classDescription: "Places Transaction Manager",
   classID: CLASS_ID,
   contractID: CONTRACT_ID,
 
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIPlacesTransactionsService,
@@ -437,17 +437,16 @@ placesCreateLivemarkTransactions.prototy
   },
 
   undoTransaction: function PCLT_undoTransaction() {
     PlacesUtils.bookmarks.removeFolder(this._id);
   }
 };
 
 function placesMoveItemTransactions(aItemId, aNewContainer, aNewIndex) {
-  Components.utils.import("resource://gre/modules/debug.js");
   NS_ASSERT(aNewIndex >= -1, "invalid insertion index");
   this._id = aItemId;
   this._oldContainer = PlacesUtils.bookmarks.getFolderIdForItem(this._id);
   this._oldIndex = PlacesUtils.bookmarks.getItemIndex(this._id);
   NS_ASSERT(this._oldContainer > 0 && this._oldIndex >= 0, "invalid item");
   this._newContainer = aNewContainer;
   this._newIndex = aNewIndex;
   this.redoTransaction = this.doTransaction;
--- a/browser/components/places/tests/unit/head_bookmarks.js
+++ b/browser/components/places/tests/unit/head_bookmarks.js
@@ -32,18 +32,16 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-version(170);
-
 const NS_APP_USER_PROFILE_50_DIR = "ProfD";
 var Ci = Components.interfaces;
 var Cc = Components.classes;
 var Cr = Components.results;
 
 function LOG(aMsg) {
   aMsg = ("*** PLACES TESTS: " + aMsg);
   Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService).
--- a/browser/components/places/tests/unit/test_384370.js
+++ b/browser/components/places/tests/unit/test_384370.js
@@ -31,291 +31,12 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-const LOAD_IN_SIDEBAR_ANNO = "bookmarkProperties/loadInSidebar";
-const DESCRIPTION_ANNO = "bookmarkProperties/description";
-const POST_DATA_ANNO = "bookmarkProperties/POSTData";
-const LAST_CHARSET_ANNO = "URIProperties/characterSet";
-
-Components.utils.import("resource://gre/modules/utils.js");
-do_check_eq(typeof PlacesUtils, "object");
-
-// main
 function run_test() {
-  /*
-    HTML+FEATURES SUMMARY:
-    - import legacy bookmarks
-    - export as json, import, test (tests integrity of html > json)
-    - export as html, import, test (tests integrity of json > html)
-
-    BACKUP/RESTORE SUMMARY:
-    - create a bookmark in each root
-    - tag multiple URIs with multiple tags
-    - export as json, import, test
-  */
-
-  // get places import/export service
-  var importer = Cc["@mozilla.org/browser/places/import-export-service;1"].getService(Ci.nsIPlacesImportExportService);
-
-  // avoid creating the places smart folder during tests
-  Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch).
-  setBoolPref("browser.places.createdSmartBookmarks", true);
-
-  // file pointer to legacy bookmarks file
-  //var bookmarksFileOld = do_get_file("browser/components/places/tests/unit/bookmarks.large.html");
-  var bookmarksFileOld = do_get_file("browser/components/places/tests/unit/bookmarks.preplaces.html");
-  // file pointer to a new places-exported json file
-  var jsonFile = dirSvc.get("ProfD", Ci.nsILocalFile);
-  jsonFile.append("bookmarks.exported.json");
-
-  // create bookmarks.exported.json
-  if (jsonFile.exists())
-    jsonFile.remove(false);
-  jsonFile.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, 0600);
-  if (!jsonFile.exists())
-    do_throw("couldn't create file: bookmarks.exported.json");
-
-  // Test importing a pre-Places canonical bookmarks file.
-  // 1. import bookmarks.preplaces.html
-  // 2. run the test-suite
-  // Note: we do not empty the db before this import to catch bugs like 380999
-  try {
-    importer.importHTMLFromFile(bookmarksFileOld, true);
-  } catch(ex) { do_throw("couldn't import legacy bookmarks file: " + ex); }
-  populate();
-  validate();
-
-  // Test exporting a Places canonical json file.
-  // 1. export to bookmarks.exported.json
-  // 2. empty bookmarks db
-  // 3. import bookmarks.exported.json
-  // 4. run the test-suite
-  try {
-    PlacesUtils.backupBookmarksToFile(jsonFile);
-  } catch(ex) { do_throw("couldn't export to file: " + ex); }
-  LOG("exported json"); 
-  try {
-    PlacesUtils.restoreBookmarksFromFile(jsonFile);
-  } catch(ex) { do_throw("couldn't import the exported file: " + ex); }
-  LOG("imported json"); 
-  validate();
-  LOG("validated import"); 
-}
-
-var tagData = [
-  { uri: uri("http://slint.us"), tags: ["indie", "kentucky", "music"] },
-  { uri: uri("http://en.wikipedia.org/wiki/Diplodocus"), tags: ["dinosaur", "dj", "rad word"] }
-];
-
-var recentTagsQueryURI = uri("place:folder=" + PlacesUtils.bookmarks.tagsFolder +
-  "&group=" + Ci.nsINavHistoryQueryOptions.GROUP_BY_FOLDER +
-  "&applyOptionsToContainers=1" +
-  "&queryType=" + Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS);
-
-var bookmarkData = [
-  //{ uri: uri("http://www.saveur.com/"), title: "Saveur Magazine" },
-  //{ uri: uri("http://twitter.com/"), title: "Twitter" },
-  { uri: uri("http://slint.us"), title: "indie, kentucky, music" },
-  { uri: uri("http://en.wikipedia.org/wiki/Diplodocus"), title: "dinosaur, dj, rad word" }
-  //{ uri: recentTagsQueryURI, title: "Recent Tags" }
-];
-
-/*
-populate data in each folder
-(menu is populated via the html import)
-*/
-function populate() {
-  // add tags
-  for each(let {uri: u, tags: t} in tagData)
-    PlacesUtils.tagging.tagURI(u, t);
-  
-  // add unfiled bookmarks
-  for each(let {uri: u, title: t} in bookmarkData) {
-    PlacesUtils.bookmarks.insertBookmark(PlacesUtils.bookmarks.unfiledBookmarksFolder,
-                                         u, PlacesUtils.bookmarks.DEFAULT_INDEX, t);
-  }
-
-  // add to the toolbar
-  for each(let {uri: u, title: t} in bookmarkData) {
-    PlacesUtils.bookmarks.insertBookmark(PlacesUtils.bookmarks.toolbarFolder,
-                                         u, PlacesUtils.bookmarks.DEFAULT_INDEX, t);
-  }
-}
-
-function validate() {
-  testCanonicalBookmarks(PlacesUtils.bookmarks.bookmarksMenuFolder);
-  testToolbarFolder();
-  testUnfiledBookmarks();
-  testTags();
+  // XXX test disabled due to backout of bug 384370
+  return;
 }
-
-// Tests a bookmarks datastore that has a set of bookmarks, etc
-// that flex each supported field and feature.
-function testCanonicalBookmarks() {
-  // query to see if the deleted folder and items have been imported
-  var query = PlacesUtils.history.getNewQuery();
-  query.setFolders([PlacesUtils.bookmarks.bookmarksMenuFolder], 1);
-  var result = PlacesUtils.history.executeQuery(query, PlacesUtils.history.getNewQueryOptions());
-  var rootNode = result.root;
-  rootNode.containerOpen = true;
-
-  // 6-2: the toolbar contents are imported to the places-toolbar folder,
-  // the separator above it is removed.
-  do_check_eq(rootNode.childCount, 4);
-
-  // get test folder
-  var testFolder = rootNode.getChild(3);
-  do_check_eq(testFolder.type, testFolder.RESULT_TYPE_FOLDER);
-  do_check_eq(testFolder.title, "test");
-
-  /*
-  // add date 
-  do_check_eq(PlacesUtils.bookmarks.getItemDateAdded(testFolder.itemId)/1000000, 1177541020);
-  // last modified
-  do_check_eq(PlacesUtils.bookmarks.getItemLastModified(testFolder.itemId)/1000000, 1177541050);
-  */
-
-  testFolder = testFolder.QueryInterface(Ci.nsINavHistoryQueryResultNode);
-  do_check_eq(testFolder.hasChildren, true);
-  // folder description
-  do_check_true(PlacesUtils.annotations.itemHasAnnotation(testFolder.itemId,
-                                                          DESCRIPTION_ANNO));
-  do_check_eq("folder test comment",
-              PlacesUtils.annotations.getItemAnnotation(testFolder.itemId, DESCRIPTION_ANNO));
-  // open test folder, and test the children
-  testFolder.containerOpen = true;
-  var cc = testFolder.childCount;
-  // XXX Bug 380468
-  // do_check_eq(cc, 2);
-  do_check_eq(cc, 1);
-
-  // test bookmark 1
-  var testBookmark1 = testFolder.getChild(0);
-  // url
-  do_check_eq("http://test/post", testBookmark1.uri);
-  // title
-  do_check_eq("test post keyword", testBookmark1.title);
-  // keyword
-  do_check_eq("test", PlacesUtils.bookmarks.getKeywordForBookmark(testBookmark1.itemId));
-  // sidebar
-  do_check_true(PlacesUtils.annotations.itemHasAnnotation(testBookmark1.itemId,
-                                                          LOAD_IN_SIDEBAR_ANNO));
-  /*
-  // add date 
-  do_check_eq(testBookmark1.dateAdded/1000000, 1177375336);
-
-  // last modified
-  do_check_eq(testBookmark1.lastModified/1000000, 1177375423);
-  */
-
-  // post data
-  do_check_true(PlacesUtils.annotations.itemHasAnnotation(testBookmark1.itemId, POST_DATA_ANNO));
-  do_check_eq("hidden1%3Dbar&text1%3D%25s",
-              PlacesUtils.annotations.getItemAnnotation(testBookmark1.itemId, POST_DATA_ANNO));
-
-  // last charset 
-  do_check_true(PlacesUtils.annotations.itemHasAnnotation(testBookmark1.itemId, LAST_CHARSET_ANNO));
-  do_check_eq("ISO-8859-1", PlacesUtils.annotations.getItemAnnotation(testBookmark1.itemId,
-                                                                      LAST_CHARSET_ANNO));
-  // description 
-  do_check_true(PlacesUtils.annotations.itemHasAnnotation(testBookmark1.itemId,
-                                                          DESCRIPTION_ANNO));
-  do_check_eq("item description",
-              PlacesUtils.annotations.getItemAnnotation(testBookmark1.itemId,
-                                                        DESCRIPTION_ANNO));
-
-  /*
-  // XXX Bug 380468
-  // test bookmark 2
-  var testBookmark2 = testFolder.getChild(1);
-  // url
-  do_check_eq("http://test/micsum", testBookmark2.uri);
-  // title
-  do_check_eq("test microsummary", testBookmark2.title);
-  // check that it's a microsummary
-  var micsum = mssvc.getMicrosummary(testBookmark2.itemId);
-  if (!micsum)
-    do_throw("Could not import microsummary");
-  // check generator uri
-  var generator = micsum.generator;
-  do_check_eq("urn:source:http://dietrich.ganx4.com/mozilla/test-microsummary.xml", generator.uri.spec);
-  // expiration and generated title can change, so don't test them
-  */
-
-  // clean up
-  testFolder.containerOpen = false;
-  rootNode.containerOpen = false;
-}
-
-function testToolbarFolder() {
-  var query = PlacesUtils.history.getNewQuery();
-  query.setFolders([PlacesUtils.bookmarks.toolbarFolder], 1);
-  var result = PlacesUtils.history.executeQuery(query, PlacesUtils.history.getNewQueryOptions());
-
-  var toolbar = result.root;
-  toolbar.containerOpen = true;
-
-  // child count (add 2 for pre-existing items)
-  do_check_eq(toolbar.childCount, bookmarkData.length + 2);
-  
-  // livemark
-  var livemark = toolbar.getChild(1);
-  // title
-  do_check_eq("Latest Headlines", livemark.title);
-  // livemark check
-  do_check_true(PlacesUtils.livemarks.isLivemark(livemark.itemId));
-  // site url
-  do_check_eq("http://en-us.fxfeeds.mozilla.com/en-US/firefox/livebookmarks/",
-              PlacesUtils.livemarks.getSiteURI(livemark.itemId).spec);
-  // feed url
-  do_check_eq("http://en-us.fxfeeds.mozilla.com/en-US/firefox/headlines.xml",
-              PlacesUtils.livemarks.getFeedURI(livemark.itemId).spec);
-
-  // test added bookmark data
-  var child = toolbar.getChild(2);
-  do_check_eq(child.uri, bookmarkData[0].uri.spec);
-  do_check_eq(child.title, bookmarkData[0].title);
-  child = toolbar.getChild(3);
-  do_check_eq(child.uri, bookmarkData[1].uri.spec);
-  do_check_eq(child.title, bookmarkData[1].title);
-
-  toolbar.containerOpen = false;
-}
-
-function testUnfiledBookmarks() {
-  var query = PlacesUtils.history.getNewQuery();
-  query.setFolders([PlacesUtils.bookmarks.unfiledBookmarksFolder], 1);
-  var result = PlacesUtils.history.executeQuery(query, PlacesUtils.history.getNewQueryOptions());
-  var rootNode = result.root;
-  rootNode.containerOpen = true;
-  do_check_eq(rootNode.childCount, bookmarkData.length);
-  for (var i = 0; i < rootNode.childCount; i++) {
-    var child = rootNode.getChild(i);
-    dump(bookmarkData[i].uri.spec + " == " + child.uri + "?\n");
-    do_check_true(bookmarkData[i].uri.equals(uri(child.uri)));
-    do_check_eq(child.title, bookmarkData[i].title);
-    /* WTF
-    if (child.tags)
-      do_check_eq(child.tags, bookmarkData[i].title);
-    */
-  }
-  rootNode.containerOpen = false;
-}
-
-function testTags() {
-  for each(let {uri: u, tags: t} in tagData) {
-    var i = 0;
-    dump("test tags for " + u.spec + ": " + t + "\n");
-    var tt = PlacesUtils.tagging.getTagsForURI(u, {});
-    dump("true tags for " + u.spec + ": " + tt + "\n");
-    do_check_true(t.every(function(el) {
-      i++;
-      return tt.indexOf(el) > -1;
-    }));
-    do_check_eq(i, t.length);
-  }
-}
--- a/browser/components/places/tests/unit/test_398914.js
+++ b/browser/components/places/tests/unit/test_398914.js
@@ -31,17 +31,22 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-Components.utils.import("resource://gre/modules/utils.js");
+version(170);
+
+var loader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
+             getService(Ci.mozIJSSubScriptLoader);
+loader.loadSubScript("chrome://global/content/debug.js");
+loader.loadSubScript("chrome://browser/content/places/utils.js");
 
 const bmsvc = PlacesUtils.bookmarks;
 const testFolderId = PlacesUtils.bookmarksMenuFolderId;
 
 // main
 function run_test() {
   var testURI = uri("http://foo.com");
 
--- a/browser/components/places/tests/unit/test_bookmarks_html.js
+++ b/browser/components/places/tests/unit/test_bookmarks_html.js
@@ -73,16 +73,17 @@ try {
 
 // Get io service
 try {
   var iosvc = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
 } catch (ex) {
   do_throw("Could not get io service\n");
 }
 
+
 const DESCRIPTION_ANNO = "bookmarkProperties/description";
 const LOAD_IN_SIDEBAR_ANNO = "bookmarkProperties/loadInSidebar";
 const POST_DATA_ANNO = "bookmarkProperties/POSTData";
 const LAST_CHARSET_ANNO = "URIProperties/characterSet";
 
 // main
 function run_test() {
   // get places import/export service
--- a/browser/components/sidebar/src/nsSidebar.js
+++ b/browser/components/sidebar/src/nsSidebar.js
@@ -124,17 +124,17 @@ function (aTitle, aContentURL, aCustomiz
     var uri = null;
     var ioService = Components.classes["@mozilla.org/network/io-service;1"]
                               .getService(Components.interfaces.nsIIOService);
     try {
       uri = ioService.newURI(aContentURL, null, null);
     }
     catch(ex) { return; }
 
-    win.PlacesUIUtils.showMinimalAddBookmarkUI(uri, aTitle, null, null, true, true);
+    win.PlacesUtils.showMinimalAddBookmarkUI(uri, aTitle, null, null, true, true);
 }
 
 nsSidebar.prototype.validateSearchEngine =
 function (engineURL, iconURL)
 {
   try
   {
     // Make sure we're using HTTP, HTTPS, or FTP.
--- a/toolkit/components/places/src/Makefile.in
+++ b/toolkit/components/places/src/Makefile.in
@@ -100,13 +100,9 @@ EXTRA_DSO_LDOPTS += \
 	$(NULL)
 
 LOCAL_INCLUDES += -I$(srcdir)/../../build
 
 EXTRA_PP_COMPONENTS = nsLivemarkService.js \
                       nsTaggingService.js \
                       $(NULL)
 
-EXTRA_JS_MODULES = utils.js
-
-EXTRA_PP_JS_MODULES = utils.js
-
 include $(topsrcdir)/config/rules.mk
--- a/toolkit/components/places/src/nsTaggingService.js
+++ b/toolkit/components/places/src/nsTaggingService.js
@@ -189,24 +189,23 @@ TaggingService.prototype = {
 
   /**
    * Removes the tag container from the tags-root if the given tag is empty.
    *
    * @param aTagId
    *        the item-id of the tag element under the tags root
    */
   _removeTagIfEmpty: function TS__removeTagIfEmpty(aTagId) {
-    var node = this._getTagNode(aTagId).QueryInterface(Ci.nsINavHistoryContainerResultNode);
-    var wasOpen = node.containerOpen;
-    if (!wasOpen)
-      node.containerOpen = true;
-    var cc = node.childCount;
-    if (wasOpen)
-      node.containerOpen = false;
-    if (cc == 0)
+    var options = this._history.getNewQueryOptions();
+    var query = this._history.getNewQuery();
+    query.setFolders([aTagId], 1);
+    var result = this._history.executeQuery(query, options);
+    var rootNode = result.root;
+    rootNode.containerOpen = true;
+    if (rootNode.childCount == 0)
       this._bms.removeFolder(aTagId);
   },
 
   // nsITaggingService
   untagURI: function TS_untagURI(aURI, aTags) {
     if (!aURI)
       throw Cr.NS_ERROR_INVALID_ARG;