Bug 575955 - Replace internal usage of old transactions shim, add a new toolkit test. r=mak
authorOHZEKI Tetsuharu <saneyuki.s.snyk@gmail.com>
Tue, 28 Feb 2012 18:40:38 -0500
changeset 87950 322e727576c810f9a212099a2af16f5961493a79
parent 87949 2742bfe821d27072840432c9b15d3ce21a6b1419
child 87951 e0913432b56e43843dd4b7bcd5c6e2cbeb32d4f6
push id22164
push usermbrubeck@mozilla.com
push dateWed, 29 Feb 2012 18:48:10 +0000
treeherdermozilla-central@3812d0ce274e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmak
bugs575955
milestone13.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 575955 - Replace internal usage of old transactions shim, add a new toolkit test. r=mak
browser/base/content/browser-places.js
browser/components/places/content/bookmarkProperties.js
browser/components/places/content/controller.js
browser/components/places/content/editBookmarkOverlay.js
browser/components/places/content/moveBookmarks.js
browser/components/places/content/places.js
browser/components/places/content/treeView.js
browser/components/places/tests/browser/browser_425884.js
browser/components/places/tests/browser/browser_457473_no_copy_guid.js
browser/components/places/tests/unit/test_placesTxn.js
browser/components/places/tests/unit/test_txnGUIDs.js
browser/components/places/tests/unit/xpcshell.ini
toolkit/components/places/tests/unit/test_placesTxn.js
toolkit/components/places/tests/unit/test_txnGUIDs.js
toolkit/components/places/tests/unit/xpcshell.ini
--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -96,35 +96,35 @@ var StarUI = {
       case "popuphidden":
         if (aEvent.originalTarget == this.panel) {
           if (!this._element("editBookmarkPanelContent").hidden)
             this.quitEditMode();
 
           this._restoreCommandsState();
           this._itemId = -1;
           if (this._batching) {
-            PlacesUIUtils.ptm.endBatch();
+            PlacesUtils.transactionManager.endBatch();
             this._batching = false;
           }
 
           switch (this._actionOnHide) {
             case "cancel": {
-              PlacesUIUtils.ptm.undoTransaction();
+              PlacesUtils.transactionManager.undoTransaction();
               break;
             }
             case "remove": {
               // Remove all bookmarks for the bookmark's url, this also removes
               // the tags for the url.
-              PlacesUIUtils.ptm.beginBatch();
+              PlacesUtils.transactionManager.beginBatch();
               let itemIds = PlacesUtils.getBookmarksForURI(this._uriForRemoval);
               for (let i = 0; i < itemIds.length; i++) {
-                let txn = PlacesUIUtils.ptm.removeItem(itemIds[i]);
-                PlacesUIUtils.ptm.doTransaction(txn);
+                let txn = new PlacesRemoveItemTransaction(itemIds[i]);
+                PlacesUtils.transactionManager.doTransaction(txn);
               }
-              PlacesUIUtils.ptm.endBatch();
+              PlacesUtils.transactionManager.endBatch();
               break;
             }
           }
           this._actionOnHide = "";
         }
         break;
       case "keypress":
         if (aEvent.defaultPrevented) {
@@ -270,17 +270,17 @@ var StarUI = {
   removeBookmarkButtonCommand: function SU_removeBookmarkButtonCommand() {
     this._uriForRemoval = PlacesUtils.bookmarks.getBookmarkURI(this._itemId);
     this._actionOnHide = "remove";
     this.panel.hidePopup();
   },
 
   beginBatch: function SU_beginBatch() {
     if (!this._batching) {
-      PlacesUIUtils.ptm.beginBatch();
+      PlacesUtils.transactionManager.beginBatch();
       this._batching = true;
     }
   }
 }
 
 var PlacesCommandHook = {
   /**
    * Adds a bookmark to the page loaded in the given browser.
@@ -320,19 +320,20 @@ var PlacesCommandHook = {
         // 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: PlacesUIUtils.DESCRIPTION_ANNO, value: description };
-      var txn = PlacesUIUtils.ptm.createItem(uri, parent, -1,
-                                             title, null, [descAnno]);
-      PlacesUIUtils.ptm.doTransaction(txn);
+      var txn = new PlacesCreateBookmarkTransaction(uri, parent, 
+                                                    PlacesUtils.bookmarks.DEFAULT_INDEX,
+                                                    title, null, [descAnno]);
+      PlacesUtils.transactionManager.doTransaction(txn);
       // Set the character-set
       if (charset)
         PlacesUtils.history.setCharsetForURI(uri, charset);
       itemId = PlacesUtils.getMostRecentBookmarkForURI(uri);
     }
 
     // Revert the contents of the location bar
     if (gURLBar)
--- a/browser/components/places/content/bookmarkProperties.js
+++ b/browser/components/places/content/bookmarkProperties.js
@@ -431,25 +431,25 @@ var BookmarkPropertiesPanel = {
         break;
     }
   },
 
   _beginBatch: function BPP__beginBatch() {
     if (this._batching)
       return;
 
-    PlacesUIUtils.ptm.beginBatch();
+    PlacesUtils.transactionManager.beginBatch();
     this._batching = true;
   },
 
   _endBatch: function BPP__endBatch() {
     if (!this._batching)
       return;
 
-    PlacesUIUtils.ptm.endBatch();
+    PlacesUtils.transactionManager.endBatch();
     this._batching = false;
   },
 
   _fillEditProperties: function BPP__fillEditProperties() {
     gEditItemOverlay.initPanel(this._itemId,
                                { hiddenRows: this._hiddenRows,
                                  forceReadOnly: this._readOnly });
   },
@@ -509,17 +509,17 @@ var BookmarkPropertiesPanel = {
 
   onDialogCancel: function BPP_onDialogCancel() {
     // The order here is important! We have to uninit the panel first, otherwise
     // changes done as part of Undo may change the panel contents and by
     // that force it to commit more transactions.
     gEditItemOverlay.uninitPanel(true);
     gEditItemOverlay = null;
     this._endBatch();
-    PlacesUIUtils.ptm.undoTransaction();
+    PlacesUtils.transactionManager.undoTransaction();
     window.arguments[0].performed = false;
   },
 
   /**
    * This method checks to see if the input fields are in a valid state.
    *
    * @returns  true if the input is valid, false otherwise
    */
@@ -572,54 +572,69 @@ var BookmarkPropertiesPanel = {
    * various fields and opening arguments of the dialog.
    */
   _getCreateNewBookmarkTransaction:
   function BPP__getCreateNewBookmarkTransaction(aContainer, aIndex) {
     var annotations = [];
     var childTransactions = [];
 
     if (this._description) {
-      childTransactions.push(
-        PlacesUIUtils.ptm.editItemDescription(-1, this._description));
+      let annoObj = { name   : PlacesUIUtils.DESCRIPTION_ANNO,
+                      type   : Ci.nsIAnnotationService.TYPE_STRING,
+                      flags  : 0,
+                      value  : this._description,
+                      expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
+      let editItemTxn = new PlacesSetItemAnnotationTransaction(-1, annoObj);
+      childTransactions.push(editItemTxn);
     }
 
     if (this._loadInSidebar) {
-      childTransactions.push(
-        PlacesUIUtils.ptm.setLoadInSidebar(-1, this._loadInSidebar));
+      let annoObj = { name   : PlacesUIUtils.LOAD_IN_SIDEBAR_ANNO,
+                      type   : Ci.nsIAnnotationService.TYPE_INT32,
+                      flags  : 0,
+                      value  : this._loadInSidebar,
+                      expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
+      let setLoadTxn = new PlacesSetItemAnnotationTransaction(-1, annoObj);
+      childTransactions.push(setLoadTxn);
     }
 
     if (this._postData) {
-      childTransactions.push(
-        PlacesUIUtils.ptm.editBookmarkPostData(-1, this._postData));
+      let postDataTxn = new PlacesEditBookmarkPostDataTransaction(-1, this._postData);
+      childTransactions.push(postDataTxn);
     }
 
     //XXX TODO: this should be in a transaction!
     if (this._charSet)
       PlacesUtils.history.setCharsetForURI(this._uri, this._charSet);
 
-    var transactions = [PlacesUIUtils.ptm.createItem(this._uri,
-                                                     aContainer, aIndex,
-                                                     this._title, this._keyword,
-                                                     annotations,
-                                                     childTransactions)];
+    let createTxn = new PlacesCreateBookmarkTransaction(this._uri,
+                                                        aContainer,
+                                                        aIndex,
+                                                        this._title,
+                                                        this._keyword,
+                                                        annotations,
+                                                        childTransactions);
 
-    return PlacesUIUtils.ptm.aggregateTransactions(this._getDialogTitle(),
-                                                   transactions);
+    return new PlacesAggregatedTransaction(this._getDialogTitle(),
+                                           [createTxn]);
   },
 
   /**
    * 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._URIs.length; ++i) {
       var uri = this._URIs[i];
       var title = this._getURITitleFromHistory(uri);
-      transactions.push(PlacesUIUtils.ptm.createItem(uri, -1, -1, title));
+      var createTxn = new PlacesCreateBookmarkTransaction(uri, -1, 
+                                                          PlacesUtils.bookmarks.DEFAULT_INDEX,
+                                                          title);
+      transactions.push(createTxn);
     }
     return transactions; 
   },
 
   /**
    * Returns a transaction for creating a new folder item representing the
    * various fields and opening arguments of the dialog.
    */
@@ -628,29 +643,30 @@ var BookmarkPropertiesPanel = {
     var annotations = [];
     var childItemsTransactions;
     if (this._URIs.length)
       childItemsTransactions = this._getTransactionsForURIList();
 
     if (this._description)
       annotations.push(this._getDescriptionAnnotation(this._description));
 
-    return PlacesUIUtils.ptm.createFolder(this._title, aContainer, aIndex,
-                                          annotations, childItemsTransactions);
+    return new PlacesCreateFolderTransaction(this._title, 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) {
-    return PlacesUIUtils.ptm.createLivemark(this._feedURI, this._siteURI,
-                                            this._title,
-                                            aContainer, aIndex);
+    return new PlacesCreateLivemarkTransaction(this._feedURI, this._siteURI,
+                                               this._title,
+                                               aContainer, aIndex);
   },
 
   /**
    * Dialog-accept code-path for creating a new item (any type)
    */
   _createNewItem: function BPP__getCreateItemTransaction() {
     var [container, index] = this._getInsertionPointDetails();
     var txn;
@@ -661,12 +677,12 @@ var BookmarkPropertiesPanel = {
         break;
       case LIVEMARK_CONTAINER:
         txn = this._getCreateNewLivemarkTransaction(container, index);
         break;      
       default: // BOOKMARK_ITEM
         txn = this._getCreateNewBookmarkTransaction(container, index);
     }
 
-    PlacesUIUtils.ptm.doTransaction(txn);
+    PlacesUtils.transactionManager.doTransaction(txn);
     this._itemId = PlacesUtils.bookmarks.getIdForItemAt(container, index);
   }
 };
--- a/browser/components/places/content/controller.js
+++ b/browser/components/places/content/controller.js
@@ -152,19 +152,19 @@ 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);
   },
 
   isCommandEnabled: function PC_isCommandEnabled(aCommand) {
     switch (aCommand) {
     case "cmd_undo":
-      return PlacesUIUtils.ptm.numberOfUndoItems > 0;
+      return PlacesUtils.transactionManager.numberOfUndoItems > 0;
     case "cmd_redo":
-      return PlacesUIUtils.ptm.numberOfRedoItems > 0;
+      return PlacesUtils.transactionManager.numberOfRedoItems > 0;
     case "cmd_cut":
     case "placesCmd_cut":
       var nodes = this._view.selectedNodes;
       // If selection includes history nodes there's no reason to allow cut.
       for (var i = 0; i < nodes.length; i++) {
         if (nodes[i].itemId == -1)
           return false;
       }
@@ -225,20 +225,20 @@ PlacesController.prototype = {
     default:
       return false;
     }
   },
 
   doCommand: function PC_doCommand(aCommand) {
     switch (aCommand) {
     case "cmd_undo":
-      PlacesUIUtils.ptm.undoTransaction();
+      PlacesUtils.transactionManager.undoTransaction();
       break;
     case "cmd_redo":
-      PlacesUIUtils.ptm.redoTransaction();
+      PlacesUtils.transactionManager.redoTransaction();
       break;
     case "cmd_cut":
     case "placesCmd_cut":
       this.cut();
       break;
     case "cmd_copy":
     case "placesCmd_copy":
       this.copy();
@@ -780,18 +780,18 @@ PlacesController.prototype = {
 
   /**
    * 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 = new PlacesCreateSeparatorTransaction(ip.itemId, ip.index);
+    PlacesUtils.transactionManager.doTransaction(txn);
     // select the new item
     var insertedNodeId = PlacesUtils.bookmarks
                                     .getIdForItemAt(ip.itemId, ip.index);
     this._view.selectItems([insertedNodeId], false);
   },
 
   /**
    * Opens a dialog for moving the selected nodes.
@@ -802,18 +802,18 @@ PlacesController.prototype = {
                       this._view.selectedNodes);
   },
 
   /**
    * 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 = new PlacesSortFolderByNameTransaction(itemId);
+    PlacesUtils.transactionManager.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.
@@ -867,30 +867,33 @@ PlacesController.prototype = {
       if (this._shouldSkipNode(node, removedFolders))
         continue;
 
       if (PlacesUtils.nodeIsTagQuery(node.parent)) {
         // This is a uri node inside a tag container.  It needs a special
         // untag transaction.
         var tagItemId = PlacesUtils.getConcreteItemId(node.parent);
         var uri = NetUtil.newURI(node.uri);
-        transactions.push(PlacesUIUtils.ptm.untagURI(uri, [tagItemId]));
+        let txn = new PlacesUntagURITransaction(uri, [tagItemId]);
+        transactions.push(txn);
       }
       else if (PlacesUtils.nodeIsTagQuery(node) && node.parent &&
                PlacesUtils.nodeIsQuery(node.parent) &&
                PlacesUtils.asQuery(node.parent).queryOptions.resultType ==
                  Ci.nsINavHistoryQueryOptions.RESULTS_AS_TAG_QUERY) {
         // This is a tag container.
         // Untag all URIs tagged with this tag only if the tag container is
         // child of the "Tags" query in the library, in all other places we
         // must only remove the query node.
         var tag = node.title;
         var URIs = PlacesUtils.tagging.getURIsForTag(tag);
-        for (var j = 0; j < URIs.length; j++)
-          transactions.push(PlacesUIUtils.ptm.untagURI(URIs[j], [tag]));
+        for (var j = 0; j < URIs.length; j++) {
+          let txn = new PlacesUntagURITransaction(URIs[j], [tag]);
+          transactions.push(txn);
+        }
       }
       else if (PlacesUtils.nodeIsURI(node) &&
                PlacesUtils.nodeIsQuery(node.parent) &&
                PlacesUtils.asQuery(node.parent).queryOptions.queryType ==
                  Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY) {
         // This is a uri node inside an history query.
         PlacesUtils.bhistory.removePage(NetUtil.newURI(node.uri));
         // History deletes are not undoable, so we don't have a transaction.
@@ -907,17 +910,18 @@ PlacesController.prototype = {
       }
       else {
         // This is a common bookmark item.
         if (PlacesUtils.nodeIsFolder(node)) {
           // If this is a folder we add it to our array of folders, used
           // to skip nodes that are children of an already removed folder.
           removedFolders.push(node);
         }
-        transactions.push(PlacesUIUtils.ptm.removeItem(node.itemId));
+        let txn = new PlacesRemoveItemTransaction(node.itemId);
+        transactions.push(txn);
       }
     }
   },
 
   /**
    * Removes the set of selected ranges from bookmarks.
    * @param   txnName
    *          See |remove|.
@@ -926,18 +930,18 @@ PlacesController.prototype = {
     var ranges = this._view.removableSelectionRanges;
     var transactions = [];
     var removedFolders = [];
 
     for (var i = 0; i < ranges.length; i++)
       this._removeRange(ranges[i], transactions, removedFolders);
 
     if (transactions.length > 0) {
-      var txn = PlacesUIUtils.ptm.aggregateTransactions(txnName, transactions);
-      PlacesUIUtils.ptm.doTransaction(txn);
+      var txn = new PlacesAggregatedTransaction(txnName, transactions);
+      PlacesUtils.transactionManager.doTransaction(txn);
     }
   },
 
   /**
    * Removes the set of selected ranges from history.
    *
    * @note history deletes are not undoable.
    */
@@ -1273,37 +1277,35 @@ PlacesController.prototype = {
     }
 
     let transactions = [];
     let insertionIndex = ip.index;
     for (let i = 0; i < items.length; ++i) {
       if (ip.isTag) {
         // Pasting into a tag container means tagging the item, regardless of
         // the requested action.
-        transactions.push(
-          new PlacesTagURITransaction(NetUtil.newURI(items[i].uri),
-                                      [ip.itemId])
-        );
+        let tagTxn = new PlacesTagURITransaction(NetUtil.newURI(items[i].uri),
+                                                 [ip.itemId]);
+        transactions.push(tagTxn);
         continue;
       }
 
       // Adjust index to make sure items are pasted in the correct position.
       // If index is DEFAULT_INDEX, items are just appended.
       if (ip.index != PlacesUtils.bookmarks.DEFAULT_INDEX)
         insertionIndex = ip.index + i;
 
       transactions.push(
         PlacesUIUtils.makeTransaction(items[i], type, ip.itemId,
                                       insertionIndex, action == "copy")
       );
     }
  
-    PlacesUtils.transactionManager.doTransaction(
-      new PlacesAggregatedTransaction("Paste", transactions)
-    );
+    let aggregatedTxn = new PlacesAggregatedTransaction("Paste", transactions);
+    PlacesUtils.transactionManager.doTransaction(aggregatedTxn);
 
     // Cut/past operations are not repeatable, so clear the clipboard.
     if (action == "cut") {
       this._clearClipboard();
     }
 
     // Select the pasted items, they should be consecutive.
     let insertedNodeIds = [];
@@ -1543,27 +1545,28 @@ let PlacesControllerDragHelper = {
       if (index != -1 && dragginUp)
         index+= movedCount++;
 
       // If dragging over a tag container we should tag the item.
       if (insertionPoint.isTag &&
           insertionPoint.orientation == Ci.nsITreeView.DROP_ON) {
         let uri = NetUtil.newURI(unwrapped.uri);
         let tagItemId = insertionPoint.itemId;
-        transactions.push(PlacesUIUtils.ptm.tagURI(uri,[tagItemId]));
+        let tagTxn = new PlacesTagURITransaction(uri, [tagItemId]);
+        transactions.push(tagTxn);
       }
       else {
         transactions.push(PlacesUIUtils.makeTransaction(unwrapped,
                           flavor, insertionPoint.itemId,
                           index, doCopy));
       }
     }
 
-    let txn = PlacesUIUtils.ptm.aggregateTransactions("DropItems", transactions);
-    PlacesUIUtils.ptm.doTransaction(txn);
+    let txn = new PlacesAggregatedTransaction("DropItems", transactions);
+    PlacesUtils.transactionManager.doTransaction(txn);
   },
 
   /**
    * Checks if we can insert into a container.
    * @param   aContainer
    *          The container were we are want to drop
    */
   disallowInsertion: function(aContainer) {
--- a/browser/components/places/content/editBookmarkOverlay.js
+++ b/browser/components/places/content/editBookmarkOverlay.js
@@ -430,25 +430,28 @@ var gEditItemOverlay = {
         if (tags.indexOf(currentTags[i]) == -1)
           tagsToRemove.push(currentTags[i]);
       }
       for (var i = 0; i < tags.length; i++) {
         if (currentTags.indexOf(tags[i]) == -1)
           tagsToAdd.push(tags[i]);
       }
 
-      if (tagsToRemove.length > 0)
-        txns.push(PlacesUIUtils.ptm.untagURI(this._uri, tagsToRemove));
-      if (tagsToAdd.length > 0)
-        txns.push(PlacesUIUtils.ptm.tagURI(this._uri, tagsToAdd));
+      if (tagsToRemove.length > 0) {
+        let untagTxn = new PlacesUntagURITransaction(this._uri, tagsToRemove);
+        txns.push(untagTxn);
+      }
+      if (tagsToAdd.length > 0) {
+        let tagTxn = new PlacesTagURITransaction(this._uri, tagsToAdd);
+        txns.push(tagTxn);
+      }
 
       if (txns.length > 0) {
-        var aggregate = PlacesUIUtils.ptm.aggregateTransactions("Update tags",
-                                                                txns);
-        PlacesUIUtils.ptm.doTransaction(aggregate);
+        let aggregate = new PlacesAggregatedTransaction("Update tags", txns);
+        PlacesUtils.transactionManager.doTransaction(aggregate);
 
         // Ensure the tagsField is in sync, clean it up from empty tags
         var tags = PlacesUtils.tagging.getTagsForURI(this._uri).join(", ");
         this._initTextField("tagsField", tags, false);
         return true;
       }
     }
     return false;
@@ -490,105 +493,116 @@ var gEditItemOverlay = {
         tagsToAdd[i] = [];
         for (var j = 0; j < tags.length; j++) {
           if (this._tags[i].indexOf(tags[j]) == -1)
             tagsToAdd[i].push(tags[j]);
         }
       }
 
       if (tagsToAdd.length > 0) {
-        for (i = 0; i < this._uris.length; i++) {
-          if (tagsToAdd[i].length > 0)
-            txns.push(PlacesUIUtils.ptm.tagURI(this._uris[i], tagsToAdd[i]));
+        for (let i = 0; i < this._uris.length; i++) {
+          if (tagsToAdd[i].length > 0) {
+            let tagTxn = new PlacesTagURITransaction(this._uris[i],
+                                                     tagsToAdd[i]);
+            txns.push(tagTxn);
+          }
         }
       }
       if (tagsToRemove.length > 0) {
-        for (var i = 0; i < this._uris.length; i++)
-          txns.push(PlacesUIUtils.ptm.untagURI(this._uris[i], tagsToRemove));
+        for (let i = 0; i < this._uris.length; i++) {
+          let untagTxn = new PlacesUntagURITransaction(this._uris[i],
+                                                       tagsToRemove);
+          txns.push(untagTxn);
+        }
       }
 
       if (txns.length > 0) {
-        var aggregate = PlacesUIUtils.ptm.aggregateTransactions("Update tags",
-                                                                txns);
-        PlacesUIUtils.ptm.doTransaction(aggregate);
+        let aggregate = new PlacesAggregatedTransaction("Update tags", txns);
+        PlacesUtils.transactionManager.doTransaction(aggregate);
 
         this._allTags = tags;
         this._tags = [];
-        for (i = 0; i < this._uris.length; i++)
+        for (let i = 0; i < this._uris.length; i++) {
           this._tags[i] = PlacesUtils.tagging.getTagsForURI(this._uris[i]);
+        }
 
         // Ensure the tagsField is in sync, clean it up from empty tags
         this._initTextField("tagsField", tags, false);
         return true;
       }
     }
     return false;
   },
 
   onNamePickerChange: function EIO_onNamePickerChange() {
     if (this._itemId == -1)
       return;
 
     var namePicker = this._element("namePicker")
-    var txns = [];
-    const ptm = PlacesUIUtils.ptm;
 
     // Here we update either the item title or its cached static title
     var newTitle = namePicker.value;
     if (!newTitle &&
         PlacesUtils.bookmarks.getFolderIdForItem(this._itemId) == PlacesUtils.tagsFolderId) {
       // We don't allow setting an empty title for a tag, restore the old one.
       this._initNamePicker();
     }
     else if (this._getItemStaticTitle() != newTitle) {
       this._mayUpdateFirstEditField("namePicker");
-      txns.push(ptm.editItemTitle(this._itemId, newTitle));
+      let txn = new PlacesEditItemTitleTransaction(this._itemId, newTitle);
+      PlacesUtils.transactionManager.doTransaction(txn);
     }
-
-    var aggregate = ptm.aggregateTransactions("Edit Item Title", txns);
-    ptm.doTransaction(aggregate);
   },
 
   onDescriptionFieldBlur: function EIO_onDescriptionFieldBlur() {
     var description = this._element("descriptionField").value;
     if (description != PlacesUIUtils.getItemDescription(this._itemId)) {
-      var txn = PlacesUIUtils.ptm
-                             .editItemDescription(this._itemId, description);
-      PlacesUIUtils.ptm.doTransaction(txn);
+      var annoObj = { name   : PlacesUIUtils.DESCRIPTION_ANNO,
+                      type   : Ci.nsIAnnotationService.TYPE_STRING,
+                      flags  : 0,
+                      value  : description,
+                      expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
+      var txn = new PlacesSetItemAnnotationTransaction(this._itemId, annoObj);
+      PlacesUtils.transactionManager.doTransaction(txn);
     }
   },
 
   onLocationFieldBlur: function EIO_onLocationFieldBlur() {
     var uri;
     try {
       uri = PlacesUIUtils.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 = new PlacesEditBookmarkURITransaction(this._itemId, uri);
+      PlacesUtils.transactionManager.doTransaction(txn);
       this._uri = uri;
     }
   },
 
   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 = new PlacesEditBookmarkKeywordTransaction(this._itemId, keyword);
+      PlacesUtils.transactionManager.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 annoObj = { name   : PlacesUIUtils.LOAD_IN_SIDEBAR_ANNO,
+                    type   : Ci.nsIAnnotationService.TYPE_INT32,
+                    flags  : 0,
+                    value  : loadInSidebarChecked,
+                    expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
+    var txn = new PlacesSetItemAnnotationTransaction(this._itemId,
+                                                     annoObj);
+    PlacesUtils.transactionManager.doTransaction(txn);
   },
 
   toggleFolderTreeVisibility: function EIO_toggleFolderTreeVisibility() {
     var expander = this._element("foldersExpander");
     var folderTreeRow = this._element("folderTreeRow");
     if (!folderTreeRow.collapsed) {
       expander.className = "expander-down";
       expander.setAttribute("tooltiptext",
@@ -667,18 +681,20 @@ 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 = new PlacesMoveItemTransaction(this._itemId, 
+                                              container, 
+                                              PlacesUtils.bookmarks.DEFAULT_INDEX);
+      PlacesUtils.transactionManager.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);
     }
@@ -715,25 +731,27 @@ var gEditItemOverlay = {
   _markFolderAsRecentlyUsed:
   function EIO__markFolderAsRecentlyUsed(aFolderId) {
     var txns = [];
 
     // Expire old unused recent folders
     var anno = this._getLastUsedAnnotationObject(false);
     while (this._recentFolders.length > MAX_FOLDER_ITEM_IN_MENU_LIST) {
       var folderId = this._recentFolders.pop().folderId;
-      txns.push(PlacesUIUtils.ptm.setItemAnnotation(folderId, anno));
+      let annoTxn = new PlacesSetItemAnnotationTransaction(folderId, anno);
+      txns.push(annoTxn);
     }
 
     // Mark folder as recently used
     anno = this._getLastUsedAnnotationObject(true);
-    txns.push(PlacesUIUtils.ptm.setItemAnnotation(aFolderId, anno));
+    let annoTxn = new PlacesSetItemAnnotationTransaction(aFolderId, anno);
+    txns.push(annoTxn);
 
-    var aggregate = PlacesUIUtils.ptm.aggregateTransactions("Update last used folders", txns);
-    PlacesUIUtils.ptm.doTransaction(aggregate);
+    let aggregate = new PlacesAggregatedTransaction("Update last used folders", txns);
+    PlacesUtils.transactionManager.doTransaction(aggregate);
   },
 
   /**
    * Returns an object which could then be used to set/unset the
    * LAST_USED_ANNO annotation for a folder.
    *
    * @param aLastUsed
    *        Whether to set or unset the LAST_USED_ANNO annotation.
@@ -835,18 +853,18 @@ var gEditItemOverlay = {
     if (!ip || ip.itemId == PlacesUIUtils.allBookmarksFolderId) {
         ip = new InsertionPoint(PlacesUtils.bookmarksMenuFolderId,
                                 PlacesUtils.bookmarks.DEFAULT_INDEX,
                                 Ci.nsITreeView.DROP_ON);
     }
 
     // XXXmano: add a separate "New Folder" string at some point...
     var defaultLabel = this._element("newFolderButton").label;
-    var txn = PlacesUIUtils.ptm.createFolder(defaultLabel, ip.itemId, ip.index);
-    PlacesUIUtils.ptm.doTransaction(txn);
+    var txn = new PlacesCreateFolderTransaction(defaultLabel, ip.itemId, ip.index);
+    PlacesUtils.transactionManager.doTransaction(txn);
     this._folderTree.focus();
     this._folderTree.selectItems([this._lastNewItem]);
     this._folderTree.startEditing(this._folderTree.view.selection.currentIndex,
                                   this._folderTree.columns.getFirstColumn());
   },
 
   // nsIDOMEventListener
   handleEvent: function EIO_nsIDOMEventListener(aEvent) {
--- a/browser/components/places/content/moveBookmarks.js
+++ b/browser/components/places/content/moveBookmarks.js
@@ -62,23 +62,25 @@ var gMoveBookmarksDialog = {
     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));
+      let txn = new PlacesMoveItemTransaction(this._nodes[i].itemId,
+                                              selectedFolderID,
+                                              PlacesUtils.bookmarks.DEFAULT_INDEX);
+      transactions.push(txn);
     }
 
     if (transactions.length != 0) {
-      var txn = PlacesUIUtils.ptm.aggregateTransactions("Move Items", transactions);
-      PlacesUIUtils.ptm.doTransaction(txn);
+      let txn = new PlacesAggregatedTransaction("Move Items", transactions);
+      PlacesUtils.transactionManager.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
@@ -823,21 +823,21 @@ var PlacesOrganizer = {
     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 = new PlacesCreateBookmarkTransaction(placeURI,
+                                                  PlacesUtils.bookmarksMenuFolderId,
+                                                  PlacesUtils.bookmarks.DEFAULT_INDEX,
+                                                  input.value);
+    PlacesUtils.transactionManager.doTransaction(txn);
 
     // select and load the new query
     this._places.selectPlaceURI(placeSpec);
   }
 };
 
 /**
  * A set of utilities relating to search within Bookmarks and History.
--- a/browser/components/places/content/treeView.js
+++ b/browser/components/places/content/treeView.js
@@ -1655,18 +1655,18 @@ PlacesTreeView.prototype = {
 
     return true;
   },
 
   setCellText: function PTV_setCellText(aRow, aColumn, aText) {
     // We may only get here if the cell is editable.
     let node = this._rows[aRow];
     if (node.title != aText) {
-      let txn = PlacesUIUtils.ptm.editItemTitle(node.itemId, aText);
-      PlacesUIUtils.ptm.doTransaction(txn);
+      let txn = new PlacesEditItemTitleTransaction(node.itemId, aText);
+      PlacesUtils.transactionManager.doTransaction(txn);
     }
   },
 
   selectionChanged: function() { },
   cycleCell: function(aRow, aColumn) { },
   isSelectable: function(aRow, aColumn) { return false; },
   performAction: function(aAction) { },
   performActionOnRow: function(aAction, aRow) { },
--- a/browser/components/places/tests/browser/browser_425884.js
+++ b/browser/components/places/tests/browser/browser_425884.js
@@ -81,40 +81,40 @@ function test() {
   folderANode.containerOpen = false;
 
   var transaction = PlacesUIUtils.makeTransaction(rawNode,
                                                   PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER,
                                                   testRootId,
                                                   -1,
                                                   true);
   ok(transaction, "create transaction");
-  PlacesUIUtils.ptm.doTransaction(transaction);
+  PlacesUtils.transactionManager.doTransaction(transaction);
   // confirm copy
   is(testRootNode.childCount, 2, "create test folder via copy");
 
   // validate the copy
   var folderBNode = testRootNode.getChild(1);
   validate(folderBNode);
 
   // undo the transaction, confirm the removal
-  PlacesUIUtils.ptm.undoTransaction();
+  PlacesUtils.transactionManager.undoTransaction();
   is(testRootNode.childCount, 1, "confirm undo removed the copied folder");
 
   // redo the transaction
-  PlacesUIUtils.ptm.redoTransaction();
+  PlacesUtils.transactionManager.redoTransaction();
   is(testRootNode.childCount, 2, "confirm redo re-copied the folder");
   folderBNode = testRootNode.getChild(1);
   validate(folderBNode);
 
   // Close containers, cleaning up their observers.
   testRootNode.containerOpen = false;
   toolbarNode.containerOpen = false;
 
   // clean up
-  PlacesUIUtils.ptm.undoTransaction();
+  PlacesUtils.transactionManager.undoTransaction();
   PlacesUtils.bookmarks.removeItem(folderAId);
 }
 
 function populate(aFolderId) {
   var folderId = PlacesUtils.bookmarks.createFolder(aFolderId, "test folder", -1);
   PlacesUtils.bookmarks.insertBookmark(folderId, PlacesUtils._uri("http://foo"), -1, "test bookmark");
   PlacesUtils.bookmarks.insertSeparator(folderId, -1);
 }
--- a/browser/components/places/tests/browser/browser_457473_no_copy_guid.js
+++ b/browser/components/places/tests/browser/browser_457473_no_copy_guid.js
@@ -80,43 +80,43 @@ function test() {
   // Create a copy transaction from the serialization.
   // this exercises the guid-filtering
   var transaction = PlacesUIUtils.makeTransaction(rawNode,
                                                   PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER,
                                                   testRootId, -1, true);
   ok(transaction, "create transaction");
 
   // execute it, copying to the test root folder
-  PlacesUIUtils.ptm.doTransaction(transaction);
+  PlacesUtils.transactionManager.doTransaction(transaction);
   is(testRootNode.childCount, 2, "create test folder via copy");
 
   // check GUIDs are different
   var folderBNode = testRootNode.getChild(1);
   ok(checkGUIDs(folderBNode, folderAGUIDs, false), "confirm folder A GUIDs don't match folder B GUIDs");
   var folderBGUIDs = getGUIDs(folderBNode);
   ok(checkGUIDs(folderBNode, folderBGUIDs, true), "confirm test of new GUIDs");
 
   // undo the transaction, confirm the removal
-  PlacesUIUtils.ptm.undoTransaction();
+  PlacesUtils.transactionManager.undoTransaction();
   is(testRootNode.childCount, 1, "confirm undo removed the copied folder");
 
   // redo the transaction
   // confirming GUIDs persist through undo/redo
-  PlacesUIUtils.ptm.redoTransaction();
+  PlacesUtils.transactionManager.redoTransaction();
   is(testRootNode.childCount, 2, "confirm redo re-copied the folder");
   folderBNode = testRootNode.getChild(1);
   ok(checkGUIDs(folderBNode, folderAGUIDs, false), "folder B GUIDs after undo/redo don't match folder A GUIDs"); // sanity check
   ok(checkGUIDs(folderBNode, folderBGUIDs, true), "folder B GUIDs after under/redo should match pre-undo/redo folder B GUIDs");
 
   // Close containers, cleaning up their observers.
   testRootNode.containerOpen = false;
   toolbarNode.containerOpen = false;
 
   // clean up
-  PlacesUIUtils.ptm.undoTransaction();
+  PlacesUtils.transactionManager.undoTransaction();
   PlacesUtils.bookmarks.removeItem(testRootId);
 }
 
 function getGUIDs(aNode) {
   PlacesUtils.asContainer(aNode);
   aNode.containerOpen = true;
   var GUIDs = {
     folder: PlacesUtils.bookmarks.getItemGUID(aNode.itemId),
--- a/browser/components/places/tests/unit/xpcshell.ini
+++ b/browser/components/places/tests/unit/xpcshell.ini
@@ -14,11 +14,9 @@ tail =
 [test_browserGlue_distribution.js]
 [test_browserGlue_migrate.js]
 [test_browserGlue_prefs.js]
 [test_browserGlue_restore.js]
 [test_browserGlue_shutdown.js]
 [test_browserGlue_smartBookmarks.js]
 [test_clearHistory_shutdown.js]
 [test_leftpane_corruption_handling.js]
-[test_placesTxn.js]
 [test_PUIU_makeTransaction.js]
-[test_txnGUIDs.js]
rename from browser/components/places/tests/unit/test_placesTxn.js
rename to toolkit/components/places/tests/unit/test_placesTxn.js
--- a/browser/components/places/tests/unit/test_placesTxn.js
+++ b/toolkit/components/places/tests/unit/test_placesTxn.js
@@ -34,19 +34,21 @@
  * 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 ***** */
 
 var bmsvc = PlacesUtils.bookmarks;
-var ptSvc = PlacesUIUtils.ptm;
 var tagssvc = PlacesUtils.tagging;
 var annosvc = PlacesUtils.annotations;
+let txnManager = PlacesUtils.transactionManager;
+const kDESCRIPTION_ANNO = "bookmarkProperties/description";
+const kLOAD_IN_SIDEBAR_ANNO = "bookmarkProperties/loadInSidebar";
 
 // create and add bookmarks observer
 var observer = {
   onBeginUpdateBatch: function() {
     this._beginUpdateBatch = true;
   },
   onEndUpdateBatch: function() {
     this._endUpdateBatch = true;
@@ -99,55 +101,56 @@ var bmStartIndex = 0;
 
 // main
 function run_test() {
   // get bookmarks root index
   var root = bmsvc.bookmarksMenuFolder;
 
   //Test creating a folder with a description
   const TEST_DESCRIPTION = "this is my test description";
-  var annos = [{ name: PlacesUIUtils.DESCRIPTION_ANNO,
+  var annos = [{ name: kDESCRIPTION_ANNO,
                  type: annosvc.TYPE_STRING,
                 flags: 0,
                 value: TEST_DESCRIPTION,
               expires: annosvc.EXPIRE_NEVER }];
-  var txn1 = ptSvc.createFolder("Testing folder", root, bmStartIndex, annos);
-  ptSvc.doTransaction(txn1);
+  var txn1 = new PlacesCreateFolderTransaction("Testing folder", root, bmStartIndex, annos);
+  txnManager.doTransaction(txn1);
 
   // This checks that calling undoTransaction on an "empty batch" doesn't
   // undo the previous transaction (getItemTitle will fail)
-  ptSvc.beginBatch();
-  ptSvc.endBatch();
-  ptSvc.undoTransaction();
+  txnManager.beginBatch();
+  txnManager.endBatch();
+  txnManager.undoTransaction();
 
   var folderId = observer._itemAddedId;
   do_check_eq(bmsvc.getItemTitle(folderId), "Testing folder");
   do_check_eq(observer._itemAddedIndex, bmStartIndex);
   do_check_eq(observer._itemAddedParent, root);
   do_check_eq(observer._itemAddedId, folderId);
   do_check_eq(TEST_DESCRIPTION, 
-              annosvc.getItemAnnotation(folderId, PlacesUIUtils.DESCRIPTION_ANNO));
+              annosvc.getItemAnnotation(folderId, kDESCRIPTION_ANNO));
 
   txn1.undoTransaction();
   do_check_eq(observer._itemRemovedId, folderId);
   do_check_eq(observer._itemRemovedFolder, root);
   do_check_eq(observer._itemRemovedIndex, bmStartIndex);
   txn1.redoTransaction();
   do_check_eq(observer._itemAddedIndex, bmStartIndex);
   do_check_eq(observer._itemAddedParent, root);
   do_check_eq(observer._itemAddedId, folderId);
   txn1.undoTransaction();
   do_check_eq(observer._itemRemovedId, folderId);
   do_check_eq(observer._itemRemovedFolder, root);
   do_check_eq(observer._itemRemovedIndex, bmStartIndex);
 
   // Test creating an item
   // Create to Root
-  var txn2 = ptSvc.createItem(uri("http://www.example.com"), root, bmStartIndex, "Testing1");
-  ptSvc.doTransaction(txn2); // Also testing doTransaction
+  var txn2 = new PlacesCreateBookmarkTransaction(uri("http://www.example.com"),
+                                                 root, bmStartIndex, "Testing1");
+  txnManager.doTransaction(txn2); // Also testing doTransaction
   var b = (bmsvc.getBookmarkIdsForURI(uri("http://www.example.com")))[0];
   do_check_eq(observer._itemAddedId, b);
   do_check_eq(observer._itemAddedIndex, bmStartIndex);
   do_check_true(bmsvc.isBookmarked(uri("http://www.example.com")));
   txn2.undoTransaction();
   do_check_eq(observer._itemRemovedId, b);
   do_check_eq(observer._itemRemovedIndex, bmStartIndex);
   do_check_false(bmsvc.isBookmarked(uri("http://www.example.com")));
@@ -158,23 +161,24 @@ function run_test() {
   do_check_eq(observer._itemAddedParent, root);
   do_check_eq(observer._itemAddedId, newId);
   txn2.undoTransaction();
   do_check_eq(observer._itemRemovedId, newId);
   do_check_eq(observer._itemRemovedFolder, root);
   do_check_eq(observer._itemRemovedIndex, bmStartIndex);
 
   // Create item to a folder
-  var txn2a = ptSvc.createFolder("Folder", root, bmStartIndex);
-  ptSvc.doTransaction(txn2a);
+  var txn2a = new PlacesCreateFolderTransaction("Folder", root, bmStartIndex);
+  txnManager.doTransaction(txn2a);
   var fldrId = observer._itemAddedId;
   do_check_eq(bmsvc.getItemTitle(fldrId), "Folder");
 
-  var txn2b = ptSvc.createItem(uri("http://www.example2.com"), fldrId, bmStartIndex, "Testing1b");
-  ptSvc.doTransaction(txn2b);
+  var txn2b = new PlacesCreateBookmarkTransaction(uri("http://www.example2.com"),
+                                                  fldrId, bmStartIndex, "Testing1b");
+  txnManager.doTransaction(txn2b);
   var b2 = (bmsvc.getBookmarkIdsForURI(uri("http://www.example2.com")))[0];
   do_check_eq(observer._itemAddedId, b2);
   do_check_eq(observer._itemAddedIndex, bmStartIndex);
   do_check_true(bmsvc.isBookmarked(uri("http://www.example2.com")));
   txn2b.undoTransaction();
   do_check_eq(observer._itemRemovedId, b2);
   do_check_eq(observer._itemRemovedIndex, bmStartIndex);
   txn2b.redoTransaction();
@@ -183,27 +187,35 @@ function run_test() {
   do_check_eq(observer._itemAddedParent, fldrId);
   do_check_eq(observer._itemAddedId, newId);
   txn2b.undoTransaction();
   do_check_eq(observer._itemRemovedId, newId);
   do_check_eq(observer._itemRemovedFolder, fldrId);
   do_check_eq(observer._itemRemovedIndex, bmStartIndex);
 
   // Testing moving an item
-  ptSvc.doTransaction(ptSvc.createItem(uri("http://www.example3.com"), root, -1, "Testing2"));
-  ptSvc.doTransaction(ptSvc.createItem(uri("http://www.example3.com"), root, -1, "Testing3"));
-  ptSvc.doTransaction(ptSvc.createItem(uri("http://www.example3.com"), fldrId, -1, "Testing4"));
+  {
+    let txnTesting2 = new PlacesCreateBookmarkTransaction(uri("http://www.example3.com"),
+                                                          root, -1, "Testing2");
+    txnManager.doTransaction(txnTesting2);
+    let txnTesting3 = new PlacesCreateBookmarkTransaction(uri("http://www.example3.com"),
+                                                          root, -1, "Testing3");
+    txnManager.doTransaction(txnTesting3);
+    let txnTesting4 = new PlacesCreateBookmarkTransaction(uri("http://www.example3.com"),
+                                                          fldrId, -1, "Testing4");
+    txnManager.doTransaction(txnTesting4);
+  }
   var bkmkIds = bmsvc.getBookmarkIdsForURI(uri("http://www.example3.com"));
   bkmkIds.sort();
   var bkmk1Id = bkmkIds[0];
   var bkmk2Id = bkmkIds[1];
   var bkmk3Id = bkmkIds[2];
 
   // Moving items between the same folder
-  var txn3 = ptSvc.moveItem(bkmk1Id, root, -1);
+  var txn3 = new PlacesMoveItemTransaction(bkmk1Id, root, -1);
   txn3.doTransaction();
   do_check_eq(observer._itemMovedId, bkmk1Id);
   do_check_eq(observer._itemMovedOldParent, root);
   do_check_eq(observer._itemMovedOldIndex, 1);
   do_check_eq(observer._itemMovedNewParent, root);
   do_check_eq(observer._itemMovedNewIndex, 2);
   txn3.undoTransaction();
   do_check_eq(observer._itemMovedId, bkmk1Id);
@@ -220,17 +232,17 @@ function run_test() {
   txn3.undoTransaction();
   do_check_eq(observer._itemMovedId, bkmk1Id);
   do_check_eq(observer._itemMovedOldParent, root);
   do_check_eq(observer._itemMovedOldIndex, 2);
   do_check_eq(observer._itemMovedNewParent, root);
   do_check_eq(observer._itemMovedNewIndex, 1);
 
   // Moving items between different folders
-  var txn3b = ptSvc.moveItem(bkmk1Id, fldrId, -1);
+  var txn3b = new PlacesMoveItemTransaction(bkmk1Id, fldrId, -1);
   txn3b.doTransaction();
   do_check_eq(observer._itemMovedId, bkmk1Id);
   do_check_eq(observer._itemMovedOldParent, root);
   do_check_eq(observer._itemMovedOldIndex, 1);
   do_check_eq(observer._itemMovedNewParent, fldrId);
   do_check_eq(observer._itemMovedNewIndex, 1);
   txn3.undoTransaction();
   do_check_eq(observer._itemMovedId, bkmk1Id);
@@ -247,21 +259,24 @@ function run_test() {
   txn3.undoTransaction();
   do_check_eq(observer._itemMovedId, bkmk1Id);
   do_check_eq(observer._itemMovedOldParent, fldrId);
   do_check_eq(observer._itemMovedOldIndex, 1);
   do_check_eq(observer._itemMovedNewParent, root);
   do_check_eq(observer._itemMovedNewIndex, 1);
 
   // Test Removing a Folder
-  ptSvc.doTransaction(ptSvc.createFolder("Folder2", root, -1));
-  var fldrId2 = observer._itemAddedId;
+  let txnFolder2 = new PlacesCreateFolderTransaction("Folder2",
+                                                     root,
+                                                     bmsvc.DEFAULT_INDEX);
+  txnManager.doTransaction(txnFolder2);
+  let fldrId2 = observer._itemAddedId;
   do_check_eq(bmsvc.getItemTitle(fldrId2), "Folder2");
 
-  var txn4 = ptSvc.removeItem(fldrId2);
+  var txn4 = new PlacesRemoveItemTransaction(fldrId2);
   txn4.doTransaction();
   do_check_eq(observer._itemRemovedId, fldrId2);
   do_check_eq(observer._itemRemovedFolder, root);
   do_check_eq(observer._itemRemovedIndex, 3);
   txn4.undoTransaction();
   do_check_eq(observer._itemAddedId, fldrId2);
   do_check_eq(observer._itemAddedParent, root);
   do_check_eq(observer._itemAddedIndex, 3);
@@ -273,17 +288,17 @@ function run_test() {
   do_check_eq(observer._itemAddedId, fldrId2);
   do_check_eq(observer._itemAddedParent, root);
   do_check_eq(observer._itemAddedIndex, 3);
 
   // Test removing an item with a keyword and a tag.
   // Notice in this case the tag persists since other bookmarks have same uri.
   bmsvc.setKeywordForBookmark(bkmk2Id, "test_keyword");
   tagssvc.tagURI(uri("http://www.example3.com"), ["test-tag"]);
-  var txn5 = ptSvc.removeItem(bkmk2Id);
+  var txn5 = new PlacesRemoveItemTransaction(bkmk2Id);
   txn5.doTransaction();
   do_check_eq(observer._itemRemovedId, bkmk2Id);
   do_check_eq(observer._itemRemovedFolder, root);
   do_check_eq(observer._itemRemovedIndex, 2);
   do_check_eq(bmsvc.getKeywordForBookmark(bkmk2Id), null);
   do_check_eq(tagssvc.getTagsForURI(uri("http://www.example3.com"))[0], "test-tag");
   txn5.undoTransaction();
   var newbkmk2Id = observer._itemAddedId;
@@ -301,35 +316,36 @@ function run_test() {
   do_check_eq(observer._itemAddedParent, root);
   do_check_eq(observer._itemAddedIndex, 2);
   do_check_eq(tagssvc.getTagsForURI(uri("http://www.example3.com"))[0], "test-tag");
   tagssvc.untagURI(uri("http://www.example3.com"), ["test-tag"]);
 
   {
     // Test removing an item with a tag (last bookmark for a uri).
     let testURI = uri("http://www.taggedbm.com/");
-    ptSvc.doTransaction(
-      ptSvc.createItem(testURI, fldrId, bmStartIndex, "TaggedBm")
-    );
+    let txnTaggedBm = new PlacesCreateBookmarkTransaction(testURI, fldrId,
+                                                          bmStartIndex, "TaggedBm");
+    txnManager.doTransaction(txnTaggedBm);
     tagssvc.tagURI(testURI, ["test-tag"]);
+
     let itemId = observer._itemAddedId;
-    txn = ptSvc.removeItem(itemId);
+    let txn = new PlacesRemoveItemTransaction(itemId);
     txn.doTransaction();
     do_check_true(tagssvc.getTagsForURI(testURI).length == 0);
     txn.undoTransaction();
     do_check_eq(tagssvc.getTagsForURI(testURI)[0], "test-tag");
     txn.redoTransaction();
     do_check_true(tagssvc.getTagsForURI(testURI).length == 0);
     txn.undoTransaction();
     do_check_eq(tagssvc.getTagsForURI(testURI)[0], "test-tag");
     txn.redoTransaction();
   }
 
   // Test creating a separator
-  var txn6 = ptSvc.createSeparator(root, 1);
+  var txn6 = new PlacesCreateSeparatorTransaction(root, 1);
   txn6.doTransaction();
   var sepId = observer._itemAddedId;
   do_check_eq(observer._itemAddedIndex, 1);
   do_check_eq(observer._itemAddedParent, root);
   txn6.undoTransaction();
   do_check_eq(observer._itemRemovedId, sepId);
   do_check_eq(observer._itemRemovedFolder, root);
   do_check_eq(observer._itemRemovedIndex, 1);
@@ -338,38 +354,40 @@ function run_test() {
   do_check_eq(observer._itemAddedIndex, 1);
   do_check_eq(observer._itemAddedParent, root);
   txn6.undoTransaction();
   do_check_eq(observer._itemRemovedId, newSepId);
   do_check_eq(observer._itemRemovedFolder, root);
   do_check_eq(observer._itemRemovedIndex, 1);
 
   // Test removing a separator
-  ptSvc.doTransaction(ptSvc.createSeparator(root, 1));
-  var sepId2 = observer._itemAddedId;
-  var txn7 = ptSvc.removeItem(sepId2);
-  txn7.doTransaction();
-  do_check_eq(observer._itemRemovedId, sepId2);
-  do_check_eq(observer._itemRemovedFolder, root);
-  do_check_eq(observer._itemRemovedIndex, 1);
-  txn7.undoTransaction();
-  do_check_eq(observer._itemAddedId, sepId2); //New separator created
-  do_check_eq(observer._itemAddedParent, root);
-  do_check_eq(observer._itemAddedIndex, 1);
-  txn7.redoTransaction();
-  do_check_eq(observer._itemRemovedId, sepId2);
-  do_check_eq(observer._itemRemovedFolder, root);
-  do_check_eq(observer._itemRemovedIndex, 1);
-  txn7.undoTransaction();
-  do_check_eq(observer._itemAddedId, sepId2); //New separator created
-  do_check_eq(observer._itemAddedParent, root);
-  do_check_eq(observer._itemAddedIndex, 1);
-
+  {
+    let separatorTxn = new PlacesCreateSeparatorTransaction(root, 1);
+    txnManager.doTransaction(separatorTxn);
+    var sepId2 = observer._itemAddedId;
+    var txn7 = new PlacesRemoveItemTransaction(sepId2);
+    txn7.doTransaction();
+    do_check_eq(observer._itemRemovedId, sepId2);
+    do_check_eq(observer._itemRemovedFolder, root);
+    do_check_eq(observer._itemRemovedIndex, 1);
+    txn7.undoTransaction();
+    do_check_eq(observer._itemAddedId, sepId2); //New separator created
+    do_check_eq(observer._itemAddedParent, root);
+    do_check_eq(observer._itemAddedIndex, 1);
+    txn7.redoTransaction();
+    do_check_eq(observer._itemRemovedId, sepId2);
+    do_check_eq(observer._itemRemovedFolder, root);
+    do_check_eq(observer._itemRemovedIndex, 1);
+    txn7.undoTransaction();
+    do_check_eq(observer._itemAddedId, sepId2); //New separator created
+    do_check_eq(observer._itemAddedParent, root);
+    do_check_eq(observer._itemAddedIndex, 1);
+  }
   // Test editing item title
-  var txn8 = ptSvc.editItemTitle(bkmk1Id, "Testing2_mod");
+  var txn8 = new PlacesEditItemTitleTransaction(bkmk1Id, "Testing2_mod");
   txn8.doTransaction();
   do_check_eq(observer._itemChangedId, bkmk1Id); 
   do_check_eq(observer._itemChangedProperty, "title");
   do_check_eq(observer._itemChangedValue, "Testing2_mod");
   txn8.undoTransaction();
   do_check_eq(observer._itemChangedId, bkmk1Id); 
   do_check_eq(observer._itemChangedProperty, "title");
   do_check_eq(observer._itemChangedValue, "Testing2");
@@ -378,17 +396,17 @@ function run_test() {
   do_check_eq(observer._itemChangedProperty, "title");
   do_check_eq(observer._itemChangedValue, "Testing2_mod");
   txn8.undoTransaction();
   do_check_eq(observer._itemChangedId, bkmk1Id); 
   do_check_eq(observer._itemChangedProperty, "title");
   do_check_eq(observer._itemChangedValue, "Testing2");
 
   // Test editing item uri
-  var txn9 = ptSvc.editBookmarkURI(bkmk1Id, uri("http://newuri.com"));
+  var txn9 = new PlacesEditBookmarkURITransaction(bkmk1Id, uri("http://newuri.com"));
   txn9.doTransaction();
   do_check_eq(observer._itemChangedId, bkmk1Id);
   do_check_eq(observer._itemChangedProperty, "uri");
   do_check_eq(observer._itemChangedValue, "http://newuri.com/");
   txn9.undoTransaction();
   do_check_eq(observer._itemChangedId, bkmk1Id);
   do_check_eq(observer._itemChangedProperty, "uri");
   do_check_eq(observer._itemChangedValue, "http://www.example3.com/");
@@ -397,50 +415,62 @@ function run_test() {
   do_check_eq(observer._itemChangedProperty, "uri");
   do_check_eq(observer._itemChangedValue, "http://newuri.com/");
   txn9.undoTransaction();
   do_check_eq(observer._itemChangedId, bkmk1Id);
   do_check_eq(observer._itemChangedProperty, "uri");
   do_check_eq(observer._itemChangedValue, "http://www.example3.com/");
   
   // Test edit description transaction.
-  var txn10 = ptSvc.editItemDescription(bkmk1Id, "Description1");
+  let txn10AnnoObj = {
+    name: kDESCRIPTION_ANNO,
+    type: Ci.nsIAnnotationService.TYPE_STRING,
+    flags: 0,
+    value: "Description1",
+    expires: Ci.nsIAnnotationService.EXPIRE_NEVER,
+  };
+  var txn10 = new PlacesSetItemAnnotationTransaction(bkmk1Id, txn10AnnoObj);
   txn10.doTransaction();
   do_check_eq(observer._itemChangedId, bkmk1Id);
-  do_check_eq(observer._itemChangedProperty, PlacesUIUtils.DESCRIPTION_ANNO);
+  do_check_eq(observer._itemChangedProperty, kDESCRIPTION_ANNO);
 
   // Testing edit keyword
-  var txn11 = ptSvc.editBookmarkKeyword(bkmk1Id, "kw1");
+  var txn11 = new PlacesEditBookmarkKeywordTransaction(bkmk1Id, "kw1");
   txn11.doTransaction();
   do_check_eq(observer._itemChangedId, bkmk1Id);
   do_check_eq(observer._itemChangedProperty, "keyword");
   do_check_eq(observer._itemChangedValue, "kw1"); 
   txn11.undoTransaction();
   do_check_eq(observer._itemChangedId, bkmk1Id);
   do_check_eq(observer._itemChangedProperty, "keyword");
   do_check_eq(observer._itemChangedValue, ""); 
 
   // Test LoadInSidebar transaction.
-  var txn16 = ptSvc.setLoadInSidebar(bkmk1Id, true);
+  let txn16AnnoObj = { name: kLOAD_IN_SIDEBAR_ANNO,
+                       type: Ci.nsIAnnotationService.TYPE_INT32,
+                       flags: 0,
+                       value: true,
+                       expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
+  var txn16 = new PlacesSetItemAnnotationTransaction(bkmk1Id, txn16AnnoObj);
   txn16.doTransaction();
   do_check_eq(observer._itemChangedId, bkmk1Id);
-  do_check_eq(observer._itemChangedProperty, PlacesUIUtils.LOAD_IN_SIDEBAR_ANNO);
+  do_check_eq(observer._itemChangedProperty, kLOAD_IN_SIDEBAR_ANNO);
   do_check_eq(observer._itemChanged_isAnnotationProperty, true);
   txn16.undoTransaction();
   do_check_eq(observer._itemChangedId, bkmk1Id);
-  do_check_eq(observer._itemChangedProperty, PlacesUIUtils.LOAD_IN_SIDEBAR_ANNO);
+  do_check_eq(observer._itemChangedProperty, kLOAD_IN_SIDEBAR_ANNO);
   do_check_eq(observer._itemChanged_isAnnotationProperty, true);
 
   // Test generic item annotation
   var itemAnnoObj = { name: "testAnno/testInt",
                       type: Ci.nsIAnnotationService.TYPE_INT32,
                       flags: 0,
                       value: 123,
                       expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
-  var genItemAnnoTxn = ptSvc.setItemAnnotation(bkmk1Id, itemAnnoObj);
+  var genItemAnnoTxn = new PlacesSetItemAnnotationTransaction(bkmk1Id, itemAnnoObj);
   genItemAnnoTxn.doTransaction();
   do_check_eq(observer._itemChangedId, bkmk1Id);
   do_check_eq(observer._itemChangedProperty, "testAnno/testInt");
   do_check_eq(observer._itemChanged_isAnnotationProperty, true);
   genItemAnnoTxn.undoTransaction();
   do_check_eq(observer._itemChangedId, bkmk1Id);
   do_check_eq(observer._itemChangedProperty, "testAnno/testInt");
   do_check_eq(observer._itemChanged_isAnnotationProperty, true);
@@ -454,119 +484,138 @@ function run_test() {
                       type: Ci.nsIAnnotationService.TYPE_INT32,
                       flags: 0,
                       value: 123,
                       expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
   var hs = Cc["@mozilla.org/browser/nav-history-service;1"].
            getService(Ci.nsINavHistoryService);
   hs.addVisit(uri("http://www.mozilla.org/"), Date.now() * 1000, null,
               hs.TRANSITION_TYPED, false, 0);
-  var genPageAnnoTxn = ptSvc.setPageAnnotation(uri("http://www.mozilla.org/"), pageAnnoObj);
+  var genPageAnnoTxn = new PlacesSetPageAnnotationTransaction(uri("http://www.mozilla.org/"), pageAnnoObj);
   genPageAnnoTxn.doTransaction();
   do_check_true(annosvc.pageHasAnnotation(uri("http://www.mozilla.org/"), "testAnno/testInt"));
   genPageAnnoTxn.undoTransaction();
   do_check_false(annosvc.pageHasAnnotation(uri("http://www.mozilla.org/"), "testAnno/testInt"));
   genPageAnnoTxn.redoTransaction();
   do_check_true(annosvc.pageHasAnnotation(uri("http://www.mozilla.org/"), "testAnno/testInt"));
 
   // sortFolderByName
-  ptSvc.doTransaction(ptSvc.createFolder("Sorting folder", root, bmStartIndex, [], null));
-  var srtFldId = observer._itemAddedId;
-  do_check_eq(bmsvc.getItemTitle(srtFldId), "Sorting folder");
-  ptSvc.doTransaction(ptSvc.createItem(uri("http://www.sortingtest.com"), srtFldId, -1, "c"));
-  ptSvc.doTransaction(ptSvc.createItem(uri("http://www.sortingtest.com"), srtFldId, -1, "b"));   
-  ptSvc.doTransaction(ptSvc.createItem(uri("http://www.sortingtest.com"), srtFldId, -1, "a"));
-  var b = bmsvc.getBookmarkIdsForURI(uri("http://www.sortingtest.com"));
-  b.sort();
-  var b1 = b[0];
-  var b2 = b[1];
-  var b3 = b[2];
-  do_check_eq(0, bmsvc.getItemIndex(b1));
-  do_check_eq(1, bmsvc.getItemIndex(b2));
-  do_check_eq(2, bmsvc.getItemIndex(b3));
-  var txn17 = ptSvc.sortFolderByName(srtFldId);
-  txn17.doTransaction();
-  do_check_eq(2, bmsvc.getItemIndex(b1));
-  do_check_eq(1, bmsvc.getItemIndex(b2));
-  do_check_eq(0, bmsvc.getItemIndex(b3));
-  txn17.undoTransaction();
-  do_check_eq(0, bmsvc.getItemIndex(b1));
-  do_check_eq(1, bmsvc.getItemIndex(b2));
-  do_check_eq(2, bmsvc.getItemIndex(b3));
-  txn17.redoTransaction();
-  do_check_eq(2, bmsvc.getItemIndex(b1));
-  do_check_eq(1, bmsvc.getItemIndex(b2));
-  do_check_eq(0, bmsvc.getItemIndex(b3));
-  txn17.undoTransaction();
-  do_check_eq(0, bmsvc.getItemIndex(b1));
-  do_check_eq(1, bmsvc.getItemIndex(b2));
-  do_check_eq(2, bmsvc.getItemIndex(b3));
+  {
+    let sortFolderTxn = new PlacesCreateFolderTransaction("Sorting folder", root,
+                                                          bmStartIndex, [], null);
+    txnManager.doTransaction(sortFolderTxn);
+    var srtFldId = observer._itemAddedId;
+    do_check_eq(bmsvc.getItemTitle(srtFldId), "Sorting folder");
+    let cTxn = new PlacesCreateBookmarkTransaction(uri("http://www.sortingtest.com"),
+                                                   srtFldId, -1, "c");
+    txnManager.doTransaction(cTxn);
+    let bTxn = new PlacesCreateBookmarkTransaction(uri("http://www.sortingtest.com"),
+                                                   srtFldId, -1, "b");
+    txnManager.doTransaction(bTxn);
+    let aTxn = new PlacesCreateBookmarkTransaction(uri("http://www.sortingtest.com"),
+                                                   srtFldId, bmsvc.DEFAULT_INDEX, "a");
+    txnManager.doTransaction(aTxn);
+
+    var b = bmsvc.getBookmarkIdsForURI(uri("http://www.sortingtest.com"));
+    b.sort();
+    var b1 = b[0];
+    var b2 = b[1];
+    var b3 = b[2];
+    do_check_eq(0, bmsvc.getItemIndex(b1));
+    do_check_eq(1, bmsvc.getItemIndex(b2));
+    do_check_eq(2, bmsvc.getItemIndex(b3));
+    var txn17 = new PlacesSortFolderByNameTransaction(srtFldId);
+    txn17.doTransaction();
+    do_check_eq(2, bmsvc.getItemIndex(b1));
+    do_check_eq(1, bmsvc.getItemIndex(b2));
+    do_check_eq(0, bmsvc.getItemIndex(b3));
+    txn17.undoTransaction();
+    do_check_eq(0, bmsvc.getItemIndex(b1));
+    do_check_eq(1, bmsvc.getItemIndex(b2));
+    do_check_eq(2, bmsvc.getItemIndex(b3));
+    txn17.redoTransaction();
+    do_check_eq(2, bmsvc.getItemIndex(b1));
+    do_check_eq(1, bmsvc.getItemIndex(b2));
+    do_check_eq(0, bmsvc.getItemIndex(b3));
+    txn17.undoTransaction();
+    do_check_eq(0, bmsvc.getItemIndex(b1));
+    do_check_eq(1, bmsvc.getItemIndex(b2));
+    do_check_eq(2, bmsvc.getItemIndex(b3));
+  }
 
   // Testing edit Post Data
-  const POST_DATA_ANNO = "bookmarkProperties/POSTData";
-  var postData = "foo";
-  var postDataURI = uri("http://foo.com");
-  ptSvc.doTransaction(
-    ptSvc.createItem(postDataURI, root, -1, "postdata test", null, null, null));
-  var postDataId = (bmsvc.getBookmarkIdsForURI(postDataURI))[0];
-  var postDataTxn = ptSvc.editBookmarkPostData(postDataId, postData);
-  postDataTxn.doTransaction();
-  do_check_true(annosvc.itemHasAnnotation(postDataId, POST_DATA_ANNO))
-  do_check_eq(annosvc.getItemAnnotation(postDataId, POST_DATA_ANNO), postData);
-  postDataTxn.undoTransaction();
-  do_check_false(annosvc.itemHasAnnotation(postDataId, POST_DATA_ANNO))
+  {
+    const POST_DATA_ANNO = "bookmarkProperties/POSTData";
+    var postData = "foo";
+    var postDataURI = uri("http://foo.com");
+    let txn = new PlacesCreateBookmarkTransaction(postDataURI, root, -1,
+                                                  "postdata test", null, null, null)
+    txnManager.doTransaction(txn);
+    var postDataId = (bmsvc.getBookmarkIdsForURI(postDataURI))[0];
+    var postDataTxn = new PlacesEditBookmarkPostDataTransaction(postDataId, postData);
+    postDataTxn.doTransaction();
+    do_check_true(annosvc.itemHasAnnotation(postDataId, POST_DATA_ANNO))
+    do_check_eq(annosvc.getItemAnnotation(postDataId, POST_DATA_ANNO), postData);
+    postDataTxn.undoTransaction();
+    do_check_false(annosvc.itemHasAnnotation(postDataId, POST_DATA_ANNO))
+  }
 
   // Test editing item date added
   var oldAdded = bmsvc.getItemDateAdded(bkmk1Id);
   var newAdded = Date.now();
-  var eidaTxn = ptSvc.editItemDateAdded(bkmk1Id, newAdded);
+  var eidaTxn = new PlacesEditItemDateAddedTransaction(bkmk1Id, newAdded);
   eidaTxn.doTransaction();
   do_check_eq(newAdded, bmsvc.getItemDateAdded(bkmk1Id));
   eidaTxn.undoTransaction();
   do_check_eq(oldAdded, bmsvc.getItemDateAdded(bkmk1Id));
 
   // Test editing item last modified 
   var oldModified = bmsvc.getItemLastModified(bkmk1Id);
   var newModified = Date.now();
-  var eilmTxn = ptSvc.editItemLastModified(bkmk1Id, newModified);
+  var eilmTxn = new PlacesEditItemLastModifiedTransaction(bkmk1Id, newModified);
   eilmTxn.doTransaction();
   do_check_eq(newModified, bmsvc.getItemLastModified(bkmk1Id));
   eilmTxn.undoTransaction();
   do_check_eq(oldModified, bmsvc.getItemLastModified(bkmk1Id));
 
   // Test tagURI/untagURI
   var tagURI = uri("http://foo.tld");
-  var tagTxn = ptSvc.tagURI(tagURI, ["foo", "bar"]);
+  var tagTxn = new PlacesTagURITransaction(tagURI, ["foo", "bar"]);
   tagTxn.doTransaction();
   do_check_eq(uneval(tagssvc.getTagsForURI(tagURI)), uneval(["bar","foo"]));
   tagTxn.undoTransaction();
   do_check_eq(tagssvc.getTagsForURI(tagURI).length, 0);
   tagTxn.redoTransaction();
   do_check_eq(uneval(tagssvc.getTagsForURI(tagURI)), uneval(["bar","foo"]));
-  var untagTxn = ptSvc.untagURI(tagURI, ["bar"]);
+  var untagTxn = new PlacesUntagURITransaction(tagURI, ["bar"]);
   untagTxn.doTransaction();
   do_check_eq(uneval(tagssvc.getTagsForURI(tagURI)), uneval(["foo"]));
   untagTxn.undoTransaction();
   do_check_eq(uneval(tagssvc.getTagsForURI(tagURI)), uneval(["bar","foo"]));
   untagTxn.redoTransaction();
   do_check_eq(uneval(tagssvc.getTagsForURI(tagURI)), uneval(["foo"]));
 
   // Test aggregate removeItem transaction
   var bkmk1Id = bmsvc.insertBookmark(root, uri("http://www.mozilla.org/"), 0, "Mozilla");
   var bkmk2Id = bmsvc.insertSeparator(root, 1);
   var bkmk3Id = bmsvc.createFolder(root, "folder", 2);
   var bkmk3_1Id = bmsvc.insertBookmark(bkmk3Id, uri("http://www.mozilla.org/"), 0, "Mozilla");
   var bkmk3_2Id = bmsvc.insertSeparator(bkmk3Id, 1);
   var bkmk3_3Id = bmsvc.createFolder(bkmk3Id, "folder", 2);
 
   var transactions = [];
-  transactions.push(ptSvc.removeItem(bkmk1Id));
-  transactions.push(ptSvc.removeItem(bkmk2Id));
-  transactions.push(ptSvc.removeItem(bkmk3Id));
-  var txn = ptSvc.aggregateTransactions("RemoveItems", transactions);
+  {
+    let txn1 = new PlacesRemoveItemTransaction(bkmk1Id);
+    transactions.push(txn1);
+    let txn2 = new PlacesRemoveItemTransaction(bkmk2Id);
+    transactions.push(txn2);
+    let txn3 = new PlacesRemoveItemTransaction(bkmk3Id);
+    transactions.push(txn3);
+  }
+  var txn = new PlacesAggregatedTransaction("RemoveItems", transactions);
 
   txn.doTransaction();
   do_check_eq(bmsvc.getItemIndex(bkmk1Id), -1);
   do_check_eq(bmsvc.getItemIndex(bkmk2Id), -1);
   do_check_eq(bmsvc.getItemIndex(bkmk3Id), -1);
   do_check_eq(bmsvc.getItemIndex(bkmk3_1Id), -1);
   do_check_eq(bmsvc.getItemIndex(bkmk3_2Id), -1);
   do_check_eq(bmsvc.getItemIndex(bkmk3_3Id), -1);
@@ -627,61 +676,65 @@ function run_test() {
   do_check_eq(bmsvc.getFolderIdForItem(newBkmk3_3Id), newBkmk3Id);
   do_check_eq(bmsvc.getItemType(newBkmk3_3Id), bmsvc.TYPE_FOLDER);
   do_check_eq(bmsvc.getItemTitle(newBkmk3_3Id), "folder");
   // Check last added back item id.
   // Notice items are restored in reverse order.
   do_check_eq(observer._itemAddedId, newBkmk1Id);
 
   // Test creating an item with child transactions.
-  var childTxns = [];
-  var newDateAdded = Date.now() - 20000;
-  childTxns.push(ptSvc.editItemDateAdded(null, newDateAdded));
-  var itemChildAnnoObj = { name: "testAnno/testInt",
-                           type: Ci.nsIAnnotationService.TYPE_INT32,
-                           flags: 0,
-                           value: 123,
-                           expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
-  childTxns.push(ptSvc.setItemAnnotation(null, itemChildAnnoObj));
-  var itemWChildTxn = ptSvc.createItem(uri("http://www.example.com"), root,
-                                       bmStartIndex, "Testing1", null, null,
-                                       childTxns);
-  try {
-    ptSvc.doTransaction(itemWChildTxn); // Also testing doTransaction
-    var itemId = (bmsvc.getBookmarkIdsForURI(uri("http://www.example.com")))[0];
-    do_check_eq(observer._itemAddedId, itemId);
-    do_check_eq(newDateAdded, bmsvc.getItemDateAdded(itemId));
-    do_check_eq(observer._itemChangedProperty, "testAnno/testInt");
-    do_check_eq(observer._itemChanged_isAnnotationProperty, true);
-    do_check_true(annosvc.itemHasAnnotation(itemId, itemChildAnnoObj.name))
-    do_check_eq(annosvc.getItemAnnotation(itemId, itemChildAnnoObj.name),
-                itemChildAnnoObj.value);
-    itemWChildTxn.undoTransaction();
-    do_check_eq(observer._itemRemovedId, itemId);
-    itemWChildTxn.redoTransaction();
-    do_check_true(bmsvc.isBookmarked(uri("http://www.example.com")));
-    var newId = (bmsvc.getBookmarkIdsForURI(uri("http://www.example.com")))[0];
-    do_check_eq(newDateAdded, bmsvc.getItemDateAdded(newId));
-    do_check_eq(observer._itemAddedId, newId);
-    do_check_eq(observer._itemChangedProperty, "testAnno/testInt");
-    do_check_eq(observer._itemChanged_isAnnotationProperty, true);
-    do_check_true(annosvc.itemHasAnnotation(newId, itemChildAnnoObj.name))
-    do_check_eq(annosvc.getItemAnnotation(newId, itemChildAnnoObj.name),
-                itemChildAnnoObj.value);
-    itemWChildTxn.undoTransaction();
-    do_check_eq(observer._itemRemovedId, newId);
-  } catch (ex) {
-    do_throw("Setting a child transaction in a createItem transaction did throw: " + ex);
+  {
+    var childTxns = [];
+    var newDateAdded = Date.now() - 20000;
+    let editDateAdddedTxn = new PlacesEditItemDateAddedTransaction(null, newDateAdded);
+    childTxns.push(editDateAdddedTxn);
+    var itemChildAnnoObj = { name: "testAnno/testInt",
+                             type: Ci.nsIAnnotationService.TYPE_INT32,
+                             flags: 0,
+                             value: 123,
+                             expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
+    let annoTxn = new PlacesSetItemAnnotationTransaction(null, itemChildAnnoObj);
+    childTxns.push(annoTxn);
+    var itemWChildTxn = new PlacesCreateBookmarkTransaction(uri("http://www.example.com"), root,
+                                                            bmStartIndex, "Testing1", null, null,
+                                                            childTxns);
+    try {
+      txnManager.doTransaction(itemWChildTxn); // Also testing doTransaction
+      var itemId = (bmsvc.getBookmarkIdsForURI(uri("http://www.example.com")))[0];
+      do_check_eq(observer._itemAddedId, itemId);
+      do_check_eq(newDateAdded, bmsvc.getItemDateAdded(itemId));
+      do_check_eq(observer._itemChangedProperty, "testAnno/testInt");
+      do_check_eq(observer._itemChanged_isAnnotationProperty, true);
+      do_check_true(annosvc.itemHasAnnotation(itemId, itemChildAnnoObj.name))
+      do_check_eq(annosvc.getItemAnnotation(itemId, itemChildAnnoObj.name),
+                  itemChildAnnoObj.value);
+      itemWChildTxn.undoTransaction();
+      do_check_eq(observer._itemRemovedId, itemId);
+      itemWChildTxn.redoTransaction();
+      do_check_true(bmsvc.isBookmarked(uri("http://www.example.com")));
+      var newId = (bmsvc.getBookmarkIdsForURI(uri("http://www.example.com")))[0];
+      do_check_eq(newDateAdded, bmsvc.getItemDateAdded(newId));
+      do_check_eq(observer._itemAddedId, newId);
+      do_check_eq(observer._itemChangedProperty, "testAnno/testInt");
+      do_check_eq(observer._itemChanged_isAnnotationProperty, true);
+      do_check_true(annosvc.itemHasAnnotation(newId, itemChildAnnoObj.name))
+      do_check_eq(annosvc.getItemAnnotation(newId, itemChildAnnoObj.name),
+                  itemChildAnnoObj.value);
+      itemWChildTxn.undoTransaction();
+      do_check_eq(observer._itemRemovedId, newId);
+    } catch (ex) {
+      do_throw("Setting a child transaction in a createItem transaction did throw: " + ex);
+    }
   }
 
   // Create a folder with child item transactions.
-  var childItemTxn = ptSvc.createItem(uri("http://www.childItem.com"), root, bmStartIndex, "childItem");
-  var folderWChildItemTxn = ptSvc.createFolder("Folder", root, bmStartIndex, null, [childItemTxn]);
+  var childItemTxn = new PlacesCreateBookmarkTransaction(uri("http://www.childItem.com"), root, bmStartIndex, "childItem");
+  var folderWChildItemTxn = new PlacesCreateFolderTransaction("Folder", root, bmStartIndex, null, [childItemTxn]);
   try {
-    ptSvc.doTransaction(folderWChildItemTxn);
+    txnManager.doTransaction(folderWChildItemTxn);
     var childItemId = (bmsvc.getBookmarkIdsForURI(uri("http://www.childItem.com")))[0];
     do_check_eq(observer._itemAddedId, childItemId);
     do_check_eq(observer._itemAddedIndex, 0);
     do_check_true(bmsvc.isBookmarked(uri("http://www.childItem.com")));
     folderWChildItemTxn.undoTransaction();
     do_check_false(bmsvc.isBookmarked(uri("http://www.childItem.com")));
     folderWChildItemTxn.redoTransaction();
     var newchildItemId = (bmsvc.getBookmarkIdsForURI(uri("http://www.childItem.com")))[0];
rename from browser/components/places/tests/unit/test_txnGUIDs.js
rename to toolkit/components/places/tests/unit/test_txnGUIDs.js
--- a/toolkit/components/places/tests/unit/xpcshell.ini
+++ b/toolkit/components/places/tests/unit/xpcshell.ini
@@ -123,9 +123,11 @@ skip-if = os == "android"
 [test_update_frecency_after_delete.js]
 # Bug 676989: test hangs consistently on Android
 skip-if = os == "android"
 [test_utils_backups_create.js]
 [test_utils_getURLsForContainerNode.js]
 [test_utils_setAnnotationsFor.js]
 [test_PlacesUtils_asyncGetBookmarkIds.js]
 [test_PlacesUtils_lazyobservers.js]
+[test_placesTxn.js]
+[test_txnGUIDs.js]
 [test_telemetry.js]