merge m-c to fx-team
authorTim Taubert <tim.taubert@gmx.de>
Wed, 28 Mar 2012 00:33:42 +0200
changeset 93709 244991519f53e0f7c54cdd80b59621e5bc69669d
parent 93703 1db916a98bd4f63839aa67d9b6bc8efc24bcef45 (current diff)
parent 93708 fb41b10cd782fa44168fc4c996598ec8d4178291 (diff)
child 93710 4f8b9ff09a8a3453ef618b64bf3702b7e670a19c
child 93807 59df0ebdf0f93ab98e2f0cfacb661198593096ff
child 93824 77f73d3a0d47a7ad714aba1b775e5aebb5d19711
push id886
push userlsblakk@mozilla.com
push dateMon, 04 Jun 2012 19:57:52 +0000
treeherdermozilla-beta@bbd8d5efd6d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone14.0a1
first release with
nightly linux32
244991519f53 / 14.0a1 / 20120328031211 / files
nightly linux64
244991519f53 / 14.0a1 / 20120328031211 / files
nightly mac
244991519f53 / 14.0a1 / 20120328031211 / files
nightly win32
244991519f53 / 14.0a1 / 20120328031211 / files
nightly win64
244991519f53 / 14.0a1 / 20120328031211 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
merge m-c to fx-team
browser/installer/windows/nsis/shared.nsh
browser/installer/windows/nsis/uninstaller.nsi
modules/libpref/src/init/all.js
--- a/browser/base/content/newtab/drop.js
+++ b/browser/base/content/newtab/drop.js
@@ -39,31 +39,30 @@ let gDrop = {
       this._rearrange();
     }
   },
 
   /**
    * Handles the 'drop' event.
    * @param aCell The drop target cell.
    * @param aEvent The 'dragexit' event.
-   * @param aCallback The callback to call when the drop is finished.
    */
-  drop: function Drop_drop(aCell, aEvent, aCallback) {
+  drop: function Drop_drop(aCell, aEvent) {
     // The cell that is the drop target could contain a pinned site. We need
     // to find out where that site has gone and re-pin it there.
     if (aCell.containsPinnedSite())
       this._repinSitesAfterDrop(aCell);
 
     // Pin the dragged or insert the new site.
     this._pinDraggedSite(aCell, aEvent);
 
     this._cancelDelayedArrange();
 
     // Update the grid and move all sites to their new places.
-    gUpdater.updateGrid(aCallback);
+    gUpdater.updateGrid();
   },
 
   /**
    * Re-pins all pinned sites in their (new) positions.
    * @param aCell The drop target cell.
    */
   _repinSitesAfterDrop: function Drop_repinSitesAfterDrop(aCell) {
     let sites = gDropPreview.rearrange(aCell);
--- a/browser/base/content/newtab/sites.js
+++ b/browser/base/content/newtab/sites.js
@@ -56,46 +56,44 @@ Site.prototype = {
       aIndex = this.cell.index;
 
     this._updateAttributes(true);
     gPinnedLinks.pin(this._link, aIndex);
   },
 
   /**
    * Unpins the site and calls the given callback when done.
-   * @param aCallback The callback to be called when finished.
    */
-  unpin: function Site_unpin(aCallback) {
+  unpin: function Site_unpin() {
     if (this.isPinned()) {
       this._updateAttributes(false);
       gPinnedLinks.unpin(this._link);
-      gUpdater.updateGrid(aCallback);
+      gUpdater.updateGrid();
     }
   },
 
   /**
    * Checks whether this site is pinned.
    * @return Whether this site is pinned.
    */
   isPinned: function Site_isPinned() {
     return gPinnedLinks.isPinned(this._link);
   },
 
   /**
    * Blocks the site (removes it from the grid) and calls the given callback
    * when done.
-   * @param aCallback The function to be called when finished.
    */
-  block: function Site_block(aCallback) {
+  block: function Site_block() {
     if (gBlockedLinks.isBlocked(this._link)) {
       if (aCallback)
         aCallback();
     } else {
       gBlockedLinks.block(this._link);
-      gUpdater.updateGrid(aCallback);
+      gUpdater.updateGrid();
     }
   },
 
   /**
    * Gets the DOM node specified by the given query selector.
    * @param aSelector The query selector.
    * @return The DOM node we found.
    */
--- a/browser/base/content/test/newtab/browser_newtab_block.js
+++ b/browser/base/content/test/newtab/browser_newtab_block.js
@@ -10,52 +10,52 @@ function runTests() {
   // we remove sites and expect the gaps to be filled as long as there still
   // are some sites available
   setLinks("0,1,2,3,4,5,6,7,8,9");
   setPinnedLinks("");
 
   yield addNewTabPageTab();
   checkGrid("0,1,2,3,4,5,6,7,8");
 
-  yield blockCell(cells[4]);
+  yield blockCell(4);
   checkGrid("0,1,2,3,5,6,7,8,9");
 
-  yield blockCell(cells[4]);
+  yield blockCell(4);
   checkGrid("0,1,2,3,6,7,8,9,");
 
-  yield blockCell(cells[4]);
+  yield blockCell(4);
   checkGrid("0,1,2,3,7,8,9,,");
 
   // we removed a pinned site
   yield restore();
   setLinks("0,1,2,3,4,5,6,7,8");
   setPinnedLinks(",1");
 
   yield addNewTabPageTab();
   checkGrid("0,1p,2,3,4,5,6,7,8");
 
-  yield blockCell(cells[1]);
+  yield blockCell(1);
   checkGrid("0,2,3,4,5,6,7,8,");
 
   // we remove the last site on the grid (which is pinned) and expect the gap
   // to be re-filled and the new site to be unpinned
   yield restore();
   setLinks("0,1,2,3,4,5,6,7,8,9");
   setPinnedLinks(",,,,,,,,8");
 
   yield addNewTabPageTab();
   checkGrid("0,1,2,3,4,5,6,7,8p");
 
-  yield blockCell(cells[8]);
+  yield blockCell(8);
   checkGrid("0,1,2,3,4,5,6,7,9");
 
   // we remove the first site on the grid with the last one pinned. all cells
   // but the last one should shift to the left and a new site fades in
   yield restore();
   setLinks("0,1,2,3,4,5,6,7,8,9");
   setPinnedLinks(",,,,,,,,8");
 
   yield addNewTabPageTab();
   checkGrid("0,1,2,3,4,5,6,7,8p");
 
-  yield blockCell(cells[0]);
+  yield blockCell(0);
   checkGrid("1,2,3,4,5,6,7,9,8p");
 }
--- a/browser/base/content/test/newtab/browser_newtab_bug722273.js
+++ b/browser/base/content/test/newtab/browser_newtab_bug722273.js
@@ -15,31 +15,22 @@ let {NewTabUtils, Sanitizer} = tmp;
 let bhist = Cc["@mozilla.org/browser/global-history;2"]
   .getService(Ci.nsIBrowserHistory);
 
 function runTests() {
   clearHistory();
   fillHistory();
   yield addNewTabPageTab();
 
-  is(cells[0].site.url, URL, "first site is our fake site");
+  is(getCell(0).site.url, URL, "first site is our fake site");
 
-  let page = {
-    update: function () {
-      executeSoon(TestRunner.next);
-    },
-
-    observe: function () {}
-  };
-
-  NewTabUtils.allPages.register(page);
+  whenPagesUpdated();
   yield clearHistory();
 
-  NewTabUtils.allPages.unregister(page);
-  ok(!cells[0].site, "the fake site is gone");
+  ok(!getCell(0).site, "the fake site is gone");
 }
 
 function fillHistory() {
   let uri = makeURI(URL);
   for (let i = 59; i > 0; i--)
     bhist.addPageWithDetails(uri, "fake site", NOW - i * 60 * 1000000);
 }
 
--- a/browser/base/content/test/newtab/browser_newtab_bug723102.js
+++ b/browser/base/content/test/newtab/browser_newtab_bug723102.js
@@ -9,10 +9,10 @@ function runTests() {
   yield addNewTabPageTab();
   let firstTab = gBrowser.selectedTab;
 
   yield addNewTabPageTab();
   gBrowser.removeTab(firstTab);
 
   ok(NewTabUtils.allPages.enabled, true, "page is enabled");
   NewTabUtils.allPages.enabled = false;
-  ok(cw.gGrid.node.hasAttribute("page-disabled"), "page is disabled");
+  ok(getGrid().node.hasAttribute("page-disabled"), "page is disabled");
 }
--- a/browser/base/content/test/newtab/browser_newtab_bug723121.js
+++ b/browser/base/content/test/newtab/browser_newtab_bug723121.js
@@ -3,46 +3,28 @@
 
 function runTests() {
   setLinks("0,1,2,3,4,5,6,7,8");
   setPinnedLinks("");
 
   yield addNewTabPageTab();
   checkGridLocked(false, "grid is unlocked");
 
-  let cell = cells[0].node;
-  let site = cells[0].site.node;
+  let cell = getCell(0).node;
+  let site = getCell(0).site.node;
   let link = site.querySelector(".newtab-link");
 
-  sendDragEvent(link, "dragstart");
+  sendDragEvent("dragstart", link);
   checkGridLocked(true, "grid is now locked");
 
-  sendDragEvent(link, "dragend");
+  sendDragEvent("dragend", link);
   checkGridLocked(false, "grid isn't locked anymore");
 
-  sendDragEvent(cell, "dragstart");
+  sendDragEvent("dragstart", cell);
   checkGridLocked(false, "grid isn't locked - dragstart was ignored");
 
-  sendDragEvent(site, "dragstart");
+  sendDragEvent("dragstart", site);
   checkGridLocked(false, "grid isn't locked - dragstart was ignored");
 }
 
 function checkGridLocked(aLocked, aMessage) {
-  is(cw.gGrid.node.hasAttribute("locked"), aLocked, aMessage);
+  is(getGrid().node.hasAttribute("locked"), aLocked, aMessage);
 }
-
-function sendDragEvent(aNode, aType) {
-  let ifaceReq = cw.QueryInterface(Ci.nsIInterfaceRequestor);
-  let windowUtils = ifaceReq.getInterface(Ci.nsIDOMWindowUtils);
-
-  let dataTransfer = {
-    mozUserCancelled: false,
-    setData: function () null,
-    setDragImage: function () null,
-    getData: function () "about:blank"
-  };
-
-  let event = cw.document.createEvent("DragEvents");
-  event.initDragEvent(aType, true, true, cw, 0, 0, 0, 0, 0,
-                      false, false, false, false, 0, null, dataTransfer);
-
-  windowUtils.dispatchDOMEventViaPresShell(aNode, event, true);
-}
--- a/browser/base/content/test/newtab/browser_newtab_bug725996.js
+++ b/browser/base/content/test/newtab/browser_newtab_bug725996.js
@@ -3,50 +3,21 @@
 
 function runTests() {
   setLinks("0,1,2,3,4,5,6,7,8");
   setPinnedLinks("");
 
   yield addNewTabPageTab();
   checkGrid("0,1,2,3,4,5,6,7,8");
 
-  let cell = cells[0].node;
+  let cell = getCell(0).node;
 
-  sendDropEvent(cell, "about:blank#99\nblank");
+  sendDragEvent("drop", cell, "about:blank#99\nblank");
   is(NewTabUtils.pinnedLinks.links[0].url, "about:blank#99",
      "first cell is pinned and contains the dropped site");
 
   yield whenPagesUpdated();
   checkGrid("99p,0,1,2,3,4,5,6,7");
 
-  sendDropEvent(cell, "");
+  sendDragEvent("drop", cell, "");
   is(NewTabUtils.pinnedLinks.links[0].url, "about:blank#99",
      "first cell is still pinned with the site we dropped before");
 }
-
-function sendDropEvent(aNode, aData) {
-  let ifaceReq = cw.QueryInterface(Ci.nsIInterfaceRequestor);
-  let windowUtils = ifaceReq.getInterface(Ci.nsIDOMWindowUtils);
-
-  let dataTransfer = {
-    mozUserCancelled: false,
-    setData: function () null,
-    setDragImage: function () null,
-    getData: function () aData,
-
-    types: {
-      contains: function (aType) aType == "text/x-moz-url"
-    },
-
-    mozGetDataAt: function (aType, aIndex) {
-      if (aIndex || aType != "text/x-moz-url")
-        return null;
-
-      return aData;
-    },
-  };
-
-  let event = cw.document.createEvent("DragEvents");
-  event.initDragEvent("drop", true, true, cw, 0, 0, 0, 0, 0,
-                      false, false, false, false, 0, null, dataTransfer);
-
-  windowUtils.dispatchDOMEventViaPresShell(aNode, event, true);
-}
--- a/browser/base/content/test/newtab/browser_newtab_bug734043.js
+++ b/browser/base/content/test/newtab/browser_newtab_bug734043.js
@@ -4,22 +4,23 @@
 function runTests() {
   setLinks("0,1,2,3,4,5,6,7,8");
   setPinnedLinks("");
 
   yield addNewTabPageTab();
   checkGrid("0,1,2,3,4,5,6,7,8");
 
   let receivedError = false;
-  let block = cw.document.querySelector(".newtab-control-block");
+  let block = getContentDocument().querySelector(".newtab-control-block");
 
   function onError() {
     receivedError = true;
   }
 
+  let cw = getContentWindow();
   cw.addEventListener("error", onError);
 
   for (let i = 0; i < 3; i++)
     EventUtils.synthesizeMouseAtCenter(block, {}, cw);
 
   yield whenPagesUpdated();
   ok(!receivedError, "we got here without any errors");
   cw.removeEventListener("error", onError);
--- a/browser/base/content/test/newtab/browser_newtab_bug735987.js
+++ b/browser/base/content/test/newtab/browser_newtab_bug735987.js
@@ -3,20 +3,20 @@
 
 function runTests() {
   setLinks("0,1,2,3,4,5,6,7,8");
   setPinnedLinks("");
 
   yield addNewTabPageTab();
   checkGrid("0,1,2,3,4,5,6,7,8");
 
-  yield simulateDrop(cells[1]);
+  yield simulateDrop(1);
   checkGrid("0,99p,1,2,3,4,5,6,7");
 
-  yield blockCell(cells[1]);
+  yield blockCell(1);
   checkGrid("0,1,2,3,4,5,6,7,8");
 
-  yield simulateDrop(cells[1]);
+  yield simulateDrop(1);
   checkGrid("0,99p,1,2,3,4,5,6,7");
 
-  yield blockCell(cells[1]);
+  yield blockCell(1);
   checkGrid("0,1,2,3,4,5,6,7,8");
 }
--- a/browser/base/content/test/newtab/browser_newtab_disable.js
+++ b/browser/base/content/test/newtab/browser_newtab_disable.js
@@ -6,29 +6,29 @@
  * decides not to use it.
  */
 function runTests() {
   // create a new tab page and hide it.
   setLinks("0,1,2,3,4,5,6,7,8");
   setPinnedLinks("");
 
   yield addNewTabPageTab();
-  let gridNode = cw.gGrid.node;
+  let gridNode = getGrid().node;
 
   ok(!gridNode.hasAttribute("page-disabled"), "page is not disabled");
 
   NewTabUtils.allPages.enabled = false;
   ok(gridNode.hasAttribute("page-disabled"), "page is disabled");
 
-  let oldGridNode = cw.gGrid.node;
+  let oldGridNode = gridNode;
 
   // create a second new tage page and make sure it's disabled. enable it
   // again and check if the former page gets enabled as well.
   yield addNewTabPageTab();
   ok(gridNode.hasAttribute("page-disabled"), "page is disabled");
 
   // check that no sites have been rendered
-  is(0, cw.document.querySelectorAll(".site").length, "no sites have been rendered");
+  is(0, getContentDocument().querySelectorAll(".site").length, "no sites have been rendered");
 
   NewTabUtils.allPages.enabled = true;
   ok(!gridNode.hasAttribute("page-disabled"), "page is not disabled");
   ok(!oldGridNode.hasAttribute("page-disabled"), "old page is not disabled");
 }
--- a/browser/base/content/test/newtab/browser_newtab_drag_drop.js
+++ b/browser/base/content/test/newtab/browser_newtab_drag_drop.js
@@ -10,106 +10,106 @@
 function runTests() {
   // test a simple drag-and-drop scenario
   setLinks("0,1,2,3,4,5,6,7,8");
   setPinnedLinks("");
 
   yield addNewTabPageTab();
   checkGrid("0,1,2,3,4,5,6,7,8");
 
-  yield simulateDrop(cells[1], cells[0]);
+  yield simulateDrop(1, 0);
   checkGrid("1,0p,2,3,4,5,6,7,8");
 
   // drag a cell to its current cell and make sure it's not pinned afterwards
   setLinks("0,1,2,3,4,5,6,7,8");
   setPinnedLinks("");
 
   yield addNewTabPageTab();
   checkGrid("0,1,2,3,4,5,6,7,8");
 
-  yield simulateDrop(cells[0], cells[0]);
+  yield simulateDrop(0, 0);
   checkGrid("0,1,2,3,4,5,6,7,8");
 
   // ensure that pinned pages aren't moved if that's not necessary
   setLinks("0,1,2,3,4,5,6,7,8");
   setPinnedLinks(",1,2");
 
   yield addNewTabPageTab();
   checkGrid("0,1p,2p,3,4,5,6,7,8");
 
-  yield simulateDrop(cells[3], cells[0]);
+  yield simulateDrop(3, 0);
   checkGrid("3,1p,2p,0p,4,5,6,7,8");
 
   // pinned sites should always be moved around as blocks. if a pinned site is
   // moved around, neighboring pinned are affected as well
   setLinks("0,1,2,3,4,5,6,7,8");
   setPinnedLinks("0,1");
 
   yield addNewTabPageTab();
   checkGrid("0p,1p,2,3,4,5,6,7,8");
 
-  yield simulateDrop(cells[0], cells[2]);
+  yield simulateDrop(0, 2);
   checkGrid("2p,0p,1p,3,4,5,6,7,8");
 
   // pinned sites should not be pushed out of the grid (unless there are only
   // pinned ones left on the grid)
   setLinks("0,1,2,3,4,5,6,7,8");
   setPinnedLinks(",,,,,,,7,8");
 
   yield addNewTabPageTab();
   checkGrid("0,1,2,3,4,5,6,7p,8p");
 
-  yield simulateDrop(cells[8], cells[2]);
+  yield simulateDrop(8, 2);
   checkGrid("0,1,3,4,5,6,7p,8p,2p");
 
   // make sure that pinned sites are re-positioned correctly
   setLinks("0,1,2,3,4,5,6,7,8");
   setPinnedLinks("0,1,2,,,5");
 
   yield addNewTabPageTab();
   checkGrid("0p,1p,2p,3,4,5p,6,7,8");
 
-  yield simulateDrop(cells[4], cells[0]);
+  yield simulateDrop(4, 0);
   checkGrid("3,1p,2p,4,0p,5p,6,7,8");
 
   // drag a new site onto the very first cell
   setLinks("0,1,2,3,4,5,6,7,8");
   setPinnedLinks(",,,,,,,7,8");
 
   yield addNewTabPageTab();
   checkGrid("0,1,2,3,4,5,6,7p,8p");
 
-  yield simulateDrop(cells[0]);
+  yield simulateDrop(0);
   checkGrid("99p,0,1,2,3,4,5,7p,8p");
 
   // drag a new site onto the grid and make sure that pinned cells don't get
   // pushed out
   setLinks("0,1,2,3,4,5,6,7,8");
   setPinnedLinks(",,,,,,,7,8");
 
   yield addNewTabPageTab();
   checkGrid("0,1,2,3,4,5,6,7p,8p");
 
-  yield simulateDrop(cells[7]);
+  yield simulateDrop(7);
   checkGrid("0,1,2,3,4,5,7p,99p,8p");
 
   // drag a new site beneath a pinned cell and make sure the pinned cell is
   // not moved
   setLinks("0,1,2,3,4,5,6,7,8");
   setPinnedLinks(",,,,,,,,8");
 
   yield addNewTabPageTab();
   checkGrid("0,1,2,3,4,5,6,7,8p");
 
-  yield simulateDrop(cells[7]);
+  yield simulateDrop(7);
   checkGrid("0,1,2,3,4,5,6,99p,8p");
 
   // drag a new site onto a block of pinned sites and make sure they're shifted
   // around accordingly
   setLinks("0,1,2,3,4,5,6,7,8");
   setPinnedLinks("0,1,2,,,,,,");
 
   yield addNewTabPageTab();
   checkGrid("0p,1p,2p");
 
-  yield simulateDrop(cells[1]);
+  yield simulateDrop(1);
   checkGrid("0p,99p,1p,2p,3,4,5,6,7");
 }
--- a/browser/base/content/test/newtab/browser_newtab_drop_preview.js
+++ b/browser/base/content/test/newtab/browser_newtab_drop_preview.js
@@ -8,14 +8,15 @@
 function runTests() {
   // the first three sites are pinned - make sure they're re-arranged correctly
   setLinks("0,1,2,3,4,5,6,7,8");
   setPinnedLinks("0,1,2,,,5");
 
   yield addNewTabPageTab();
   checkGrid("0p,1p,2p,3,4,5p,6,7,8");
 
-  cw.gDrag._draggedSite = cells[0].site;
-  let sites = cw.gDropPreview.rearrange(cells[4]);
+  let cw = getContentWindow();
+  cw.gDrag._draggedSite = getCell(0).site;
+  let sites = cw.gDropPreview.rearrange(getCell(4));
   cw.gDrag._draggedSite = null;
 
   checkGrid("3,1p,2p,4,0p,5p,6,7,8", sites);
 }
--- a/browser/base/content/test/newtab/browser_newtab_private_browsing.js
+++ b/browser/base/content/test/newtab/browser_newtab_private_browsing.js
@@ -11,31 +11,31 @@ let pb = Cc["@mozilla.org/privatebrowsin
          .getService(Ci.nsIPrivateBrowsingService);
 
 function runTests() {
   // prepare the grid
   setLinks("0,1,2,3,4,5,6,7,8,9");
   ok(!pb.privateBrowsingEnabled, "private browsing is disabled");
 
   yield addNewTabPageTab();
-  pinCell(cells[0]);
+  pinCell(0);
   checkGrid("0p,1,2,3,4,5,6,7,8");
 
   // enter private browsing mode
   yield togglePrivateBrowsing();
   ok(pb.privateBrowsingEnabled, "private browsing is enabled");
 
   yield addNewTabPageTab();
   checkGrid("0p,1,2,3,4,5,6,7,8");
 
   // modify the grid while we're in pb mode
-  yield blockCell(cells[1]);
+  yield blockCell(1);
   checkGrid("0p,2,3,4,5,6,7,8");
 
-  yield unpinCell(cells[0]);
+  yield unpinCell(0);
   checkGrid("0,2,3,4,5,6,7,8");
 
   // exit private browsing mode
   yield togglePrivateBrowsing();
   ok(!pb.privateBrowsingEnabled, "private browsing is disabled");
 
   // check that the grid is the same as before entering pb mode
   yield addNewTabPageTab();
--- a/browser/base/content/test/newtab/browser_newtab_reset.js
+++ b/browser/base/content/test/newtab/browser_newtab_reset.js
@@ -8,21 +8,21 @@ function runTests() {
   // Disabled until bug 716543 is fixed.
   return;
 
   // create a new tab page and check its modified state after blocking a site
   setLinks("0,1,2,3,4,5,6,7,8");
   setPinnedLinks("");
 
   yield addNewTabPageTab();
-  let resetButton = cw.document.getElementById("toolbar-button-reset");
+  let resetButton = getContentDocument().getElementById("toolbar-button-reset");
 
   checkGrid("0,1,2,3,4,5,6,7,8");
   ok(!resetButton.hasAttribute("modified"), "page is not modified");
 
-  yield blockCell(cells[4]);
+  yield blockCell(4);
   checkGrid("0,1,2,3,5,6,7,8,");
   ok(resetButton.hasAttribute("modified"), "page is modified");
 
-  yield cw.gToolbar.reset(TestRunner.next);
+  yield getContentWindow().gToolbar.reset(TestRunner.next);
   checkGrid("0,1,2,3,4,5,6,7,8");
   ok(!resetButton.hasAttribute("modified"), "page is not modified");
 }
--- a/browser/base/content/test/newtab/browser_newtab_tabsync.js
+++ b/browser/base/content/test/newtab/browser_newtab_tabsync.js
@@ -12,50 +12,50 @@ function runTests() {
   return;
 
   setLinks("0,1,2,3,4,5,6,7,8,9");
   setPinnedLinks(",1");
 
   yield addNewTabPageTab();
   checkGrid("0,1p,2,3,4,5,6,7,8");
 
-  let resetButton = cw.document.getElementById("toolbar-button-reset");
+  let resetButton = getContentDocument().getElementById("toolbar-button-reset");
   ok(!resetButton.hasAttribute("modified"), "page is not modified");
 
-  let oldCw = cw;
+  let oldSites = getGrid().sites;
   let oldResetButton = resetButton;
 
   // create the new tab page
   yield addNewTabPageTab();
   checkGrid("0,1p,2,3,4,5,6,7,8");
 
-  resetButton = cw.document.getElementById("toolbar-button-reset");
+  resetButton = getContentDocument().getElementById("toolbar-button-reset");
   ok(!resetButton.hasAttribute("modified"), "page is not modified");
 
   // unpin a cell
-  yield unpinCell(cells[1]);
+  yield unpinCell(1);
   checkGrid("0,1,2,3,4,5,6,7,8");
-  checkGrid("0,1,2,3,4,5,6,7,8", oldCw.gGrid.sites);
+  checkGrid("0,1,2,3,4,5,6,7,8", oldSites);
 
   // remove a cell
-  yield blockCell(cells[1]);
+  yield blockCell(1);
   checkGrid("0,2,3,4,5,6,7,8,9");
-  checkGrid("0,2,3,4,5,6,7,8,9", oldCw.gGrid.sites);
+  checkGrid("0,2,3,4,5,6,7,8,9", oldSites);
   ok(resetButton.hasAttribute("modified"), "page is modified");
   ok(oldResetButton.hasAttribute("modified"), "page is modified");
 
   // insert a new cell by dragging
-  yield simulateDrop(cells[1]);
+  yield simulateDrop(1);
   checkGrid("0,99p,2,3,4,5,6,7,8");
-  checkGrid("0,99p,2,3,4,5,6,7,8", oldCw.gGrid.sites);
+  checkGrid("0,99p,2,3,4,5,6,7,8", oldSites);
 
   // drag a cell around
-  yield simulateDrop(cells[1], cells[2]);
+  yield simulateDrop(1, 2);
   checkGrid("0,2p,99p,3,4,5,6,7,8");
-  checkGrid("0,2p,99p,3,4,5,6,7,8", oldCw.gGrid.sites);
+  checkGrid("0,2p,99p,3,4,5,6,7,8", oldSites);
 
   // reset the new tab page
-  yield cw.gToolbar.reset(TestRunner.next);
+  yield getContentWindow().gToolbar.reset(TestRunner.next);
   checkGrid("0,1,2,3,4,5,6,7,8");
-  checkGrid("0,1,2,3,4,5,6,7,8", oldCw.gGrid.sites);
+  checkGrid("0,1,2,3,4,5,6,7,8", oldSites);
   ok(!resetButton.hasAttribute("modified"), "page is not modified");
   ok(!oldResetButton.hasAttribute("modified"), "page is not modified");
 }
--- a/browser/base/content/test/newtab/browser_newtab_unpin.js
+++ b/browser/base/content/test/newtab/browser_newtab_unpin.js
@@ -9,48 +9,48 @@ function runTests() {
   // we have a pinned link that didn't change its position since it was pinned.
   // nothing should happend when we unpin it.
   setLinks("0,1,2,3,4,5,6,7,8");
   setPinnedLinks(",1");
 
   yield addNewTabPageTab();
   checkGrid("0,1p,2,3,4,5,6,7,8");
 
-  yield unpinCell(cells[1]);
+  yield unpinCell(1);
   checkGrid("0,1,2,3,4,5,6,7,8");
 
   // we have a pinned link that is not anymore in the list of the most-visited
   // links. this should disappear, the remaining links adjust their positions
   // and a new link will appear at the end of the grid.
   setLinks("0,1,2,3,4,5,6,7,8");
   setPinnedLinks(",99");
 
   yield addNewTabPageTab();
   checkGrid("0,99p,1,2,3,4,5,6,7");
 
-  yield unpinCell(cells[1]);
+  yield unpinCell(1);
   checkGrid("0,1,2,3,4,5,6,7,8");
 
   // we have a pinned link that changed its position since it was pinned. it
   // should be moved to its new position after being unpinned.
   setLinks("0,1,2,3,4,5,6,7");
   setPinnedLinks(",1,,,,,,,0");
 
   yield addNewTabPageTab();
   checkGrid("2,1p,3,4,5,6,7,,0p");
 
-  yield unpinCell(cells[1]);
+  yield unpinCell(1);
   checkGrid("1,2,3,4,5,6,7,,0p");
 
-  yield unpinCell(cells[8]);
+  yield unpinCell(8);
   checkGrid("0,1,2,3,4,5,6,7,");
 
   // we have pinned link that changed its position since it was pinned. the
   // link will disappear from the grid because it's now a much lower priority
   setLinks("0,1,2,3,4,5,6,7,8,9");
   setPinnedLinks("9");
 
   yield addNewTabPageTab();
   checkGrid("9p,0,1,2,3,4,5,6,7");
 
-  yield unpinCell(cells[0]);
+  yield unpinCell(0);
   checkGrid("0,1,2,3,4,5,6,7,8");
 }
--- a/browser/base/content/test/newtab/head.js
+++ b/browser/base/content/test/newtab/head.js
@@ -12,22 +12,16 @@ let NewTabUtils = tmp.NewTabUtils;
 registerCleanupFunction(function () {
   while (gBrowser.tabs.length > 1)
     gBrowser.removeTab(gBrowser.tabs[1]);
 
   Services.prefs.clearUserPref(PREF_NEWTAB_ENABLED);
 });
 
 /**
- * Global variables that are accessed by tests.
- */
-let cw;
-let cells;
-
-/**
  * We'll want to restore the original links provider later.
  */
 let originalProvider = NewTabUtils.links._provider;
 
 /**
  * Provide the default test function to start our test runner.
  */
 function test() {
@@ -77,16 +71,49 @@ let TestRunner = {
     if (numCallbacks)
       callbacks.splice(0, numCallbacks, cleanupAndFinish);
     else
       cleanupAndFinish();
   }
 };
 
 /**
+ * Returns the selected tab's content window.
+ * @return The content window.
+ */
+function getContentWindow() {
+  return gBrowser.selectedBrowser.contentWindow;
+}
+
+/**
+ * Returns the selected tab's content document.
+ * @return The content document.
+ */
+function getContentDocument() {
+  return gBrowser.selectedBrowser.contentDocument;
+}
+
+/**
+ * Returns the newtab grid of the selected tab.
+ * @return The newtab grid.
+ */
+function getGrid() {
+  return getContentWindow().gGrid;
+}
+
+/**
+ * Returns the cell at the given index of the selected tab's newtab grid.
+ * @param aIndex The cell index.
+ * @return The newtab cell.
+ */
+function getCell(aIndex) {
+  return getGrid().cells[aIndex];
+}
+
+/**
  * Allows to provide a list of links that is used to construct the grid.
  * @param aLinksPattern the pattern (see below)
  *
  * Example: setLinks("1,2,3")
  * Result: [{url: "about:blank#1", title: "site#1"},
  *          {url: "about:blank#2", title: "site#2"}
  *          {url: "about:blank#3", title: "site#3"}]
  */
@@ -138,154 +165,150 @@ function restore() {
 function addNewTabPageTab() {
   let tab = gBrowser.selectedTab = gBrowser.addTab("about:newtab");
   let browser = tab.linkedBrowser;
 
   // Wait for the new tab page to be loaded.
   browser.addEventListener("load", function onLoad() {
     browser.removeEventListener("load", onLoad, true);
 
-    cw = browser.contentWindow;
-
     if (NewTabUtils.allPages.enabled) {
       // Continue when the link cache has been populated.
       NewTabUtils.links.populateCache(function () {
-        cells = cw.gGrid.cells;
         executeSoon(TestRunner.next);
       });
     } else {
       TestRunner.next();
     }
-
   }, true);
 }
 
 /**
  * Compares the current grid arrangement with the given pattern.
  * @param the pattern (see below)
  * @param the array of sites to compare with (optional)
  *
  * Example: checkGrid("3p,2,,1p")
  * Result: We expect the first cell to contain the pinned site 'about:blank#3'.
  *         The second cell contains 'about:blank#2'. The third cell is empty.
  *         The fourth cell contains the pinned site 'about:blank#4'.
  */
 function checkGrid(aSitesPattern, aSites) {
-  let valid = true;
-
-  aSites = aSites || cw.gGrid.sites;
-
-  aSitesPattern.split(/\s*,\s*/).forEach(function (id, index) {
-    let site = aSites[index];
-    let match = id.match(/^\d+/);
-
-    // We expect the cell to be empty.
-    if (!match) {
-      if (site) {
-        valid = false;
-        ok(false, "expected cell#" + index + " to be empty");
-      }
-
-      return;
-    }
-
-    // We expect the cell to contain a site.
-    if (!site) {
-      valid = false;
-      ok(false, "didn't expect cell#" + index + " to be empty");
-
-      return;
-    }
-
-    let num = match[0];
+  let length = aSitesPattern.split(",").length;
+  let sites = (aSites || getGrid().sites).slice(0, length);
+  let expected = sites.map(function (aSite) {
+    if (!aSite)
+      return "";
 
-    // Check the site's url.
-    if (site.url != "about:blank#" + num) {
-      valid = false;
-      is(site.url, "about:blank#" + num, "cell#" + index + " has the wrong url");
-    }
-
-    let shouldBePinned = /p$/.test(id);
-    let cellContainsPinned = site.isPinned();
-    let cssClassPinned = site.node && site.node.querySelector(".newtab-control-pin").hasAttribute("pinned");
+    let pinned = aSite.isPinned();
+    let pinButton = aSite.node.querySelector(".newtab-control-pin");
+    let hasPinnedAttr = pinButton.hasAttribute("pinned");
 
-    // Check if the site should be and is pinned.
-    if (shouldBePinned) {
-      if (!cellContainsPinned) {
-        valid = false;
-        ok(false, "expected cell#" + index + " to be pinned");
-      } else if (!cssClassPinned) {
-        valid = false;
-        ok(false, "expected cell#" + index + " to have css class 'pinned'");
-      }
-    } else {
-      if (cellContainsPinned) {
-        valid = false;
-        ok(false, "didn't expect cell#" + index + " to be pinned");
-      } else if (cssClassPinned) {
-        valid = false;
-        ok(false, "didn't expect cell#" + index + " to have css class 'pinned'");
-      }
-    }
+    if (pinned != hasPinnedAttr)
+      ok(false, "invalid state (site.isPinned() != site[pinned])");
+
+    return aSite.url.replace(/^about:blank#(\d+)$/, "$1") + (pinned ? "p" : "");
   });
 
-  // If every test passed, say so.
-  if (valid)
-    ok(true, "grid status = " + aSitesPattern);
+  is(aSitesPattern, expected, "grid status = " + aSitesPattern);
 }
 
 /**
- * Blocks the given cell's site from the grid.
- * @param aCell the cell that contains the site to block
+ * Blocks a site from the grid.
+ * @param aIndex The cell index.
  */
-function blockCell(aCell) {
-  aCell.site.block(function () executeSoon(TestRunner.next));
+function blockCell(aIndex) {
+  whenPagesUpdated();
+  getCell(aIndex).site.block();
 }
 
 /**
- * Pins a given cell's site on a given position.
- * @param aCell the cell that contains the site to pin
- * @param aIndex the index the defines where the site should be pinned
+ * Pins a site on a given position.
+ * @param aIndex The cell index.
+ * @param aPinIndex The index the defines where the site should be pinned.
  */
-function pinCell(aCell, aIndex) {
-  aCell.site.pin(aIndex);
+function pinCell(aIndex, aPinIndex) {
+  getCell(aIndex).site.pin(aPinIndex);
 }
 
 /**
  * Unpins the given cell's site.
- * @param aCell the cell that contains the site to unpin
+ * @param aIndex The cell index.
  */
-function unpinCell(aCell) {
-  aCell.site.unpin(function () executeSoon(TestRunner.next));
+function unpinCell(aIndex) {
+  whenPagesUpdated();
+  getCell(aIndex).site.unpin();
 }
 
 /**
  * Simulates a drop and drop operation.
- * @param aDropTarget the cell that is the drop target
- * @param aDragSource the cell that contains the dragged site (optional)
+ * @param aDropIndex The cell index of the drop target.
+ * @param aDragIndex The cell index containing the dragged site (optional).
+ */
+function simulateDrop(aDropIndex, aDragIndex) {
+  let draggedSite;
+  let {gDrag: drag, gDrop: drop} = getContentWindow();
+  let event = createDragEvent("drop", "about:blank#99\nblank");
+
+  if (typeof aDragIndex != "undefined")
+    draggedSite = getCell(aDragIndex).site;
+
+  if (draggedSite)
+    drag.start(draggedSite, event);
+
+  whenPagesUpdated();
+  drop.drop(getCell(aDropIndex), event);
+
+  if (draggedSite)
+    drag.end(draggedSite);
+}
+
+/**
+ * Sends a custom drag event to a given DOM element.
+ * @param aEventType The drag event's type.
+ * @param aTarget The DOM element that the event is dispatched to.
+ * @param aData The event's drag data (optional).
  */
-function simulateDrop(aDropTarget, aDragSource) {
-  let event = {
-    clientX: 0,
-    clientY: 0,
-    dataTransfer: {
-      mozUserCancelled: false,
-      setData: function () null,
-      setDragImage: function () null,
-      getData: function () "about:blank#99\nblank"
+function sendDragEvent(aEventType, aTarget, aData) {
+  let event = createDragEvent(aEventType, aData);
+  let ifaceReq = getContentWindow().QueryInterface(Ci.nsIInterfaceRequestor);
+  let windowUtils = ifaceReq.getInterface(Ci.nsIDOMWindowUtils);
+  windowUtils.dispatchDOMEventViaPresShell(aTarget, event, true);
+}
+
+/**
+ * Creates a custom drag event.
+ * @param aEventType The drag event's type.
+ * @param aData The event's drag data (optional).
+ * @return The drag event.
+ */
+function createDragEvent(aEventType, aData) {
+  let dataTransfer = {
+    mozUserCancelled: false,
+    setData: function () null,
+    setDragImage: function () null,
+    getData: function () aData,
+
+    types: {
+      contains: function (aType) aType == "text/x-moz-url"
+    },
+
+    mozGetDataAt: function (aType, aIndex) {
+      if (aIndex || aType != "text/x-moz-url")
+        return null;
+
+      return aData;
     }
   };
 
-  if (aDragSource)
-    cw.gDrag.start(aDragSource.site, event);
+  let event = getContentDocument().createEvent("DragEvents");
+  event.initDragEvent(aEventType, true, true, getContentWindow(), 0, 0, 0, 0, 0,
+                      false, false, false, false, 0, null, dataTransfer);
 
-  cw.gDrop.drop(aDropTarget, event, function () executeSoon(TestRunner.next));
-
-  if (aDragSource)
-    cw.gDrag.end(aDragSource.site);
+  return event;
 }
 
 /**
  * Resumes testing when all pages have been updated.
  */
 function whenPagesUpdated(aCallback) {
   let page = {
     update: function () {
--- a/browser/components/nsBrowserContentHandler.js
+++ b/browser/components/nsBrowserContentHandler.js
@@ -742,20 +742,16 @@ nsDefaultCommandLineHandler.prototype = 
   QueryInterface : function dch_QI(iid) {
     if (!iid.equals(nsISupports) &&
         !iid.equals(nsICommandLineHandler))
       throw Components.results.NS_ERROR_NO_INTERFACE;
 
     return this;
   },
 
-  // List of uri's that were passed via the command line without the app
-  // running and have already been handled. This is compared against uri's
-  // opened using DDE on Win32 so we only open one of the requests.
-  _handledURIs: [ ],
 #ifdef XP_WIN
   _haveProfile: false,
 #endif
 
   /* nsICommandLineHandler */
   handle : function dch_handle(cmdLine) {
     var urilist = [];
 
@@ -779,35 +775,18 @@ nsDefaultCommandLineHandler.prototype = 
         cmdLine.preventDefault = true;
       }
     }
 #endif
 
     try {
       var ar;
       while ((ar = cmdLine.handleFlagWithParam("url", false))) {
-        var found = false;
         var uri = resolveURIInternal(cmdLine, ar);
-        // count will never be greater than zero except on Win32.
-        var count = this._handledURIs.length;
-        for (var i = 0; i < count; ++i) {
-          if (this._handledURIs[i].spec == uri.spec) {
-            this._handledURIs.splice(i, 1);
-            found = true;
-            cmdLine.preventDefault = true;
-            break;
-          }
-        }
-        if (!found) {
-          urilist.push(uri);
-          // The requestpending command line flag is only used on Win32.
-          if (cmdLine.handleFlag("requestpending", false) &&
-              cmdLine.state == nsICommandLine.STATE_INITIAL_LAUNCH)
-            this._handledURIs.push(uri)
-        }
+        urilist.push(uri);
       }
     }
     catch (e) {
       Components.utils.reportError(e);
     }
 
     count = cmdLine.length;
 
--- a/browser/components/shell/src/nsWindowsShellService.cpp
+++ b/browser/components/shell/src/nsWindowsShellService.cpp
@@ -72,17 +72,20 @@
 
 #ifdef _WIN32_WINNT
 #undef _WIN32_WINNT
 #endif
 #define _WIN32_WINNT 0x0600
 #define INITGUID
 #include <shlobj.h>
 
+#pragma comment(lib, "shlwapi.lib") // for SHDeleteKeyW
+
 #include <mbstring.h>
+#include <shlwapi.h>
 
 #ifndef MAX_BUF
 #define MAX_BUF 4096
 #endif
 
 #define REG_SUCCEEDED(val) \
   (val == ERROR_SUCCESS)
 
@@ -124,49 +127,40 @@ OpenKeyForReading(HKEY aKeyRoot, const n
 //   are mapped like so:
 //
 //   HKCU\SOFTWARE\Classes\.<ext>\      (default)         REG_SZ     FirefoxHTML
 //
 //   as aliases to the class:
 //
 //   HKCU\SOFTWARE\Classes\FirefoxHTML\
 //     DefaultIcon                      (default)         REG_SZ     <apppath>,1
-//     shell\open\command               (default)         REG_SZ     <apppath> -requestPending -osint -url "%1"
-//     shell\open\ddeexec               (default)         REG_SZ     "%1",,0,0,,,,
-//     shell\open\ddeexec               NoActivateHandler REG_SZ
-//                       \Application   (default)         REG_SZ     Firefox
-//                       \Topic         (default)         REG_SZ     WWW_OpenURL
+//     shell\open\command               (default)         REG_SZ     <apppath> -osint -url "%1"
+//     shell\open\ddeexec               (default)         REG_SZ     <empty string>
 //
-// - Windows Vista Protocol Handler
+// - Windows Vista and above Protocol Handler
 //
 //   HKCU\SOFTWARE\Classes\FirefoxURL\  (default)         REG_SZ     <appname> URL
 //                                      EditFlags         REG_DWORD  2
 //                                      FriendlyTypeName  REG_SZ     <appname> URL
 //     DefaultIcon                      (default)         REG_SZ     <apppath>,1
-//     shell\open\command               (default)         REG_SZ     <apppath> -requestPending -osint -url "%1"
-//     shell\open\ddeexec               (default)         REG_SZ     "%1",,0,0,,,,
-//     shell\open\ddeexec               NoActivateHandler REG_SZ
-//                       \Application   (default)         REG_SZ     Firefox
-//                       \Topic         (default)         REG_SZ     WWW_OpenURL
+//     shell\open\command               (default)         REG_SZ     <apppath> -osint -url "%1"
+//     shell\open\ddeexec               (default)         REG_SZ     <empty string>
 //
 // - Protocol Mappings
 //   -----------------
 //   The following protocols:
 //    HTTP, HTTPS, FTP
 //   are mapped like so:
 //
 //   HKCU\SOFTWARE\Classes\<protocol>\
 //     DefaultIcon                      (default)         REG_SZ     <apppath>,1
-//     shell\open\command               (default)         REG_SZ     <apppath> -requestPending -osint -url "%1"
-//     shell\open\ddeexec               (default)         REG_SZ     "%1",,0,0,,,,
-//     shell\open\ddeexec               NoActivateHandler REG_SZ
-//                       \Application   (default)         REG_SZ     Firefox
-//                       \Topic         (default)         REG_SZ     WWW_OpenURL
+//     shell\open\command               (default)         REG_SZ     <apppath> -osint -url "%1"
+//     shell\open\ddeexec               (default)         REG_SZ     <empty string>
 //
-// - Windows Start Menu (Win2K SP2, XP SP1, and newer)
+// - Windows Start Menu (XP SP1 and newer)
 //   -------------------------------------------------
 //   The following keys are set to make Firefox appear in the Start Menu as the
 //   browser:
 //   
 //   HKCU\SOFTWARE\Clients\StartMenuInternet\FIREFOX.EXE\
 //                                      (default)         REG_SZ     <appname>
 //     DefaultIcon                      (default)         REG_SZ     <apppath>,0
 //     InstallInfo                      HideIconsCommand  REG_SZ     <uninstpath> /HideShortcuts
@@ -175,50 +169,71 @@ OpenKeyForReading(HKEY aKeyRoot, const n
 //     InstallInfo                      ShowIconsCommand  REG_SZ     <uninstpath> /ShowShortcuts
 //     shell\open\command               (default)         REG_SZ     <apppath>
 //     shell\properties                 (default)         REG_SZ     <appname> &Options
 //     shell\properties\command         (default)         REG_SZ     <apppath> -preferences
 //     shell\safemode                   (default)         REG_SZ     <appname> &Safe Mode
 //     shell\safemode\command           (default)         REG_SZ     <apppath> -safe-mode
 //
 
+// The values checked are all default values so the value name is not needed.
 typedef struct {
   char* keyName;
-  char* valueName;
   char* valueData;
+  char* oldValueData;
 } SETTING;
 
 #define APP_REG_NAME L"Firefox"
-#define CLS_HTML "FirefoxHTML"
-#define CLS_URL "FirefoxURL"
-#define VAL_OPEN "\"%APPPATH%\" -requestPending -osint -url \"%1\""
 #define VAL_FILE_ICON "%APPPATH%,1"
+#define VAL_OPEN "\"%APPPATH%\" -osint -url \"%1\""
+#define OLD_VAL_OPEN "\"%APPPATH%\" -requestPending -osint -url \"%1\""
 #define DI "\\DefaultIcon"
-#define SOP "\\shell\\open\\command"
+#define SOC "\\shell\\open\\command"
+#define SOD "\\shell\\open\\ddeexec"
+// Used for updating the FTP protocol handler's shell open command under HKCU.
+#define FTP_SOC L"Software\\Classes\\ftp\\shell\\open\\command"
 
 #define MAKE_KEY_NAME1(PREFIX, MID) \
   PREFIX MID
 
 // The DefaultIcon registry key value should never be used when checking if
 // Firefox is the default browser for file handlers since other applications
 // (e.g. MS Office) may modify the DefaultIcon registry key value to add Icon
 // Handlers. see http://msdn2.microsoft.com/en-us/library/aa969357.aspx for
-// more info.
+// more info. The FTP protocol is not checked so advanced users can set the FTP
+// handler to another application and still have Firefox check if it is the
+// default HTTP and HTTPS handler.
 static SETTING gSettings[] = {
   // File Handler Class
-  { MAKE_KEY_NAME1(CLS_HTML, SOP), "", VAL_OPEN },
+  { MAKE_KEY_NAME1("FirefoxHTML", SOC), VAL_OPEN, OLD_VAL_OPEN },
 
   // Protocol Handler Class - for Vista and above
-  { MAKE_KEY_NAME1(CLS_URL, SOP), "", VAL_OPEN },
+  { MAKE_KEY_NAME1("FirefoxURL", SOC), VAL_OPEN, OLD_VAL_OPEN },
 
   // Protocol Handlers
-  { MAKE_KEY_NAME1("HTTP", DI),    "", VAL_FILE_ICON },
-  { MAKE_KEY_NAME1("HTTP", SOP),   "", VAL_OPEN },
-  { MAKE_KEY_NAME1("HTTPS", DI),   "", VAL_FILE_ICON },
-  { MAKE_KEY_NAME1("HTTPS", SOP),  "", VAL_OPEN }
+  { MAKE_KEY_NAME1("HTTP", DI), VAL_FILE_ICON },
+  { MAKE_KEY_NAME1("HTTP", SOC), VAL_OPEN, OLD_VAL_OPEN },
+  { MAKE_KEY_NAME1("HTTPS", DI), VAL_FILE_ICON },
+  { MAKE_KEY_NAME1("HTTPS", SOC), VAL_OPEN, OLD_VAL_OPEN }
+};
+
+// The settings to disable DDE are separate from the default browser settings
+// since they are only checked when Firefox is the default browser and if they
+// are incorrect they are fixed without notifying the user.
+static SETTING gDDESettings[] = {
+  // File Handler Class
+  { MAKE_KEY_NAME1("Software\\Classes\\FirefoxHTML", SOD) },
+
+  // Protocol Handler Class - for Vista and above
+  { MAKE_KEY_NAME1("Software\\Classes\\FirefoxURL", SOD) },
+
+  // Protocol Handlers
+  { MAKE_KEY_NAME1("Software\\Classes\\FTP", SOD) },
+  { MAKE_KEY_NAME1("Software\\Classes\\HTTP", SOD) },
+  { MAKE_KEY_NAME1("Software\\Classes\\HTTPS", SOD) }
 };
 
 nsresult
 GetHelperPath(nsAutoString& aPath)
 {
   nsresult rv;
   nsCOMPtr<nsIProperties> directoryService = 
     do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
@@ -240,21 +255,20 @@ GetHelperPath(nsAutoString& aPath)
 }
 
 nsresult
 LaunchHelper(nsAutoString& aPath)
 {
   STARTUPINFOW si = {sizeof(si), 0};
   PROCESS_INFORMATION pi = {0};
 
-  BOOL ok = CreateProcessW(NULL, (LPWSTR)aPath.get(), NULL, NULL,
-                           FALSE, 0, NULL, NULL, &si, &pi);
-
-  if (!ok)
+  if (!CreateProcessW(NULL, (LPWSTR)aPath.get(), NULL, NULL, FALSE, 0, NULL,
+                      NULL, &si, &pi)) {
     return NS_ERROR_FAILURE;
+  }
 
   CloseHandle(pi.hProcess);
   CloseHandle(pi.hThread);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsWindowsShellService::ShortcutMaintenance()
@@ -362,66 +376,194 @@ nsWindowsShellService::IsDefaultBrowser(
                                         bool* aIsDefaultBrowser)
 {
   // If this is the first browser window, maintain internal state that we've
   // checked this session (so that subsequent window opens don't show the 
   // default browser dialog).
   if (aStartupCheck)
     mCheckedThisSession = true;
 
-  SETTING* settings;
-  SETTING* end = gSettings + sizeof(gSettings)/sizeof(SETTING);
-
   *aIsDefaultBrowser = true;
 
   PRUnichar exePath[MAX_BUF];
   if (!::GetModuleFileNameW(0, exePath, MAX_BUF))
     return NS_ERROR_FAILURE;
 
   // Convert the path to a long path since GetModuleFileNameW returns the path
   // that was used to launch Firefox which is not necessarily a long path.
   if (!::GetLongPathNameW(exePath, exePath, MAX_BUF))
     return NS_ERROR_FAILURE;
 
   nsAutoString appLongPath(exePath);
 
+  HKEY theKey;
+  DWORD res;
   nsresult rv;
   PRUnichar currValue[MAX_BUF];
+
+  SETTING* settings;
+  SETTING* end = gSettings + sizeof(gSettings) / sizeof(SETTING);
+
   for (settings = gSettings; settings < end; ++settings) {
-    NS_ConvertUTF8toUTF16 dataLongPath(settings->valueData);
-    NS_ConvertUTF8toUTF16 key(settings->keyName);
-    NS_ConvertUTF8toUTF16 value(settings->valueName);
-    PRInt32 offset = dataLongPath.Find("%APPPATH%");
-    dataLongPath.Replace(offset, 9, appLongPath);
+    NS_ConvertUTF8toUTF16 keyName(settings->keyName);
+    NS_ConvertUTF8toUTF16 valueData(settings->valueData);
+    PRInt32 offset = valueData.Find("%APPPATH%");
+    valueData.Replace(offset, 9, appLongPath);
 
-    ::ZeroMemory(currValue, sizeof(currValue));
-    HKEY theKey;
-    rv = OpenKeyForReading(HKEY_CLASSES_ROOT, key, &theKey);
+    rv = OpenKeyForReading(HKEY_CLASSES_ROOT, keyName, &theKey);
     if (NS_FAILED(rv)) {
       *aIsDefaultBrowser = false;
       return NS_OK;
     }
 
+    ::ZeroMemory(currValue, sizeof(currValue));
     DWORD len = sizeof currValue;
-    DWORD res = ::RegQueryValueExW(theKey, PromiseFlatString(value).get(),
-                                   NULL, NULL, (LPBYTE)currValue, &len);
-    // Close the key we opened.
+    res = ::RegQueryValueExW(theKey, L"", NULL, NULL, (LPBYTE)currValue, &len);
+    // Close the key that was opened.
     ::RegCloseKey(theKey);
     if (REG_FAILED(res) ||
-        !dataLongPath.Equals(currValue, CaseInsensitiveCompare)) {
-      // Key wasn't set, or was set to something other than our registry entry
-      *aIsDefaultBrowser = false;
-      return NS_OK;
+        !valueData.Equals(currValue, CaseInsensitiveCompare)) {
+      // Key wasn't set or was set to something other than our registry entry.
+      NS_ConvertUTF8toUTF16 oldValueData(settings->oldValueData);
+      offset = oldValueData.Find("%APPPATH%");
+      oldValueData.Replace(offset, 9, appLongPath);
+      // The current registry value doesn't match the current or the old format.
+      if (!oldValueData.Equals(currValue, CaseInsensitiveCompare)) {
+        *aIsDefaultBrowser = false;
+        return NS_OK;
+      }
+
+      res = ::RegOpenKeyExW(HKEY_CLASSES_ROOT, PromiseFlatString(keyName).get(),
+                            0, KEY_SET_VALUE, &theKey);
+      if (REG_FAILED(res)) {
+        // If updating the open command fails try to update it using the helper
+        // application when setting Firefox as the default browser.
+        *aIsDefaultBrowser = false;
+        return NS_OK;
+      }
+
+      const nsString &flatValue = PromiseFlatString(valueData);
+      res = ::RegSetValueExW(theKey, L"", 0, REG_SZ,
+                             (const BYTE *) flatValue.get(),
+                             (flatValue.Length() + 1) * sizeof(PRUnichar));
+      // Close the key that was created.
+      ::RegCloseKey(theKey);
+      if (REG_FAILED(res)) {
+        // If updating the open command fails try to update it using the helper
+        // application when setting Firefox as the default browser.
+        *aIsDefaultBrowser = false;
+        return NS_OK;
+      }
     }
   }
 
-  // Only check if Firefox is the default browser on Vista if the previous
-  // checks show that Firefox is the default browser.
-  if (*aIsDefaultBrowser)
+  // Only check if Firefox is the default browser on Vista and above if the
+  // previous checks show that Firefox is the default browser.
+  if (*aIsDefaultBrowser) {
     IsDefaultBrowserVista(aIsDefaultBrowser);
+  }
+
+  // To handle the case where DDE isn't disabled due for a user because there
+  // account didn't perform a Firefox update this will check if Firefox is the
+  // default browser and if dde is disabled for each handler
+  // and if it isn't disable it. When Firefox is not the default browser the
+  // helper application will disable dde for each handler.
+  if (*aIsDefaultBrowser) {
+    // Check ftp settings
+
+    end = gDDESettings + sizeof(gDDESettings) / sizeof(SETTING);
+
+    for (settings = gDDESettings; settings < end; ++settings) {
+      NS_ConvertUTF8toUTF16 keyName(settings->keyName);
+
+      rv = OpenKeyForReading(HKEY_CURRENT_USER, keyName, &theKey);
+      if (NS_FAILED(rv)) {
+        ::RegCloseKey(theKey);
+        // If disabling DDE fails try to disable it using the helper
+        // application when setting Firefox as the default browser.
+        *aIsDefaultBrowser = false;
+        return NS_OK;
+      }
+
+      ::ZeroMemory(currValue, sizeof(currValue));
+      DWORD len = sizeof currValue;
+      res = ::RegQueryValueExW(theKey, L"", NULL, NULL, (LPBYTE)currValue,
+                               &len);
+      // Close the key that was opened.
+      ::RegCloseKey(theKey);
+      if (REG_FAILED(res) || PRUnichar('\0') != *currValue) {
+        // Key wasn't set or was set to something other than our registry entry.
+        // Delete the key along with all of its childrean and then recreate it.
+        const nsString &flatName = PromiseFlatString(keyName);
+        ::SHDeleteKeyW(HKEY_CURRENT_USER, flatName.get());
+        res = ::RegCreateKeyExW(HKEY_CURRENT_USER, flatName.get(), 0, NULL,
+                                REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL,
+                                &theKey, NULL);
+        if (REG_FAILED(res)) {
+          // If disabling DDE fails try to disable it using the helper
+          // application when setting Firefox as the default browser.
+          *aIsDefaultBrowser = false;
+          return NS_OK;
+        }
+
+        res = ::RegSetValueExW(theKey, L"", 0, REG_SZ, (const BYTE *) L"",
+                               sizeof(PRUnichar));
+        // Close the key that was created.
+        ::RegCloseKey(theKey);
+        if (REG_FAILED(res)) {
+          // If disabling DDE fails try to disable it using the helper
+          // application when setting Firefox as the default browser.
+          *aIsDefaultBrowser = false;
+          return NS_OK;
+        }
+      }
+    }
+
+    // Update the FTP protocol handler's shell open command if it is the old
+    // format.
+    res = ::RegOpenKeyExW(HKEY_CURRENT_USER, FTP_SOC, 0, KEY_ALL_ACCESS,
+                          &theKey);
+    // Don't update the FTP protocol handler's shell open command when opening
+    // its registry key fails under HKCU since it most likely doesn't exist.
+    if (NS_FAILED(rv)) {
+      return NS_OK;
+    }
+
+    NS_ConvertUTF8toUTF16 oldValueOpen(OLD_VAL_OPEN);
+    PRInt32 offset = oldValueOpen.Find("%APPPATH%");
+    oldValueOpen.Replace(offset, 9, appLongPath);
+
+    ::ZeroMemory(currValue, sizeof(currValue));
+    DWORD len = sizeof currValue;
+    res = ::RegQueryValueExW(theKey, L"", NULL, NULL, (LPBYTE)currValue,
+                             &len);
+
+    // Don't update the FTP protocol handler's shell open command when the
+    // current registry value doesn't exist or matches the old format.
+    if (REG_FAILED(res) ||
+        !oldValueOpen.Equals(currValue, CaseInsensitiveCompare)) {
+      ::RegCloseKey(theKey);
+      return NS_OK;
+    }
+
+    NS_ConvertUTF8toUTF16 valueData(VAL_OPEN);
+    valueData.Replace(offset, 9, appLongPath);
+    const nsString &flatValue = PromiseFlatString(valueData);
+    res = ::RegSetValueExW(theKey, L"", 0, REG_SZ,
+                           (const BYTE *) flatValue.get(),
+                           (flatValue.Length() + 1) * sizeof(PRUnichar));
+    // Close the key that was created.
+    ::RegCloseKey(theKey);
+    // If updating the FTP protocol handlers shell open command fails try to
+    // update it using the helper application when setting Firefox as the
+    // default browser.
+    if (REG_FAILED(res)) {
+      *aIsDefaultBrowser = false;
+    }
+  }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsWindowsShellService::SetDefaultBrowser(bool aClaimAllTypes, bool aForAllUsers)
 {
   nsAutoString appHelperPath;
--- a/browser/components/thumbnails/PageThumbsProtocol.js
+++ b/browser/components/thumbnails/PageThumbsProtocol.js
@@ -20,19 +20,16 @@
 const Cu = Components.utils;
 const Cc = Components.classes;
 const Cr = Components.results;
 const Ci = Components.interfaces;
 
 Cu.import("resource:///modules/PageThumbs.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
-XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
-  "resource://gre/modules/NetUtil.jsm");
-
 XPCOMUtils.defineLazyModuleGetter(this, "Services",
   "resource://gre/modules/Services.jsm");
 
 /**
  * Implements the thumbnail protocol handler responsible for moz-page-thumb: URIs.
  */
 function Protocol() {
 }
@@ -99,345 +96,294 @@ function Channel(aURI) {
   // nsIChannel
   this.originalURI = aURI;
 
   // nsIHttpChannel
   this._responseHeaders = {"content-type": PageThumbs.contentType};
 }
 
 Channel.prototype = {
-  /**
-   * Tracks if the channel has been opened, yet.
-   */
+  _uri: null,
+  _referrer: null,
+  _canceled: false,
+  _status: Cr.NS_OK,
+  _isPending: false,
   _wasOpened: false,
+  _responseText: "OK",
+  _responseStatus: 200,
+  _responseHeaders: null,
+  _requestMethod: "GET",
+  _requestStarted: false,
+  _allowPipelining: true,
+  _requestSucceeded: true,
+
+  /* :::::::: nsIChannel ::::::::::::::: */
+
+  get URI() this._uri,
+  owner: null,
+  notificationCallbacks: null,
+  get securityInfo() null,
+
+  contentType: PageThumbs.contentType,
+  contentCharset: null,
+  contentLength: -1,
 
-  /**
-   * Opens this channel asynchronously.
-   * @param aListener The listener that receives the channel data when available.
-   * @param aContext A custom context passed to the listener's methods.
-   */
+  get contentDisposition() {
+    throw (Components.returnCode = Cr.NS_ERROR_NOT_AVAILABLE);
+  },
+
+  get contentDispositionFilename() {
+    throw (Components.returnCode = Cr.NS_ERROR_NOT_AVAILABLE);
+  },
+
+  get contentDispositionHeader() {
+    throw (Components.returnCode = Cr.NS_ERROR_NOT_AVAILABLE);
+  },
+
+  open: function Channel_open() {
+    throw (Components.returnCode = Cr.NS_ERROR_NOT_IMPLEMENTED);
+  },
+
   asyncOpen: function Channel_asyncOpen(aListener, aContext) {
+    if (this._isPending)
+      throw (Components.returnCode = Cr.NS_ERROR_IN_PROGRESS);
+
     if (this._wasOpened)
-      throw Cr.NS_ERROR_ALREADY_OPENED;
+      throw (Components.returnCode = Cr.NS_ERROR_ALREADY_OPENED);
 
-    if (this.canceled)
-      return;
-
-    this._listener = aListener;
-    this._context = aContext;
+    if (this._canceled)
+      return (Components.returnCode = this._status);
 
     this._isPending = true;
     this._wasOpened = true;
 
-    // Try to read the data from the thumbnail cache.
-    this._readCache(function (aData) {
-      let telemetryThumbnailFound = true;
+    this._listener = aListener;
+    this._context = aContext;
 
-      // Update response if there's no data.
-      if (!aData) {
-        this._responseStatus = 404;
-        this._responseText = "Not Found";
-        telemetryThumbnailFound = false;
-      }
-
-      Services.telemetry.getHistogramById("FX_THUMBNAILS_HIT_OR_MISS")
-        .add(telemetryThumbnailFound);
-
-      this._startRequest();
-
-      if (!this.canceled) {
-        this._addToLoadGroup();
+    if (this.loadGroup)
+      this.loadGroup.addRequest(this, null);
 
-        if (aData)
-          this._serveData(aData);
-
-        if (!this.canceled)
-          this._stopRequest();
-      }
-    }.bind(this));
-  },
+    if (this._canceled)
+      return;
 
-  /**
-   * Reads a data stream from the cache entry.
-   * @param aCallback The callback the data is passed to.
-   */
-  _readCache: function Channel_readCache(aCallback) {
     let {url} = parseURI(this._uri);
-
-    // Return early if there's no valid URL given.
     if (!url) {
-      aCallback(null);
+      this._serveThumbnailNotFound();
       return;
     }
 
-    // Try to get a cache entry.
     PageThumbsCache.getReadEntry(url, function (aEntry) {
       let inputStream = aEntry && aEntry.openInputStream(0);
-
-      function closeEntryAndFinish(aData) {
-        if (aEntry) {
+      if (!inputStream || !inputStream.available()) {
+        if (aEntry)
           aEntry.close();
-        }
-        aCallback(aData);
-      }
-
-      // Check if we have a valid entry and if it has any data.
-      if (!inputStream || !inputStream.available()) {
-        closeEntryAndFinish();
+        this._serveThumbnailNotFound();
         return;
       }
 
-      try {
-        // Read the cache entry's data.
-        NetUtil.asyncFetch(inputStream, function (aData, aStatus) {
-          // We might have been canceled while waiting.
-          if (this.canceled)
-            return;
+      this._entry = aEntry;
+      this._pump = Cc["@mozilla.org/network/input-stream-pump;1"].
+                   createInstance(Ci.nsIInputStreamPump);
 
-          // Check if we have a valid data stream.
-          if (!Components.isSuccessCode(aStatus) || !aData.available())
-            aData = null;
+      this._pump.init(inputStream, -1, -1, 0, 0, true);
+      this._pump.asyncRead(this, null);
 
-          closeEntryAndFinish(aData);
-        }.bind(this));
-      } catch (e) {
-        closeEntryAndFinish();
-      }
+      this._trackThumbnailHitOrMiss(true);
     }.bind(this));
   },
 
   /**
-   * Calls onStartRequest on the channel listener.
-   */
-  _startRequest: function Channel_startRequest() {
-    try {
-      this._listener.onStartRequest(this, this._context);
-    } catch (e) {
-      // The listener might throw if the request has been canceled.
-      this.cancel(Cr.NS_BINDING_ABORTED);
-    }
-  },
-
-  /**
-   * Calls onDataAvailable on the channel listener and passes the data stream.
-   * @param aData The data to be delivered.
+   * Serves a "404 Not Found" if we didn't find the requested thumbnail.
    */
-  _serveData: function Channel_serveData(aData) {
-    try {
-      let available = aData.available();
-      this._listener.onDataAvailable(this, this._context, aData, 0, available);
-    } catch (e) {
-      // The listener might throw if the request has been canceled.
-      this.cancel(Cr.NS_BINDING_ABORTED);
-    }
-  },
+  _serveThumbnailNotFound: function Channel_serveThumbnailNotFound() {
+    this._responseStatus = 404;
+    this._responseText = "Not Found";
+    this._requestSucceeded = false;
 
-  /**
-   * Calls onStopRequest on the channel listener.
-   */
-  _stopRequest: function Channel_stopRequest() {
-    try {
-      this._listener.onStopRequest(this, this._context, this.status);
-    } catch (e) {
-      // This might throw but is generally ignored.
-    }
+    this.onStartRequest(this, null);
+    this.onStopRequest(this, null, Cr.NS_OK);
 
-    // The request has finished, clean up after ourselves.
-    this._cleanup();
+    this._trackThumbnailHitOrMiss(false);
   },
 
   /**
-   * Adds this request to the load group, if any.
+   * Implements telemetry tracking for thumbnail cache hits and misses.
+   * @param aFound Whether the thumbnail was found.
    */
-  _addToLoadGroup: function Channel_addToLoadGroup() {
-    if (this.loadGroup)
-      this.loadGroup.addRequest(this, this._context);
+  _trackThumbnailHitOrMiss: function Channel_trackThumbnailHitOrMiss(aFound) {
+    Services.telemetry.getHistogramById("FX_THUMBNAILS_HIT_OR_MISS")
+      .add(aFound);
   },
 
-  /**
-   * Removes this request from its load group, if any.
-   */
-  _removeFromLoadGroup: function Channel_removeFromLoadGroup() {
-    if (!this.loadGroup)
-      return;
+  /* :::::::: nsIStreamListener ::::::::::::::: */
+
+  onStartRequest: function Channel_onStartRequest(aRequest, aContext) {
+    if (!this.canceled && Components.isSuccessCode(this._status))
+      this._status = aRequest.status;
 
-    try {
-      this.loadGroup.removeRequest(this, this._context, this.status);
-    } catch (e) {
-      // This might throw but is ignored.
-    }
+    this._requestStarted = true;
+    this._listener.onStartRequest(this, this._context);
+  },
+
+  onDataAvailable: function Channel_onDataAvailable(aRequest, aContext,
+                                                    aInStream, aOffset, aCount) {
+    this._listener.onDataAvailable(this, this._context, aInStream, aOffset, aCount);
   },
 
-  /**
-   * Cleans up the channel when the request has finished.
-   */
-  _cleanup: function Channel_cleanup() {
-    this._removeFromLoadGroup();
-    this.loadGroup = null;
+  onStopRequest: function Channel_onStopRequest(aRequest, aContext, aStatus) {
+    this._isPending = false;
+    this._status = aStatus;
 
-    this._isPending = false;
+    this._listener.onStopRequest(this, this._context, aStatus);
+    this._listener = null;
+    this._context = null;
 
-    delete this._listener;
-    delete this._context;
+    if (this._entry)
+      this._entry.close();
+
+    if (this.loadGroup)
+      this.loadGroup.removeRequest(this, null, aStatus);
   },
 
-  /* :::::::: nsIChannel ::::::::::::::: */
+  /* :::::::: nsIRequest ::::::::::::::: */
+
+  get status() this._status,
+  get name() this._uri.spec,
+  isPending: function Channel_isPending() this._isPending,
 
-  contentType: PageThumbs.contentType,
-  contentLength: -1,
-  owner: null,
-  contentCharset: null,
-  notificationCallbacks: null,
+  loadFlags: Ci.nsIRequest.LOAD_NORMAL,
+  loadGroup: null,
+
+  cancel: function Channel_cancel(aStatus) {
+    if (this._canceled)
+      return;
 
-  get URI() this._uri,
-  get securityInfo() null,
+    this._canceled = true;
+    this._status = aStatus;
+
+    if (this._pump)
+      this._pump.cancel(aStatus);
+  },
 
-  /**
-   * Opens this channel synchronously. Not supported.
-   */
-  open: function Channel_open() {
-    // Synchronous data delivery is not implemented.
-    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+  suspend: function Channel_suspend() {
+    if (this._pump)
+      this._pump.suspend();
+  },
+
+  resume: function Channel_resume() {
+    if (this._pump)
+      this._pump.resume();
   },
 
   /* :::::::: nsIHttpChannel ::::::::::::::: */
 
-  redirectionLimit: 10,
-  requestMethod: "GET",
-  allowPipelining: true,
-  referrer: null,
+  get referrer() this._referrer,
 
-  get requestSucceeded() true,
+  set referrer(aReferrer) {
+    if (this._wasOpened)
+      throw (Components.returnCode = Cr.NS_ERROR_IN_PROGRESS);
 
-  _responseStatus: 200,
-  get responseStatus() this._responseStatus,
+    this._referrer = aReferrer;
+  },
 
-  _responseText: "OK",
-  get responseStatusText() this._responseText,
+  get requestMethod() this._requestMethod,
 
-  /**
-   * Checks if the server sent the equivalent of a "Cache-control: no-cache"
-   * response header.
-   * @return Always false.
-   */
-  isNoCacheResponse: function () false,
+  set requestMethod(aMethod) {
+    if (this._wasOpened)
+      throw (Components.returnCode = Cr.NS_ERROR_IN_PROGRESS);
+
+    this._requestMethod = aMethod.toUpperCase();
+  },
 
-  /**
-   * Checks if the server sent the equivalent of a "Cache-control: no-cache"
-   * response header.
-   * @return Always false.
-   */
-  isNoStoreResponse: function () false,
+  get allowPipelining() this._allowPipelining,
 
-  /**
-   * Returns the value of a particular request header. Not implemented.
-   */
-  getRequestHeader: function Channel_getRequestHeader() {
-    throw Cr.NS_ERROR_NOT_AVAILABLE;
+  set allowPipelining(aAllow) {
+    if (this._wasOpened)
+      throw (Components.returnCode = Cr.NS_ERROR_FAILURE);
+
+    this._allowPipelining = aAllow;
   },
 
-  /**
-   * This method is called to set the value of a particular request header.
-   * Not implemented.
-   */
-  setRequestHeader: function Channel_setRequestHeader() {
-    if (this._wasOpened)
-      throw Cr.NS_ERROR_IN_PROGRESS;
+  redirectionLimit: 10,
+
+  get responseStatus() {
+    if (this._requestStarted)
+      throw (Components.returnCode = Cr.NS_ERROR_NOT_AVAILABLE);
+
+    return this._responseStatus;
+  },
+
+  get responseStatusText() {
+    if (this._requestStarted)
+      throw (Components.returnCode = Cr.NS_ERROR_NOT_AVAILABLE);
+
+    return this._responseText;
   },
 
-  /**
-   * Call this method to visit all request headers. Not implemented.
-   */
-  visitRequestHeaders: function () {},
+  get requestSucceeded() {
+    if (this._requestStarted)
+      throw (Components.returnCode = Cr.NS_ERROR_NOT_AVAILABLE);
+
+    return this._requestSucceeded;
+  },
+
+  isNoCacheResponse: function Channel_isNoCacheResponse() false,
+  isNoStoreResponse: function Channel_isNoStoreResponse() false,
 
-  /**
-   * Gets the value of a particular response header.
-   * @param aHeader The case-insensitive name of the response header to query.
-   * @return The header value.
-   */
+  getRequestHeader: function Channel_getRequestHeader() {
+    throw (Components.returnCode = Cr.NS_ERROR_NOT_AVAILABLE);
+  },
+
+  setRequestHeader: function Channel_setRequestHeader() {
+    if (this._wasOpened)
+      throw (Components.returnCode = Cr.NS_ERROR_IN_PROGRESS);
+  },
+
+  visitRequestHeaders: function Channel_visitRequestHeaders() {},
+
   getResponseHeader: function Channel_getResponseHeader(aHeader) {
     let name = aHeader.toLowerCase();
     if (name in this._responseHeaders)
       return this._responseHeaders[name];
 
-    throw Cr.NS_ERROR_NOT_AVAILABLE;
+    throw (Components.returnCode = Cr.NS_ERROR_NOT_AVAILABLE);
   },
 
-  /**
-   * This method is called to set the value of a particular response header.
-   * @param aHeader The case-insensitive name of the response header to query.
-   * @param aValue The response header value to set.
-   */
   setResponseHeader: function Channel_setResponseHeader(aHeader, aValue, aMerge) {
     let name = aHeader.toLowerCase();
     if (!aValue && !aMerge)
       delete this._responseHeaders[name];
     else
       this._responseHeaders[name] = aValue;
   },
 
-  /**
-   * Call this method to visit all response headers.
-   * @param aVisitor The header visitor.
-   */
   visitResponseHeaders: function Channel_visitResponseHeaders(aVisitor) {
     for (let name in this._responseHeaders) {
       let value = this._responseHeaders[name];
 
       try {
         aVisitor.visitHeader(name, value);
       } catch (e) {
         // The visitor can throw to stop the iteration.
         return;
       }
     }
   },
 
-  /* :::::::: nsIRequest ::::::::::::::: */
-
-  loadFlags: Ci.nsIRequest.LOAD_NORMAL,
-  loadGroup: null,
-
-  get name() this._uri.spec,
-
-  _status: Cr.NS_OK,
-  get status() this._status,
-
-  _isPending: false,
-  isPending: function () this._isPending,
-
-  resume: function () {},
-  suspend: function () {},
-
-  /**
-   * Cancels this request.
-   * @param aStatus The reason for cancelling.
-   */
-  cancel: function Channel_cancel(aStatus) {
-    if (this.canceled)
-      return;
-
-    this._isCanceled = true;
-    this._status = aStatus;
-
-    this._cleanup();
-  },
-
   /* :::::::: nsIHttpChannelInternal ::::::::::::::: */
 
   documentURI: null,
-
-  _isCanceled: false,
-  get canceled() this._isCanceled,
+  get canceled() this._canceled,
+  allowSpdy: false,
 
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIChannel,
                                          Ci.nsIHttpChannel,
                                          Ci.nsIHttpChannelInternal,
                                          Ci.nsIRequest])
-};
+}
 
 /**
  * Parses a given URI and extracts all parameters relevant to this protocol.
  * @param aURI The URI to parse.
  * @return The parsed parameters.
  */
 function parseURI(aURI) {
   let {scheme, staticHost} = PageThumbs;
--- a/browser/installer/windows/nsis/installer.nsi
+++ b/browser/installer/windows/nsis/installer.nsi
@@ -98,17 +98,17 @@ Var PageName
 !include locales.nsi
 
 VIAddVersionKey "FileDescription" "${BrandShortName} Installer"
 VIAddVersionKey "OriginalFilename" "setup.exe"
 
 ; Must be inserted before other macros that use logging
 !insertmacro _LoggingCommon
 
-!insertmacro AddDDEHandlerValues
+!insertmacro AddDisabledDDEHandlerValues
 !insertmacro ChangeMUIHeaderImage
 !insertmacro CheckForFilesInUse
 !insertmacro CleanUpdatesDir
 !insertmacro CopyFilesFromDir
 !insertmacro CreateRegKey
 !insertmacro GetPathFromString
 !insertmacro GetParent
 !insertmacro InitHashAppModelId
@@ -347,27 +347,25 @@ Section "-Application" APP_IDX
 
   ${FixClassKeys}
 
   ; Uninstall keys can only exist under HKLM on some versions of windows. Since
   ; it doesn't cause problems always add them.
   ${SetUninstallKeys}
 
   ; On install always add the FirefoxHTML and FirefoxURL keys.
-  ; An empty string is used for the 5th param because FirefoxHTML and FirefoxURL
-  ; are not protocol handlers.
+  ; An empty string is used for the 5th param because FirefoxHTML is not a
+  ; protocol handler.
   ${GetLongPath} "$INSTDIR\${FileMainEXE}" $8
-  StrCpy $2 "$\"$8$\" -requestPending -osint -url $\"%1$\""
-  StrCpy $3 "$\"%1$\",,0,0,,,,"
+  StrCpy $2 "$\"$8$\" -osint -url $\"%1$\""
 
-  ${AddDDEHandlerValues} "FirefoxHTML" "$2" "$8,1" "${AppRegName} Document" "" \
-                         "${DDEApplication}" "$3" "WWW_OpenURL"
-
-  ${AddDDEHandlerValues} "FirefoxURL" "$2" "$8,1" "${AppRegName} URL" "true" \
-                         "${DDEApplication}" "$3" "WWW_OpenURL"
+  ${AddDisabledDDEHandlerValues} "FirefoxHTML" "$2" "$8,1" \
+                                 "${AppRegName} Document" ""
+  ${AddDisabledDDEHandlerValues} "FirefoxURL" "$2" "$8,1" "${AppRegName} URL" \
+                                 "true"
 
   ; The following keys should only be set if we can write to HKLM
   ${If} $TmpVal == "HKLM"
     ; Set the Start Menu Internet and Vista Registered App HKLM registry keys.
     ${SetStartMenuInternet}
     ${FixShellIconHandler}
 
     ; If we are writing to HKLM and create either the desktop or start menu
--- a/browser/installer/windows/nsis/shared.nsh
+++ b/browser/installer/windows/nsis/shared.nsh
@@ -74,17 +74,17 @@
     ${StrFilter} "${FileMainEXE}" "+" "" "" $1
     ReadRegStr $0 HKLM "Software\Clients\StartMenuInternet\$1\DefaultIcon" ""
     ${GetPathFromString} "$0" $0
     ${GetParent} "$0" $0
     ${If} ${FileExists} "$0"
       ${GetLongPath} "$0" $0
     ${EndIf}
     ${If} "$0" == "$INSTDIR"
-      ${SetStartMenuInternet}
+      ${SetStartMenuInternet} ; Does not use SHCTX
     ${EndIf}
 
     ReadRegStr $0 HKLM "Software\mozilla.org\Mozilla" "CurrentVersion"
     ${If} "$0" != "${GREVersion}"
       WriteRegStr HKLM "Software\mozilla.org\Mozilla" "CurrentVersion" "${GREVersion}"
     ${EndIf}
   ${EndIf}
 
@@ -151,22 +151,22 @@
     ${EndIf}
   ${EndIf}
 !endif
 
 !macroend
 !define PostUpdate "!insertmacro PostUpdate"
 
 !macro SetAsDefaultAppGlobal
-  ${RemoveDeprecatedKeys}
+  ${RemoveDeprecatedKeys} ; Does not use SHCTX
 
   SetShellVarContext all      ; Set SHCTX to all users (e.g. HKLM)
-  ${SetHandlers}
-  ${SetStartMenuInternet}
-  ${FixShellIconHandler}
+  ${SetHandlers} ; Uses SHCTX
+  ${SetStartMenuInternet} ; Does not use SHCTX
+  ${FixShellIconHandler} ; Does not use SHCTX
   ${ShowShortcuts}
   ${StrFilter} "${FileMainEXE}" "+" "" "" $R9
   WriteRegStr HKLM "Software\Clients\StartMenuInternet" "" "$R9"
 !macroend
 !define SetAsDefaultAppGlobal "!insertmacro SetAsDefaultAppGlobal"
 
 ; Removes shortcuts for this installation. This should also remove the
 ; application from Open With for the file types the application handles
@@ -301,17 +301,17 @@
 !define ShowShortcuts "!insertmacro ShowShortcuts"
 
 ; Adds the protocol and file handler registry entries for making Firefox the
 ; default handler (uses SHCTX).
 !macro SetHandlers
   ${GetLongPath} "$INSTDIR\${FileMainEXE}" $8
 
   StrCpy $0 "SOFTWARE\Classes"
-  StrCpy $2 "$\"$8$\" -requestPending -osint -url $\"%1$\""
+  StrCpy $2 "$\"$8$\" -osint -url $\"%1$\""
 
   ; Associate the file handlers with FirefoxHTML
   ReadRegStr $6 SHCTX "$0\.htm" ""
   ${If} "$6" != "FirefoxHTML"
     WriteRegStr SHCTX "$0\.htm"   "" "FirefoxHTML"
   ${EndIf}
 
   ReadRegStr $6 SHCTX "$0\.html" ""
@@ -335,35 +335,30 @@
   ${EndIf}
 
   ; Only add webm if it's not present
   ${CheckIfRegistryKeyExists} "$0" ".webm" $7
   ${If} $7 == "false"
     WriteRegStr SHCTX "$0\.webm"  "" "FirefoxHTML"
   ${EndIf}
 
-  StrCpy $3 "$\"%1$\",,0,0,,,,"
-
   ; An empty string is used for the 5th param because FirefoxHTML is not a
   ; protocol handler
-  ${AddDDEHandlerValues} "FirefoxHTML" "$2" "$8,1" "${AppRegName} HTML Document" "" \
-                         "${DDEApplication}" "$3" "WWW_OpenURL"
+  ${AddDisabledDDEHandlerValues} "FirefoxHTML" "$2" "$8,1" \
+                                 "${AppRegName} HTML Document" ""
 
-  ${AddDDEHandlerValues} "FirefoxURL" "$2" "$8,1" "${AppRegName} URL" "true" \
-                         "${DDEApplication}" "$3" "WWW_OpenURL"
+  ${AddDisabledDDEHandlerValues} "FirefoxURL" "$2" "$8,1" "${AppRegName} URL" \
+                                 "true"
 
   ; An empty string is used for the 4th & 5th params because the following
   ; protocol handlers already have a display name and the additional keys
   ; required for a protocol handler.
-  ${AddDDEHandlerValues} "ftp" "$2" "$8,1" "" "" \
-                         "${DDEApplication}" "$3" "WWW_OpenURL"
-  ${AddDDEHandlerValues} "http" "$2" "$8,1" "" "" \
-                         "${DDEApplication}" "$3" "WWW_OpenURL"
-  ${AddDDEHandlerValues} "https" "$2" "$8,1" "" "" \
-                         "${DDEApplication}" "$3" "WWW_OpenURL"
+  ${AddDisabledDDEHandlerValues} "ftp" "$2" "$8,1" "" ""
+  ${AddDisabledDDEHandlerValues} "http" "$2" "$8,1" "" ""
+  ${AddDisabledDDEHandlerValues} "https" "$2" "$8,1" "" ""
 !macroend
 !define SetHandlers "!insertmacro SetHandlers"
 
 ; Adds the HKLM\Software\Clients\StartMenuInternet\FIREFOX.EXE registry
 ; entries (does not use SHCTX).
 ;
 ; The values for StartMenuInternet are only valid under HKLM and there can only
 ; be one installation registerred under StartMenuInternet per application since
@@ -562,52 +557,51 @@
 !macroend
 !define FixClassKeys "!insertmacro FixClassKeys"
 
 ; Updates protocol handlers if their registry open command value is for this
 ; install location (uses SHCTX).
 !macro UpdateProtocolHandlers
   ; Store the command to open the app with an url in a register for easy access.
   ${GetLongPath} "$INSTDIR\${FileMainEXE}" $8
-  StrCpy $2 "$\"$8$\" -requestPending -osint -url $\"%1$\""
-  StrCpy $3 "$\"%1$\",,0,0,,,,"
+  StrCpy $2 "$\"$8$\" -osint -url $\"%1$\""
 
   ; Only set the file and protocol handlers if the existing one under HKCR is
   ; for this install location.
 
   ${IsHandlerForInstallDir} "FirefoxHTML" $R9
   ${If} "$R9" == "true"
     ; An empty string is used for the 5th param because FirefoxHTML is not a
     ; protocol handler.
-    ${AddDDEHandlerValues} "FirefoxHTML" "$2" "$8,1" "${AppRegName} HTML Document" "" \
-                           "${DDEApplication}" "$3" "WWW_OpenURL"
+    ${AddDisabledDDEHandlerValues} "FirefoxHTML" "$2" "$8,1" \
+                                   "${AppRegName} HTML Document" ""
   ${EndIf}
 
   ${IsHandlerForInstallDir} "FirefoxURL" $R9
   ${If} "$R9" == "true"
-    ${AddDDEHandlerValues} "FirefoxURL" "$2" "$8,1" "${AppRegName} URL" "true" \
-                           "${DDEApplication}" "$3" "WWW_OpenURL"
+    ${AddDisabledDDEHandlerValues} "FirefoxURL" "$2" "$8,1" \
+                                   "${AppRegName} URL" "true"
   ${EndIf}
 
+  ; An empty string is used for the 4th & 5th params because the following
+  ; protocol handlers already have a display name and the additional keys
+  ; required for a protocol handler.
   ${IsHandlerForInstallDir} "ftp" $R9
   ${If} "$R9" == "true"
-    ${AddDDEHandlerValues} "ftp" "$2" "$8,1" "" "" \
-                           "${DDEApplication}" "$3" "WWW_OpenURL"
+    ${AddDisabledDDEHandlerValues} "ftp" "$2" "$8,1" "" ""
   ${EndIf}
 
   ${IsHandlerForInstallDir} "http" $R9
   ${If} "$R9" == "true"
-    ${AddDDEHandlerValues} "http" "$2" "$8,1" "" "" \
-                           "${DDEApplication}" "$3" "WWW_OpenURL"
+    ${AddDisabledDDEHandlerValues} "http" "$2" "$8,1" "" ""
   ${EndIf}
 
   ${IsHandlerForInstallDir} "https" $R9
   ${If} "$R9" == "true"
-    ${AddDDEHandlerValues} "https" "$2" "$8,1" "" "" \
-                           "${DDEApplication}" "$3" "WWW_OpenURL"
+    ${AddDisabledDDEHandlerValues} "https" "$2" "$8,1" "" ""
   ${EndIf}
 !macroend
 !define UpdateProtocolHandlers "!insertmacro UpdateProtocolHandlers"
 
 !ifdef MOZ_MAINTENANCE_SERVICE
 ; Adds maintenance service certificate keys for the install dir.
 ; For the cert to work, it must also be signed by a trusted cert for the user.
 !macro AddMaintCertKeys
@@ -1159,21 +1153,23 @@ Function SetAsDefaultAppUser
   ${EndUnless}
 
   ; The code after ElevateUAC won't be executed on Vista and above when the
   ; user:
   ; a) is a member of the administrators group (e.g. elevation is required)
   ; b) is not a member of the administrators group and chooses to elevate
   ${ElevateUAC}
 
-  ${SetStartMenuInternet}
+  ${SetStartMenuInternet} ; Does not use SHCTX
 
   SetShellVarContext all  ; Set SHCTX to all users (e.g. HKLM)
-  ${FixShellIconHandler}
-  ${RemoveDeprecatedKeys}
+
+  ${FixClassKeys} ; Does not use SHCTX
+  ${FixShellIconHandler} ; Does not use SHCTX
+  ${RemoveDeprecatedKeys} ; Does not use SHCTX
 
   ClearErrors
   ${GetParameters} $0
   ${GetOptions} "$0" "/UAC:" $0
   ${If} ${Errors}
     Call SetAsDefaultAppUserHKCU
   ${Else}
     GetFunctionAddress $0 SetAsDefaultAppUserHKCU
--- a/browser/installer/windows/nsis/uninstaller.nsi
+++ b/browser/installer/windows/nsis/uninstaller.nsi
@@ -87,17 +87,17 @@ Var MaintCertKey
 !include common.nsh
 !include locales.nsi
 
 ; This is named BrandShortName helper because we use this for software update
 ; post update cleanup.
 VIAddVersionKey "FileDescription" "${BrandShortName} Helper"
 VIAddVersionKey "OriginalFilename" "helper.exe"
 
-!insertmacro AddDDEHandlerValues
+!insertmacro AddDisabledDDEHandlerValues
 !insertmacro CleanVirtualStore
 !insertmacro ElevateUAC
 !insertmacro GetLongPath
 !insertmacro GetPathFromString
 !insertmacro InitHashAppModelId
 !insertmacro IsHandlerForInstallDir
 !insertmacro IsPinnedToTaskBar
 !insertmacro IsUserAdmin
--- a/js/src/tests/e4x/Regress/regress-308111.js
+++ b/js/src/tests/e4x/Regress/regress-308111.js
@@ -625,17 +625,16 @@ var xml = <prefs>
 <pref><name>security.ui.enable</name></pref>
 <pref><name>editor.use_css</name></pref>
 <pref><name>network.IDN.whitelist.io</name></pref>
 <pref><name>browser.related.enabled</name></pref>
 <pref><name>browser.sessionhistory.max_viewers</name></pref>
 <pref><name>font.size.variable.x-guru</name></pref>
 <pref><name>font.size.variable.x-gujr</name></pref>
 <pref><name>network.protocol-handler.external.vnd.ms.radio</name></pref>
-<pref><name>advanced.system.supportDDEExec</name></pref>
 <pref><name>browser.tabs.opentabfor.urlbar</name></pref>
 <pref><name>font.name.sans-serif.x-khmr</name></pref>
 <pref><name>mousewheel.horizscroll.withshiftkey.sysnumlines</name></pref>
 <pref><name>network.protocol-handler.external.afp</name></pref>
 <pref><name>font.name-list.serif.x-guru</name></pref>
 <pref><name>intl.charsetmenu.browser.more5</name></pref>
 <pref><name>security.ssl3.rsa_rc4_128_md5</name></pref>
 <pref><name>font.default.he</name></pref>
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -2080,23 +2080,16 @@ pref("plugin.scan.plid.all", true);
 
 // Allow the new AsyncDrawing mode to be used for plugins.
 pref("plugin.allow.asyncdrawing", false);
 
 // Help Windows NT, 2000, and XP dialup a RAS connection
 // when a network address is unreachable.
 pref("network.autodial-helper.enabled", true);
 
-// Pref to control whether we set ddeexec subkeys for the http
-// Internet shortcut protocol if we are handling it.  These
-// subkeys will be set only while we are running (to avoid the
-// problem of Windows showing an alert when it tries to use DDE
-// and we're not already running).
-pref("advanced.system.supportDDEExec", true);
-
 // Switch the keyboard layout per window
 pref("intl.keyboard.per_window_layout", false);
 
 #ifdef NS_ENABLE_TSF
 // Enable/Disable TSF support
 pref("intl.enable_tsf_support", false);
 
 // We need to notify the layout change to TSF, but we cannot check the actual
--- a/toolkit/mozapps/installer/windows/nsis/common.nsh
+++ b/toolkit/mozapps/installer/windows/nsis/common.nsh
@@ -1188,17 +1188,19 @@
 /**
  * Writes common registry values for a handler using SHCTX.
  *
  * @param   _KEY
  *          The subkey in relation to the key root.
  * @param   _VALOPEN
  *          The path and args to launch the application.
  * @param   _VALICON
- *          The path to an exe that contains an icon and the icon resource id.
+ *          The path to the binary that contains the icon group for the default icon
+ *          followed by a comma and either the icon group's resource index or the icon
+ *          group's resource id prefixed with a minus sign
  * @param   _DISPNAME
  *          The display name for the handler. If emtpy no value will be set.
  * @param   _ISPROTOCOL
  *          Sets protocol handler specific registry values when "true".
  * @param   _ISDDE
  *          Sets DDE specific registry values when "true".
  *
  * $R3 = string value of the current registry key path.
@@ -1232,20 +1234,19 @@
 
       StrCmp "$R7" "" +6 +1
       ReadRegStr $R3 SHCTX "$R4" "FriendlyTypeName"
 
       StrCmp "$R3" "" +1 +3
       WriteRegStr SHCTX "$R4" "" "$R7"
       WriteRegStr SHCTX "$R4" "FriendlyTypeName" "$R7"
 
-      StrCmp "$R8" "true" +1 +8
+      StrCmp "$R8" "true" +1 +2
       WriteRegStr SHCTX "$R4" "URL Protocol" ""
       StrCpy $R3 ""
-      ClearErrors
       ReadRegDWord $R3 SHCTX "$R4" "EditFlags"
       StrCmp $R3 "" +1 +3  ; Only add EditFlags if a value doesn't exist
       DeleteRegValue SHCTX "$R4" "EditFlags"
       WriteRegDWord SHCTX "$R4" "EditFlags" 0x00000002
 
       StrCmp "$R6" "" +2 +1
       WriteRegStr SHCTX "$R4\DefaultIcon" "" "$R6"
 
@@ -1331,17 +1332,19 @@
  * Writes common registry values for a handler that uses DDE using SHCTX.
  *
  * @param   _KEY
  *          The key name in relation to the HKCR root. SOFTWARE\Classes is
  *          prefixed to this value when using SHCTX.
  * @param   _VALOPEN
  *          The path and args to launch the application.
  * @param   _VALICON
- *          The path to an exe that contains an icon and the icon resource id.
+ *          The path to the binary that contains the icon group for the default icon
+ *          followed by a comma and either the icon group's resource index or the icon
+ *          group's resource id prefixed with a minus sign
  * @param   _DISPNAME
  *          The display name for the handler. If emtpy no value will be set.
  * @param   _ISPROTOCOL
  *          Sets protocol handler specific registry values when "true".
  * @param   _DDE_APPNAME
  *          Sets DDE specific registry values when not an empty string.
  *
  * $R0 = storage for SOFTWARE\Classes
@@ -1384,20 +1387,19 @@
       StrCpy $R0 "SOFTWARE\Classes"
       StrCmp "$R5" "" +6 +1
       ReadRegStr $R1 SHCTX "$R2" "FriendlyTypeName"
 
       StrCmp "$R1" "" +1 +3
       WriteRegStr SHCTX "$R0\$R2" "" "$R5"
       WriteRegStr SHCTX "$R0\$R2" "FriendlyTypeName" "$R5"
 
-      StrCmp "$R6" "true" +1 +8
+      StrCmp "$R6" "true" +1 +2
       WriteRegStr SHCTX "$R0\$R2" "URL Protocol" ""
       StrCpy $R1 ""
-      ClearErrors
       ReadRegDWord $R1 SHCTX "$R0\$R2" "EditFlags"
       StrCmp $R1 "" +1 +3  ; Only add EditFlags if a value doesn't exist
       DeleteRegValue SHCTX "$R0\$R2" "EditFlags"
       WriteRegDWord SHCTX "$R0\$R2" "EditFlags" 0x00000002
 
       StrCmp "$R4" "" +2 +1
       WriteRegStr SHCTX "$R0\$R2\DefaultIcon" "" "$R4"
 
@@ -1480,16 +1482,164 @@
     !insertmacro AddDDEHandlerValues
 
     !undef _MOZFUNC_UN
     !define _MOZFUNC_UN
     !verbose pop
   !endif
 !macroend
 
+/**
+ * Writes common registry values for a handler that DOES NOT use DDE using SHCTX.
+ *
+ * @param   _KEY
+ *          The key name in relation to the HKCR root. SOFTWARE\Classes is
+ *          prefixed to this value when using SHCTX.
+ * @param   _VALOPEN
+ *          The path and args to launch the application.
+ * @param   _VALICON
+ *          The path to the binary that contains the icon group for the default icon
+ *          followed by a comma and either the icon group's resource index or the icon
+ *          group's resource id prefixed with a minus sign
+ * @param   _DISPNAME
+ *          The display name for the handler. If emtpy no value will be set.
+ * @param   _ISPROTOCOL
+ *          Sets protocol handler specific registry values when "true".
+ *
+ * $R3 = storage for SOFTWARE\Classes
+ * $R4 = string value of the current registry key path.
+ * $R5 = _KEY
+ * $R6 = _VALOPEN
+ * $R7 = _VALICON
+ * $R8 = _DISPNAME
+ * $R9 = _ISPROTOCOL
+ */
+!macro AddDisabledDDEHandlerValues
+
+  !ifndef ${_MOZFUNC_UN}AddDisabledDDEHandlerValues
+    !verbose push
+    !verbose ${_MOZFUNC_VERBOSE}
+    !define ${_MOZFUNC_UN}AddDisabledDDEHandlerValues "!insertmacro ${_MOZFUNC_UN}AddDisabledDDEHandlerValuesCall"
+
+    Function ${_MOZFUNC_UN}AddDisabledDDEHandlerValues
+      Exch $R9 ; true if a protocol handler
+      Exch 1
+      Exch $R8 ; FriendlyTypeName
+      Exch 2
+      Exch $R7 ; icon index
+      Exch 3
+      Exch $R6 ; shell\open\command
+      Exch 4
+      Exch $R5 ; reg key
+      Push $R4 ;
+      Push $R3 ; base reg class
+
+      StrCpy $R3 "SOFTWARE\Classes"
+      StrCmp "$R8" "" +6 +1
+      ReadRegStr $R4 SHCTX "$R5" "FriendlyTypeName"
+
+      StrCmp "$R4" "" +1 +3
+      WriteRegStr SHCTX "$R3\$R5" "" "$R8"
+      WriteRegStr SHCTX "$R3\$R5" "FriendlyTypeName" "$R8"
+
+      StrCmp "$R9" "true" +1 +2
+      WriteRegStr SHCTX "$R3\$R5" "URL Protocol" ""
+      StrCpy $R4 ""
+      ReadRegDWord $R4 SHCTX "$R3\$R5" "EditFlags"
+      StrCmp $R4 "" +1 +3  ; Only add EditFlags if a value doesn't exist
+      DeleteRegValue SHCTX "$R3\$R5" "EditFlags"
+      WriteRegDWord SHCTX "$R3\$R5" "EditFlags" 0x00000002
+
+      StrCmp "$R7" "" +2 +1
+      WriteRegStr SHCTX "$R3\$R5\DefaultIcon" "" "$R7"
+
+      ; Main command handler for the app
+      WriteRegStr SHCTX "$R3\$R5\shell\open\command" "" "$R6"
+
+      ; Drop support for DDE (bug 491947), and remove old dde entries if
+      ; they exist.
+      ;
+      ; Note, changes in SHCTX should propegate to hkey classes root when
+      ; current user or local machine entries are written. Windows will also
+      ; attempt to propegate entries when a handler is used. CR entries are a
+      ; combination of LM and CU, with CU taking priority. 
+      ;
+      ; To disable dde, an empty shell/ddeexec key must be created in current
+      ; user or local machine. Unfortunately, settings have various different
+      ; behaviors depending on the windows version. The following code attempts
+      ; to address these differences.
+      ;
+      ; On XP (no SP, SP1, SP2), Vista: An empty default string
+      ; must be set under ddeexec. Empty strings propagate to CR.
+      ;
+      ; Win7: IE does not configure ddeexec, so issues with left over ddeexec keys
+      ; in LM are reduced. We configure an empty ddeexec key with an empty default
+      ; string in CU to be sure.
+      ;
+      DeleteRegKey SHCTX "SOFTWARE\Classes\$R5\shell\open\ddeexec"
+      WriteRegStr SHCTX "SOFTWARE\Classes\$R5\shell\open\ddeexec" "" ""
+
+      ClearErrors
+
+      Pop $R3
+      Pop $R4
+      Exch $R5
+      Exch 4
+      Exch $R6
+      Exch 3
+      Exch $R7
+      Exch 2
+      Exch $R8
+      Exch 1
+      Exch $R9
+    FunctionEnd
+
+    !verbose pop
+  !endif
+!macroend
+
+!macro AddDisabledDDEHandlerValuesCall _KEY _VALOPEN _VALICON _DISPNAME _ISPROTOCOL
+  !verbose push
+  !verbose ${_MOZFUNC_VERBOSE}
+  Push "${_KEY}"
+  Push "${_VALOPEN}"
+  Push "${_VALICON}"
+  Push "${_DISPNAME}"
+  Push "${_ISPROTOCOL}"
+  Call AddDisabledDDEHandlerValues
+  !verbose pop
+!macroend
+
+!macro un.AddDisabledDDEHandlerValuesCall _KEY _VALOPEN _VALICON _DISPNAME _ISPROTOCOL
+  !verbose push
+  !verbose ${_MOZFUNC_VERBOSE}
+  Push "${_KEY}"
+  Push "${_VALOPEN}"
+  Push "${_VALICON}"
+  Push "${_DISPNAME}"
+  Push "${_ISPROTOCOL}"
+  Call un.AddDisabledDDEHandlerValues
+  !verbose pop
+!macroend
+
+!macro un.AddDisabledDDEHandlerValues
+  !ifndef un.AddDisabledDDEHandlerValues
+    !verbose push
+    !verbose ${_MOZFUNC_VERBOSE}
+    !undef _MOZFUNC_UN
+    !define _MOZFUNC_UN "un."
+
+    !insertmacro AddDisabledDDEHandlerValues
+
+    !undef _MOZFUNC_UN
+    !define _MOZFUNC_UN
+    !verbose pop
+  !endif
+!macroend
+
 
 ################################################################################
 # Macros for handling DLL registration
 
 !macro RegisterDLL DLL
 
   ; The x64 regsvr32.exe registers x86 DLL's properly on Windows Vista and above
   ; (not on Windows XP http://support.microsoft.com/kb/282747) so just use it
@@ -2799,16 +2949,17 @@
       StrCmp "$R8" "" end +1
       ${un.GetLongPath} "$INSTDIR" $R7
       ${un.GetPathFromString} "$R8" $R8
       ${un.GetParent} "$R8" $R8
       ${un.GetLongPath} "$R8" $R8
       StrCmp "$R7" "$R8" +1 end
       DeleteRegValue HKLM "Software\Classes\$R9\DefaultIcon" ""
       DeleteRegValue HKLM "Software\Classes\$R9\shell\open" ""
+      DeleteRegValue HKLM "Software\Classes\$R9\shell\open\command" ""
       DeleteRegValue HKLM "Software\Classes\$R9\shell\ddeexec" ""
       DeleteRegValue HKLM "Software\Classes\$R9\shell\ddeexec\Application" ""
       DeleteRegValue HKLM "Software\Classes\$R9\shell\ddeexec\Topic" ""
 
       end:
 
       Pop $R7
       Pop $R8