Merge from cvs-trunk-mirror
authorjorendorff@mozilla.com
Wed, 12 Sep 2007 15:23:10 -0400
changeset 5861 556751d911ac1194b31f3b2f367e8733900269a7
parent 5648 412cc3929707170f23248ea3e777a343ce90d63d (current diff)
parent 5860 c4ed14e576cdad60e53160e821ec152d691211e8 (diff)
child 5943 b490108eb99c774a9cfad70941da5ab964064aec
push id1
push userbsmedberg@mozilla.com
push dateThu, 20 Mar 2008 16:49:24 +0000
treeherdermozilla-central@61007906a1f8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone1.9a8pre
Merge from cvs-trunk-mirror
browser/components/preferences/applications.js
browser/components/preferences/applications.xul
browser/components/preferences/changeaction.js
browser/components/preferences/changeaction.xul
browser/components/preferences/downloadactions.js
browser/components/preferences/downloadactions.xul
browser/components/preferences/feeds.js
browser/components/preferences/feeds.xul
browser/components/preferences/handlers.css
browser/components/preferences/handlers.xml
browser/locales/en-US/chrome/browser/preferences/applications.dtd
browser/locales/en-US/chrome/browser/preferences/changeaction.dtd
browser/locales/en-US/chrome/browser/preferences/downloadactions.dtd
browser/locales/en-US/chrome/browser/preferences/feeds.dtd
browser/locales/en-US/chrome/browser/preferences/feeds.properties
browser/themes/pinstripe/browser/places/tag.png
browser/themes/winstripe/browser/places/tag.png
configure.in
editor/ui/composer/content/contents-region.rdf
editor/ui/composer/content/contents.rdf
editor/ui/locales/generic/chrome/composer/contents.rdf
editor/ui/locales/generic/chrome/region/contents.rdf
gfx/src/os2/Makefile.in
gfx/src/os2/gfxos2.pkg
gfx/src/os2/nsDeviceContextOS2.cpp
gfx/src/os2/nsDeviceContextOS2.h
gfx/src/os2/nsDrawingSurfaceOS2.cpp
gfx/src/os2/nsDrawingSurfaceOS2.h
gfx/src/os2/nsFontMetricsOS2.cpp
gfx/src/os2/nsFontMetricsOS2.h
gfx/src/os2/nsGfxDefs.cpp
gfx/src/os2/nsGfxDefs.h
gfx/src/os2/nsGfxFactoryOS2.cpp
gfx/src/os2/nsIRenderingContextOS2.h
gfx/src/os2/nsImageOS2.cpp
gfx/src/os2/nsImageOS2.h
gfx/src/os2/nsOS2Uni.cpp
gfx/src/os2/nsOS2Uni.h
gfx/src/os2/nsPaletteOS2.cpp
gfx/src/os2/nsPaletteOS2.h
gfx/src/os2/nsPrintOS2.cpp
gfx/src/os2/nsPrintOS2.h
gfx/src/os2/nsRegionOS2.cpp
gfx/src/os2/nsRegionOS2.h
gfx/src/os2/nsRenderingContextOS2.cpp
gfx/src/os2/nsRenderingContextOS2.h
gfx/src/os2/nsScreenManagerOS2.cpp
gfx/src/os2/nsScreenManagerOS2.h
gfx/src/os2/nsScreenOS2.cpp
gfx/src/os2/nsScreenOS2.h
js/src/Makefile.in
js/src/js.cpp
js/src/jsdbgapi.cpp
js/src/jsgc.cpp
js/src/jsobj.cpp
js/src/jsregexp.cpp
js/tests/js1_8/extensions/regress-394709.js
testing/performance/talos/ffinfo.py
testing/performance/talos/ffprofile.py
testing/performance/talos/initialize.html
testing/performance/talos/tp.py
testing/performance/talos/tp_linux.py
testing/performance/talos/tp_mac.py
testing/performance/talos/tp_win32.py
testing/performance/talos/ts.py
toolkit/mozapps/preferences/actionsshared.js
toolkit/themes/gnomestripe/global/menu/Menu-arrow-disabled-rtl.png
toolkit/themes/gnomestripe/global/menu/Menu-arrow-hover-rtl.png
toolkit/themes/gnomestripe/global/menu/Menu-arrow-rtl.png
toolkit/themes/winstripe/global/menu/Menu-arrow-disabled-rtl.png
toolkit/themes/winstripe/global/menu/Menu-arrow-disabled.png
toolkit/themes/winstripe/global/menu/Menu-arrow-hover-rtl.png
toolkit/themes/winstripe/global/menu/Menu-arrow-hover.png
toolkit/themes/winstripe/global/menu/Menu-arrow-rtl.png
toolkit/themes/winstripe/global/menu/Menu-arrow.png
toolkit/themes/winstripe/global/menu/menu-arrow-disabled.gif
toolkit/themes/winstripe/global/menu/menu-arrow-hover.gif
toolkit/themes/winstripe/global/menu/menu-arrow.gif
toolkit/themes/winstripe/global/menu/menu-check-disabled.gif
toolkit/themes/winstripe/global/menu/menu-check-hover.gif
toolkit/themes/winstripe/global/menu/menu-check.gif
toolkit/themes/winstripe/global/menu/menu-radio-disabled.gif
toolkit/themes/winstripe/global/menu/menu-radio-hover.gif
toolkit/themes/winstripe/global/menu/menu-radio.gif
uriloader/exthandler/nsHandlerService.js
uriloader/exthandler/nsHelperAppRDF.h
uriloader/exthandler/nsIHandlerService.idl
uriloader/exthandler/tests/unit/test_handlerService.js
--- a/Makefile.in
+++ b/Makefile.in
@@ -49,37 +49,37 @@ default alldep all::
 	$(RM) -rf $(DIST)/include
 	$(RM) -rf _tests
 	$(MAKE) -C config export
 
 TIERS += base
 
 #
 # tier "base" - basic setup
-# 
+#
 tier_base_dirs = \
 	config \
 	build \
 	$(NULL)
 
 include $(topsrcdir)/$(MOZ_BUILD_APP)/build.mk
 
 TIERS += testharness
 
-# test harnesses 
+# test harnesses
 ifdef ENABLE_TESTS
 tier_testharness_dirs += tools/test-harness
 endif
 
 GARBAGE_DIRS += dist
 DIST_GARBAGE = config.cache config.log config.status config-defs.h \
    dependencies.beos config/autoconf.mk config/myrules.mk config/myconfig.mk \
    unallmakefiles mozilla-config.h \
    gfx/gfx-config.h netwerk/necko-config.h xpcom/xpcom-config.h xpcom/xpcom-private.h \
-   $(topsrcdir)/.mozconfig.mk $(topsrcdir)/.mozconfig.out 
+   $(topsrcdir)/.mozconfig.mk $(topsrcdir)/.mozconfig.out
 
 # Build pseudo-external modules first when export is explicitly called
 export::
 	$(RM) -rf $(DIST)/sdk
 	$(MAKE) -C config export
 	$(MAKE) tier_nspr
 
 include $(topsrcdir)/config/rules.mk
@@ -158,36 +158,39 @@ MAKE_SYM_STORE_ARGS := --vcs-info
 DUMP_SYMS_BIN ?= $(DIST)/host/bin/dump_syms
 MAKE_SYM_STORE_PATH := $(DIST)/bin
 endif
 
 ifdef MOZ_SYMBOLS_EXTRA_BUILDID
 EXTRA_BUILDID := -$(MOZ_SYMBOLS_EXTRA_BUILDID)
 endif
 
+SYMBOL_ARCHIVE_BASENAME := \
+  $(MOZ_APP_NAME)-$(MOZ_APP_VERSION)-$(OS_ARCH)-$(BUILDID)$(EXTRA_BUILDID)
+
 buildsymbols:
 ifdef MOZ_CRASHREPORTER
 	echo building symbol store
 	mkdir -p $(DIST)/crashreporter-symbols/$(BUILDID)
 	$(PYTHON) $(topsrcdir)/toolkit/crashreporter/tools/symbolstore.py    \
 	  $(MAKE_SYM_STORE_ARGS) -s $(topsrcdir) $(DUMP_SYMS_BIN)     \
 	  $(DIST)/crashreporter-symbols/$(BUILDID)                    \
 	  $(MAKE_SYM_STORE_PATH) >                                    \
-	  $(DIST)/crashreporter-symbols/$(BUILDID)/$(MOZ_APP_NAME)-$(MOZ_APP_VERSION)-$(OS_ARCH)-$(BUILDID)$(EXTRA_BUILDID)-symbols.txt
+	  $(DIST)/crashreporter-symbols/$(BUILDID)/$(SYMBOL_ARCHIVE_BASENAME)-symbols.txt
 	echo packing symbols
 	mkdir -p $(topsrcdir)/../$(BUILDID)
 	cd $(DIST)/crashreporter-symbols/$(BUILDID) && \
-          zip -r9D ../crashreporter-symbols-$(BUILDID).zip .
-	mv $(DIST)/crashreporter-symbols/crashreporter-symbols-$(BUILDID).zip \
+          zip -r9D ../crashreporter-symbols-$(SYMBOL_ARCHIVE_BASENAME).zip .
+	mv $(DIST)/crashreporter-symbols/crashreporter-symbols-$(SYMBOL_ARCHIVE_BASENAME).zip \
           $(topsrcdir)/../$(BUILDID)
 endif # MOZ_CRASHREPORTER
 
 uploadsymbols:
 ifdef MOZ_CRASHREPORTER
-	$(topsrcdir)/toolkit/crashreporter/tools/upload_symbols.sh $(topsrcdir)/../$(BUILDID)/crashreporter-symbols-$(BUILDID).zip
+	$(topsrcdir)/toolkit/crashreporter/tools/upload_symbols.sh $(topsrcdir)/../$(BUILDID)/crashreporter-symbols-$(SYMBOL_ARCHIVE_BASENAME).zip
 endif
 
 ifeq ($(OS_ARCH),WINNT)
 signnss:
 ifdef MOZILLA_OFFICIAL
 	echo signing NSS libs
 	cd $(DIST)/bin; ./shlibsign.exe -v -i softokn3.dll
 	cd $(DIST)/bin; ./shlibsign.exe -v -i freebl3.dll
--- a/accessible/public/nsIAccessibleText.idl
+++ b/accessible/public/nsIAccessibleText.idl
@@ -52,16 +52,20 @@ interface nsIAccessibleText : nsISupport
   const nsAccessibleTextBoundary BOUNDARY_WORD_START = 1;
   const nsAccessibleTextBoundary BOUNDARY_WORD_END = 2;
   const nsAccessibleTextBoundary BOUNDARY_SENTENCE_START = 3; // don't use, deprecated
   const nsAccessibleTextBoundary BOUNDARY_SENTENCE_END = 4;  // don't use, deprecated
   const nsAccessibleTextBoundary BOUNDARY_LINE_START = 5;
   const nsAccessibleTextBoundary BOUNDARY_LINE_END = 6;
   const nsAccessibleTextBoundary BOUNDARY_ATTRIBUTE_RANGE = 7;
 
+  /**
+   * The current current caret offset.
+   * If set < 0 then caret will be placed  at the end of the text
+   */
   attribute long caretOffset;
 
   readonly attribute long characterCount;
   readonly attribute long selectionCount;
 
     /**
       * String methods may need to return multibyte-encoded strings,
       * since some locales can't be encoded using 16-bit chars.
@@ -155,19 +159,23 @@ interface nsIAccessibleText : nsISupport
    */
   long getOffsetAtPoint (in long x, in long y,
                          in unsigned long coordType);
 
   void getSelectionBounds (in long selectionNum,
                            out long startOffset,
                            out long endOffset);
 
+  /**
+   * Set the bounds for the given selection range
+   * Offsets < 0 will be treated as the equal to the end of the text
+   */
   void setSelectionBounds (in long selectionNum,
-                              in long startOffset,
-                              in long endOffset);
+                           in long startOffset,
+                           in long endOffset);
 
   void addSelection (in long startOffset, in long endOffset);
 
   void removeSelection (in long selectionNum);
 
 
   /**
    * Makes a specific part of string visible on screen.
--- a/accessible/src/atk/nsMaiInterfaceComponent.cpp
+++ b/accessible/src/atk/nsMaiInterfaceComponent.cpp
@@ -106,42 +106,21 @@ getExtentsCB(AtkComponent *aComponent,
 
     PRInt32 nsAccX, nsAccY, nsAccWidth, nsAccHeight;
     // Returned in screen coordinates
     nsresult rv = accWrap->GetBounds(&nsAccX, &nsAccY,
                                      &nsAccWidth, &nsAccHeight);
     if (NS_FAILED(rv))
         return;
     if (aCoordType == ATK_XY_WINDOW) {
-      // Make coordinates relative to top level window instead of screen
-      nsCOMPtr<nsIDOMNode> domNode;
-      accWrap->GetDOMNode(getter_AddRefs(domNode));
-      nsCOMPtr<nsIDocShellTreeItem> treeItem = nsAccessNode::GetDocShellTreeItemFor(domNode);
-      nsCOMPtr<nsIDocShellTreeItem> rootTreeItem;
-      treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem));
-      nsCOMPtr<nsIDOMDocument> domDoc = do_GetInterface(rootTreeItem);
-      nsCOMPtr<nsIDOMDocumentView> docView(do_QueryInterface(domDoc));
-      if (!docView) {
-        return;
-      }
-
-      nsCOMPtr<nsIDOMAbstractView> abstractView;
-      docView->GetDefaultView(getter_AddRefs(abstractView));
-      nsCOMPtr<nsIDOMWindowInternal> windowInter(do_QueryInterface(abstractView));
-      if (!windowInter) {
-        return;
-      }
-
-      PRInt32 screenX, screenY;
-      if (NS_FAILED(windowInter->GetScreenX(&screenX)) ||
-          NS_FAILED(windowInter->GetScreenY(&screenY))) {
-        return;
-      }
-      nsAccX -= screenX;
-      nsAccY -= screenY;
+        nsCOMPtr<nsIDOMNode> domNode;
+        accWrap->GetDOMNode(getter_AddRefs(domNode));
+        nsIntPoint winCoords = nsAccUtils::GetScreenCoordsForWindow(domNode);
+        nsAccX -= winCoords.x;
+        nsAccY -= winCoords.y;
     }
 
     *aAccX = nsAccX;
     *aAccY = nsAccY;
     *aAccWidth = nsAccWidth;
     *aAccHeight = nsAccHeight;
 }
 
--- a/accessible/src/base/nsAccessNode.cpp
+++ b/accessible/src/base/nsAccessNode.cpp
@@ -54,16 +54,17 @@
 #include "nsIDOMHTMLDocument.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsIDOMNSHTMLElement.h"
 #include "nsIDOMViewCSS.h"
 #include "nsIDOMWindow.h"
 #include "nsPIDOMWindow.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIFrame.h"
+#include "nsIScrollableFrame.h"
 #include "nsIPrefService.h"
 #include "nsIPrefBranch.h"
 #include "nsPresContext.h"
 #include "nsIPresShell.h"
 #include "nsIServiceManager.h"
 #include "nsIStringBundle.h"
 #include "nsITimer.h"
 #include "nsRootAccessible.h"
@@ -331,18 +332,18 @@ nsPresContext* nsAccessNode::GetPresCont
 
 already_AddRefed<nsIAccessibleDocument> nsAccessNode::GetDocAccessible()
 {
   return GetDocAccessibleFor(mWeakShell); // Addref'd
 }
 
 already_AddRefed<nsRootAccessible> nsAccessNode::GetRootAccessible()
 {
-  nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem = 
-    GetDocShellTreeItemFor(mDOMNode);
+  nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
+    nsAccUtils::GetDocShellTreeItemFor(mDOMNode);
   NS_ASSERTION(docShellTreeItem, "No docshell tree item for mDOMNode");
   if (!docShellTreeItem) {
     return nsnull;
   }
   nsCOMPtr<nsIDocShellTreeItem> root;
   docShellTreeItem->GetRootTreeItem(getter_AddRefs(root));
   NS_ASSERTION(root, "No root content tree item");
   if (!root) {
@@ -429,17 +430,87 @@ nsAccessNode::ScrollTo(PRUint32 aScrollT
   PRInt16 vPercent, hPercent;
   nsAccUtils::ConvertScrollTypeToPercents(aScrollType, &vPercent, &hPercent);
   return shell->ScrollContentIntoView(content, vPercent, hPercent);
 }
 
 NS_IMETHODIMP
 nsAccessNode::ScrollToPoint(PRUint32 aCoordinateType, PRInt32 aX, PRInt32 aY)
 {
-  return NS_ERROR_NOT_IMPLEMENTED;
+  nsIFrame *frame = GetFrame();
+  if (!frame)
+    return NS_ERROR_FAILURE;
+
+  nsPresContext *presContext = frame->PresContext();
+
+  switch (aCoordinateType) {
+    case nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE:
+      break;
+
+    case nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE:
+    {
+      nsIntPoint wndCoords = nsAccUtils::GetScreenCoordsForWindow(mDOMNode);
+      aX += wndCoords.x;
+      aY += wndCoords.y;
+      break;
+    }
+
+    case nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE:
+    {
+      nsCOMPtr<nsPIAccessNode> parent;
+
+      nsCOMPtr<nsIAccessible> accessible;
+      nsresult rv = QueryInterface(NS_GET_IID(nsIAccessible),
+                                   getter_AddRefs(accessible));
+      if (NS_SUCCEEDED(rv) && accessible) {
+        nsCOMPtr<nsIAccessible> parentAccessible;
+        accessible->GetParent(getter_AddRefs(parentAccessible));
+        parent = do_QueryInterface(parentAccessible);
+      } else {
+        nsCOMPtr<nsIAccessNode> parentAccessNode;
+        GetParentNode(getter_AddRefs(parentAccessNode));
+        parent = do_QueryInterface(parentAccessNode);
+      }
+
+      NS_ENSURE_STATE(parent);
+      nsIFrame *parentFrame = parent->GetFrame();
+      NS_ENSURE_STATE(parentFrame);
+
+      nsIntRect parentRect = parentFrame->GetScreenRectExternal();
+      aX += parentRect.x;
+      aY += parentRect.y;
+      break;
+    }
+
+    default:
+      return NS_ERROR_INVALID_ARG;
+  }
+
+  nsIFrame *parentFrame = frame;
+  while (parentFrame = parentFrame->GetParent()) {
+    nsIScrollableFrame *scrollableFrame = nsnull;
+    CallQueryInterface(parentFrame, &scrollableFrame);
+    if (scrollableFrame) {
+      nsIntRect frameRect = frame->GetScreenRectExternal();
+      PRInt32 devDeltaX = aX - frameRect.x;
+      PRInt32 devDeltaY = aY - frameRect.y;
+
+      nsPoint deltaPoint;
+      deltaPoint.x = presContext->DevPixelsToAppUnits(devDeltaX);
+      deltaPoint.y = presContext->DevPixelsToAppUnits(devDeltaY);
+
+      nsPoint scrollPoint = scrollableFrame->GetScrollPosition();
+
+      scrollPoint -= deltaPoint;
+
+      scrollableFrame->ScrollTo(scrollPoint);
+    }
+  }
+
+  return NS_OK;
 }
 
 nsresult
 nsAccessNode::MakeAccessNode(nsIDOMNode *aNode, nsIAccessNode **aAccessNode)
 {
   *aAccessNode = nsnull;
   
   nsIAccessibilityService *accService = GetAccService();
@@ -676,40 +747,16 @@ nsAccessNode::GetPresShellFor(nsIDOMNode
   nsIPresShell *presShell = nsnull;
   if (doc) {
     presShell = doc->GetPrimaryShell();
     NS_IF_ADDREF(presShell);
   }
   return presShell;
 }
 
-
-already_AddRefed<nsIDocShellTreeItem>
-nsAccessNode::GetDocShellTreeItemFor(nsIDOMNode *aStartNode)
-{
-  if (!aStartNode) {
-    return nsnull;
-  }
-  nsCOMPtr<nsIDOMDocument> domDoc;
-  aStartNode->GetOwnerDocument(getter_AddRefs(domDoc));
-  nsCOMPtr<nsIDocument> doc(do_QueryInterface(domDoc));
-  if (!doc) {
-    doc = do_QueryInterface(aStartNode);
-  }
-  NS_ASSERTION(doc, "No document for node passed in");
-  NS_ENSURE_TRUE(doc, nsnull);
-  nsCOMPtr<nsISupports> container = doc->GetContainer();
-  nsIDocShellTreeItem *docShellTreeItem = nsnull;
-  if (container) {
-    CallQueryInterface(container, &docShellTreeItem);
-  }
-
-  return docShellTreeItem;
-}
-
 already_AddRefed<nsIDOMNode>
 nsAccessNode::GetDOMNodeForContainer(nsISupports *aContainer)
 {
   nsIDOMNode* node = nsnull;
   nsCOMPtr<nsIDocShell> shell = do_QueryInterface(aContainer);
   nsCOMPtr<nsIContentViewer> cv;
   shell->GetContentViewer(getter_AddRefs(cv));
   if (cv) {
--- a/accessible/src/base/nsAccessNode.h
+++ b/accessible/src/base/nsAccessNode.h
@@ -44,17 +44,16 @@
 #define _nsAccessNode_H_
 
 #include "nsCOMPtr.h"
 #include "nsAccessibilityAtoms.h"
 #include "nsIAccessibleTypes.h"
 #include "nsIAccessNode.h"
 #include "nsIContent.h"
 #include "nsPIAccessNode.h"
-#include "nsIDocShellTreeItem.h"
 #include "nsIDOMNode.h"
 #include "nsINameSpaceManager.h"
 #include "nsIStringBundle.h"
 #include "nsWeakReference.h"
 #include "nsInterfaceHashtable.h"
 #include "nsIAccessibilityService.h"
 
 class nsIPresShell;
@@ -99,17 +98,16 @@ class nsAccessNode: public nsIAccessNode
 
     static PLDHashOperator PR_CALLBACK ClearCacheEntry(const void* aKey, nsCOMPtr<nsIAccessNode>& aAccessNode, void* aUserArg);
 
     // Static cache methods for global document cache
     static already_AddRefed<nsIAccessibleDocument> GetDocAccessibleFor(nsIWeakReference *aPresShell);
     static already_AddRefed<nsIAccessibleDocument> GetDocAccessibleFor(nsISupports *aContainer, PRBool aCanCreate = PR_FALSE);
     static already_AddRefed<nsIAccessibleDocument> GetDocAccessibleFor(nsIDOMNode *aNode);
 
-    static already_AddRefed<nsIDocShellTreeItem> GetDocShellTreeItemFor(nsIDOMNode *aStartNode);
     static already_AddRefed<nsIDOMNode> GetDOMNodeForContainer(nsISupports *aContainer);
     static already_AddRefed<nsIPresShell> GetPresShellFor(nsIDOMNode *aStartNode);
     
     // Return PR_TRUE if there is a role attribute
     static PRBool HasRoleAttribute(nsIContent *aContent)
     {
       return (aContent->IsNodeOfType(nsINode::eHTML) && aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::role)) ||
               aContent->HasAttr(kNameSpaceID_XHTML, nsAccessibilityAtoms::role) ||
--- a/accessible/src/base/nsAccessibilityUtils.cpp
+++ b/accessible/src/base/nsAccessibilityUtils.cpp
@@ -37,28 +37,34 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsAccessibilityUtils.h"
 
 #include "nsIAccessibleTypes.h"
 #include "nsPIAccessible.h"
 #include "nsAccessibleEventData.h"
 
+#include "nsIDocument.h"
+#include "nsIDOMAbstractView.h"
+#include "nsIDOMDocument.h"
+#include "nsIDOMDocumentView.h"
 #include "nsIDOMRange.h"
 #include "nsIDOMXULSelectCntrlEl.h"
 #include "nsIDOMXULSelectCntrlItemEl.h"
+#include "nsIDOMWindowInternal.h"
 #include "nsIEventListenerManager.h"
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsIEventStateManager.h"
 #include "nsISelection2.h"
 #include "nsISelectionController.h"
 
 #include "nsContentCID.h"
 #include "nsComponentManagerUtils.h"
+#include "nsIInterfaceRequestorUtils.h"
 
 static NS_DEFINE_IID(kRangeCID, NS_RANGE_CID);
 
 void
 nsAccUtils::GetAccAttr(nsIPersistentProperties *aAttributes, nsIAtom *aAttrName,
                        nsAString& aAttrValue)
 {
   nsCAutoString attrName;
@@ -342,8 +348,57 @@ nsAccUtils::ConvertScrollTypeToPercents(
       *aHPercent = NS_PRESSHELL_SCROLL_RIGHT;
       break;
     default:
       *aVPercent = NS_PRESSHELL_SCROLL_ANYWHERE;
       *aHPercent = NS_PRESSHELL_SCROLL_ANYWHERE;
   }
 }
 
+nsIntPoint
+nsAccUtils::GetScreenCoordsForWindow(nsIDOMNode *aNode)
+{
+  nsIntPoint coords(0, 0);
+  nsCOMPtr<nsIDocShellTreeItem> treeItem(GetDocShellTreeItemFor(aNode));
+  if (!treeItem)
+    return coords;
+
+  nsCOMPtr<nsIDocShellTreeItem> rootTreeItem;
+  treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem));
+  nsCOMPtr<nsIDOMDocument> domDoc = do_GetInterface(rootTreeItem);
+  nsCOMPtr<nsIDOMDocumentView> docView(do_QueryInterface(domDoc));
+  if (!docView)
+    return coords;
+
+  nsCOMPtr<nsIDOMAbstractView> abstractView;
+  docView->GetDefaultView(getter_AddRefs(abstractView));
+  nsCOMPtr<nsIDOMWindowInternal> windowInter(do_QueryInterface(abstractView));
+  if (!windowInter)
+    return coords;
+
+  windowInter->GetScreenX(&coords.x);
+  windowInter->GetScreenY(&coords.y);
+  return coords;
+}
+
+already_AddRefed<nsIDocShellTreeItem>
+nsAccUtils::GetDocShellTreeItemFor(nsIDOMNode *aNode)
+{
+  if (!aNode)
+    return nsnull;
+
+  nsCOMPtr<nsIDOMDocument> domDoc;
+  aNode->GetOwnerDocument(getter_AddRefs(domDoc));
+  nsCOMPtr<nsIDocument> doc(do_QueryInterface(domDoc));
+  if (!doc)
+    doc = do_QueryInterface(aNode);
+
+  NS_ASSERTION(doc, "No document for node passed in");
+  NS_ENSURE_TRUE(doc, nsnull);
+
+  nsCOMPtr<nsISupports> container = doc->GetContainer();
+  nsIDocShellTreeItem *docShellTreeItem = nsnull;
+  if (container)
+    CallQueryInterface(container, &docShellTreeItem);
+
+  return docShellTreeItem;
+}
+
--- a/accessible/src/base/nsAccessibilityUtils.h
+++ b/accessible/src/base/nsAccessibilityUtils.h
@@ -41,16 +41,18 @@
 
 #include "nsAccessibilityAtoms.h"
 #include "nsIAccessible.h"
 
 #include "nsIDOMNode.h"
 #include "nsIPersistentProperties2.h"
 #include "nsIContent.h"
 #include "nsIFrame.h"
+#include "nsIDocShellTreeItem.h"
+#include "nsPoint.h"
 
 class nsAccUtils
 {
 public:
   /**
    * Returns value of attribute from the given attributes container.
    *
    * @param aAttributes - attributes container
@@ -160,12 +162,25 @@ public:
 
   /**
    * Converts scroll type constant defined in nsIAccessibleScrollType to
    * vertical and horizontal percents.
    */
   static void ConvertScrollTypeToPercents(PRUint32 aScrollType,
                                           PRInt16 *aVPercent,
                                           PRInt16 *aHPercent);
+
+  /**
+   * Returns coordinates relative screen for the top level window.
+   *
+   * @param - aNode - the DOM node hosted in the window.
+   */
+  static nsIntPoint GetScreenCoordsForWindow(nsIDOMNode *aNode);
+
+  /**
+   * Return document shell tree item for the given DOM node.
+   */
+  static already_AddRefed<nsIDocShellTreeItem>
+    GetDocShellTreeItemFor(nsIDOMNode *aNode);
 };
 
 #endif
 
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -1046,16 +1046,20 @@ nsAccessible::GetState(PRUint32 *aState,
   PRBool isOffscreen;
   if (!IsVisible(&isOffscreen)) {
     *aState |= nsIAccessibleStates::STATE_INVISIBLE;
   }
   if (isOffscreen) {
     *aState |= nsIAccessibleStates::STATE_OFFSCREEN;
   }
 
+  nsIFrame *frame = GetFrame();
+  if (frame && (frame->GetStateBits() & NS_FRAME_OUT_OF_FLOW))
+    *aState |= nsIAccessibleStates::STATE_FLOATING;
+
   return NS_OK;
 }
 
   /* readonly attribute boolean focusedChild; */
 NS_IMETHODIMP nsAccessible::GetFocusedChild(nsIAccessible **aFocusedChild) 
 { 
   nsCOMPtr<nsIAccessible> focusedChild;
   if (gLastFocusedNode == mDOMNode) {
@@ -1077,80 +1081,83 @@ NS_IMETHODIMP nsAccessible::GetFocusedCh
     }
   }
 
   NS_IF_ADDREF(*aFocusedChild = focusedChild);
   return NS_OK;
 }
 
   /* nsIAccessible getChildAtPoint (in long x, in long y); */
-NS_IMETHODIMP nsAccessible::GetChildAtPoint(PRInt32 tx, PRInt32 ty, nsIAccessible **aAccessible)
+NS_IMETHODIMP
+nsAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
+                              nsIAccessible **aAccessible)
 {
+  NS_ENSURE_ARG_POINTER(aAccessible);
   *aAccessible = nsnull;
 
-  nsCOMPtr<nsIAccessible> child;
-  GetFirstChild(getter_AddRefs(child));
-
-  PRInt32 x, y, w, h;
-  PRUint32 state;
-
-  nsCOMPtr<nsIAccessible> childAtPoint;
-  while (child) {
-    child->GetBounds(&x, &y, &w, &h);
-    if (tx >= x && tx < x + w && ty >= y && ty < y + h) {
-      nsCOMPtr<nsPIAccessNode> accessNode(do_QueryInterface(child));
-      if (accessNode) {
-        nsIFrame *frame = accessNode->GetFrame();
-        if (!frame) {
-          state = State(child);
-          // In some cases accessibles don't have a frame; examples are
-          // tree items or combo box dropdown markers. For these cases
-          // just ensure that the returned accessible is visible.
-          if ((state & (nsIAccessibleStates::STATE_OFFSCREEN |
-              nsIAccessibleStates::STATE_INVISIBLE)) == 0) {
-            // Don't walk into offscreen or invisible items
-            NS_IF_ADDREF(*aAccessible = child);
-            return NS_OK;
-          }
-        }
-        else {
-          // If there are multiple accessibles the contain the point 
-          // and they overlap then pick the one with a frame that contains the point
-          // For example, A point that's in block #2 is also in block #1, but we want to return #2:
-          // [[block #1 is long wrapped text that continues to
-          // another line]]  [[here is a shorter block #2]]
-          while (frame) {
-            if (frame->GetScreenRectExternal().Contains(tx, ty)) {
-              childAtPoint = child;
-              break; // Definitely in this accessible, since one of its frame matches the point
-            }
-            frame = frame->GetNextContinuation();
-          }
-        }
-      }
-    }
-    nsCOMPtr<nsIAccessible> next;
-    child->GetNextSibling(getter_AddRefs(next));
-    child = next;
+  // Search an accessible at the given point starting from accessible document
+  // because containing block (see CSS2) for out of flow element (for example,
+  // absolutely positioned element) may be different from its DOM parent and
+  // therefore accessible for containing block may be different from accessible
+  // for DOM parent but GetFrameForPoint() should be called for containing block
+  // to get an out of flow element.
+  nsCOMPtr<nsIAccessibleDocument> accDocument;
+  nsresult rv = GetAccessibleDocument(getter_AddRefs(accDocument));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  if (!accDocument)
+    return NS_OK;
+
+  nsCOMPtr<nsPIAccessNode> accessNodeDocument(do_QueryInterface(accDocument));
+  NS_ASSERTION(accessNodeDocument,
+               "nsIAccessibleDocument doesn't implement nsPIAccessNode");
+
+  nsIFrame *frame = accessNodeDocument->GetFrame();
+  NS_ENSURE_STATE(frame);
+
+  nsPresContext *presContext = frame->PresContext();
+
+  nsIntRect screenRect = frame->GetScreenRectExternal();
+  nsPoint offset(presContext->DevPixelsToAppUnits(aX - screenRect.x),
+                 presContext->DevPixelsToAppUnits(aY - screenRect.y));
+
+  nsCOMPtr<nsIPresShell> presShell = presContext->PresShell();
+  nsIFrame *foundFrame = presShell->GetFrameForPoint(frame, offset);
+  if (!foundFrame)
+    return NS_OK;
+
+  nsCOMPtr<nsIContent> content(foundFrame->GetContent());
+  if (!content)
+    return NS_OK;
+
+  nsCOMPtr<nsIDOMNode> node(do_QueryInterface(content));
+  nsCOMPtr<nsIAccessibilityService> accService = GetAccService();
+
+  nsCOMPtr<nsIDOMNode> relevantNode;
+  accService->GetRelevantContentNodeFor(node, getter_AddRefs(relevantNode));
+  if (!relevantNode)
+    return NS_OK;
+
+  nsCOMPtr<nsIAccessible> accessible;
+  accService->GetAccessibleFor(relevantNode, getter_AddRefs(accessible));
+  if (!accessible)
+    return NS_OK;
+
+  nsCOMPtr<nsIAccessible> parent;
+  accessible->GetParent(getter_AddRefs(parent));
+
+  while (parent && parent != this) {
+    accessible.swap(parent);
+    accessible->GetParent(getter_AddRefs(parent));
   }
 
-  if (childAtPoint) {
-    NS_ADDREF(*aAccessible = childAtPoint);
-    return NS_OK;
-  }
-  GetState(&state, nsnull);
-  GetBounds(&x, &y, &w, &h);
-  if ((state & (nsIAccessibleStates::STATE_OFFSCREEN |
-                nsIAccessibleStates::STATE_INVISIBLE)) == 0 &&
-      tx >= x && tx < x + w && ty >= y && ty < y + h) {
-    *aAccessible = this;
-    NS_ADDREF_THIS();
-    return NS_OK;
-  }
-  return NS_ERROR_FAILURE;
+  if (parent)
+    NS_ADDREF(*aAccessible = accessible);
+
+  return NS_OK;
 }
 
 void nsAccessible::GetBoundsRect(nsRect& aTotalBounds, nsIFrame** aBoundingFrame)
 {
 /*
  * This method is used to determine the bounds of a content node.
  * Because HTML wraps and links are not always rectangular, this
  * method uses the following algorithm:
@@ -2218,22 +2225,24 @@ PRBool nsAccessible::MappedAttrState(nsI
 
   nsAutoString attribValue;
   nsCOMPtr<nsIAtom> attribAtom = do_GetAtom(aStateMapEntry->attributeName); // XXX put atoms directly in entry
   NS_ENSURE_TRUE(attribAtom, NS_ERROR_OUT_OF_MEMORY);
   if (aContent->GetAttr(kNameSpaceID_WAIProperties, attribAtom, attribValue)) {
     if (aStateMapEntry->attributeValue == kBoolState) {
       // No attribute value map specified in state map entry indicates state cleared
       if (attribValue.EqualsLiteral("false")) {
-        return *aStateInOut &= ~aStateMapEntry->state;
+        *aStateInOut &= ~aStateMapEntry->state;
       }
-      return *aStateInOut |= aStateMapEntry->state;
+      else {
+        *aStateInOut |= aStateMapEntry->state;
+      }
     }
-    if (NS_ConvertUTF16toUTF8(attribValue).Equals(aStateMapEntry->attributeValue)) {
-      return *aStateInOut |= aStateMapEntry->state;
+    else if (NS_ConvertUTF16toUTF8(attribValue).Equals(aStateMapEntry->attributeValue)) {
+      *aStateInOut |= aStateMapEntry->state;
     }
   }
 
   return PR_TRUE;
 }
 
 NS_IMETHODIMP
 nsAccessible::GetFinalState(PRUint32 *aState, PRUint32 *aExtraState)
@@ -3144,22 +3153,23 @@ PRInt32 nsAccessible::TextLength(nsIAcce
 {
   if (!IsText(aAccessible))
     return 1;
 
   nsCOMPtr<nsPIAccessNode> pAccNode(do_QueryInterface(aAccessible));
   NS_ASSERTION(pAccNode, "QI to nsPIAccessNode failed");
 
   nsIFrame *frame = pAccNode->GetFrame();
-  if (frame) { // Optimal way to get the text length -- no string copy
+  if (frame && frame->GetType() == nsAccessibilityAtoms::textFrame) {
+    // Ensure that correct text length is calculated (with non-rendered whitespace chars not counted)
     nsIContent *content = frame->GetContent();
     if (content) {
       PRUint32 length;
       nsresult rv = nsHyperTextAccessible::ContentToRenderedOffset(frame, content->TextLength(), &length);
-      return NS_SUCCEEDED(rv) ? length : -1;
+      return NS_SUCCEEDED(rv) ? static_cast<PRInt32>(length) : -1;
     }
   }
 
   // For list bullets (or anything other accessible which would compute its own text
   // They don't have their own frame.
   // XXX In the future, list bullets may have frame and anon content, so 
   // we should be able to remove this at that point
   nsCOMPtr<nsPIAccessible> pAcc(do_QueryInterface(aAccessible));
--- a/accessible/src/base/nsCaretAccessible.cpp
+++ b/accessible/src/base/nsCaretAccessible.cpp
@@ -247,16 +247,18 @@ nsCaretAccessible::GetCaretRect(nsIWidge
 
   nsICaret *caret;
   presShell->GetCaret(&caret);
   NS_ENSURE_TRUE(caret, caretRect);
 
   PRBool isCollapsed;
   nsIView *view;
   nsCOMPtr<nsISelection> caretSelection(do_QueryReferent(mLastUsedSelection));
+  NS_ENSURE_TRUE(caretSelection, caretRect);
+  
   caret->GetCaretCoordinates(nsICaret::eRenderingViewCoordinates, caretSelection,
                              &caretRect, &isCollapsed, &view);
   if (!view || caretRect.IsEmpty()) {
     return nsRect(); // Return empty rect
   }
 
   PRBool isVisible;
   caret->GetCaretVisible(&isVisible);
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -104,18 +104,18 @@ nsDocAccessible::nsDocAccessible(nsIDOMN
         mWnd = widget->GetNativeData(NS_NATIVE_WINDOW);
       }
     }
   }
 
   // XXX aaronl should we use an algorithm for the initial cache size?
   mAccessNodeCache.Init(kDefaultCacheSize);
 
-  nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =                              
-    GetDocShellTreeItemFor(mDOMNode);
+  nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
+    nsAccUtils::GetDocShellTreeItemFor(mDOMNode);
   nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(docShellTreeItem);
   if (docShell) {
     PRUint32 busyFlags;
     docShell->GetBusyFlags(&busyFlags);
     if (busyFlags == nsIDocShell::BUSY_FLAGS_NONE) {
       mIsContentLoaded = PR_TRUE;                                               
     }
   }
@@ -159,17 +159,17 @@ NS_IMETHODIMP nsDocAccessible::GetName(n
   return rv;
 }
 
 NS_IMETHODIMP nsDocAccessible::GetRole(PRUint32 *aRole)
 {
   *aRole = nsIAccessibleRole::ROLE_PANE; // Fall back
 
   nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
-    GetDocShellTreeItemFor(mDOMNode);
+    nsAccUtils::GetDocShellTreeItemFor(mDOMNode);
   if (docShellTreeItem) {
     nsCOMPtr<nsIDocShellTreeItem> sameTypeRoot;
     docShellTreeItem->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot));
     PRInt32 itemType;
     docShellTreeItem->GetItemType(&itemType);
     if (sameTypeRoot == docShellTreeItem) {
       // Root of content or chrome tree
       if (itemType == nsIDocShellTreeItem::typeChrome) {
@@ -273,21 +273,26 @@ NS_IMETHODIMP nsDocAccessible::TakeFocus
 {
   NS_ENSURE_TRUE(mDocument, NS_ERROR_FAILURE);
   PRUint32 state;
   GetState(&state, nsnull);
   if (0 == (state & nsIAccessibleStates::STATE_FOCUSABLE)) {
     return NS_ERROR_FAILURE; // Not focusable
   }
 
-  nsCOMPtr<nsIDocShellTreeItem> treeItem = GetDocShellTreeItemFor(mDOMNode);
+  nsCOMPtr<nsIDocShellTreeItem> treeItem =
+    nsAccUtils::GetDocShellTreeItemFor(mDOMNode);
   nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(treeItem);
   NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIPresShell> shell(GetPresShell());
+  if (!shell) {
+    NS_WARNING("Was not shutdown properly via InvalidateCacheSubtree()");
+    return NS_ERROR_FAILURE;
+  }
   nsIEventStateManager *esm = shell->GetPresContext()->EventStateManager();
   NS_ENSURE_TRUE(esm, NS_ERROR_FAILURE);
 
   // Focus the document
   nsresult rv = docShell->SetHasFocus(PR_TRUE);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Clear out any existing focus state
@@ -520,17 +525,18 @@ NS_IMETHODIMP nsDocAccessible::Destroy()
 }
 
 NS_IMETHODIMP nsDocAccessible::Shutdown()
 {
   if (!mWeakShell) {
     return NS_OK;  // Already shutdown
   }
 
-  nsCOMPtr<nsIDocShellTreeItem> treeItem = GetDocShellTreeItemFor(mDOMNode);
+  nsCOMPtr<nsIDocShellTreeItem> treeItem =
+    nsAccUtils::GetDocShellTreeItemFor(mDOMNode);
   ShutdownChildDocuments(treeItem);
 
   if (mDocLoadTimer) {
     mDocLoadTimer->Cancel();
     mDocLoadTimer = nsnull;
   }
 
   RemoveEventListeners();
@@ -782,17 +788,18 @@ NS_IMETHODIMP nsDocAccessible::FireDocLo
     if (!mDocLoadTimer) {
       mDocLoadTimer = do_CreateInstance("@mozilla.org/timer;1");
     }
     if (mDocLoadTimer) {
       mDocLoadTimer->InitWithFuncCallback(DocLoadCallback, this, 0,
                                           nsITimer::TYPE_ONE_SHOT);
     }
   } else {
-    nsCOMPtr<nsIDocShellTreeItem> treeItem = GetDocShellTreeItemFor(mDOMNode);
+    nsCOMPtr<nsIDocShellTreeItem> treeItem =
+      nsAccUtils::GetDocShellTreeItemFor(mDOMNode);
     if (!treeItem) {
       return NS_OK;
     }
 
     nsCOMPtr<nsIDocShellTreeItem> sameTypeRoot;
     treeItem->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot));
     if (sameTypeRoot != treeItem) {
       return NS_OK; 
@@ -1163,21 +1170,28 @@ void nsDocAccessible::ContentStatesChang
   if (0 == (aStateMask & NS_EVENT_STATE_CHECKED)) {
     return;
   }
 
   nsHTMLSelectOptionAccessible::SelectionChangedIfOption(aContent1);
   nsHTMLSelectOptionAccessible::SelectionChangedIfOption(aContent2);
 }
 
+void nsDocAccessible::CharacterDataWillChange(nsIDocument *aDocument,
+                                              nsIContent* aContent,
+                                              CharacterDataChangeInfo* aInfo)
+{
+  FireTextChangeEventForText(aContent, aInfo, PR_FALSE);
+}
+
 void nsDocAccessible::CharacterDataChanged(nsIDocument *aDocument,
                                            nsIContent* aContent,
                                            CharacterDataChangeInfo* aInfo)
 {
-  FireTextChangedEventOnDOMCharacterDataModified(aContent, aInfo);
+  FireTextChangeEventForText(aContent, aInfo, PR_TRUE);
 }
 
 void
 nsDocAccessible::ContentInserted(nsIDocument *aDocument, nsIContent* aContainer,
                                  nsIContent* aChild, PRInt32 aIndexInContainer)
 {
   // InvalidateCacheSubtree will not fire the EVENT_SHOW for the new node
   // unless an accessible can be created for the passed in node, which it
@@ -1198,18 +1212,19 @@ nsDocAccessible::ContentRemoved(nsIDocum
 }
 
 void
 nsDocAccessible::ParentChainChanged(nsIContent *aContent)
 {
 }
 
 void
-nsDocAccessible::FireTextChangedEventOnDOMCharacterDataModified(nsIContent *aContent,
-                                                                CharacterDataChangeInfo* aInfo)
+nsDocAccessible::FireTextChangeEventForText(nsIContent *aContent,
+                                            CharacterDataChangeInfo* aInfo,
+                                            PRBool aIsInserted)
 {
   if (!mIsContentLoaded || !mDocument) {
     return;
   }
 
   nsCOMPtr<nsIDOMNode> node(do_QueryInterface(aContent));
   if (!node)
     return;
@@ -1221,36 +1236,48 @@ nsDocAccessible::FireTextChangedEventOnD
 
   nsRefPtr<nsHyperTextAccessible> textAccessible;
   rv = accessible->QueryInterface(NS_GET_IID(nsHyperTextAccessible),
                                   getter_AddRefs(textAccessible));
   if (NS_FAILED(rv) || !textAccessible)
     return;
 
   PRInt32 start = aInfo->mChangeStart;
-  PRUint32 end = aInfo->mChangeEnd;
-  PRInt32 length = end - start;
-  PRUint32 replaceLen = aInfo->mReplaceLength;
 
   PRInt32 offset = 0;
   rv = textAccessible->DOMPointToHypertextOffset(node, start, &offset);
   if (NS_FAILED(rv))
     return;
 
-  // Text has been removed.
+  PRInt32 length = aIsInserted ?
+    aInfo->mReplaceLength: // text has been added
+    aInfo->mChangeEnd - start; // text has been removed
+
   if (length > 0) {
+    nsCOMPtr<nsIPresShell> shell(do_QueryReferent(mWeakShell));
+    if (!shell)
+      return;
+
+    PRUint32 renderedStartOffset, renderedEndOffset;
+    nsIFrame* frame = shell->GetPrimaryFrameFor(aContent);
+
+    rv = textAccessible->ContentToRenderedOffset(frame, start,
+                                                 &renderedStartOffset);
+    if (NS_FAILED(rv))
+      return;
+
+    rv = textAccessible->ContentToRenderedOffset(frame, start + length,
+                                                 &renderedEndOffset);
+    if (NS_FAILED(rv))
+      return;
+
     nsCOMPtr<nsIAccessibleTextChangeEvent> event =
-      new nsAccTextChangeEvent(accessible, offset, length, PR_FALSE);
-    textAccessible->FireAccessibleEvent(event);
-  }
-
-  // Text has been added.
-  if (replaceLen) {
-    nsCOMPtr<nsIAccessibleTextChangeEvent> event =
-      new nsAccTextChangeEvent(accessible, offset, replaceLen, PR_TRUE);
+      new nsAccTextChangeEvent(accessible, offset,
+                               renderedEndOffset - renderedStartOffset,
+                               aIsInserted, PR_FALSE);
     textAccessible->FireAccessibleEvent(event);
   }
 }
 
 already_AddRefed<nsIAccessibleTextChangeEvent>
 nsDocAccessible::CreateTextChangeEventForNode(nsIAccessible *aContainerAccessible,
                                               nsIDOMNode *aChangeNode,
                                               nsIAccessible *aAccessibleForChangeNode,
@@ -1847,17 +1874,17 @@ void nsDocAccessible::DocLoadCallback(ns
       // A frame or iframe has finished loading new content
       docAcc->InvalidateCacheSubtree(nsnull, nsIAccessibleEvent::EVENT_DOM_SIGNIFICANT_CHANGE);
       return;
     }
 
     // Fire STATE_CHANGE event for doc load finish if focus is in same doc tree
     if (gLastFocusedNode) {
       nsCOMPtr<nsIDocShellTreeItem> focusedTreeItem =
-        GetDocShellTreeItemFor(gLastFocusedNode);
+        nsAccUtils::GetDocShellTreeItemFor(gLastFocusedNode);
       if (focusedTreeItem) {
         nsCOMPtr<nsIDocShellTreeItem> sameTypeRootOfFocus;
         focusedTreeItem->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRootOfFocus));
         if (sameTypeRoot == sameTypeRootOfFocus) {
           nsCOMPtr<nsIAccessibleStateChangeEvent> accEvent =
             new nsAccStateChangeEvent(docAcc, nsIAccessibleStates::STATE_BUSY,
                                       PR_FALSE, PR_FALSE);
           docAcc->FireAccessibleEvent(accEvent);
--- a/accessible/src/base/nsDocAccessible.h
+++ b/accessible/src/base/nsDocAccessible.h
@@ -152,20 +152,27 @@ class nsDocAccessible : public nsHyperTe
      * Fires accessible events when ARIA attribute is chaned.
      *
      * @param aContent - node that attribute is changed for
      * @param aAttribute - changed attribute
      */
     void ARIAAttributeChanged(nsIContent* aContent, nsIAtom* aAttribute);
 
     /**
-     * Fire text changed event for charackter data changed.
+     * Fire text changed event for character data changed. The method is used
+     * from nsIMutationObserver methods.
+     *
+     * @param aContent     the text node holding changed data
+     * @param aInfo        info structure describing how the data was changed
+     * @param aIsInserted  the flag pointed whether removed or inserted
+     *                     characters should be cause of event
      */
-    void FireTextChangedEventOnDOMCharacterDataModified(nsIContent *aContent,
-                                                        CharacterDataChangeInfo* aInfo);
+    void FireTextChangeEventForText(nsIContent *aContent,
+                                    CharacterDataChangeInfo* aInfo,
+                                    PRBool aIsInserted);
 
     /**
      * Create a text change event for a changed node
      * @param aContainerAccessible, the first accessible in the container
      * @param aChangeNode, the node that is being inserted or removed, or shown/hidden
      * @param aAccessibleForChangeNode, the accessible for that node, or nsnull if none exists
      * @param aIsInserting, is aChangeNode being created or shown (vs. removed or hidden)
      */
--- a/accessible/src/base/nsRootAccessible.cpp
+++ b/accessible/src/base/nsRootAccessible.cpp
@@ -127,17 +127,17 @@ NS_IMETHODIMP nsRootAccessible::GetName(
   if (mRoleMapEntry) {
     nsAccessible::GetName(aName);
     if (!aName.IsEmpty()) {
       return NS_OK;
     }
   }
 
   nsCOMPtr<nsIDocShellTreeItem> docShellAsItem =
-    GetDocShellTreeItemFor(mDOMNode);
+    nsAccUtils::GetDocShellTreeItemFor(mDOMNode);
   NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
   docShellAsItem->GetTreeOwner(getter_AddRefs(treeOwner));
 
   nsCOMPtr<nsIBaseWindow> baseWindow(do_QueryInterface(treeOwner));
   if (baseWindow) {
     nsXPIDLString title;
@@ -186,17 +186,18 @@ NS_IMETHODIMP nsRootAccessible::GetRole(
 }
 
 #ifdef MOZ_XUL
 PRUint32 nsRootAccessible::GetChromeFlags()
 {
   // Return the flag set for the top level window as defined 
   // by nsIWebBrowserChrome::CHROME_WINDOW_[FLAGNAME]
   // Not simple: nsIXULWindow is not just a QI from nsIDOMWindow
-  nsCOMPtr<nsIDocShellTreeItem> treeItem = GetDocShellTreeItemFor(mDOMNode);
+  nsCOMPtr<nsIDocShellTreeItem> treeItem =
+    nsAccUtils::GetDocShellTreeItemFor(mDOMNode);
   NS_ENSURE_TRUE(treeItem, 0);
   nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
   treeItem->GetTreeOwner(getter_AddRefs(treeOwner));
   NS_ENSURE_TRUE(treeOwner, 0);
   nsCOMPtr<nsIXULWindow> xulWin(do_GetInterface(treeOwner));
   if (!xulWin) {
     return 0;
   }
@@ -372,17 +373,17 @@ void nsRootAccessible::TryFireEarlyLoadE
 
   // Note, we don't fire any page load finished events for chrome or for
   // frame/iframe page loads during the initial complete page load -- that page
   // load event for the entire content pane needs to stand alone.
 
   // This also works for firing events for error pages
 
   nsCOMPtr<nsIDocShellTreeItem> treeItem =
-    GetDocShellTreeItemFor(aDocNode);
+    nsAccUtils::GetDocShellTreeItemFor(aDocNode);
   NS_ASSERTION(treeItem, "No docshelltreeitem for aDocNode");
   if (!treeItem) {
     return;
   }
   PRInt32 itemType;
   treeItem->GetItemType(&itemType);
   if (itemType != nsIDocShellTreeItem::typeContent) {
     return;
@@ -970,17 +971,18 @@ NS_IMETHODIMP nsRootAccessible::GetAcces
                                                      nsIAccessible **aRelated)
 {
   *aRelated = nsnull;
 
   if (!mDOMNode || aRelationType != nsIAccessibleRelation::RELATION_EMBEDS) {
     return nsDocAccessibleWrap::GetAccessibleRelated(aRelationType, aRelated);
   }
 
-  nsCOMPtr<nsIDocShellTreeItem> treeItem = GetDocShellTreeItemFor(mDOMNode);   
+  nsCOMPtr<nsIDocShellTreeItem> treeItem =
+    nsAccUtils::GetDocShellTreeItemFor(mDOMNode);
   nsCOMPtr<nsIDocShellTreeItem> contentTreeItem = GetContentDocShell(treeItem);
   // there may be no content area, so we need a null check
   if (contentTreeItem) {
     nsCOMPtr<nsIAccessibleDocument> accDoc =
       GetDocAccessibleFor(contentTreeItem, PR_TRUE);
     NS_ASSERTION(accDoc, "No EMBEDS document");
     if (accDoc) {
       accDoc->QueryInterface(NS_GET_IID(nsIAccessible), (void**)aRelated);
@@ -991,17 +993,17 @@ NS_IMETHODIMP nsRootAccessible::GetAcces
 
 NS_IMETHODIMP nsRootAccessible::FireDocLoadEvents(PRUint32 aEventType)
 {
   if (!mDocument || !mWeakShell) {
     return NS_OK;  // Document has been shut down
   }
 
   nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
-    nsAccessNode::GetDocShellTreeItemFor(mDOMNode);
+    nsAccUtils::GetDocShellTreeItemFor(mDOMNode);
   NS_ASSERTION(docShellTreeItem, "No doc shell tree item for document");
   NS_ENSURE_TRUE(docShellTreeItem, NS_ERROR_FAILURE);
   PRInt32 contentType;
   docShellTreeItem->GetItemType(&contentType);
   if (contentType == nsIDocShellTreeItem::typeContent) {
     return nsDocAccessibleWrap::FireDocLoadEvents(aEventType); // Content might need to fire event
   }
 
--- a/accessible/src/html/nsHyperTextAccessible.cpp
+++ b/accessible/src/html/nsHyperTextAccessible.cpp
@@ -237,16 +237,21 @@ void nsHyperTextAccessible::CacheChildre
 }
 
 // Substring must be entirely within the same text node
 nsIntRect nsHyperTextAccessible::GetBoundsForString(nsIFrame *aFrame, PRUint32 aStartRenderedOffset,
                                                     PRUint32 aEndRenderedOffset)
 {
   nsIntRect screenRect;
   NS_ENSURE_TRUE(aFrame, screenRect);
+  if (aFrame->GetType() != nsAccessibilityAtoms::textFrame) {
+    // XXX fallback for non-text frames, happens for bullets right now
+    // but in the future bullets will have proper text frames
+    return aFrame->GetScreenRectExternal();
+  }
 
   PRInt32 startContentOffset, endContentOffset;
   nsresult rv = RenderedToContentOffset(aFrame, aStartRenderedOffset, &startContentOffset);
   NS_ENSURE_SUCCESS(rv, screenRect);
   rv = RenderedToContentOffset(aFrame, aEndRenderedOffset, &endContentOffset);
   NS_ENSURE_SUCCESS(rv, screenRect);
 
   nsIFrame *frame;
@@ -359,39 +364,48 @@ nsHyperTextAccessible::GetPosAndText(PRI
     nsIFrame *frame = accessNode->GetFrame();
     if (!frame) {
       continue;
     }
     nsIFrame *primaryFrame = frame;
     if (IsText(accessible)) {
       // We only need info up to rendered offset -- that is what we're
       // converting to content offset
-      PRInt32 substringEndOffset;
-      nsresult rv = frame->GetRenderedText(nsnull, &skipChars, &iter);
-      PRUint32 ourRenderedStart = iter.GetSkippedOffset();
-      PRInt32 ourContentStart = iter.GetOriginalOffset();
-      if (NS_SUCCEEDED(rv)) {
-        substringEndOffset =
-          iter.ConvertOriginalToSkipped(skipChars.GetOriginalCharCount() +
-                                        ourContentStart) -
-          ourRenderedStart;
+      PRInt32 substringEndOffset = -1;
+      PRUint32 ourRenderedStart = 0;
+      PRInt32 ourContentStart = 0;
+      if (frame->GetType() == nsAccessibilityAtoms::textFrame) {
+        nsresult rv = frame->GetRenderedText(nsnull, &skipChars, &iter);
+        if (NS_SUCCEEDED(rv)) {
+          ourRenderedStart = iter.GetSkippedOffset();
+          ourContentStart = iter.GetOriginalOffset();
+          substringEndOffset =
+            iter.ConvertOriginalToSkipped(skipChars.GetOriginalCharCount() +
+                                          ourContentStart) - ourRenderedStart;
+        }
       }
-      else {
+      if (substringEndOffset < 0) {
         // XXX for non-textframe text like list bullets,
         // should go away after list bullet rewrite
         substringEndOffset = TextLength(accessible);
       }
       if (startOffset < substringEndOffset) {
         // Our start is within this substring
         if (startOffset > 0 || endOffset < substringEndOffset) {
           // We don't want the whole string for this accessible
           // Get out the continuing text frame with this offset
           PRInt32 outStartLineUnused;
-          PRInt32 contentOffset = iter.ConvertSkippedToOriginal(startOffset) +
-                                  ourRenderedStart - ourContentStart;
+          PRInt32 contentOffset;
+          if (frame->GetType() == nsAccessibilityAtoms::textFrame) {
+            contentOffset = iter.ConvertSkippedToOriginal(startOffset) +
+                            ourRenderedStart - ourContentStart;
+          }
+          else {
+            contentOffset = startOffset;
+          }
           frame->GetChildFrameContainingOffset(contentOffset, PR_TRUE,
                                                &outStartLineUnused, &frame);
           if (aEndFrame) {
             *aEndFrame = frame; // We ended in the current frame
             if (aEndAcc)
               NS_ADDREF(*aEndAcc = accessible);
           }
           if (substringEndOffset > endOffset) {
@@ -649,19 +663,20 @@ nsHyperTextAccessible::GetRelativeOffset
   nsresult rv;
   PRInt32 contentOffset = aFromOffset;
   if (IsText(aFromAccessible)) {
     nsCOMPtr<nsPIAccessNode> accessNode(do_QueryInterface(aFromAccessible));
     NS_ASSERTION(accessNode, "nsIAccessible doesn't support nsPIAccessNode");
 
     nsIFrame *frame = accessNode->GetFrame();
     NS_ENSURE_TRUE(frame, -1);
-
-    rv = RenderedToContentOffset(frame, aFromOffset, &contentOffset);
-    NS_ENSURE_SUCCESS(rv, -1);
+    if (frame->GetType() == nsAccessibilityAtoms::textFrame) {
+      rv = RenderedToContentOffset(frame, aFromOffset, &contentOffset);
+      NS_ENSURE_SUCCESS(rv, -1);
+    }
   }
 
   pos.SetData(aAmount, aDirection, contentOffset,
               0, kIsJumpLinesOk, kIsScrollViewAStop, kIsKeyboardSelect, kIsVisualBidi,
               wordMovementType);
   rv = aFromFrame->PeekOffset(&pos);
   if (NS_FAILED(rv)) {
     if (aDirection == eDirPrevious) {
@@ -1084,17 +1099,17 @@ nsHyperTextAccessible::GetOffsetAtPoint(
     nsIFrame *frame = primaryFrame;
     while (frame) {
       nsIContent *content = frame->GetContent();
       NS_ENSURE_TRUE(content, NS_ERROR_FAILURE);
       nsPoint pointInFrame = pointInHyperText - frame->GetOffsetToExternal(hyperFrame);
       nsSize frameSize = frame->GetSize();
       if (pointInFrame.x < frameSize.width && pointInFrame.y < frameSize.height) {
         // Finished
-        if (IsText(accessible)) {
+        if (frame->GetType() == nsAccessibilityAtoms::textFrame) {
           nsIFrame::ContentOffsets contentOffsets = frame->GetContentOffsetsFromPointExternal(pointInFrame, PR_TRUE);
           if (contentOffsets.IsNull() || contentOffsets.content != content) {
             return NS_OK; // Not found, will return -1
           }
           PRUint32 addToOffset;
           nsresult rv = ContentToRenderedOffset(primaryFrame,
                                                 contentOffsets.offset,
                                                 &addToOffset);
@@ -1260,20 +1275,34 @@ nsHyperTextAccessible::GetAssociatedEdit
 {
   NS_ENSURE_ARG_POINTER(aEditor);
 
   *aEditor = nsnull;
   nsCOMPtr<nsIContent> content = do_QueryInterface(mDOMNode);
   NS_ENSURE_TRUE(content, NS_ERROR_FAILURE);
 
   if (!content->HasFlag(NODE_IS_EDITABLE)) {
+    // If we're inside an editable container, then return that container's editor
+    nsCOMPtr<nsIAccessible> ancestor, current = this;
+    while (NS_SUCCEEDED(current->GetParent(getter_AddRefs(ancestor))) && ancestor) {
+      nsRefPtr<nsHyperTextAccessible> ancestorTextAccessible;
+      ancestor->QueryInterface(NS_GET_IID(nsHyperTextAccessible),
+                               getter_AddRefs(ancestorTextAccessible));
+      if (ancestorTextAccessible) {
+        // Recursion will stop at container doc because it has its own impl
+        // of GetAssociatedEditor()
+        return ancestorTextAccessible->GetAssociatedEditor(aEditor);
+      }
+      current = ancestor;
+    }
     return NS_OK;
   }
 
-  nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem = GetDocShellTreeItemFor(mDOMNode);
+  nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
+    nsAccUtils::GetDocShellTreeItemFor(mDOMNode);
   nsCOMPtr<nsIEditingSession> editingSession(do_GetInterface(docShellTreeItem));
   if (!editingSession)
     return NS_OK; // No editing session interface
 
   nsCOMPtr<nsIPresShell> shell = GetPresShell();
   NS_ENSURE_TRUE(shell, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIDocument> doc = shell->GetDocument();
@@ -1474,41 +1503,61 @@ NS_IMETHODIMP nsHyperTextAccessible::Set
     domSel->GetRangeAt(aSelectionNum, getter_AddRefs(range));
     NS_ENSURE_TRUE(range, NS_ERROR_FAILURE);
   }
 
   nsIFrame *endFrame;
   nsIFrame *startFrame = GetPosAndText(aStartOffset, aEndOffset, nsnull, &endFrame);
   NS_ENSURE_TRUE(startFrame, NS_ERROR_FAILURE);
 
+  nsCOMPtr<nsIPresShell> shell = GetPresShell();
+
   nsIContent *startParentContent = startFrame->GetContent();
+  PRInt32 startOffset;
   if (startFrame->GetType() != nsAccessibilityAtoms::textFrame) {
     nsIContent *newParent = startParentContent->GetParent();
-    aStartOffset = newParent->IndexOf(startParentContent);
+    startOffset = newParent->IndexOf(startParentContent);
     startParentContent = newParent;
   }
+  else {
+    // We have a rendered offset into the text frame, and it needs to be
+    // a content offset for us to set the caret
+    nsIFrame *startPrimaryFrame =
+      shell->GetPrimaryFrameFor(startFrame->GetContent());
+    rv = RenderedToContentOffset(startPrimaryFrame, aStartOffset, &startOffset);
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
   nsCOMPtr<nsIDOMNode> startParentNode(do_QueryInterface(startParentContent));
   NS_ENSURE_TRUE(startParentNode, NS_ERROR_FAILURE);
-  rv = range->SetStart(startParentNode, aStartOffset);
+  rv = range->SetStart(startParentNode, startOffset);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (isOnlyCaret) { 
     rv = range->Collapse(PR_TRUE);
     NS_ENSURE_SUCCESS(rv, rv);
   }
   else {
     nsIContent *endParentContent = endFrame->GetContent();
+    PRInt32 endOffset;
     if (endFrame->GetType() != nsAccessibilityAtoms::textFrame) {
       nsIContent *newParent = endParentContent->GetParent();
-      aEndOffset = newParent->IndexOf(endParentContent);
+      endOffset = newParent->IndexOf(endParentContent);
       endParentContent = newParent;
     }
+    else {
+      // We have a rendered offset into the text frame, and it needs to be
+      // a content offset for us to set the caret
+      nsIFrame *endPrimaryFrame =
+        shell->GetPrimaryFrameFor(endFrame->GetContent());
+      rv = RenderedToContentOffset(endPrimaryFrame, aEndOffset, &endOffset);
+      NS_ENSURE_SUCCESS(rv, rv);
+    }
     nsCOMPtr<nsIDOMNode> endParentNode(do_QueryInterface(endParentContent));
     NS_ENSURE_TRUE(endParentNode, NS_ERROR_FAILURE);
-    rv = range->SetEnd(endParentNode, aEndOffset);
+    rv = range->SetEnd(endParentNode, endOffset);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   if (aSelectionNum == rangeCount) { // Add successfully created new range
     return domSel->AddRange(range);
   }
   return NS_OK;
 }
@@ -1559,35 +1608,33 @@ nsHyperTextAccessible::ScrollSubstringTo
                              nsnull, &endFrame, nsnull,
                              getter_AddRefs(startAcc), getter_AddRefs(endAcc));
   if (!startFrame || !endFrame)
     return NS_ERROR_FAILURE;
 
   nsCOMPtr<nsIDOMNode> startNode;
   nsCOMPtr<nsIContent> startContent(startFrame->GetContent());
 
-  PRBool isStartAccText = IsText(startAcc);
-  if (isStartAccText) {
+  if (startFrame->GetType() == nsAccessibilityAtoms::textFrame) {
     nsresult rv = RenderedToContentOffset(startFrame, startOffset,
                                           &startOffset);
     NS_ENSURE_SUCCESS(rv, rv);
     startNode = do_QueryInterface(startContent);
   } else {
     nsCOMPtr<nsIContent> startParent(startContent->GetParent());
     NS_ENSURE_STATE(startParent);
     startOffset = startParent->IndexOf(startContent);
     startNode = do_QueryInterface(startParent);
   }
   NS_ENSURE_STATE(startNode);
 
   nsCOMPtr<nsIDOMNode> endNode;
   nsCOMPtr<nsIContent> endContent(endFrame->GetContent());
 
-  PRBool isEndAccText = IsText(endAcc);
-  if (isEndAccText) {
+  if (endFrame->GetType() == nsAccessibilityAtoms::textFrame) {
     nsresult rv = RenderedToContentOffset(endFrame, endOffset,
                                           &endOffset);
     NS_ENSURE_SUCCESS(rv, rv);
     endNode = do_QueryInterface(endContent);
   } else {
     nsCOMPtr<nsIContent> endParent(endContent->GetParent());
     NS_ENSURE_STATE(endParent);
     endOffset = endParent->IndexOf(endContent);
@@ -1597,16 +1644,21 @@ nsHyperTextAccessible::ScrollSubstringTo
 
   return nsAccUtils::ScrollSubstringTo(GetFrame(), startNode, startOffset,
                                        endNode, endOffset, aScrollType);
 }
 
 nsresult nsHyperTextAccessible::ContentToRenderedOffset(nsIFrame *aFrame, PRInt32 aContentOffset,
                                                         PRUint32 *aRenderedOffset)
 {
+  NS_ASSERTION(aFrame->GetType() == nsAccessibilityAtoms::textFrame,
+               "Need text frame for offset conversion");
+  NS_ASSERTION(aFrame->GetPrevContinuation() == nsnull,
+               "Call on primary frame only");
+
   gfxSkipChars skipChars;
   gfxSkipCharsIterator iter;
   // Only get info up to original ofset, we know that will be larger than skipped offset
   nsresult rv = aFrame->GetRenderedText(nsnull, &skipChars, &iter, 0, aContentOffset);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRUint32 ourRenderedStart = iter.GetSkippedOffset();
   PRInt32 ourContentStart = iter.GetOriginalOffset();
@@ -1615,16 +1667,21 @@ nsresult nsHyperTextAccessible::ContentT
                     ourRenderedStart;
 
   return NS_OK;
 }
 
 nsresult nsHyperTextAccessible::RenderedToContentOffset(nsIFrame *aFrame, PRUint32 aRenderedOffset,
                                                         PRInt32 *aContentOffset)
 {
+  NS_ASSERTION(aFrame->GetType() == nsAccessibilityAtoms::textFrame,
+               "Need text frame for offset conversion");
+  NS_ASSERTION(aFrame->GetPrevContinuation() == nsnull,
+               "Call on primary frame only");
+
   gfxSkipChars skipChars;
   gfxSkipCharsIterator iter;
   // We only need info up to skipped offset -- that is what we're converting to original offset
   nsresult rv = aFrame->GetRenderedText(nsnull, &skipChars, &iter, 0, aRenderedOffset);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRUint32 ourRenderedStart = iter.GetSkippedOffset();
   PRInt32 ourContentStart = iter.GetOriginalOffset();
--- a/accessible/src/msaa/nsAccessNodeWrap.cpp
+++ b/accessible/src/msaa/nsAccessNodeWrap.cpp
@@ -50,16 +50,18 @@
 #include "nsIFrame.h"
 #include "nsINameSpaceManager.h"
 #include "nsIPrefService.h"
 #include "nsIPrefBranch.h"
 #include "nsIPresShell.h"
 #include "nsPIDOMWindow.h"
 #include "nsRootAccessible.h"
 #include "nsIServiceManager.h"
+#include "AccessibleApplication.h"
+#include "nsApplicationAccessibleWrap.h"
 
 /// the accessible library and cached methods
 HINSTANCE nsAccessNodeWrap::gmAccLib = nsnull;
 HINSTANCE nsAccessNodeWrap::gmUserLib = nsnull;
 LPFNACCESSIBLEOBJECTFROMWINDOW nsAccessNodeWrap::gmAccessibleObjectFromWindow = nsnull;
 LPFNNOTIFYWINEVENT nsAccessNodeWrap::gmNotifyWinEvent = nsnull;
 LPFNGETGUITHREADINFO nsAccessNodeWrap::gmGetGUIThreadInfo = nsnull;
 
@@ -121,16 +123,44 @@ STDMETHODIMP nsAccessNodeWrap::QueryInte
 
   if (nsnull == *ppv)
     return E_NOINTERFACE;      //iid not supported.
    
   (reinterpret_cast<IUnknown*>(*ppv))->AddRef(); 
   return S_OK;
 }
 
+STDMETHODIMP
+nsAccessNodeWrap::QueryService(REFGUID guidService, REFIID iid, void** ppv)
+{
+  // Can get to IAccessibleApplication from any node via QS
+  if (iid == IID_IAccessibleApplication) {
+    nsRefPtr<nsApplicationAccessibleWrap> app =
+      GetApplicationAccessible();
+    nsresult rv = app->QueryNativeInterface(iid, ppv);
+    return NS_SUCCEEDED(rv) ? S_OK : E_NOINTERFACE;
+  }
+
+  /**
+   * To get an ISimpleDOMNode, ISimpleDOMDocument, ISimpleDOMText
+   * or any IAccessible2 interface on should use IServiceProvider like this:
+   * -----------------------------------------------------------------------
+   * ISimpleDOMDocument *pAccDoc = NULL;
+   * IServiceProvider *pServProv = NULL;
+   * pAcc->QueryInterface(IID_IServiceProvider, (void**)&pServProv);
+   * if (pServProv) {
+   *   const GUID unused;
+   *   pServProv->QueryService(unused, IID_ISimpleDOMDocument, (void**)&pAccDoc);
+   *   pServProv->Release();
+   * }
+   */
+
+  return QueryInterface(iid, ppv);
+}
+
 //-----------------------------------------------------
 // ISimpleDOMNode methods
 //-----------------------------------------------------
 
 STDMETHODIMP nsAccessNodeWrap::get_nodeInfo( 
     /* [out] */ BSTR __RPC_FAR *aNodeName,
     /* [out] */ short __RPC_FAR *aNameSpaceID,
     /* [out] */ BSTR __RPC_FAR *aNodeValue,
--- a/accessible/src/msaa/nsAccessNodeWrap.h
+++ b/accessible/src/msaa/nsAccessNodeWrap.h
@@ -56,22 +56,26 @@
 #include "winable.h"
 #undef ERROR /// Otherwise we can't include nsIDOMNSEvent.h if we include this
 
 typedef LRESULT (STDAPICALLTYPE *LPFNNOTIFYWINEVENT)(DWORD event,HWND hwnd,LONG idObjectType,LONG idObject);
 typedef LRESULT (STDAPICALLTYPE *LPFNGETGUITHREADINFO)(DWORD idThread, GUITHREADINFO* pgui);
 
 class nsAccessNodeWrap :  public nsAccessNode,
                           public nsIWinAccessNode,
-                          public ISimpleDOMNode
+                          public ISimpleDOMNode,
+                          public IServiceProvider
 {
   public:
     NS_DECL_ISUPPORTS_INHERITED
     NS_DECL_NSIWINACCESSNODE
 
+  public: // IServiceProvider
+    STDMETHODIMP QueryService(REFGUID guidService, REFIID riid, void** ppv);
+
   public: // construction, destruction
     nsAccessNodeWrap(nsIDOMNode *, nsIWeakReference* aShell);
     virtual ~nsAccessNodeWrap();
 
     // IUnknown
     STDMETHODIMP QueryInterface(REFIID, void**);
 
   public:
--- a/accessible/src/msaa/nsAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsAccessibleWrap.cpp
@@ -1001,37 +1001,16 @@ STDMETHODIMP nsAccessibleWrap::put_accVa
       /* [in] */ BSTR szValue)
 {
   return E_NOTIMPL;
 }
 
 #include "mshtml.h"
 
 STDMETHODIMP
-nsAccessibleWrap::QueryService(REFGUID guidService, REFIID iid, void** ppv)
-{
-  /**
-   * To get an ISimpleDOMNode, ISimpleDOMDocument or ISimpleDOMText
-   * from an IAccessible you have to use IServiceProvider like this:
-   * --------------------------------------------------------------
-   * ISimpleDOMDocument *pAccDoc = NULL;
-   * IServiceProvider *pServProv = NULL;
-   * pAcc->QueryInterface(IID_IServiceProvider, (void**)&pServProv);
-   * if (pServProv) {
-   *   const GUID unused;
-   *   pServProv->QueryService(unused, IID_ISimpleDOMDocument, (void**)&pAccDoc);
-   *   pServProv->Release();
-   * }
-   */
-
-  return QueryInterface(iid, ppv);
-}
-
-
-STDMETHODIMP
 nsAccessibleWrap::Next(ULONG aNumElementsRequested, VARIANT FAR* pvar, ULONG FAR* aNumElementsFetched)
 {
   // If there are two clients using this at the same time, and they are
   // each using a different mEnumVariant position it would be bad, because
   // we have only 1 object and can only keep of mEnumVARIANT position once
 
   // Children already cached via QI to IEnumVARIANT
   *aNumElementsFetched = 0;
--- a/accessible/src/msaa/nsAccessibleWrap.h
+++ b/accessible/src/msaa/nsAccessibleWrap.h
@@ -89,32 +89,28 @@ Class::QueryInterface(REFIID iid, void**
   IMPL_IUNKNOWN_QUERY_TAIL                                                    \
 
 
 class nsAccessibleWrap : public nsAccessible,
                          public CAccessibleComponent,
                          public CAccessibleHyperlink,
                          public CAccessibleValue,
                          public IAccessible2,
-                         public IEnumVARIANT,
-                         public IServiceProvider
+                         public IEnumVARIANT
 {
   public: // construction, destruction
     nsAccessibleWrap(nsIDOMNode*, nsIWeakReference *aShell);
     virtual ~nsAccessibleWrap();
 
     // nsISupports
     NS_DECL_ISUPPORTS_INHERITED
 
   public: // IUnknown methods - see iunknown.h for documentation
     STDMETHODIMP QueryInterface(REFIID, void**);
 
-  public: // IServiceProvider
-    STDMETHODIMP QueryService(REFGUID guidService, REFIID riid, void** ppv);
-
   // Return the registered OLE class ID of this object's CfDataObj.
     CLSID GetClassID() const;
 
   public: // COM interface IAccessible
     virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accParent( 
         /* [retval][out] */ IDispatch __RPC_FAR *__RPC_FAR *ppdispParent);
 
     virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accChildCount( 
--- a/accessible/src/xul/nsXULTreeAccessible.cpp
+++ b/accessible/src/xul/nsXULTreeAccessible.cpp
@@ -314,16 +314,52 @@ NS_IMETHODIMP nsXULTreeAccessible::GetFo
         return NS_OK;  // Already addref'd by getter
       }
     }
   }
   NS_ADDREF(*aFocusedChild = this);
   return NS_OK;
 }
 
+// nsIAccessible::getChildAtPoint(in long x, in long y)
+NS_IMETHODIMP
+nsXULTreeAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
+                                     nsIAccessible **aAccessible)
+{
+  nsIFrame *frame = GetFrame();
+  if (!frame)
+    return NS_ERROR_FAILURE;
+
+  nsPresContext *presContext = frame->PresContext();
+  nsCOMPtr<nsIPresShell> presShell = presContext->PresShell();
+
+  nsIFrame *rootFrame = presShell->GetRootFrame();
+  NS_ENSURE_STATE(rootFrame);
+
+  nsIntRect rootRect = rootFrame->GetScreenRectExternal();
+
+  PRInt32 clientX = presContext->AppUnitsToIntCSSPixels(
+    presContext->DevPixelsToAppUnits(aX - rootRect.x));
+  PRInt32 clientY = presContext->AppUnitsToIntCSSPixels(
+    presContext->DevPixelsToAppUnits(aY - rootRect.y));
+
+  PRInt32 row = -1;
+  nsCOMPtr<nsITreeColumn> column;
+  nsCAutoString childEltUnused;
+  mTree->GetCellAt(clientX, clientY, &row, getter_AddRefs(column),
+                   childEltUnused);
+
+  // If we failed to find tree cell for the given point then it might be
+  // tree columns.
+  if (row == -1 || !column)
+    return nsXULSelectableAccessible::GetChildAtPoint(aX, aY, aAccessible);
+
+  return GetCachedTreeitemAccessible(row, column, aAccessible);
+}
+
 // Ask treeselection to get all selected children
 NS_IMETHODIMP nsXULTreeAccessible::GetSelectedChildren(nsIArray **_retval)
 {
   *_retval = nsnull;
 
   NS_ENSURE_TRUE(mTree && mTreeView, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsITreeSelection> selection;
@@ -593,28 +629,21 @@ nsXULTreeitemAccessible::GetState(PRUint
     *aExtraState = 0;
 
   NS_ENSURE_TRUE(mColumn && mTree && mTreeView, NS_ERROR_FAILURE);
 
   *aState = nsIAccessibleStates::STATE_FOCUSABLE |
             nsIAccessibleStates::STATE_SELECTABLE;
 
   // get expanded/collapsed state
-  PRBool isContainer, isContainerOpen, isContainerEmpty;
-  mTreeView->IsContainer(mRow, &isContainer);
-  if (isContainer) {
-    mTreeView->IsContainerEmpty(mRow, &isContainerEmpty);
-    if (!isContainerEmpty) {
-      if (aExtraState)
-        *aExtraState |= nsIAccessibleStates::EXT_STATE_EXPANDABLE;
-
-      mTreeView->IsContainerOpen(mRow, &isContainerOpen);
-      *aState |= isContainerOpen? PRUint32(nsIAccessibleStates::STATE_EXPANDED):
-                                  PRUint32(nsIAccessibleStates::STATE_COLLAPSED);
-    }
+  if (IsExpandable()) {
+    PRBool isContainerOpen;
+    mTreeView->IsContainerOpen(mRow, &isContainerOpen);
+    *aState |= isContainerOpen? PRUint32(nsIAccessibleStates::STATE_EXPANDED):
+                                PRUint32(nsIAccessibleStates::STATE_COLLAPSED);
   }
 
   // get selected state
   nsCOMPtr<nsITreeSelection> selection;
   mTreeView->GetSelection(getter_AddRefs(selection));
   if (selection) {
     PRBool isSelected;
     selection->IsSelected(mRow, &isSelected);
@@ -648,27 +677,41 @@ nsXULTreeitemAccessible::GetState(PRUint
     if (checked.EqualsIgnoreCase("true")) {
       *aState |= nsIAccessibleStates::STATE_CHECKED;
     }
   }
 
   return NS_OK;
 }
 
+PRBool nsXULTreeitemAccessible::IsExpandable()
+{
+  NS_ENSURE_TRUE(mTree && mTreeView && mColumn, NS_ERROR_FAILURE);
+  PRBool isContainer;
+  mTreeView->IsContainer(mRow, &isContainer);
+  if (isContainer) {
+    PRBool isEmpty; 
+    mTreeView->IsContainerEmpty(mRow, &isEmpty);
+    if (!isEmpty) {
+      PRBool isPrimary;
+      mColumn->GetPrimary(&isPrimary);
+      if (isPrimary) {
+        return PR_TRUE;
+      }
+    }
+  }
+  return PR_FALSE;
+}
+
 // "activate" (xor "cycle") action is available for all treeitems
 // "expand/collapse" action is avaible for treeitem which is container
-NS_IMETHODIMP nsXULTreeitemAccessible::GetNumActions(PRUint8 *_retval)
+NS_IMETHODIMP nsXULTreeitemAccessible::GetNumActions(PRUint8 *aNumActions)
 {
-  NS_ENSURE_TRUE(mTree && mTreeView, NS_ERROR_FAILURE);
-  PRBool isContainer;
-  mTreeView->IsContainer(mRow, &isContainer);
-  if (isContainer)
-    *_retval = 2;
-  else
-    *_retval = 1;
+  NS_ENSURE_TRUE(mTree && mTreeView && mColumn, NS_ERROR_FAILURE);
+  *aNumActions = IsExpandable() ? 2 : 1;
 
   return NS_OK;
 }
 
 // Return the name of our actions
 NS_IMETHODIMP nsXULTreeitemAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
 {
   NS_ENSURE_TRUE(mColumn && mTree && mTreeView, NS_ERROR_FAILURE);
@@ -679,27 +722,23 @@ NS_IMETHODIMP nsXULTreeitemAccessible::G
     if (isCycler) {
       aName.AssignLiteral("cycle");
     }
     else {
       aName.AssignLiteral("activate");
     }
     return NS_OK;
   }
-  else if (aIndex == eAction_Expand) {
-    PRBool isContainer, isContainerOpen;
-    mTreeView->IsContainer(mRow, &isContainer);
-    if (isContainer) {
-      mTreeView->IsContainerOpen(mRow, &isContainerOpen);
-      if (isContainerOpen)
-        aName.AssignLiteral("collapse");
-      else
-        aName.AssignLiteral("expand");
-    }
-
+  else if (aIndex == eAction_Expand && IsExpandable()) {
+    PRBool isContainerOpen;
+    mTreeView->IsContainerOpen(mRow, &isContainerOpen);
+    if (isContainerOpen)
+      aName.AssignLiteral("collapse");
+    else
+      aName.AssignLiteral("expand");
     return NS_OK;
   }
 
   return NS_ERROR_INVALID_ARG;
 }
 
 nsresult
 nsXULTreeitemAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
@@ -879,21 +918,18 @@ NS_IMETHODIMP nsXULTreeitemAccessible::D
       mTreeView->GetSelection(getter_AddRefs(selection));
       if (selection) {
         rv = selection->Select(mRow);
         mTree->EnsureRowIsVisible(mRow);
       }
     }
     return rv;
   }
-  else if (index == eAction_Expand) {
-    PRBool isContainer;
-    mTreeView->IsContainer(mRow, &isContainer);
-    if (isContainer)
-      return mTreeView->ToggleOpenState(mRow);
+  else if (index == eAction_Expand && IsExpandable()) {
+    return mTreeView->ToggleOpenState(mRow);
   }
 
   return NS_ERROR_INVALID_ARG;
 }
 
 NS_IMETHODIMP nsXULTreeitemAccessible::GetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height)
 {
   *x = *y = *width = *height = 0;
--- a/accessible/src/xul/nsXULTreeAccessible.h
+++ b/accessible/src/xul/nsXULTreeAccessible.h
@@ -67,16 +67,18 @@ public:
   NS_IMETHOD GetRole(PRUint32 *_retval);
   NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetValue(nsAString& _retval);
 
   NS_IMETHOD GetFirstChild(nsIAccessible **_retval);
   NS_IMETHOD GetLastChild(nsIAccessible **_retval);
   NS_IMETHOD GetChildCount(PRInt32 *_retval);
   NS_IMETHOD GetFocusedChild(nsIAccessible **aFocusedChild);
+  NS_IMETHOD GetChildAtPoint(PRInt32 aX, PRInt32 aY,
+                             nsIAccessible **aAccessible);
 
   static void GetTreeBoxObject(nsIDOMNode* aDOMNode, nsITreeBoxObject** aBoxObject);
   static nsresult GetColumnCount(nsITreeBoxObject* aBoxObject, PRInt32 *aCount);
 
   static PRBool IsColumnHidden(nsITreeColumn *aColumn);
   static already_AddRefed<nsITreeColumn> GetNextVisibleColumn(nsITreeColumn *aColumn);
   static already_AddRefed<nsITreeColumn> GetFirstVisibleColumn(nsITreeBoxObject *aTree);
   static already_AddRefed<nsITreeColumn> GetLastVisibleColumn(nsITreeBoxObject *aTree);
@@ -121,16 +123,17 @@ public:
   NS_IMETHOD SetSelected(PRBool aSelect); 
   NS_IMETHOD TakeFocus(void); 
 
   NS_IMETHOD GetAccessibleRelated(PRUint32 aRelationType, nsIAccessible **aRelated);
   /* ------ nsIAccessNode ----- */
   NS_IMETHOD GetUniqueID(void **aUniqueID);
 
 protected:
+  PRBool IsExpandable();
   nsCOMPtr<nsITreeBoxObject> mTree;
   nsCOMPtr<nsITreeView> mTreeView;
   PRInt32 mRow;
   nsCOMPtr<nsITreeColumn> mColumn;
 };
 
 class nsXULTreeColumnsAccessible : public nsAccessibleWrap
 {
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -336,19 +336,16 @@ pref("privacy.sanitize.promptOnSanitize"
 
 pref("network.proxy.share_proxy_settings",  false); // use the same proxy settings for all protocols
 
 pref("network.cookie.cookieBehavior",       0); // cookies enabled
 pref("network.cookie.enableForCurrentSessionOnly", false);
 
 // l12n and i18n
 pref("intl.accept_languages", "chrome://global/locale/intl.properties");
-// collationOption is only set on linux for japanese. see bug 18338 and 62015
-// we need to check if this pref is still useful.
-pref("intl.collationOption",  "chrome://global-platform/locale/intl.properties");
 pref("intl.charsetmenu.browser.static", "chrome://global/locale/intl.properties");
 pref("intl.charsetmenu.browser.more1",  "chrome://global/locale/intl.properties");
 pref("intl.charsetmenu.browser.more2",  "chrome://global/locale/intl.properties");
 pref("intl.charsetmenu.browser.more3",  "chrome://global/locale/intl.properties");
 pref("intl.charsetmenu.browser.more4",  "chrome://global/locale/intl.properties");
 pref("intl.charsetmenu.browser.more5",  "chrome://global/locale/intl.properties");
 pref("intl.charsetmenu.browser.unicode",  "chrome://global/locale/intl.properties");
 pref("intl.charset.detector", "chrome://global/locale/intl.properties");
@@ -494,16 +491,30 @@ pref("browser.contentHandlers.types.4.ti
 pref("browser.contentHandlers.types.4.uri", "chrome://browser-region/locale/region.properties");
 pref("browser.contentHandlers.types.4.type", "application/vnd.mozilla.maybe.feed");
 pref("browser.contentHandlers.types.5.title", "chrome://browser-region/locale/region.properties");
 pref("browser.contentHandlers.types.5.uri", "chrome://browser-region/locale/region.properties");
 pref("browser.contentHandlers.types.5.type", "application/vnd.mozilla.maybe.feed");
 
 pref("browser.feeds.handler", "ask");
 
+// For now, this is living in content rather than in locales, as per Pike.
+// Eventually it will get merged into region.properties; see bug 395277.
+//
+// At startup, if the handler service notices that the version number here
+// is newer than the version number in the handler service datastore, it will
+// add any handlers it finds in the prefs (as seeded by this file) to its
+// datastore.  
+pref("gecko.handlerService.defaultHandlersVersion", "0");
+//
+// The default set of web-based protocol handlers shown in the application
+// selection dialog
+pref("gecko.handlerService.schemes.webcal.0.name", "WebCal Test Handler");
+pref("gecko.handlerService.schemes.webcal.0.uriTemplate", "http://handler-test.mozilla.org/webcal?url=%s");
+
 #ifdef MOZ_SAFE_BROWSING
 // Safe browsing does nothing unless both these prefs are set.
 pref("browser.safebrowsing.enabled", true);
 pref("browser.safebrowsing.remoteLookups", false);
 
 // Prevent loading of pages identified as malware
 pref("browser.safebrowsing.malware.enabled", true);
 
--- a/browser/base/content/aboutDialog.css
+++ b/browser/base/content/aboutDialog.css
@@ -40,16 +40,30 @@
 }
 
 #version {
   font-weight: bold;
   color: #909090;
   margin: 1em 0px 10px 17px;
 }
 
+#distribution {
+  font-weight: bold;
+  color: #909090;
+  display: none;
+  margin: 0em 0px 0px 17px;
+}
+
+#distributionId {
+  font-weight: bold;
+  color: #909090;
+  display: none;
+  margin: 0em 0px 10px 17px;
+}
+
 #copyright {
   margin: 0px 0px 3px 16px;
 }
 
 button[dlgtype="extra2"] {
   margin-left: 13px;
 }
 
--- a/browser/base/content/aboutDialog.js
+++ b/browser/base/content/aboutDialog.js
@@ -36,16 +36,39 @@
 # ***** END LICENSE BLOCK ***** -->
 
 var gSelectedPage = 0;
 
 function init(aEvent) 
 {
   if (aEvent.target != document)
     return;
+
+  var prefs = Components.classes["@mozilla.org/preferences-service;1"]
+                        .getService(Components.interfaces.nsIPrefBranch);
+
+  try {
+    var distroId = prefs.getCharPref("distribution.id");
+    if (distroId) {
+      var distroVersion = prefs.getCharPref("distribution.version");
+      var distroAbout = prefs.getComplexValue("distribution.about", Ci.nsISupportsString);
+  
+      var distroField = document.getElementById("distribution");
+      distroField.value = distroAbout;
+      distroField.style.display = "block";
+    
+      var distroIdField = document.getElementById("distributionId");
+      distroIdField.value = distroId + " - " + distroVersion;
+      distroIdField.style.display = "block";
+    }
+  }
+  catch (e) {
+    // Pref is unset
+  }
+
   var userAgentField = document.getElementById("userAgent");
   userAgentField.value = navigator.userAgent;
 
   var button = document.documentElement.getButton("extra2");
   button.setAttribute("label", document.documentElement.getAttribute("creditslabel"));
   button.setAttribute("accesskey", document.documentElement.getAttribute("creditsaccesskey"));
   button.addEventListener("command", switchPage, false);
 
--- a/browser/base/content/aboutDialog.xul
+++ b/browser/base/content/aboutDialog.xul
@@ -68,16 +68,18 @@
         aboutlabel="&aboutLink;"
         aboutaccesskey="&aboutLink.accesskey;">
     
   <script type="application/x-javascript" src="chrome://browser/content/aboutDialog.js"/>
 
   <deck id="modes" flex="1">
     <vbox flex="1" id="clientBox">
 #expand <label id="version" value="&aboutVersion; __MOZ_APP_VERSION__"/>
+      <label id="distribution"/>
+      <label id="distributionId"/>
       <description id="copyright">&copyrightText;</description>
       <textbox id="userAgent" multiline="true" readonly="true"/>
     </vbox>
     <vbox flex="1" id="creditsBox">
       <iframe id="creditsIframe" flex="1"/>
     </vbox>    
   </deck>
   <separator class="groove" id="groove"/>
--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -766,17 +766,18 @@ var PlacesStarButton = {
   _batching: false,
 
   updateState: function PSB_updateState() {
     var starIcon = document.getElementById("star-button");
     if (!starIcon)
       return;
 
     var uri = getBrowser().currentURI;
-    this._starred = uri && (PlacesUtils.getMostRecentBookmarkForURI(uri) != -1);
+    this._starred = uri && (PlacesUtils.getMostRecentBookmarkForURI(uri) != -1 ||
+                            PlacesUtils.getMostRecentFolderForFeedURI(uri) != -1);
     if (this._starred)
       starIcon.setAttribute("starred", "true");
     else
       starIcon.removeAttribute("starred");
   },
 
   onClick: function PSB_onClick(aEvent) {
     PlacesCommandHook.bookmarkCurrentPage(this._starred);
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -3019,45 +3019,36 @@ function BrowserCustomizeToolbar()
   var menubar = document.getElementById("main-menubar");
   for (var i = 0; i < menubar.childNodes.length; ++i)
     menubar.childNodes[i].setAttribute("disabled", true);
 
   var cmd = document.getElementById("cmd_CustomizeToolbars");
   cmd.setAttribute("disabled", "true");
 
 #ifdef TOOLBAR_CUSTOMIZATION_SHEET
-  document.getElementById("customizeToolbarSheetBox").hidden = false;
-
-  /**
-   * XXXmano hack: when a new tab is added while the sheet is visible,
-   * the new tabpanel is overlaying the sheet. We workaround this issue by
-   * hiding and reopening the sheet when a new tab is added.
-   */
-  function TabOpenSheetHandler(aEvent) {
-    getBrowser().removeEventListener("TabOpen", TabOpenSheetHandler, false);
-
-    document.getElementById("customizeToolbarSheetIFrame")
-            .contentWindow.gCustomizeToolbarSheet.done();
-    document.getElementById("customizeToolbarSheetBox").hidden = true;
-    BrowserCustomizeToolbar();
-    
-  }
-  getBrowser().addEventListener("TabOpen", TabOpenSheetHandler, false);
+  var sheetFrame = document.getElementById("customizeToolbarSheetIFrame");
+  sheetFrame.hidden = false;
+  // XXXmano: there's apparently no better way to get this when the iframe is
+  // hidden
+  var sheetWidth = sheetFrame.style.width.match(/([0-9]+)px/)[1];
+  document.getElementById("customizeToolbarSheetPopup")
+          .openPopup(getNavToolbox(), "after_start", (window.innerWidth - sheetWidth) / 2, 0);
 #else
   window.openDialog("chrome://global/content/customizeToolbar.xul",
                     "CustomizeToolbar",
                     "chrome,all,dependent",
                     getNavToolbox());
 #endif
 }
 
 function BrowserToolboxCustomizeDone(aToolboxChanged)
 {
 #ifdef TOOLBAR_CUSTOMIZATION_SHEET
-  document.getElementById("customizeToolbarSheetBox").hidden = true;
+  document.getElementById("customizeToolbarSheetIFrame").hidden = true;
+  document.getElementById("customizeToolbarSheetPopup").hidePopup();
 #endif
 
   // Update global UI elements that may have been added or removed
   if (aToolboxChanged) {
     gURLBar = document.getElementById("urlbar");
     gProxyButton = document.getElementById("page-proxy-button");
     gProxyFavIcon = document.getElementById("page-proxy-favicon");
     gProxyDeck = document.getElementById("page-proxy-deck");
@@ -3693,19 +3684,18 @@ nsBrowserStatusHandler.prototype =
         this.securityButton.removeAttribute("level");
         if (this.urlBar)
           this.urlBar.removeAttribute("level");
         break;
     }
 
     var securityUI = gBrowser.securityUI;
     this.securityButton.setAttribute("tooltiptext", securityUI.tooltipText);
-    var lockIcon = document.getElementById("lock-icon");
-    if (lockIcon)
-      lockIcon.setAttribute("tooltiptext", securityUI.tooltipText);
+    
+    getIdentityHandler().checkIdentity(aWebProgress, aRequest, aState);
   },
 
   // simulate all change notifications after switching tabs
   onUpdateCurrentBrowser : function(aStateFlags, aStatus, aMessage, aTotalProgress)
   {
     var nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
     var loadingDone = aStateFlags & nsIWebProgressListener.STATE_STOP;
     // use a pseudo-object instead of a (potentially non-existing) channel for getting
@@ -5578,8 +5568,206 @@ function showToolbars() {
   }
   
   var goButtonStack = document.getElementById("go-button-stack");
   if (goButtonStack)
     goButtonStack.removeAttribute("hidden");
   
   return false; // Dismiss the notification message
 }
+
+/**
+ * Utility class to handle manipulations of the identity indicators in the UI
+ */
+function IdentityHandler() {}
+
+IdentityHandler.prototype = {
+
+  // Mode strings used to control CSS display
+  IDENTITY_MODE_IDENTIFIED       : "verifiedIdentity", // High-quality identity information
+  IDENTITY_MODE_DOMAIN_VERIFIED  : "verifiedDomain",   // Minimal SSL CA-signed domain verification
+  IDENTITY_MODE_UNKNOWN          : "unknownIdentity",  // No trusted identity information
+
+  // Cache the most recently seen SSLStatus and URI to prevent unnecessary updates
+  _lastStatus : null,
+  _lastURI : null,
+
+  /**
+   * Handler for mouseclicks on the "Tell me more about this website" link text
+   * in the "identity-popup" panel.
+   */
+  handleMoreInfoClick : function(event) {
+    if (event.button == 0) {
+      displaySecurityInfo();
+      event.stopPropagation();
+    }   
+  },
+  
+  /**
+   * Determine the identity of the page being displayed by examining its SSL cert
+   * (if available) and, if necessary, update the UI to reflect this.  Intended to
+   * be called by an nsIWebProgressListener.
+   *
+   * @param nsIWebProgress webProgress
+   * @param nsIRequest request
+   * @param PRUint32 state
+   */
+  checkIdentity : function(webProgress, request, state) {
+    var currentStatus = gBrowser.securityUI
+                                .QueryInterface(Components.interfaces.nsISSLStatusProvider)
+                                .SSLStatus;
+    var currentURI = gBrowser.currentURI;
+    if (currentStatus == this._lastStatus && currentURI == this._lastURI) {
+      // No need to update, this is a no-op check
+      return;
+    }
+
+    this._lastStatus = currentStatus;
+    this._lastURI = currentURI;
+    
+    if (state & Components.interfaces.nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL)
+      this.setMode(this.IDENTITY_MODE_IDENTIFIED);
+    else if (state & Components.interfaces.nsIWebProgressListener.STATE_SECURE_HIGH)
+      this.setMode(this.IDENTITY_MODE_DOMAIN_VERIFIED);
+    else
+      this.setMode(this.IDENTITY_MODE_UNKNOWN);
+  },
+  
+  /**
+   * Update the UI to reflect the specified mode, which should be one of the
+   * IDENTITY_MODE_* constants.
+   */
+  setMode : function(newMode) {
+    document.getElementById("identity-popup").className = newMode;
+    document.getElementById("identity-box").className = newMode;
+    document.getElementById("identity-popup-content-box").className = newMode;
+    this.setMessages(newMode);
+  },
+  
+  /**
+   * Set up the title and content messages for the identity message bubble, and
+   * primary UI based on the specified mode, and the details of the SSL cert, where
+   * applicable
+   *
+   * @param newMode The newly set identity mode.  Should be one of the IDENTITY_MODE_* constants.
+   */
+  setMessages : function(newMode) {
+      
+    var stringBundle = document.getElementById("bundle_browser");
+    
+    // Initialize the optional strings to empty values
+    var supplemental = "";
+    var verifier = "";
+      
+    if (newMode == this.IDENTITY_MODE_DOMAIN_VERIFIED) {
+      var title = stringBundle.getString("identity.domainverified.title");
+      var encryption_label = stringBundle.getString("identity.encrypted");
+      var status = this._lastStatus.QueryInterface(Components.interfaces.nsISSLStatus);
+      var cert = status.serverCert;
+
+      // It would be sort of nice to use the CN= field in the cert, since that's
+      // typically what we want here, but thanks to x509 certs being extensible,
+      // it's not the only place you have to check, there can be more than one domain,
+      // et cetera, ad nauseum.  We know the cert is valid for location.host, so
+      // let's just use that, it's what the status bar does too.
+      var body = this._lastURI.host;
+      var caOrg = cert.issuerOrganization || cert.issuerCommonName;      
+      verifier = stringBundle.getFormattedString("identity.identified.verifier",
+                                                 [caOrg]);
+      supplemental = stringBundle.getString("identity.domainverified.supplemental");
+      
+      var icon_label = body;
+      var tooltip = verifier;
+    }
+    else if (newMode == this.IDENTITY_MODE_IDENTIFIED) {
+      title = stringBundle.getString("identity.identified.title");
+      encryption_label = stringBundle.getString("identity.encrypted");
+  
+      // If it's identified, then we can populate the dialog with credentials
+      status = this._lastStatus.QueryInterface(Components.interfaces.nsISSLStatus);
+      cert = status.serverCert;
+
+      // Pull the basics out with fallback options in case common
+      // (optional) fields are left blank
+      body = cert.organization || cert.commonName;
+      caOrg = cert.issuerOrganization || cert.issuerCommonName;        
+      verifier = tooltip = stringBundle.getFormattedString("identity.identified.verifier",
+                                                           [caOrg]);
+            
+      // Now try to extract out supplemental location fields and append
+      // them, where available.  subjectName is a comma-delimited list of
+      // key=value pairs.
+      if (cert.subjectName) {
+        var subjectNameFields = {};
+        cert.subjectName.split(",").forEach(function(v) {
+          var field = v.split("=");
+          this[field[0]] = field[1];
+        }, subjectNameFields);
+
+        if (subjectNameFields.L) // City
+          supplemental += subjectNameFields.L + "\n";
+                
+        if (subjectNameFields.ST && subjectNameFields.C) // State and Country
+          supplemental += stringBundle.getFormattedString("identity.identified.state_and_country",
+                                                          [subjectNameFields.ST,
+                                                          subjectNameFields.C]);
+        else if (subjectNameFields.ST) // State only
+          supplemental += subjectNameFields.ST;
+        else if (subjectNameFields.C) // Country only
+          supplemental += subjectNameFields.C;
+          
+        // Include country code in top-level label, if we have one
+        if (subjectNameFields.C)
+          icon_label = stringBundle.getFormattedString("identity.identified.title_with_country",
+                                                       [body, subjectNameFields.C]);
+        else
+          icon_label = body;
+      }
+    }
+    else {
+      encryption_label = stringBundle.getString("identity.unencrypted");
+      title = stringBundle.getString("identity.unknown.title");
+      body = stringBundle.getString("identity.unknown.body");
+      icon_label = "";
+      tooltip = body;
+    }
+    
+    // Push the appropriate strings out to the UI
+    document.getElementById("identity-popup-title").value = title;
+    document.getElementById("identity-popup-content").textContent = body;
+    document.getElementById("identity-popup-content-supplemental")
+            .textContent = supplemental;
+    document.getElementById("identity-popup-content-verifier")
+            .textContent = verifier;
+    document.getElementById("identity-popup-encryption-label")
+            .textContent = encryption_label;
+    document.getElementById("identity-box").tooltipText = tooltip;
+    document.getElementById("identity-icon-label").value = icon_label;
+  },
+  
+  /**
+   * Click handler for the identity-box element in primary chrome.  
+   */
+  handleMouseUp : function(event) {
+    if (event.button != 0)
+      return; // We only want left-clicks
+        
+    // Make sure that the display:none style we set in xul is removed now that
+    // the popup is actually needed
+    var popup = document.getElementById('identity-popup');
+    popup.hidden = false;
+    
+    // Now open the popup, anchored off the primary chrome element
+    popup.openPopup(document.getElementById('identity-box'), 'after_start');
+  }
+};
+
+var gIdentityHandler; 
+
+/**
+ * Returns the singleton instance of the identity handler class.  Should always be
+ * used instead of referencing the global variable directly or creating new instances
+ */
+function getIdentityHandler() {
+  if (!gIdentityHandler)
+    gIdentityHandler = new IdentityHandler();
+  return gIdentityHandler;    
+}
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -23,16 +23,17 @@
 # the Initial Developer. All Rights Reserved.
 #
 # Contributor(s):
 #   Blake Ross <blake@cs.stanford.edu>
 #   David Hyatt <hyatt@mozilla.org>
 #   Joe Hewitt <hewitt@netscape.com>
 #   Pierre Chanial <chanial@noos.fr>
 #   Dean Tessman <dean_tessman@hotmail.com>
+#   Johnathan Nightingale <johnath@mozilla.com>
 #
 # Alternatively, the contents of this file may be used under the terms of
 # either the GNU General Public License Version 2 or later (the "GPL"), or
 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 # in which case the provisions of the GPL or the LGPL are applicable instead
 # of those above. If you wish to allow use of your version of this file only
 # under the terms of either the GPL or the LGPL, and not to allow others to
 # use your version of this file under the terms of the MPL, indicate your
@@ -131,16 +132,44 @@
     <popup id="contentAreaContextMenu"
            onpopupshowing="if (event.target != this) return true; gContextMenu = new nsContextMenu(this, window.getBrowser()); return gContextMenu.shouldDisplay;"
            onpopuphiding="if (event.target == this) { gContextMenu = null; }">
 #include browser-context.inc
     </popup>
 
     <popup id="placesContext"/>
 
+    <!-- Popup for site identity information -->
+    <panel id="identity-popup" position="after_start" hidden="true">
+      <hbox id="identity-popup-container" align="top">
+        <image id="identity-popup-icon"/>
+        <vbox id="identity-popup-content-box">
+          <!-- Title Bar -->
+          <label id="identity-popup-title"/>
+          <!-- Content area -->
+          <description id="identity-popup-content"/>
+          <description id="identity-popup-content-supplemental"/>
+          <description id="identity-popup-content-verifier"/>
+          <hbox id="identity-popup-encryption" flex="1">
+            <vbox>
+              <image id="identity-popup-encryption-icon"/>
+              <spacer flex="1"/>
+            </vbox>
+            <description id="identity-popup-encryption-label" flex="1"/>
+          </hbox>
+          <spacer flex="1"/>
+          <!-- Footer link to page info -->
+          <label id="identity-popup-more-info-link"
+                 class="text-link plain"
+                 value="&identity.moreInfoLinkText;"
+                 onclick="getIdentityHandler().handleMoreInfoClick(event);"/>
+        </vbox>
+      </hbox>
+    </panel>
+
     <tooltip id="urlTooltip">
       <label crop="center" flex="1"/>
     </tooltip>
   </popupset>
 
   <!-- bookmarks toolbar tooltip -->
   <tooltip id="btTooltip" noautohide="true"
            onpopupshowing="return BookmarksEventHandler.fillInBTTooltip(document.tooltipNode)">
@@ -226,42 +255,47 @@
                      showcommentcolumn="true"
                      showimagecolumn="true" 
                      enablehistory="true"
                      maxrows="10"
                      newlines="stripsurroundingwhitespace"
                      oninput="gBrowser.userTypedValue = this.value"
                      ontextentered="return handleURLBarCommand(param);"
                      ontextreverted="return handleURLBarRevert();">
-              <deck id="page-proxy-deck" onclick="PageProxyClickHandler(event);">
-                <image id="page-proxy-button"
-                        ondraggesture="PageProxyDragGesture(event);"
-                        tooltiptext="&proxyIcon.tooltip;"/>
-                <image id="page-proxy-favicon" validate="never"
-                        ondraggesture="PageProxyDragGesture(event);"
-                        onload="this.parentNode.selectedIndex = 1;
-                                event.stopPropagation();"
-                        onerror="gBrowser.addToMissedIconCache(this.src);
-                                 this.removeAttribute('src');
-                                 this.parentNode.selectedIndex = 0;"
-                        tooltiptext="&proxyIcon.tooltip;"/>
-              </deck>
+              <!-- Use onmouseup instead of normal popup= syntax since the popup
+                   code fires onmousedown, and hence eats our favicon drag events -->
+              <box id="identity-box" align="center"
+                   onmouseup="getIdentityHandler().handleMouseUp(event);">
+                <deck id="page-proxy-deck" onclick="PageProxyClickHandler(event);">
+                  <image id="page-proxy-button"
+                         ondraggesture="PageProxyDragGesture(event);"
+                         tooltiptext="&proxyIcon.tooltip;"/>
+                  <image id="page-proxy-favicon" validate="never"
+                         ondraggesture="PageProxyDragGesture(event);"
+                         onload="this.parentNode.selectedIndex = 1;
+                                 event.stopPropagation();"
+                         onerror="gBrowser.addToMissedIconCache(this.src);
+                                  this.removeAttribute('src');
+                                  this.parentNode.selectedIndex = 0;"
+                         tooltiptext="&proxyIcon.tooltip;"/>
+                </deck>
+                <label id="identity-icon-label"/>
+              </box> 
               <hbox id="urlbar-icons">
                 <button type="menu"
                         style="-moz-user-focus: none"
                         class="plain"
                         id="feed-button"
                         chromedir="&locale.dir;"
                         onclick="return FeedHandler.onFeedButtonClick(event);">
                   <menupopup position="after_end"
                              onpopupshowing="return FeedHandler.buildFeedList(this);"
                              oncommand="return FeedHandler.subscribeToFeed(null, event);"
                              onclick="checkForMiddleClick(this, event);"/>
                 </button>
-                <image id="lock-icon" onclick="if (event.button == 0) displaySecurityInfo(); event.stopPropagation();"/>
 #ifdef MOZ_SAFE_BROWSING
                 <image id="safebrowsing-urlbar-icon" tooltiptext="&safeb.urlbaricon.tooltip;"
                        level="safe"
                        onclick="goDoCommand('safebrowsing-show-warning')" />
 #endif
               </hbox>
             </textbox>
             <stack id="go-button-stack">
@@ -409,52 +443,46 @@
     <toolbar id="PersonalToolbar" mode="icons"  iconsize="small" 
              class="chromeclass-directories"
              context="toolbar-context-menu" 
              defaultset="bookmarksBarShowPlaces,personal-bookmarks"
              toolbarname="&personalbarCmd.label;" accesskey="&personalbarCmd.accesskey;"
              customizable="true"/>
   </toolbox>
   
-  <stack id="browser-stack" flex="1">
-    <hbox flex="1" id="browser">
-      <vbox id="sidebar-box" hidden="true" class="chromeclass-extrachrome">
-        <sidebarheader align="center">
-          <label id="sidebar-title" persist="value" flex="1" crop="end" control="sidebar"/>
-          <image id="sidebar-throbber"/>
-          <toolbarbutton class="tabs-closebutton" tooltiptext="&sidebarCloseButton.tooltip;" oncommand="toggleSidebar();"/>
-        </sidebarheader>        
-        <browser id="sidebar" flex="1" autoscroll="false"
-                 style="min-width: 14em; width: 18em; max-width: 36em;"/>
-      </vbox>    
+  <hbox flex="1" id="browser">
+    <vbox id="sidebar-box" hidden="true" class="chromeclass-extrachrome">
+      <sidebarheader align="center">
+        <label id="sidebar-title" persist="value" flex="1" crop="end" control="sidebar"/>
+        <image id="sidebar-throbber"/>
+        <toolbarbutton class="tabs-closebutton" tooltiptext="&sidebarCloseButton.tooltip;" oncommand="toggleSidebar();"/>
+      </sidebarheader>        
+      <browser id="sidebar" flex="1" autoscroll="false"
+                style="min-width: 14em; width: 18em; max-width: 36em;"/>
+    </vbox>    
     
-      <splitter id="sidebar-splitter" class="chromeclass-extrachrome" hidden="true"/>
-      <vbox id="appcontent" flex="1">
-        <tabbrowser id="content" disablehistory="true"
-                    flex="1" contenttooltip="aHTMLTooltip"
-                    contentcontextmenu="contentAreaContextMenu"
-                    onnewtab="BrowserOpenTab();"
-                    autocompletepopup="PopupAutoComplete"
-                    ondragdrop="nsDragAndDrop.drop(event, contentAreaDNDObserver);"
-                    onclick="return contentAreaClick(event, false);"/>
-      </vbox>
-    </hbox>
+    <splitter id="sidebar-splitter" class="chromeclass-extrachrome" hidden="true"/>
+    <vbox id="appcontent" flex="1">
+      <tabbrowser id="content" disablehistory="true"
+                  flex="1" contenttooltip="aHTMLTooltip"
+                  contentcontextmenu="contentAreaContextMenu"
+                  onnewtab="BrowserOpenTab();"
+                  autocompletepopup="PopupAutoComplete"
+                  ondragdrop="nsDragAndDrop.drop(event, contentAreaDNDObserver);"
+                  onclick="return contentAreaClick(event, false);"/>
+    </vbox>
+  </hbox>
 #ifdef TOOLBAR_CUSTOMIZATION_SHEET
-    <hbox flex="1" hidden="true" id="customizeToolbarSheetBox">
-      <hbox flex="1"/>
-      <vbox flex="1">
-        <iframe id="customizeToolbarSheetIFrame"
-                style="&dialog.style;"
-                src="chrome://global/content/customizeToolbar.xul"/>
-        <vbox flex="1"/>
-      </vbox>
-      <hbox flex="1"/>
-    </hbox>
+  <panel id="customizeToolbarSheetPopup" noautohide="true">
+    <iframe id="customizeToolbarSheetIFrame"
+            style="&dialog.style;"
+            src="chrome://global/content/customizeToolbar.xul"
+            hidden="true"/>
+  </panel>
 #endif
-  </stack>
 
   <findbar browserid="content" id="FindToolbar"/>
   
   <statusbar class="chromeclass-status" id="status-bar"
              ondragdrop="nsDragAndDrop.drop(event, contentAreaDNDObserver);">
     <statusbarpanel id="statusbar-display" label="" flex="1"/>
     <statusbarpanel class="statusbarpanel-progress" collapsed="true" id="statusbar-progresspanel">
       <progressmeter class="progressmeter-statusbar" id="statusbar-icon" mode="normal" value="0"/>
--- a/browser/base/content/credits.xhtml
+++ b/browser/base/content/credits.xhtml
@@ -252,17 +252,16 @@
             <li>Marco Casteleijn</li>
             <li>Biswatosh Chakraborty</li>
             <li>Tony Chang</li>
             <li>Wan-Teh Chang</li>
             <li>Ginn Chen</li>
             <li>Pascal Chevrel</li>
             <li>Bob Clary</li>
             <li>Wil Clouser</li>
-            <li>Stephen Colbert</li>
             <li>Mary Colvig</li>
             <li>Majken Connor</li>
             <li>Mike Connor</li>
             <li>Chris Cooper</li>
             <li>Michael Daumling</li>
             <li>Neil Deakin</li>
             <li>Sherman Dickman</li>
             <li>Stephen Donner</li>
@@ -479,24 +478,30 @@
           Mozilla Foundation. You are not granted rights or licenses to the trademarks
           of the Mozilla Foundation or any party, including without limitation the
           Firefox name or logo.</p>
 
         <p class="footnote">
           Gecko&reg; is a registered trademark of Netscape Communications Corporation.</p>
 
         <p class="footnote">
+          Some image files in Mozilla Firefox&reg; are from the
+          <a href="" link="http://www.famfamfam.com/lab/icons/silk/" onclick="visitLink(event);">FAMFAMFAM Silk Icon Set</a>
+          which is licensed under a
+          <a href="" link="http://creativecommons.org/licenses/by/2.5/" onclick="visitLink(event);">Creative Commons Attribution 2.5 License</a>.</p>
+
+        <p class="footnote">
           U.S. GOVERNMENT END USERS. The Software is a &ldquo;commercial item,&rdquo;
           as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of
           &ldquo;commercial computer software&rdquo; and &ldquo;commercial computer software
           documentation,&rdquo; as such terms are used in 48 C.F.R. 12.212 (Sept. 1995).
           Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through
           227.7202-4 (June 1995), all U.S. Government End Users acquire the
           Software with only those rights set forth herein.</p>
-
+          
     </div>
 
     <div id="footerBox">
       <img src="chrome://branding/content/aboutFooter.png" />
     </div>
   </body>
 </html>
 
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -41,17 +41,17 @@
 <bindings id="urlbarBindings" xmlns="http://www.mozilla.org/xbl"
           xmlns:html="http://www.w3.org/1999/xhtml"
           xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
           xmlns:xbl="http://www.mozilla.org/xbl">
 
   <binding id="urlbar" extends="chrome://global/content/bindings/autocomplete.xml#autocomplete">
     <content sizetopopup="pref">
       <xul:hbox class="autocomplete-textbox-container" flex="1">
-        <children includes="image|deck|stack">
+        <children includes="image|deck|stack|box">
           <xul:image class="autocomplete-icon" allowevents="true"/>
         </children>
 
         <xul:stack flex="1" class="textbox-stack">
           <xul:hbox anonid="textbox-input-box" class="textbox-input-box"
                     flex="1" xbl:inherits="tooltiptext=inputtooltiptext">
             <children/>
             <html:input anonid="input" class="autocomplete-textbox textbox-input"
--- a/browser/components/Makefile.in
+++ b/browser/components/Makefile.in
@@ -50,16 +50,18 @@ XPIDLSRCS = \
 	nsIBrowserGlue.idl \
 	$(NULL)
 
 EXTRA_PP_COMPONENTS = \
 	nsBrowserContentHandler.js \
 	nsBrowserGlue.js \
 	$(NULL)
 
+EXTRA_JS_MODULES = distribution.js
+
 DIRS = \
 	dirprovider \
 	microsummaries \
 	migration \
 	preferences \
 	search \
 	sessionstore \
 	shell \
--- a/browser/components/bookmarks/content/bookmarksManager.xul
+++ b/browser/components/bookmarks/content/bookmarksManager.xul
@@ -197,17 +197,17 @@
       </menu>
 #ifdef XP_MACOSX
       <menu id="windowMenu"/>
       <menupopup id="menu_ToolsPopup"/>
 #endif
       <menu id="helpMenu"/>
     </menubar>
 
-    <toolbar id="command-toolbar" tbalign="stretch" class="chromeclass-toolbar">
+    <toolbar id="command-toolbar" class="chromeclass-toolbar">
       <toolbarbutton id="newbookmark" label="&menuitem.newBookmark.label;"
                      accesskey="&menuitem.newBookmark.accesskey;"
                      command="cmd_bm_newbookmark"/>
       <toolbarbutton id="newfolder" label="&menuitem.newFolder.label;"
                      accesskey="&menuitem.newFolder.accesskey;"
                      command="cmd_bm_newfolder"/>
       <toolbarbutton id="newseparator" label="&menuitem.newSeparator.label;" 
                      accesskey="&menuitem.newSeparator.accesskey;"
--- a/browser/components/build/Makefile.in
+++ b/browser/components/build/Makefile.in
@@ -74,17 +74,16 @@ ifdef MOZ_SAFE_BROWSING
 REQUIRES += safebrowsing
 LOCAL_INCLUDES += -I$(srcdir)/../safebrowsing/src
 SHARED_LIBRARY_LIBS += ../safebrowsing/src/$(LIB_PREFIX)safebrowsing_s.$(LIB_SUFFIX)
 endif
 
 EXTRA_DSO_LDOPTS += \
 	$(call EXPAND_LIBNAME_PATH,unicharutil_external_s,$(LIBXUL_DIST)/lib) \
 	$(LIBXUL_DIST)/lib/$(LIB_PREFIX)mozreg_s.$(LIB_SUFFIX) \
-	$(MOZ_JS_LIBS) \
 	$(LIBXUL_DIST)/lib/$(LIB_PREFIX)xpcomglue_s.$(LIB_SUFFIX) \
 	$(MOZ_COMPONENT_LIBS) \
 	$(NULL)
 
 # Mac: Need to link with CoreFoundation for Mac Migrators (PList reading code)
 # GTK2: Need to link with glib for GNOME shell service
 ifneq (,$(filter mac cocoa gtk2,$(MOZ_WIDGET_TOOLKIT)))
 EXTRA_DSO_LDOPTS += \
--- a/browser/components/dirprovider/nsBrowserDirectoryProvider.cpp
+++ b/browser/components/dirprovider/nsBrowserDirectoryProvider.cpp
@@ -195,30 +195,120 @@ AppendFileKey(const char *key, nsIProper
   PRBool exists;
   rv = file->Exists(&exists);
   if (NS_FAILED(rv) || !exists)
     return;
 
   array.AppendObject(file);
 }
 
+// Appends the distribution-specific search engine directories to the
+// array.  The directory structure is as follows:
+
+// appdir/
+// \- distribution/
+//    \- searchplugins/
+//       |- common/
+//       \- locale/
+//          |- <locale 1>/
+//          ...
+//          \- <locale N>/
+
+// common engines are loaded for all locales.  If there is no locale
+// directory for the current locale, there is a pref:
+// "distribution.searchplugins.defaultLocale"
+// which specifies a default locale to use.
+
+static void
+AppendDistroSearchDirs(nsIProperties* aDirSvc, nsCOMArray<nsIFile> &array)
+{
+  nsCOMPtr<nsIFile> searchPlugins;
+  nsresult rv = aDirSvc->Get(NS_XPCOM_CURRENT_PROCESS_DIR,
+                             NS_GET_IID(nsIFile),
+                             getter_AddRefs(searchPlugins));
+  if (NS_FAILED(rv))
+    return;
+  searchPlugins->AppendNative(NS_LITERAL_CSTRING("distribution"));
+  searchPlugins->AppendNative(NS_LITERAL_CSTRING("searchplugins"));
+
+  PRBool exists;
+  rv = searchPlugins->Exists(&exists);
+  if (NS_FAILED(rv) || !exists)
+    return;
+
+  nsCOMPtr<nsIFile> commonPlugins;
+  rv = searchPlugins->Clone(getter_AddRefs(commonPlugins));
+  if (NS_SUCCEEDED(rv)) {
+    commonPlugins->AppendNative(NS_LITERAL_CSTRING("common"));
+    rv = commonPlugins->Exists(&exists);
+    if (NS_SUCCEEDED(rv) && exists)
+        array.AppendObject(commonPlugins);
+  }
+
+  nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
+  if (prefs) {
+
+    nsCOMPtr<nsIFile> localePlugins;
+    rv = searchPlugins->Clone(getter_AddRefs(localePlugins));
+    if (NS_FAILED(rv))
+      return;
+
+    localePlugins->AppendNative(NS_LITERAL_CSTRING("locale"));
+
+    nsCString locale;
+    rv = prefs->GetCharPref("general.useragent.locale", getter_Copies(locale));
+    if (NS_SUCCEEDED(rv)) {
+
+      nsCOMPtr<nsIFile> curLocalePlugins;
+      rv = localePlugins->Clone(getter_AddRefs(curLocalePlugins));
+      if (NS_SUCCEEDED(rv)) {
+
+        curLocalePlugins->AppendNative(locale);
+        rv = curLocalePlugins->Exists(&exists);
+        if (NS_SUCCEEDED(rv) && exists) {
+          array.AppendObject(curLocalePlugins);
+          return; // all done
+        }
+      }
+    }
+
+    // we didn't append the locale dir - try the default one
+    nsCString defLocale;
+    rv = prefs->GetCharPref("distribution.searchplugins.defaultLocale",
+                            getter_Copies(defLocale));
+    if (NS_SUCCEEDED(rv)) {
+
+      nsCOMPtr<nsIFile> defLocalePlugins;
+      rv = localePlugins->Clone(getter_AddRefs(defLocalePlugins));
+      if (NS_SUCCEEDED(rv)) {
+
+        defLocalePlugins->AppendNative(defLocale);
+        rv = defLocalePlugins->Exists(&exists);
+        if (NS_SUCCEEDED(rv) && exists)
+          array.AppendObject(defLocalePlugins);
+      }
+    }
+  }
+}
+
 NS_IMETHODIMP
 nsBrowserDirectoryProvider::GetFiles(const char *aKey,
                                      nsISimpleEnumerator* *aResult)
 {
   nsresult rv;
 
   if (!strcmp(aKey, NS_APP_SEARCH_DIR_LIST)) {
     nsCOMPtr<nsIProperties> dirSvc
       (do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
     if (!dirSvc)
       return NS_ERROR_FAILURE;
 
     nsCOMArray<nsIFile> baseFiles;
 
+    AppendDistroSearchDirs(dirSvc, baseFiles);
     AppendFileKey(NS_APP_SEARCH_DIR, dirSvc, baseFiles);
     AppendFileKey(NS_APP_USER_SEARCH_DIR, dirSvc, baseFiles);
 
     nsCOMPtr<nsISimpleEnumerator> baseEnum;
     rv = NS_NewArrayEnumerator(getter_AddRefs(baseEnum), baseFiles);
     if (NS_FAILED(rv))
       return rv;
 
new file mode 100644
--- /dev/null
+++ b/browser/components/distribution.js
@@ -0,0 +1,331 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Firefox Distribution Customizations.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Dan Mills <thunder@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * 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 ***** */
+
+EXPORTED_SYMBOLS = [ "DistributionCustomizer" ];
+
+const Ci = Components.interfaces;
+const Cc = Components.classes;
+const Cr = Components.results;
+const Cu = Components.utils;
+
+function DistributionCustomizer() {
+  this._distroDir = this._dirSvc.get("XCurProcD", Ci.nsIFile);
+  this._distroDir.append("distribution");
+
+  let iniFile = this._distroDir.clone();
+  iniFile.append("distribution.ini");
+  this._iniExists = iniFile.exists();
+
+  if (!this._iniExists)
+    return;
+
+  this._ini = Cc["@mozilla.org/xpcom/ini-parser-factory;1"].
+    getService(Ci.nsIINIParserFactory).createINIParser(iniFile);
+
+  this._prefs = this._prefSvc.getBranch(null);
+  this._locale = this._prefs.getCharPref("general.useragent.locale");
+
+}
+DistributionCustomizer.prototype = {
+  __bmSvc: null,
+  get _bmSvc() {
+    if (!this.__bmSvc)
+      this.__bmSvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
+                   getService(Ci.nsINavBookmarksService);
+    return this.__bmSvc;
+  },
+
+  __annoSvc: null,
+  get _annoSvc() {
+    if (!this.__annoSvc)
+      this.__annoSvc = Cc["@mozilla.org/browser/annotation-service;1"].
+                   getService(Ci.nsIAnnotationService);
+    return this.__annoSvc;
+  },
+
+  __dirSvc: null,
+  get _dirSvc() {
+    if (!this.__dirSvc)
+      this.__dirSvc = Cc["@mozilla.org/file/directory_service;1"].
+        getService(Ci.nsIProperties);
+    return this.__dirSvc;
+  },
+
+  __prefSvc: null,
+  get _prefSvc() {
+    if (!this.__prefSvc)
+      this.__prefSvc = Cc["@mozilla.org/preferences-service;1"].
+        getService(Ci.nsIPrefService);
+    return this.__prefSvc;
+  },
+
+  __iosvc: null,
+  get _iosvc() {
+    if (!this.__iosvc)
+      this.__iosvc = Cc["@mozilla.org/network/io-service;1"].
+                   getService(Ci.nsIIOService);
+    return this.__iosvc;
+  },
+
+  _locale: "en-US",
+  _distroDir: null,
+  _iniExists: false,
+  _ini: null,
+
+
+  _makeURI: function DIST__makeURI(spec) {
+    return this._iosvc.newURI(spec, null, null);
+  },
+  _parseBookmarksSection: function DIST_parseBookmarksSection(parentId, section) {
+    let keys = [];
+    for (let i in enumerate(this._ini.getKeys(section)))
+      keys.push(i);
+    keys.sort();
+    let items = {};
+    let defaultItemId = -1;
+    let maxItemId = -1;
+
+    for (let i = 0; i < keys.length; i++) {
+      let m = /^item\.(\d+)\.(\w+)\.?(\w*)/.exec(keys[i]);
+      if (m) {
+        let [foo, iid, iprop, ilocale] = m;
+
+        if (ilocale)
+          continue;
+
+        if (!items[iid])
+          items[iid] = {};
+        if (keys.indexOf(keys[i] + "." + this._locale) >= 0) {
+          items[iid][iprop] = this._ini.getString(section, keys[i] + "." +
+                                                  this._locale);
+        } else {
+          items[iid][iprop] = this._ini.getString(section, keys[i]);
+        }
+
+        if (iprop == "type" && items[iid]["type"] == "default")
+          defaultItemId = iid;
+
+        if (maxItemId < iid)
+          maxItemId = iid;
+      } else {
+        dump("Key did not match: " + keys[i] + "\n");
+      }
+    }
+
+    let prependIndex = 0;
+    for (let iid = 0; iid <= maxItemId; iid++) {
+      if (!items[iid])
+        continue;
+
+      let index = -1;
+      let newId;
+
+      switch (items[iid]["type"]) {
+      case "default":
+        break;
+
+      case "folder":
+        if (iid < defaultItemId)
+          index = prependIndex++;
+
+        newId = this._bmSvc.createFolder(parentId, items[iid]["title"], index);
+
+        this._parseBookmarksSection(newId, "BookmarksFolder-" +
+                                    items[iid]["folderId"]);
+
+        if (items[iid]["description"])
+          this._annoSvc.setItemAnnotation(newId, "bookmarkProperties/description",
+                                          items[iid]["description"], 0,
+                                          this._annoSvc.EXPIRE_NEVER);
+
+        break;
+
+      case "separator":
+        if (iid < defaultItemId)
+          index = prependIndex++;
+        this._bmSvc.insertSeparator(parentId, index);
+        break;
+
+      case "bookmark":
+      default:
+        if (iid < defaultItemId)
+          index = prependIndex++;
+
+        newId = this._bmSvc.insertBookmark(parentId,
+                                           this._makeURI(items[iid]["link"]),
+                                           index, items[iid]["title"]);
+
+        if (items[iid]["description"])
+          this._annoSvc.setItemAnnotation(newId, "bookmarkProperties/description",
+                                          items[iid]["description"], 0,
+                                          this._annoSvc.EXPIRE_NEVER);
+
+        break;
+      }
+    }
+  },
+  applyCustomizations: function DIST_applyCustomizations() {
+    if (!this._iniExists)
+      return;
+
+    // nsPrefService loads very early.  Reload prefs so we can set
+    // distribution defaults during the prefservice:after-app-defaults
+    // notification (see applyPrefDefaults below)
+    this._prefSvc.QueryInterface(Ci.nsIObserver);
+    this._prefSvc.observe(null, "reload-default-prefs", null);
+
+    let sections = enumToObject(this._ini.getSections());
+
+    // The global section, and several of its fields, is required
+    // (we also check here to be consistent with applyPrefDefaults below)
+    if (!sections["Global"])
+      return;
+    let globalPrefs = enumToObject(this._ini.getKeys("Global"));
+    if (!(globalPrefs["id"] && globalPrefs["version"] && globalPrefs["about"]))
+      return;
+
+    let bmProcessed = false;
+    let bmProcessedPref = "distribution." +
+      this._ini.getString("Global", "id") + ".bookmarksProcessed";
+    try {
+      bmProcessed = this._prefs.getBoolPref(bmProcessedPref);
+    } catch (e) {}
+
+    if (!bmProcessed) {
+      if (sections["BookmarksMenu"])
+        this._parseBookmarksSection(this._bmSvc.bookmarksRoot,
+                                    "BookmarksMenu");
+      if (sections["BookmarksToolbar"])
+        this._parseBookmarksSection(this._bmSvc.toolbarFolder,
+                                    "BookmarksToolbar");
+      this._prefs.setBoolPref(bmProcessedPref, true);
+    }
+  },
+  applyPrefDefaults: function DIST_applyPrefDefaults() {
+    if (!this._iniExists)
+      return;
+
+    let sections = enumToObject(this._ini.getSections());
+
+    // The global section, and several of its fields, is required
+    if (!sections["Global"])
+      return;
+    let globalPrefs = enumToObject(this._ini.getKeys("Global"));
+    if (!(globalPrefs["id"] && globalPrefs["version"] && globalPrefs["about"]))
+      return;
+
+    let defaults = this._prefSvc.getDefaultBranch(null);
+
+    // Global really contains info we set as prefs.  They're only
+    // separate because they are "special" (read: required)
+
+    defaults.setCharPref("distribution.id", this._ini.getString("Global", "id"));
+    defaults.setCharPref("distribution.version",
+                         this._ini.getString("Global", "version"));
+
+    let partnerAbout = Cc["@mozilla.org/supports-string;1"].
+      createInstance(Ci.nsISupportsString);
+    if (globalPrefs["about." + this._locale]) {
+      partnerAbout.data = this._ini.getString("Global", "about." + this._locale);
+    } else {
+      partnerAbout.data = this._ini.getString("Global", "about");
+    }
+    defaults.setComplexValue("distribution.about",
+                             Ci.nsISupportsString, partnerAbout);
+
+    if (sections["Preferences"]) {
+      for (let key in enumerate(this._ini.getKeys("Preferences"))) {
+        try {
+          let value = eval(this._ini.getString("Preferences", key));
+          switch (typeof value) {
+          case "bool":
+            defaults.setBoolPref(key, value);
+            break;
+          case "int":
+            defaults.setIntPref(key, value);
+            break;
+          case "string":
+            defaults.setCharPref(key, value);
+            break;
+          case "undefined":
+            defaults.setCharPref(key, value);
+            break;
+          }
+        } catch (e) { /* ignore bad prefs and move on */ }
+      }
+    }
+
+    // We eval() the localizable prefs as well (even though they'll
+    // always get set as a string) to keep the INI format consistent:
+    // string prefs always need to be in quotes
+
+    let localizedStr = Cc["@mozilla.org/pref-localizedstring;1"].
+      createInstance(Ci.nsIPrefLocalizedString);
+
+    if (sections["LocalizablePreferences"]) {
+      for (let key in enumerate(this._ini.getKeys("LocalizablePreferences"))) {
+        try {
+          let value = eval(this._ini.getString("LocalizablePreferences", key));
+          value = value.replace("%LOCALE%", this._locale, "g");
+          localizedStr.data = "data:text/plain," + key + "=" + value;
+          defaults.setComplexValue(key, Ci.nsIPrefLocalizedString, localizedStr);
+        } catch (e) { /* ignore bad prefs and move on */ }
+      }
+    }
+
+    if (sections["LocalizablePreferences-" + this._locale]) {
+      for (let key in enumerate(this._ini.getKeys("LocalizablePreferences-" + this._locale))) {
+        try {
+          let value = eval(this._ini.getString("LocalizablePreferences-" + this._locale, key));
+          localizedStr.data = "data:text/plain," + key + "=" + value;
+          defaults.setComplexValue(key, Ci.nsIPrefLocalizedString, localizedStr);
+        } catch (e) { /* ignore bad prefs and move on */ }
+      }
+    }
+  }
+};
+
+function enumerate(UTF8Enumerator) {
+  while (UTF8Enumerator.hasMore())
+    yield UTF8Enumerator.getNext();
+}
+
+function enumToObject(UTF8Enumerator) {
+  let ret = {};
+  for (let i in enumerate(UTF8Enumerator))
+    ret[i] = 1;
+  return ret;
+}
--- a/browser/components/feeds/public/nsIWebContentConverterRegistrar.idl
+++ b/browser/components/feeds/public/nsIWebContentConverterRegistrar.idl
@@ -31,55 +31,42 @@
  * 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 ***** */
 
 #include "nsISupports.idl"
+#include "nsIMIMEInfo.idl"
 
 interface nsIRequest;
 
-[scriptable, uuid(2bd97d63-e928-4d52-9fd4-34061349a9a6)]
-interface nsIWebContentHandlerInfo : nsISupports
+[scriptable, uuid(eb361098-5158-4b21-8f98-50b445f1f0b2)]
+interface nsIWebContentHandlerInfo : nsIHandlerApp
 {
   /**
    * The content type handled by the handler
    */
   readonly attribute AString contentType;
 
   /**
    * The uri of the handler, with an embedded %s where the URI of the loaded
    * document will be encoded.
    */
   readonly attribute AString uri;
 
-  /**
-   * A human readable title of the handler.
-   */
-  readonly attribute AString name;
-
   /** 
    * Gets the service URL Spec, with the loading document URI encoded in it.
    * @param   uri
    *          The URI of the document being loaded
    * @returns The URI of the service with the loading document URI encoded in 
    *          it.
    */
   AString getHandlerURI(in AString uri);
-
-  /**
-   * Determines if this handler object is equivalent to another.
-   * @param   other
-   *          The other handler info object
-   * @returns true if the two objects are equivalent (same content type, 
-   *          same uri).
-   */
-  boolean equals(in nsIWebContentHandlerInfo other);
 };
 
 [scriptable, uuid(632b16a8-5c6b-4dc5-a8db-01771af7a79d)]
 interface nsIWebContentConverterService : nsISupports
 {
   /**
    * Specifies the handler to be used to automatically handle all links of a
    * certain content type from now on. 
--- a/browser/components/feeds/src/FeedConverter.js
+++ b/browser/components/feeds/src/FeedConverter.js
@@ -352,37 +352,35 @@ var FeedResultService = {
 
     var handler = safeGetCharPref(PREF_SELECTED_ACTION, "bookmarks");
     if (handler == "ask" || handler == "reader")
       handler = safeGetCharPref(PREF_SELECTED_READER, "bookmarks");
 
     switch (handler) {
     case "client":
       var clientApp = prefs.getComplexValue(PREF_SELECTED_APP, Ci.nsILocalFile);
-#ifdef XP_MACOSX
-      // On OS X, the built in feed dispatcher (Safari) sends feeds to other
-      // applications (When Default Reader is adjusted) in the following format:
+
+      // For the benefit of applications that might know how to deal with more
+      // URLs than just feeds, send feed: URLs in the following format:
       //
       // http urls: replace scheme with feed, e.g.
       // http://foo.com/index.rdf -> feed://foo.com/index.rdf
-      // other urils: prepend feed: scheme, e.g.
+      // other urls: prepend feed: scheme, e.g.
       // https://foo.com/index.rdf -> feed:https://foo.com/index.rdf
-      //
-      // We duplicate this here for compatibility. 
       var ios = 
           Cc["@mozilla.org/network/io-service;1"].
           getService(Ci.nsIIOService);
-      var macURI = ios.newURI(spec, null, null);
-      if (macURI.schemeIs("http")) {
-        macURI.scheme = "feed";
-        spec = macURI.spec;
+      var feedURI = ios.newURI(spec, null, null);
+      if (feedURI.schemeIs("http")) {
+        feedURI.scheme = "feed";
+        spec = feedURI.spec;
       }
       else
         spec = "feed:" + spec;
-#endif
+
       var ss = 
           Cc["@mozilla.org/browser/shell-service;1"].
           getService(Ci.nsIShellService);
       ss.openApplicationWithURI(clientApp, spec);
       break;
 
     default:
       // "web" should have been handled elsewhere
--- a/browser/components/feeds/src/WebContentConverter.js
+++ b/browser/components/feeds/src/WebContentConverter.js
@@ -106,51 +106,58 @@ var WebContentConverterFactory = {
 
 function ServiceInfo(contentType, uri, name) {
   this._contentType = contentType;
   this._uri = uri;
   this._name = name;
 }
 ServiceInfo.prototype = {
   /**
+   * See nsIHandlerApp
+   */
+  get name() {
+    return this._name;
+  },
+  
+  /**
+   * See nsIHandlerApp
+   */
+  equals: function SI_equals(aHandlerApp) {
+    if (!aHandlerApp)
+      throw Cr.NS_ERROR_NULL_POINTER;
+
+    if (aHandlerApp instanceof Ci.nsIWebContentHandlerInfo &&
+        aHandlerApp.contentType == this.contentType &&
+        aHandlerApp.uri == this.uri)
+      return true;
+
+    return false;
+  },
+
+  /**
    * See nsIWebContentHandlerInfo
    */
   get contentType() {
     return this._contentType;
   },
 
   /**
    * See nsIWebContentHandlerInfo
    */
   get uri() {
     return this._uri;
   },
 
   /**
    * See nsIWebContentHandlerInfo
    */
-  get name() {
-    return this._name;
-  },
-  
-  /**
-   * See nsIWebContentHandlerInfo
-   */
   getHandlerURI: function SI_getHandlerURI(uri) {
     return this._uri.replace(/%s/gi, encodeURIComponent(uri));
   },
   
-  /**
-   * See nsIWebContentHandlerInfo
-   */
-  equals: function SI_equals(other) {
-    return this.contentType == other.contentType &&
-           this.uri == other.uri;
-  },
-  
   QueryInterface: function SI_QueryInterface(iid) {
     if (iid.equals(Ci.nsIWebContentHandlerInfo) ||
         iid.equals(Ci.nsISupports))
       return this;
     throw Cr.NS_ERROR_NO_INTERFACE;
   }
 };
 
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -1,78 +1,91 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is the Firefox Browser Glue Service.
- *
- * The Initial Developer of the Original Code is
- * Giorgio Maone
- * Portions created by the Initial Developer are Copyright (C) 2005
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Giorgio Maone <g.maone@informaction.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * 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 ***** */
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Browser Search Service.
+#
+# The Initial Developer of the Original Code is
+# Giorgio Maone
+# Portions created by the Initial Developer are Copyright (C) 2005
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Giorgio Maone <g.maone@informaction.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
 
 const Ci = Components.interfaces;
 const Cc = Components.classes;
 const Cr = Components.results;
+const Cu = Components.utils;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource:///modules/distribution.js");
+
+// Factory object
+const BrowserGlueServiceFactory = {
+  _instance: null,
+  createInstance: function (outer, iid) 
+  {
+    if (outer != null)
+      throw Components.results.NS_ERROR_NO_AGGREGATION;
+    return this._instance == null ?
+      this._instance = new BrowserGlue() : this._instance;
+  }
+};
 
 // Constructor
 
 function BrowserGlue() {
   this._init();
   this._profileStarted = false;
 }
 
 BrowserGlue.prototype = {
   _saveSession: false,
 
-  QueryInterface: function(iid) 
-  {
-     xpcomCheckInterfaces(iid, kServiceIIds, Cr.NS_ERROR_NO_INTERFACE);
-     return this;
-  }
-,
   // nsIObserver implementation 
   observe: function(subject, topic, data) 
   {
     switch(topic) {
       case "xpcom-shutdown":
         this._dispose();
         break;
       case "profile-before-change":
         this._onProfileChange();
         break;
       case "profile-change-teardown": 
         this._onProfileShutdown();
         break;
+      case "prefservice:after-app-defaults":
+        this._onAppDefaults();
+        break;
       case "final-ui-startup":
         this._onProfileStartup();
         break;
       case "browser:purge-session-history":
         // reset the console service's error buffer
         const cs = Cc["@mozilla.org/consoleservice;1"].
                    getService(Ci.nsIConsoleService);
         cs.logStringMessage(null); // clear the console (in case it's open)
@@ -95,37 +108,47 @@ BrowserGlue.prototype = {
   _init: function() 
   {
     // observer registration
     const osvr = Cc['@mozilla.org/observer-service;1'].
                  getService(Ci.nsIObserverService);
     osvr.addObserver(this, "profile-before-change", false);
     osvr.addObserver(this, "profile-change-teardown", false);
     osvr.addObserver(this, "xpcom-shutdown", false);
+    osvr.addObserver(this, "prefservice:after-app-defaults", false);
     osvr.addObserver(this, "final-ui-startup", false);
     osvr.addObserver(this, "browser:purge-session-history", false);
     osvr.addObserver(this, "quit-application-requested", false);
     osvr.addObserver(this, "quit-application-granted", false);
   },
 
   // cleanup (called on application shutdown)
   _dispose: function() 
   {
     // observer removal 
     const osvr = Cc['@mozilla.org/observer-service;1'].
                  getService(Ci.nsIObserverService);
     osvr.removeObserver(this, "profile-before-change");
     osvr.removeObserver(this, "profile-change-teardown");
     osvr.removeObserver(this, "xpcom-shutdown");
+    osvr.removeObserver(this, "prefservice:after-app-defaults");
     osvr.removeObserver(this, "final-ui-startup");
     osvr.removeObserver(this, "browser:purge-session-history");
     osvr.removeObserver(this, "quit-application-requested");
     osvr.removeObserver(this, "quit-application-granted");
   },
 
+  _onAppDefaults: function()
+  {
+    // apply distribution customizations (prefs)
+    // other customizations are applied in _onProfileStartup()
+    var distro = new DistributionCustomizer();
+    distro.applyPrefDefaults();
+  },
+
   // profile startup handler (contains profile initialization routines)
   _onProfileStartup: function() 
   {
     // check to see if the EULA must be shown on startup
     try {
       var mustDisplayEULA = true;
       var prefBranch = Cc["@mozilla.org/preferences-service;1"].
                        getService(Ci.nsIPrefBranch);
@@ -150,16 +173,21 @@ BrowserGlue.prototype = {
                getService(Ci.nsIWindowWatcher);
       ww.openWindow(null, "chrome://browser/content/safeMode.xul", 
                     "_blank", "chrome,centerscreen,modal,resizable=no", null);
     }
 
     // initialize Places
     this._initPlaces();
 
+    // apply distribution customizations
+    // prefs are applied in _onAppDefaults()
+    var distro = new DistributionCustomizer();
+    distro.applyCustomizations();
+
     // indicate that the profile was initialized
     this._profileStarted = true;
   },
 
   _onProfileChange: function()
   {
     // this block is for code that depends on _onProfileStartup() having 
     // been called.
@@ -361,116 +389,36 @@ BrowserGlue.prototype = {
   
   // ------------------------------
   // public nsIBrowserGlue members
   // ------------------------------
   
   sanitize: function(aParentWindow) 
   {
     this.Sanitizer.sanitize(aParentWindow);
-  }
-}
-
-
-// XPCOM Scaffolding code
-
-// component defined in this file
+  },
 
-const kServiceName = "Firefox Browser Glue Service";
-const kServiceId = "{eab9012e-5f74-4cbc-b2b5-a590235513cc}";
-const kServiceCtrId = "@mozilla.org/browser/browserglue;1";
-const kServiceConstructor = BrowserGlue;
-
-const kServiceCId = Components.ID(kServiceId);
-
-// interfaces implemented by this component
-const kServiceIIds = [ 
-  Ci.nsIObserver,
-  Ci.nsISupports,
-  Ci.nsISupportsWeakReference,
-  Ci.nsIBrowserGlue
-  ];
+  // for XPCOM
+  classDescription: "Firefox Browser Glue Service",
+  classID:          Components.ID("{eab9012e-5f74-4cbc-b2b5-a590235513cc}"),
+  contractID:       "@mozilla.org/browser/browserglue;1",
 
-// categories which this component is registered in
-const kServiceCats = ["app-startup"];
-
-// Factory object
-const kServiceFactory = {
-  _instance: null,
-  createInstance: function (outer, iid) 
-  {
-    if (outer != null) throw Cr.NS_ERROR_NO_AGGREGATION;
+  QueryInterface : XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupports,
+                                          Ci.nsISupportsWeakReference,
+                                          Ci.nsIBrowserGlue]),
 
-    xpcomCheckInterfaces(iid, kServiceIIds, 
-                          Cr.NS_ERROR_INVALID_ARG);
-    return this._instance == null ?
-      this._instance = new kServiceConstructor() : this._instance;
-  }
-};
+  // redefine the default factory for XPCOMUtils
+  _xpcom_factory: BrowserGlueServiceFactory,
 
-function xpcomCheckInterfaces(iid, iids, ex) {
-  for (var j = iids.length; j-- >0;) {
-    if (iid.equals(iids[j])) return true;
-  }
-  throw ex;
+  // get this contractID registered for certain categories via XPCOMUtils
+  _xpcom_categories: [
+    // make BrowserGlue a startup observer
+    { category: "app-startup", service: true }
+  ]
 }
 
-// Module
+//module initialization
+function NSGetModule(aCompMgr, aFileSpec) {
+  return XPCOMUtils.generateModule([BrowserGlue]);
+}
 
-var Module = {
-  registered: false,
-  
-  registerSelf: function(compMgr, fileSpec, location, type) 
-  {
-    if (!this.registered) {
-      compMgr.QueryInterface(Ci.nsIComponentRegistrar)
-             .registerFactoryLocation(kServiceCId,
-                                      kServiceName,
-                                      kServiceCtrId, 
-                                      fileSpec,
-                                      location, 
-                                      type);
-      const catman = Cc['@mozilla.org/categorymanager;1'].
-                     getService(Ci.nsICategoryManager);
-      var len = kServiceCats.length;
-      for (var j = 0; j < len; j++) {
-        catman.addCategoryEntry(kServiceCats[j],
-          kServiceCtrId, kServiceCtrId, true, true);
-      }
-      this.registered = true;
-    } 
-  },
-  
-  unregisterSelf: function(compMgr, fileSpec, location) 
-  {
-    compMgr.QueryInterface(Ci.nsIComponentRegistrar)
-           .unregisterFactoryLocation(kServiceCId, fileSpec);
-    const catman = Cc['@mozilla.org/categorymanager;1'].
-                   getService(Ci.nsICategoryManager);
-    var len = kServiceCats.length;
-    for (var j = 0; j < len; j++) {
-      catman.deleteCategoryEntry(kServiceCats[j], kServiceCtrId, true);
-    }
-  },
-  
-  getClassObject: function(compMgr, cid, iid) 
-  {
-    if(cid.equals(kServiceCId))
-      return kServiceFactory;
-    
-    throw Cr[
-      iid.equals(Ci.nsIFactory)
-      ? "NS_ERROR_NO_INTERFACE"
-      : "NS_ERROR_NOT_IMPLEMENTED"
-    ];
-    
-  },
-  
-  canUnload: function(compMgr) 
-  {
-    return true;
-  }
-};
+	
 
-// entrypoint
-function NSGetModule(compMgr, fileSpec) {
-  return Module;
-}
--- a/browser/components/places/content/places.js
+++ b/browser/components/places/content/places.js
@@ -265,17 +265,17 @@ var PlacesOrganizer = {
     // The migrator window will set this to true when it closes, if the user
     // chose to migrate from a specific file.
     window.fromFile = false;
     openDialog("chrome://browser/content/migration/migration.xul",
                "migration", features, "bookmarks");
     if (window.fromFile)
     this.importFromFile();
   },
-  
+
   /**
    * Open a file-picker and import the selected file into the bookmarks store
    */
   importFromFile: function PO_importFromFile() {
     var fp = Cc["@mozilla.org/filepicker;1"].
              createInstance(Ci.nsIFilePicker);
     fp.init(window, PlacesUtils.getString("SelectImport"),
             Ci.nsIFilePicker.modeOpen);
@@ -302,16 +302,151 @@ var PlacesOrganizer = {
     fp.defaultString = "bookmarks.html";
     if (fp.show() != Ci.nsIFilePicker.returnCancel) {
       var exporter = Cc["@mozilla.org/browser/places/import-export-service;1"].
                      getService(Ci.nsIPlacesImportExportService);
       exporter.exportHTMLToFile(fp.file);
     }
   },
 
+  /**
+   * Populates the restore menu with the dates of the backups available.
+   */
+  populateRestoreMenu: function PO_populateRestoreMenu() {
+    var restorePopup = document.getElementById("fileRestorePopup");
+
+    // remove existing menu items
+    // last item is the restoreFromFile item
+    while (restorePopup.childNodes.length > 1)
+      restorePopup.removeChild(restorePopup.firstChild);
+
+    // get bookmarks backup dir
+    var dirSvc = Cc["@mozilla.org/file/directory_service;1"].
+                     getService(Ci.nsIProperties);
+    var bookmarksBackupDir = dirSvc.get("ProfD", Ci.nsIFile);
+    bookmarksBackupDir.append("bookmarkbackups"); 
+    if (!bookmarksBackupDir.exists())
+      return; // no backup files
+
+    // get list of files
+    var fileList = [];
+    var files = bookmarksBackupDir.directoryEntries;
+    while (files.hasMoreElements()) {
+      var f = files.getNext().QueryInterface(Ci.nsIFile);
+      if (!f.isHidden() && f.leafName.match(/\.html?$/))
+        fileList.push(f);
+    }
+
+    fileList.sort(function PO_fileList_compare(a, b) {
+        return b.lastModifiedTime - a.lastModifiedTime;
+      });
+
+    if (fileList.length == 0)
+      return;
+
+    // populate menu
+    for (var i = 0; i < fileList.length; i++) {
+      var m = restorePopup.insertBefore
+        (document.createElement("menuitem"),
+         document.getElementById("restoreFromFile"));
+      var dateStr = fileList[i].leafName.replace("bookmarks-", "").
+        replace(".html", "");
+      if (!dateStr.length)
+        dateStr = fileList[i].leafName;
+      m.setAttribute("label", dateStr);
+      m.setAttribute("value", fileList[i].leafName);
+      m.setAttribute("oncommand",
+                     "PlacesOrganizer.onRestoreMenuItemClick(this);");
+    }
+    restorePopup.insertBefore(document.createElement("menuseparator"),
+                              document.getElementById("restoreFromFile"));
+  },
+
+  /**
+   * Called when a menuitem is selected from the restore menu.
+   */
+  onRestoreMenuItemClick: function PO_onRestoreMenuItemClick(aMenuItem) {
+    var dirSvc = Cc["@mozilla.org/file/directory_service;1"].
+                     getService(Ci.nsIProperties);
+    var bookmarksFile = dirSvc.get("ProfD", Ci.nsIFile);
+    bookmarksFile.append("bookmarkbackups"); 
+    bookmarksFile.append(aMenuItem.getAttribute("value"));
+    if (!bookmarksFile.exists())
+      return;
+
+    var prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"].
+      getService(Ci.nsIPromptService);
+    if (!prompts.confirm(null,
+                         PlacesUtils.getString("bookmarksRestoreAlertTitle"),
+                         PlacesUtils.getString("bookmarksRestoreAlert")))
+      return;
+
+    var ieSvc = Cc["@mozilla.org/browser/places/import-export-service;1"].
+      getService(Ci.nsIPlacesImportExportService);
+    ieSvc.importHTMLFromFile(bookmarksFile, true);
+  },
+
+  /**
+   * Backup bookmarks to desktop, auto-generate a filename with a date
+   */
+  backupBookmarks: function PO_backupBookmarks() {
+    var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
+    fp.init(window, PlacesUtils.getString("bookmarksBackupTitle"),
+            Ci.nsIFilePicker.modeSave);
+    fp.appendFilters(Ci.nsIFilePicker.filterHTML);
+  
+    var dirSvc = Cc["@mozilla.org/file/directory_service;1"].
+      getService(Ci.nsIProperties);
+    var backupsDir = dirSvc.get("Desk", Ci.nsILocalFile);
+    fp.displayDirectory = backupsDir;
+  
+    var dateService = Cc["@mozilla.org/intl/scriptabledateformat;1"].
+      getService(Ci.nsIScriptableDateFormat);
+
+    var d = new Date();
+    var date = dateService.FormatDate("", dateService.dateFormatShort,
+                           d.getFullYear(), d.getMonth() + 1, d.getDate());
+    fp.defaultString = PlacesUtils.getFormattedString("bookmarksBackupFilename",
+                                                      [date]);
+  
+    if (fp.show() != Ci.nsIFilePicker.returnCancel) {
+      var ieSvc = Cc["@mozilla.org/browser/places/import-export-service;1"].
+        getService(Ci.nsIPlacesImportExportService);
+      ieSvc.exportHTMLToFile(fp.file);
+    }
+  },
+
+  /**
+   * Called when 'Choose File...' is selected from the Revert menupopup
+   * Prompts for a file and reverts bookmarks to those in the file
+   */
+  restoreFromFile: function PO_restoreFromFile() {
+    var prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"].
+      getService(Ci.nsIPromptService);
+    if (!prompts.confirm(null, PlacesUtils.getString("bookmarksRestoreAlertTitle"),
+                         PlacesUtils.getString("bookmarksRestoreAlert")))
+      return;
+  
+    var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
+    fp.init(window, PlacesUtils.getString("bookmarksRestoreTitle"),
+            Ci.nsIFilePicker.modeOpen);
+    fp.appendFilters(Ci.nsIFilePicker.filterHTML);
+  
+    var dirSvc = Cc["@mozilla.org/file/directory_service;1"].
+      getService(Ci.nsIProperties);
+    var backupsDir = dirSvc.get("Desk", Ci.nsILocalFile);
+    fp.displayDirectory = backupsDir;
+  
+    if (fp.show() != Ci.nsIFilePicker.returnCancel) {
+      var ieSvc = Cc["@mozilla.org/browser/places/import-export-service;1"].
+                     getService(Ci.nsIPlacesImportExportService);
+      ieSvc.importHTMLFromFile(fp.file, true);
+    }
+  },
+
   updateStatusBarForView: function PO_updateStatusBarForView(aView) {
     var statusText = "";
     var selectedNode = aView.selectedNode;
     if (selectedNode) {
       if (PlacesUtils.nodeIsFolder(selectedNode)) {
         var childsCount = 
           PlacesUtils.getFolderContents(selectedNode.itemId).root.childCount;
         statusText = PlacesUtils.getFormattedString("status_foldercount",
--- a/browser/components/places/content/places.xul
+++ b/browser/components/places/content/places.xul
@@ -81,16 +81,20 @@
     <command id="OrganizerCommand_find:current"
              label="&cmd.findCurrent.label;"
              accesskey="&cmd.findCurrent.accesskey;"
              oncommand="PlacesSearchBox.findCurrent();"/>
     <command id="OrganizerCommand_export"
              oncommand="PlacesOrganizer.exportBookmarks();"/>
     <command id="OrganizerCommand_import"
              oncommand="PlacesOrganizer.importBookmarks();"/>
+    <command id="OrganizerCommand_backup"
+             oncommand="PlacesOrganizer.backupBookmarks();"/>
+    <command id="OrganizerCommand_restoreFromFile"
+             oncommand="PlacesOrganizer.restoreFromFile();"/>
     <command id="OrganizerCommand_search:save"
              oncommand="PlacesOrganizer.saveSearch();"/>
     <command id="OrganizerCommand_search:moreCriteria"
              oncommand="PlacesQueryBuilder.addRow();"/>
   </commandset>
 
   <broadcasterset id="placesGroupingBroadcasters">
     <broadcaster id="placesBC_grouping:off"/>
@@ -183,16 +187,30 @@
                     command="OrganizerCommand_import"
                     label="&cmd.import.label;"
                     accesskey="&cmd.import.accesskey;"/>
           <menuitem id="fileExport"
                     command="OrganizerCommand_export"
                     label="&cmd.export.label;"
                     accesskey="&cmd.export.accesskey;"/>
           <menuseparator/>
+          <menuitem id="backupBookmarks"
+                    command="OrganizerCommand_backup"
+                    label="&cmd.backup.label;"
+                    accesskey="&cmd.backup.accesskey;"/>
+          <menu id="fileRestoreMenu" label="&cmd.restore.label;"
+                    accesskey="&cmd.export.accesskey;">
+            <menupopup id="fileRestorePopup" onpopupshowing="PlacesOrganizer.populateRestoreMenu();">
+              <menuitem id="restoreFromFile"
+                        command="OrganizerCommand_restoreFromFile"
+                        label="&cmd.restoreFromFile.label;"
+                        accesskey="&cmd.restoreFromFile.accesskey;"/>
+            </menupopup>
+          </menu>
+          <menuseparator/>
           <menuitem id="fileClose"
                     key="placesKey_close" 
                     label="&file.close.label;"
                     accesskey="&file.close.accesskey;" 
                     oncommand="close();"/>
         </menupopup>
       </menu>
       <menu id="editMenu" label="&edit.label;" accesskey="&edit.accesskey;">
--- a/browser/components/places/content/placesOverlay.xul
+++ b/browser/components/places/content/placesOverlay.xul
@@ -153,26 +153,29 @@
               accesskey="&cmd.new_separator.accesskey;"
               closemenu="single"
               selection="mutable"/>
     <menuseparator id="placesContext_newSeparator"/>
     <menuitem id="placesContext_cut"
               command="cmd_cut"
               label="&cutCmd.label;"
               accesskey="&cutCmd.accesskey;" 
+              closemenu="single"
               selection="separator|link|folder|mixed|query"
               forcehideselection="livemarkChild"/>
     <menuitem id="placesContext_copy"
               command="cmd_copy"
               label="&copyCmd.label;"
+              closemenu="single"
               accesskey="&copyCmd.accesskey;" 
               selection="separator|link|folder|query"/>
     <menuitem id="placesContext_paste"
               command="cmd_paste"
               label="&pasteCmd.label;"
+              closemenu="single"
               accesskey="&pasteCmd.accesskey;"
               selection="mutable|query"/>
     <menuseparator id="placesContext_editSeparator"/>
     <menuitem id="placesContext_delete"
               command="cmd_delete"
               label="&deleteCmd.label;"
               accesskey="&deleteCmd.accesskey;"
               closemenu="single"
--- a/browser/components/places/content/toolbar.xml
+++ b/browser/components/places/content/toolbar.xml
@@ -789,24 +789,26 @@
           else {
             // Dragging over a normal toolbarbutton,
             // show indicator bar and move it to the appropriate drop point.
             if (!ib.hasAttribute("dragging"))
               ib.setAttribute("dragging", "true");
             var ind = ib.firstChild;
             var direction = document.defaultView.getComputedStyle(this._self.parentNode, "").direction;
             if (direction == "ltr") {
-              if (dropPoint.beforeIndex == -1)
+              if (!this._self.childNodes.length)
+                ind.style.marginLeft = 0 - this._self.boxObject.x - 7 + 'px'
+              else if (dropPoint.beforeIndex == -1)
                 ind.style.marginLeft = this._self.lastChild.boxObject.x + 
                                        this._self.lastChild.boxObject.width - this._self.boxObject.x - 7 + 'px';
               else
                 ind.style.marginLeft = this._self.childNodes[dropPoint.beforeIndex].boxObject.x -
                                        this._self.boxObject.x - 7 + 'px';
             } else {
-              if (dropPoint.beforeIndex == -1)
+              if (dropPoint.beforeIndex == -1 || !this._self.childNodes.length)
                 ind.style.marginRight = '0px';
               else
                 ind.style.marginRight = (this._self.childNodes[this._self.childNodes.length - 1].boxObject.x +
                                          this._self.childNodes[this._self.childNodes.length - 1].boxObject.width) -
                                         (this._self.childNodes[dropPoint.beforeIndex].boxObject.x) - 5 + 'px';
             }
             // Clear out old folder information
             this._clearOverFolder();
--- a/browser/components/places/content/utils.js
+++ b/browser/components/places/content/utils.js
@@ -46,16 +46,17 @@ var Ci = Components.interfaces;
 var Cc = Components.classes;
 var Cr = Components.results;
 
 Components.utils.import("resource://gre/modules/JSON.jsm");
 
 const LOAD_IN_SIDEBAR_ANNO = "bookmarkProperties/loadInSidebar";
 const DESCRIPTION_ANNO = "bookmarkProperties/description";
 const POST_DATA_ANNO = "URIProperties/POSTData";
+const LMANNO_FEEDURI = "livemark/feedURI";
 
 #ifdef XP_MACOSX
 // On Mac OSX, the transferable system converts "\r\n" to "\n\n", where we
 // really just want "\n".
 const NEWLINE= "\n";
 #else
 // On other platforms, the transferable system converts "\r\n" to "\n".
 const NEWLINE = "\r\n";
@@ -393,17 +394,17 @@ var PlacesUtils = {
   * Determines whether a result node is a remote container registered by the
   * livemark service.
   * @param aNode
   *        A result Node
   * @returns true if the node is a livemark container item
   */
   nodeIsLivemarkContainer: function PU_nodeIsLivemarkContainer(aNode) {
     return this.nodeIsFolder(aNode) &&
-           this.annotations.itemHasAnnotation(aNode.itemId, "livemark/feedURI");
+           this.annotations.itemHasAnnotation(aNode.itemId, LMANNO_FEEDURI);
   },
 
  /**
   * Determines whether a result node is a live-bookmark item
   * @param aNode
   *        A result node
   * @returns true if the node is a livemark container item
   */
@@ -1502,22 +1503,34 @@ var PlacesUtils = {
     var bmkIds = this.bookmarks.getBookmarkIdsForURI(aURI, {});
     for each (var bk in bmkIds) {
       // Find the first folder which isn't a tag container
       var parent = this.bookmarks.getFolderIdForItem(bk);
       if (parent == this.placesRootId)
         return bk;
       var grandparent = this.bookmarks.getFolderIdForItem(parent);
       if (grandparent != this.tagRootId &&
-          !this.annotations.itemHasAnnotation(parent, "livemark/feedURI"))
+          !this.annotations.itemHasAnnotation(parent, LMANNO_FEEDURI))
         return bk;
     }
     return -1;
   },
 
+  getMostRecentFolderForFeedURI:
+  function PU_getMostRecentFolderForFeedURI(aURI) {
+    var feedSpec = aURI.spec
+    var annosvc = this.annotations;
+    var livemarks = annosvc.getItemsWithAnnotation(LMANNO_FEEDURI, {});
+    for (var i = 0; i < livemarks.length; i++) {
+      if (annosvc.getItemAnnotation(livemarks[i], LMANNO_FEEDURI) == feedSpec)
+        return livemarks[i];
+    }
+    return -1;
+  },
+
   getURLsForContainerNode: function PU_getURLsForContainerNode(aNode) {
     let urls = [];
     if (this.nodeIsFolder(aNode) && asQuery(aNode).queryOptions.excludeItems) {
       // grab manually
       let contents = this.getFolderContents(node.itemId, false, false).root;
       for (let i = 0; i < contents.childCount; ++i) {
         let child = contents.getChild(i);
         if (this.nodeIsURI(child))
new file mode 100755
--- /dev/null
+++ b/browser/components/preferences/applications.js
@@ -0,0 +1,1513 @@
+/*
+# -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Download Actions Manager.
+#
+# The Initial Developer of the Original Code is
+# Ben Goodger.
+# Portions created by the Initial Developer are Copyright (C) 2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Ben Goodger <ben@mozilla.org>
+#   Jeff Walden <jwalden+code@mit.edu>
+#   Asaf Romano <mozilla.mano@sent.com>
+#   Myk Melez <myk@mozilla.org>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# 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 *****
+ */
+
+//****************************************************************************//
+// Constants & Enumeration Values
+
+/*
+#ifndef XP_MACOSX
+*/
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cr = Components.results;
+var TYPE_MAYBE_FEED = "application/vnd.mozilla.maybe.feed";
+const kXULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+/*
+#endif
+*/
+
+const PREF_DISABLED_PLUGIN_TYPES = "plugin.disable_full_page_plugin_for_types";
+
+// Preferences that affect which entries to show in the list.
+const PREF_SHOW_PLUGINS_IN_LIST = "browser.download.show_plugins_in_list";
+const PREF_HIDE_PLUGINS_WITHOUT_EXTENSIONS =
+  "browser.download.hide_plugins_without_extensions";
+
+/*
+ * Preferences where we store handling information about the feed type.
+ *
+ * browser.feeds.handler
+ * - "bookmarks", "reader" (clarified further using the .default preference),
+ *   or "ask" -- indicates the default handler being used to process feeds;
+ *   "bookmarks" is obsolete; to specify that the handler is bookmarks,
+ *   set browser.feeds.handler.default to "bookmarks";
+ *
+ * browser.feeds.handler.default
+ * - "bookmarks", "client" or "web" -- indicates the chosen feed reader used
+ *   to display feeds, either transiently (i.e., when the "use as default"
+ *   checkbox is unchecked, corresponds to when browser.feeds.handler=="ask")
+ *   or more permanently (i.e., the item displayed in the dropdown in Feeds
+ *   preferences)
+ *
+ * browser.feeds.handler.webservice
+ * - the URL of the currently selected web service used to read feeds
+ *
+ * browser.feeds.handlers.application
+ * - nsILocalFile, stores the current client-side feed reading app if one has
+ *   been chosen
+ */
+const PREF_FEED_SELECTED_APP    = "browser.feeds.handlers.application";
+const PREF_FEED_SELECTED_WEB    = "browser.feeds.handlers.webservice";
+const PREF_FEED_SELECTED_ACTION = "browser.feeds.handler";
+const PREF_FEED_SELECTED_READER = "browser.feeds.handler.default";
+
+// The nsHandlerInfoAction enumeration values in nsIHandlerInfo identify
+// the actions the application can take with content of various types.
+// But since nsIHandlerInfo doesn't support plugins, there's no value
+// identifying the "use plugin" action, so we use this constant instead.
+const kActionUsePlugin = 5;
+
+
+//****************************************************************************//
+// Utilities
+
+function getDisplayNameForFile(aFile) {
+/*
+#ifdef XP_WIN
+*/
+  if (aFile instanceof Ci.nsILocalFileWin) {
+    try {
+      return aFile.getVersionInfoField("FileDescription"); 
+    }
+    catch(ex) {
+      // fall through to the file name
+    }
+  }
+/*
+#endif
+#ifdef XP_MACOSX
+*/
+  if (aFile instanceof Ci.nsILocalFileMac) {
+    try {
+      return aFile.bundleDisplayName;
+    }
+    catch(ex) {
+      // fall through to the file name
+    }
+  }
+/*
+#endif
+*/
+
+  return Cc["@mozilla.org/network/io-service;1"].
+         getService(Ci.nsIIOService).
+         newFileURI(aFile).
+         QueryInterface(Ci.nsIURL).
+         fileName;
+}
+
+function getLocalHandlerApp(aFile) {
+  var localHandlerApp = Cc["@mozilla.org/uriloader/local-handler-app;1"].
+                        createInstance(Ci.nsILocalHandlerApp);
+  localHandlerApp.name = getDisplayNameForFile(aFile);
+  localHandlerApp.executable = aFile;
+
+  return localHandlerApp;
+}
+
+
+//****************************************************************************//
+// HandlerInfoWrapper
+
+/**
+ * This object wraps nsIHandlerInfo with some additional functionality
+ * the Applications prefpane needs to display and allow modification of
+ * the list of handled types.
+ * 
+ * We create an instance of this wrapper for each entry we might display
+ * in the prefpane, and we compose the instances from various sources,
+ * including navigator.plugins and the handler service.
+ *
+ * We don't implement all the original nsIHandlerInfo functionality,
+ * just the stuff that the prefpane needs.
+ * 
+ * In theory, all of the custom functionality in this wrapper should get
+ * pushed down into nsIHandlerInfo eventually.
+ */
+function HandlerInfoWrapper(aType, aHandlerInfo) {
+  this._type = aType;
+  this.wrappedHandlerInfo = aHandlerInfo;
+}
+
+HandlerInfoWrapper.prototype = {
+  // The wrapped nsIHandlerInfo object.  In general, this object is private,
+  // but there are a couple cases where callers access it directly for things
+  // we haven't (yet?) implemented, so we make it a public property.
+  wrappedHandlerInfo: null,
+
+  //**************************************************************************//
+  // Convenience Utils
+
+  _handlerSvc: Cc["@mozilla.org/uriloader/handler-service;1"].
+               getService(Ci.nsIHandlerService),
+
+  // Retrieve this as nsIPrefBranch and then immediately QI to nsIPrefBranch2
+  // so both interfaces are available to callers.
+  _prefSvc: Cc["@mozilla.org/preferences-service;1"].
+            getService(Ci.nsIPrefBranch).
+            QueryInterface(Ci.nsIPrefBranch2),
+
+  _categoryMgr: Cc["@mozilla.org/categorymanager;1"].
+                getService(Ci.nsICategoryManager),
+
+  element: function(aID) {
+    return document.getElementById(aID);
+  },
+
+
+  //**************************************************************************//
+  // nsISupports
+
+  QueryInterface: function(aIID) {
+    if (aIID.equals(Ci.nsIHandlerInfo) ||
+        aIID.equals(Ci.nsISupports) ||
+        (aIID.equals(Ci.nsIMIMEInfo) &&
+         this.wrappedHandlerInfo instanceof Ci.nsIMIMEInfo))
+      return this;
+
+    throw Cr.NS_ERROR_NO_INTERFACE;
+  },
+
+
+  //**************************************************************************//
+  // nsIHandlerInfo
+
+  // The MIME type or protocol scheme.
+  _type: null,
+  get type() {
+    return this._type;
+  },
+
+  get description() {
+    if (this.wrappedHandlerInfo.description)
+      return this.wrappedHandlerInfo.description;
+
+    if (this.primaryExtension) {
+      let bundle = this.element("bundlePreferences");
+      var extension = this.primaryExtension.toUpperCase();
+      return bundle.getFormattedString("fileEnding", [extension]);
+    }
+
+    return this.type;
+  },
+
+  get preferredApplicationHandler() {
+    return this.wrappedHandlerInfo.preferredApplicationHandler;
+  },
+
+  set preferredApplicationHandler(aNewValue) {
+    this.wrappedHandlerInfo.preferredApplicationHandler = aNewValue;
+
+    // Make sure the preferred handler is in the set of possible handlers.
+    if (aNewValue) {
+      var found = false;
+      var possibleApps = this.possibleApplicationHandlers.
+                         QueryInterface(Ci.nsIArray).enumerate();
+      while (possibleApps.hasMoreElements() && !found)
+        found = possibleApps.getNext().equals(aNewValue);
+      if (!found)
+        this.possibleApplicationHandlers.appendElement(aNewValue, false);
+    }
+  },
+
+  get possibleApplicationHandlers() {
+    return this.wrappedHandlerInfo.possibleApplicationHandlers;
+  },
+
+  get hasDefaultHandler() {
+    return this.wrappedHandlerInfo.hasDefaultHandler;
+  },
+
+  get defaultDescription() {
+    return this.wrappedHandlerInfo.defaultDescription;
+  },
+
+  // What to do with content of this type.
+  get preferredAction() {
+    // If we have an enabled plugin, then the action is to use that plugin.
+    if (this.plugin && !this.isDisabledPluginType)
+      return kActionUsePlugin;
+
+    // XXX nsIMIMEService::getFromTypeAndExtension returns handler infos
+    // whose default action is saveToDisk; should we do that here too?
+    // And will there ever be handler info objects with no preferred action?
+    if (!this.wrappedHandlerInfo.preferredAction) {
+      if (gApplicationsPane.isValidHandlerApp(this.preferredApplicationHandler))
+        return Ci.nsIHandlerInfo.useHelperApp;
+      else
+        return Ci.nsIHandlerInfo.useSystemDefault;
+    }
+
+    // If the action is to use a helper app, but we don't have a preferred
+    // helper app, switch to using the system default.
+    if (this.wrappedHandlerInfo.preferredAction == Ci.nsIHandlerInfo.useHelperApp &&
+        !gApplicationsPane.isValidHandlerApp(this.preferredApplicationHandler))
+      return Ci.nsIHandlerInfo.useSystemDefault;
+
+    return this.wrappedHandlerInfo.preferredAction;
+  },
+
+  set preferredAction(aNewValue) {
+    // We don't modify the preferred action if the new action is to use a plugin
+    // because handler info objects don't understand our custom "use plugin"
+    // value.  Also, leaving it untouched means that we can automatically revert
+    // to the old setting if the user ever removes the plugin.
+
+    if (aNewValue != kActionUsePlugin)
+      this.wrappedHandlerInfo.preferredAction = aNewValue;
+  },
+
+  get alwaysAskBeforeHandling() {
+    // If this type is handled only by a plugin, we can't trust the value
+    // in the handler info object, since it'll be a default based on the absence
+    // of any user configuration, and the default in that case is to always ask,
+    // even though we never ask for content handled by a plugin, so special case
+    // plugin-handled types by returning false here.
+    if (this.plugin && this.handledOnlyByPlugin)
+      return false;
+
+    return this.wrappedHandlerInfo.alwaysAskBeforeHandling;
+  },
+
+  set alwaysAskBeforeHandling(aNewValue) {
+    this.wrappedHandlerInfo.alwaysAskBeforeHandling = aNewValue;
+  },
+
+
+  //**************************************************************************//
+  // nsIMIMEInfo
+
+  // The primary file extension associated with this type, if any.
+  //
+  // XXX Plugin objects contain an array of MimeType objects with "suffixes"
+  // properties; if this object has an associated plugin, shouldn't we check
+  // those properties for an extension?
+  get primaryExtension() {
+    try {
+      if (this.wrappedHandlerInfo instanceof Ci.nsIMIMEInfo &&
+          this.wrappedHandlerInfo.primaryExtension)
+        return this.wrappedHandlerInfo.primaryExtension
+    } catch(ex) {}
+
+    return null;
+  },
+
+
+  //**************************************************************************//
+  // Plugin Handling
+
+  // A plugin that can handle this type, if any.
+  //
+  // Note: just because we have one doesn't mean it *will* handle the type.
+  // That depends on whether or not the type is in the list of types for which
+  // plugin handling is disabled.
+  plugin: null,
+
+  // Whether or not this type is only handled by a plugin or is also handled
+  // by some user-configured action as specified in the handler info object.
+  //
+  // Note: we can't just check if there's a handler info object for this type,
+  // because OS and user configuration is mixed up in the handler info object,
+  // so we always need to retrieve it for the OS info and can't tell whether
+  // it represents only OS-default information or user-configured information.
+  //
+  // FIXME: once handler info records are broken up into OS-provided records
+  // and user-configured records, stop using this boolean flag and simply
+  // check for the presence of a user-configured record to determine whether
+  // or not this type is only handled by a plugin.  Filed as bug 395142.
+  handledOnlyByPlugin: undefined,
+
+  get isDisabledPluginType() {
+    return this._getDisabledPluginTypes().indexOf(this.type) != -1;
+  },
+
+  _getDisabledPluginTypes: function() {
+    var types = "";
+
+    if (this._prefSvc.prefHasUserValue(PREF_DISABLED_PLUGIN_TYPES))
+      types = this._prefSvc.getCharPref(PREF_DISABLED_PLUGIN_TYPES);
+
+    // Only split if the string isn't empty so we don't end up with an array
+    // containing a single empty string.
+    if (types != "")
+      return types.split(",");
+
+    return [];
+  },
+
+  disablePluginType: function() {
+    var disabledPluginTypes = this._getDisabledPluginTypes();
+
+    if (disabledPluginTypes.indexOf(this.type) == -1)
+      disabledPluginTypes.push(this.type);
+
+    this._prefSvc.setCharPref(PREF_DISABLED_PLUGIN_TYPES,
+                              disabledPluginTypes.join(","));
+
+    // Update the category manager so existing browser windows update.
+    this._categoryMgr.deleteCategoryEntry("Gecko-Content-Viewers",
+                                          this.type,
+                                          false);
+  },
+
+  enablePluginType: function() {
+    var disabledPluginTypes = this._getDisabledPluginTypes();
+
+    var type = this.type;
+    disabledPluginTypes = disabledPluginTypes.filter(function(v) v != type);
+
+    this._prefSvc.setCharPref(PREF_DISABLED_PLUGIN_TYPES,
+                              disabledPluginTypes.join(","));
+
+    // Update the category manager so existing browser windows update.
+    this._categoryMgr.
+      addCategoryEntry("Gecko-Content-Viewers",
+                       this.type,
+                       "@mozilla.org/content/plugin/document-loader-factory;1",
+                       false,
+                       true);
+  },
+
+
+  //**************************************************************************//
+  // Storage
+
+  store: function() {
+    this._handlerSvc.store(this.wrappedHandlerInfo);
+  },
+
+  remove: function() {
+    this._handlerSvc.remove(this.wrappedHandlerInfo);
+  },
+
+
+  //**************************************************************************//
+  // Icons
+
+  get smallIcon() {
+    return this._getIcon(16);
+  },
+
+  get largeIcon() {
+    return this._getIcon(32);
+  },
+
+  _getIcon: function(aSize) {
+    if (this.primaryExtension)
+      return "moz-icon://goat." + this.primaryExtension + "?size=" + aSize;
+
+    if (this.wrappedHandlerInfo instanceof Ci.nsIMIMEInfo)
+      return "moz-icon://goat?size=" + aSize + "&contentType=" + this.type;
+
+    // FIXME: consider returning some generic icon when we can't get a URL for
+    // one (for example in the case of protocol schemes).  Filed as bug 395141.
+    return null;
+  }
+
+};
+
+
+//****************************************************************************//
+// Feed Handler Info
+
+/**
+ * This object implements nsIHandlerInfo for the feed type.  It's a separate
+ * object because we currently store handling information for the feed type
+ * in a set of preferences rather than the nsIHandlerService-managed datastore.
+ * 
+ * This object inherits from HandlerInfoWrapper in order to get functionality
+ * that isn't special to the feed type.
+ * 
+ * XXX Should we inherit from HandlerInfoWrapper?  After all, we override
+ * most of that wrapper's properties and methods, and we have to dance around
+ * the fact that the wrapper expects to have a wrappedHandlerInfo, which we
+ * don't provide.
+ */
+var feedHandlerInfo = {
+
+  __proto__: new HandlerInfoWrapper(TYPE_MAYBE_FEED, null),
+
+
+  //**************************************************************************//
+  // Convenience Utils
+
+  _converterSvc:
+    Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
+    getService(Ci.nsIWebContentConverterService),
+
+  _shellSvc: Cc["@mozilla.org/browser/shell-service;1"].
+             getService(Ci.nsIShellService),
+
+
+  //**************************************************************************//
+  // nsIHandlerInfo
+
+  get description() {
+    return gApplicationsPane._bundle.getString("webFeed");
+  },
+
+  get preferredApplicationHandler() {
+    switch (this.element(PREF_FEED_SELECTED_READER).value) {
+      case "client":
+        var file = this.element(PREF_FEED_SELECTED_APP).value;
+        if (file)
+          return getLocalHandlerApp(file);
+
+        return null;
+
+      case "web":
+        var uri = this.element(PREF_FEED_SELECTED_WEB).value;
+        if (!uri)
+          return null;
+        return this._converterSvc.getWebContentHandlerByURI(TYPE_MAYBE_FEED,
+                                                            uri);
+
+      case "bookmarks":
+      default:
+        // When the pref is set to bookmarks, we handle feeds internally,
+        // we don't forward them to a local or web handler app, so there is
+        // no preferred handler.
+        return null;
+    }
+  },
+
+  set preferredApplicationHandler(aNewValue) {
+    if (aNewValue instanceof Ci.nsILocalHandlerApp) {
+      this.element(PREF_FEED_SELECTED_APP).value = aNewValue.executable;
+      this.element(PREF_FEED_SELECTED_READER).value = "client";
+    }
+    else if (aNewValue instanceof Ci.nsIWebContentHandlerInfo) {
+      this.element(PREF_FEED_SELECTED_WEB).value = aNewValue.uri;
+      this.element(PREF_FEED_SELECTED_READER).value = "web";
+      // Make the web handler be the new "auto handler" for feeds.
+      // Note: we don't have to unregister the auto handler when the user picks
+      // a non-web handler (local app, Live Bookmarks, etc.) because the service
+      // only uses the "auto handler" when the selected reader is a web handler.
+      // We also don't have to unregister it when the user turns on "always ask"
+      // (i.e. preview in browser), since that also overrides the auto handler.
+      this._converterSvc.setAutoHandler(this.type, aNewValue);
+    }
+  },
+
+  get possibleApplicationHandlers() {
+    var handlerApps = Cc["@mozilla.org/array;1"].
+                      createInstance(Ci.nsIMutableArray);
+
+    // Add the "selected" local application, if there is one and it's different
+    // from the default handler for the OS.  Unlike for other types, there can
+    // be only one of these at a time for the feed type, since feed preferences
+    // only store a single local app.
+    var preferredAppFile = this.element(PREF_FEED_SELECTED_APP).value;
+    if (preferredAppFile && preferredAppFile.exists()) {
+      let preferredApp = getLocalHandlerApp(preferredAppFile);
+      let defaultApp = this._defaultApplicationHandler;
+      if (!defaultApp || !defaultApp.equals(preferredApp))
+        handlerApps.appendElement(preferredApp, false);
+    }
+
+    // Add the registered web handlers.  There can be any number of these.
+    var webHandlers = this._converterSvc.getContentHandlers(this.type, {});
+    for each (let webHandler in webHandlers)
+      handlerApps.appendElement(webHandler, false);
+
+    return handlerApps;
+  },
+
+  __defaultApplicationHandler: undefined,
+  get _defaultApplicationHandler() {
+    if (typeof this.__defaultApplicationHandler != "undefined")
+      return this.__defaultApplicationHandler;
+
+    var defaultFeedReader;
+    try {
+      defaultFeedReader = this._shellSvc.defaultFeedReader;
+    }
+    catch(ex) {
+      // no default reader
+    }
+
+    if (defaultFeedReader) {
+      let handlerApp = Cc["@mozilla.org/uriloader/local-handler-app;1"].
+                       createInstance(Ci.nsIHandlerApp);
+      handlerApp.name = getDisplayNameForFile(defaultFeedReader);
+      handlerApp.QueryInterface(Ci.nsILocalHandlerApp);
+      handlerApp.executable = defaultFeedReader;
+
+      this.__defaultApplicationHandler = handlerApp;
+    }
+    else {
+      this.__defaultApplicationHandler = null;
+    }
+
+    return this.__defaultApplicationHandler;
+  },
+
+  get hasDefaultHandler() {
+    try {
+      if (this._shellSvc.defaultFeedReader)
+        return true;
+    }
+    catch(ex) {
+      // no default reader
+    }
+
+    return false;
+  },
+
+  get defaultDescription() {
+    if (this.hasDefaultHandler)
+      return this._defaultApplicationHandler.name;
+
+    // Should we instead return null?
+    return "";
+  },
+
+  // What to do with content of this type.
+  get preferredAction() {
+    switch (this.element(PREF_FEED_SELECTED_ACTION).value) {
+
+      case "bookmarks":
+        return Ci.nsIHandlerInfo.handleInternally;
+
+      case "reader":
+        let preferredApp = this.preferredApplicationHandler;
+        let defaultApp = this._defaultApplicationHandler;
+
+        // If we have a valid preferred app, return useSystemDefault if it's
+        // the default app; otherwise return useHelperApp.
+        if (gApplicationsPane.isValidHandlerApp(preferredApp)) {
+          if (defaultApp && defaultApp.equals(preferredApp))
+            return Ci.nsIHandlerInfo.useSystemDefault;
+
+          return Ci.nsIHandlerInfo.useHelperApp;
+        }
+
+        // The pref is set to "reader", but we don't have a valid preferred app.
+        // What do we do now?  Not sure this is the best option (perhaps we
+        // should direct the user to the default app, if any), but for now let's
+        // direct the user to live bookmarks.
+        return Ci.nsIHandlerInfo.handleInternally;
+
+      // If the action is "ask", then alwaysAskBeforeHandling will override
+      // the action, so it doesn't matter what we say it is, it just has to be
+      // something that doesn't cause the controller to hide the type.
+      case "ask":
+      default:
+        return Ci.nsIHandlerInfo.handleInternally;
+    }
+  },
+
+  set preferredAction(aNewValue) {
+    switch (aNewValue) {
+
+      case Ci.nsIHandlerInfo.handleInternally:
+        this.element(PREF_FEED_SELECTED_READER).value = "bookmarks";
+        break;
+
+      case Ci.nsIHandlerInfo.useHelperApp:
+        this.element(PREF_FEED_SELECTED_ACTION).value = "reader";
+        // The controller has already set preferredApplicationHandler
+        // to the new helper app.
+        break;
+
+      case Ci.nsIHandlerInfo.useSystemDefault:
+        this.element(PREF_FEED_SELECTED_ACTION).value = "reader";
+        this.preferredApplicationHandler = this._defaultApplicationHandler;
+        break;
+    }
+  },
+
+  get alwaysAskBeforeHandling() {
+    return this.element(PREF_FEED_SELECTED_ACTION).value == "ask";
+  },
+
+  set alwaysAskBeforeHandling(aNewValue) {
+    if (aNewValue == true)
+      this.element(PREF_FEED_SELECTED_ACTION).value = "ask";
+    else
+      this.element(PREF_FEED_SELECTED_ACTION).value = "reader";
+  },
+
+
+  //**************************************************************************//
+  // nsIMIMEInfo
+
+  get primaryExtension() {
+    return "xml";
+  },
+
+
+  //**************************************************************************//
+  // Plugin Handling
+
+  handledOnlyByPlugin: false,
+
+
+  //**************************************************************************//
+  // Storage
+
+  // Changes to the preferred action and handler take effect immediately
+  // (we write them out to the preferences right as they happen), so we don't
+  // need to do anything when the controller calls store() after modifying
+  // the handler.
+  // XXX Should we hold off on making the changes until this method gets called?
+  store: function() {},
+
+  // The feed type cannot be removed.
+  remove: function() {},
+
+
+  //**************************************************************************//
+  // Icons
+
+  get smallIcon() {
+    return "chrome://browser/skin/feeds/feedIcon16.png";
+  },
+
+  get largeIcon() {
+    return "chrome://browser/skin/feeds/feedIcon.png";
+  }
+
+};
+
+
+//****************************************************************************//
+// Prefpane Controller
+
+var gApplicationsPane = {
+  // The set of types the app knows how to handle.  A hash of HandlerInfoWrapper
+  // objects, indexed by type.
+  _handledTypes: {},
+
+  _bundle       : null,
+  _list         : null,
+  _filter       : null,
+
+  // Retrieve this as nsIPrefBranch and then immediately QI to nsIPrefBranch2
+  // so both interfaces are available to callers.
+  _prefSvc      : Cc["@mozilla.org/preferences-service;1"].
+                  getService(Ci.nsIPrefBranch).
+                  QueryInterface(Ci.nsIPrefBranch2),
+
+  _mimeSvc      : Cc["@mozilla.org/uriloader/external-helper-app-service;1"].
+                  getService(Ci.nsIMIMEService),
+
+  _helperAppSvc : Cc["@mozilla.org/uriloader/external-helper-app-service;1"].
+                  getService(Ci.nsIExternalHelperAppService),
+
+  _handlerSvc   : Cc["@mozilla.org/uriloader/handler-service;1"].
+                  getService(Ci.nsIHandlerService),
+
+  _ioSvc        : Cc["@mozilla.org/network/io-service;1"].
+                  getService(Ci.nsIIOService),
+
+
+  //**************************************************************************//
+  // Initialization & Destruction
+
+  init: function() {
+    // Initialize shortcuts to some commonly accessed elements.
+    this._bundle = document.getElementById("bundlePreferences");
+    this._list = document.getElementById("handlersView");
+    this._filter = document.getElementById("filter");
+
+    // Observe preferences that influence what we display so we can rebuild
+    // the view when they change.
+    this._prefSvc.addObserver(PREF_SHOW_PLUGINS_IN_LIST, this, false);
+    this._prefSvc.addObserver(PREF_HIDE_PLUGINS_WITHOUT_EXTENSIONS, this, false);
+    this._prefSvc.addObserver(PREF_FEED_SELECTED_APP, this, false);
+    this._prefSvc.addObserver(PREF_FEED_SELECTED_WEB, this, false);
+    this._prefSvc.addObserver(PREF_FEED_SELECTED_ACTION, this, false);
+    this._prefSvc.addObserver(PREF_FEED_SELECTED_READER, this, false);
+
+    // Listen for window unload so we can remove our preference observers.
+    window.addEventListener("unload", this, false);
+
+    // Figure out how we should be sorting the list.  We persist sort settings
+    // across sessions, so we can't assume the default sort column and direction.
+    // XXX should we be using the XUL sort service instead?
+    if (document.getElementById("typeColumn").hasAttribute("sortDirection"))
+      this._sortColumn = document.getElementById("typeColumn");
+    else if (document.getElementById("actionColumn").hasAttribute("sortDirection"))
+      this._sortColumn = document.getElementById("actionColumn");
+
+    // Load the data and build the list of handlers.
+    // By doing this in a timeout, we let the preferences dialog resize itself
+    // to an appropriate size before we add a bunch of items to the list.
+    // Otherwise, if there are many items, and the Applications prefpane
+    // is the one that gets displayed when the user first opens the dialog,
+    // the dialog might stretch too much in an attempt to fit them all in.
+    // XXX Shouldn't we perhaps just set a max-height on the richlistbox?
+    var _delayedPaneLoad = function(self) {
+      self._loadData();
+      self.rebuildView();
+      self._list.focus();
+    }
+    setTimeout(_delayedPaneLoad, 0, this);
+  },
+
+  destroy: function() {
+    window.removeEventListener("unload", this, false);
+    this._prefSvc.removeObserver(PREF_SHOW_PLUGINS_IN_LIST, this);
+    this._prefSvc.removeObserver(PREF_HIDE_PLUGINS_WITHOUT_EXTENSIONS, this);
+    this._prefSvc.removeObserver(PREF_FEED_SELECTED_APP, this);
+    this._prefSvc.removeObserver(PREF_FEED_SELECTED_WEB, this);
+    this._prefSvc.removeObserver(PREF_FEED_SELECTED_ACTION, this);
+    this._prefSvc.removeObserver(PREF_FEED_SELECTED_READER, this);
+  },
+
+
+  //**************************************************************************//
+  // nsISupports
+
+  QueryInterface: function(aIID) {
+    if (aIID.equals(Ci.nsIObserver) ||
+        aIID.equals(Ci.nsIDOMEventListener ||
+        aIID.equals(Ci.nsISupports)))
+      return this;
+
+    throw Cr.NS_ERROR_NO_INTERFACE;
+  },
+
+
+  //**************************************************************************//
+  // nsIObserver
+
+  observe: function (aSubject, aTopic, aData) {
+    // Rebuild the list when there are changes to preferences that influence
+    // whether or not to show certain entries in the list.
+    if (aTopic == "nsPref:changed")
+      this.rebuildView();
+  },
+
+
+  //**************************************************************************//
+  // nsIDOMEventListener
+
+  handleEvent: function(aEvent) {
+    if (aEvent.type == "unload") {
+      this.destroy();
+    }
+  },
+
+
+  //**************************************************************************//
+  // Composed Model Construction
+
+  _loadData: function() {
+    this._loadFeedHandler();
+    this._loadPluginHandlers();
+    this._loadApplicationHandlers();
+  },
+
+  _loadFeedHandler: function() {
+    this._handledTypes[TYPE_MAYBE_FEED] = feedHandlerInfo;
+  },
+
+  /**
+   * Load the set of handlers defined by plugins.
+   *
+   * Note: if there's more than one plugin for a given MIME type, we assume
+   * the last one is the one that the application will use.  That may not be
+   * correct, but it's how we've been doing it for years.
+   *
+   * Perhaps we should instead query navigator.mimeTypes for the set of types
+   * supported by the application and then get the plugin from each MIME type's
+   * enabledPlugin property.  But if there's a plugin for a type, we need
+   * to know about it even if it isn't enabled, since we're going to give
+   * the user an option to enable it.
+   * 
+   * I'll also note that my reading of nsPluginTag::RegisterWithCategoryManager
+   * suggests that enabledPlugin is only determined during registration
+   * and does not get updated when plugin.disable_full_page_plugin_for_types
+   * changes (unless modification of that preference spawns reregistration).
+   * So even if we could use enabledPlugin to get the plugin that would be used,
+   * we'd still need to check the pref ourselves to find out if it's enabled.
+   */
+  _loadPluginHandlers: function() {
+    for (let i = 0; i < navigator.plugins.length; ++i) {
+      let plugin = navigator.plugins[i];
+      for (let j = 0; j < plugin.length; ++j) {
+        let type = plugin[j].type;
+        let handlerInfoWrapper;
+
+        if (typeof this._handledTypes[type] == "undefined") {
+          let wrappedHandlerInfo =
+            this._mimeSvc.getFromTypeAndExtension(type, null);
+          handlerInfoWrapper = new HandlerInfoWrapper(type, wrappedHandlerInfo);
+          this._handledTypes[type] = handlerInfoWrapper;
+        }
+        else
+          handlerInfoWrapper = this._handledTypes[type];
+
+        handlerInfoWrapper.plugin = plugin;
+        handlerInfoWrapper.handledOnlyByPlugin = true;
+      }
+    }
+  },
+
+  /**
+   * Load the set of handlers defined by the application datastore.
+   */
+  _loadApplicationHandlers: function() {
+    var wrappedHandlerInfos = this._handlerSvc.enumerate();
+    while (wrappedHandlerInfos.hasMoreElements()) {
+      let wrappedHandlerInfo = wrappedHandlerInfos.getNext().
+                               QueryInterface(Ci.nsIHandlerInfo);
+      let type = wrappedHandlerInfo.type;
+      let handlerInfoWrapper;
+
+      if (typeof this._handledTypes[type] == "undefined") {
+        handlerInfoWrapper = new HandlerInfoWrapper(type, wrappedHandlerInfo);
+        this._handledTypes[type] = handlerInfoWrapper;
+      }
+      else
+        handlerInfoWrapper = this._handledTypes[type];
+
+      handlerInfoWrapper.handledOnlyByPlugin = false;
+    }
+  },
+
+
+  //**************************************************************************//
+  // View Construction
+
+  rebuildView: function() {
+    // Clear the list of entries.
+    while (this._list.childNodes.length > 1)
+      this._list.removeChild(this._list.lastChild);
+
+    var visibleTypes = this._getVisibleTypes();
+
+    if (this._sortColumn)
+      this._sortTypes(visibleTypes);
+
+    for each (let visibleType in visibleTypes) {
+      let item = document.createElement("richlistitem");
+      item.setAttribute("type", visibleType.type);
+      item.setAttribute("typeDescription", visibleType.description);
+      item.setAttribute("typeIcon", visibleType.smallIcon);
+      item.setAttribute("actionDescription",
+                        this._describePreferredAction(visibleType));
+      item.setAttribute("actionIcon",
+                        this._getIconURLForPreferredAction(visibleType));
+      this._list.appendChild(item);
+      if (visibleType.type == this._list.getAttribute("lastSelectedType"))
+        this._list.selectedItem = item;
+    }
+  },
+
+  _getVisibleTypes: function() {
+    var visibleTypes = [];
+
+    var showPlugins = this._prefSvc.getBoolPref(PREF_SHOW_PLUGINS_IN_LIST);
+    var hideTypesWithoutExtensions =
+      this._prefSvc.getBoolPref(PREF_HIDE_PLUGINS_WITHOUT_EXTENSIONS);
+
+    for (let type in this._handledTypes) {
+      let handlerInfo = this._handledTypes[type];
+
+      // Hide types without extensions if so prefed so we don't show a whole
+      // bunch of obscure types handled by plugins on Mac.
+      // Note: though protocol types don't have extensions, we still show them;
+      // the pref is only meant to be applied to MIME types.
+      // FIXME: if the type has a plugin, should we also check the "suffixes"
+      // property of the plugin?  Filed as bug 395135.
+      if (hideTypesWithoutExtensions &&
+          handlerInfo.wrappedHandlerInfo instanceof Ci.nsIMIMEInfo &&
+          !handlerInfo.primaryExtension)
+        continue;
+
+      // Hide types handled only by plugins if so prefed.
+      if (handlerInfo.handledOnlyByPlugin && !showPlugins)
+        continue;
+
+      // Hide types handled only by disabled plugins.
+      // FIXME: we should show these types to give the user a chance to reenable
+      // the plugins.  Filed as bug 395136.
+      if (handlerInfo.handledOnlyByPlugin && handlerInfo.isDisabledPluginType)
+        continue;
+
+      // Don't display entries for types we always ask about before handling.
+      // FIXME: that's what the old code did, but we should be showing these
+      // types and letting users choose to do something different.  Filed as
+      // bug 395138.
+      if (handlerInfo.alwaysAskBeforeHandling &&
+          handlerInfo.type != TYPE_MAYBE_FEED)
+        continue;
+
+      // If the user is filtering the list, then only show matching types.
+      if (this._filter.value && !this._matchesFilter(handlerInfo))
+        continue;
+
+      // We couldn't find any reason to exclude the type, so include it.
+      visibleTypes.push(handlerInfo);
+    }
+
+    return visibleTypes;
+  },
+
+  // FIXME: we filter on type and primary extension, but we don't show those
+  // values to users, unlike the description and action description, which we
+  // do show, and that could be confusing, so filter only on the values we show.
+  // Filed as bug 395139.
+  _matchesFilter: function(aType) {
+    var filterValue = this._filter.value.toLowerCase();
+    return aType.description.toLowerCase().indexOf(filterValue) != -1 ||
+           this._describePreferredAction(aType).toLowerCase().indexOf(filterValue) != -1 ||
+           aType.type.toLowerCase().indexOf(filterValue) != -1 ||
+           (aType.primaryExtension &&
+            aType.primaryExtension.toLowerCase().indexOf(filterValue) != -1);
+  },
+
+  /**
+   * Describe, in a human-readable fashion, the preferred action to take on
+   * the type represented by the given handler info object.
+   *
+   * XXX Should this be part of the HandlerInfoWrapper interface?  It would
+   * violate the separation of model and view, but it might make more sense
+   * nonetheless (f.e. it would make sortTypes easier).
+   *
+   * @param aHandlerInfo {nsIHandlerInfo} the type whose preferred action
+   *                                      is being described
+   */
+  _describePreferredAction: function(aHandlerInfo) {
+    // alwaysAskBeforeHandling overrides the preferred action, so if that flag
+    // is set, then describe that behavior instead.  Currently we hide all types
+    // with alwaysAskBeforeHandling except for the feed type, so here we use
+    // a feed-specific message to describe the behavior.
+    if (aHandlerInfo.alwaysAskBeforeHandling)
+      return this._bundle.getString("alwaysAskAboutFeed");
+
+    switch (aHandlerInfo.preferredAction) {
+      case Ci.nsIHandlerInfo.saveToDisk:
+        return this._bundle.getString("saveToDisk");
+
+      case Ci.nsIHandlerInfo.useHelperApp:
+        return aHandlerInfo.preferredApplicationHandler.name;
+
+      case Ci.nsIHandlerInfo.handleInternally:
+        // For the feed type, handleInternally means live bookmarks.
+        if (aHandlerInfo.type == TYPE_MAYBE_FEED)
+          return this._bundle.getString("liveBookmarks");
+
+        // For other types, handleInternally looks like either useHelperApp
+        // or useSystemDefault depending on whether or not there's a preferred
+        // handler app.
+        if (this.isValidHandlerApp(aHandlerInfo.preferredApplicationHandler))
+          return aHandlerInfo.preferredApplicationHandler.name;
+
+        return aHandlerInfo.defaultDescription;
+
+        // XXX Why don't we say the app will handle the type internally?
+        // Is it because the app can't actually do that?  But if that's true,
+        // then why would a preferredAction ever get set to this value
+        // in the first place?
+
+      case Ci.nsIHandlerInfo.useSystemDefault:
+        return aHandlerInfo.defaultDescription;
+
+      case kActionUsePlugin:
+        return aHandlerInfo.plugin.name;
+    }
+  },
+
+  /**
+   * Whether or not the given handler app is valid.
+   *
+   * @param aHandlerApp {nsIHandlerApp} the handler app in question
+   *
+   * @returns {boolean} whether or not it's valid
+   */
+  isValidHandlerApp: function(aHandlerApp) {
+    if (!aHandlerApp)
+      return false;
+
+    if (aHandlerApp instanceof Ci.nsILocalHandlerApp)
+      return aHandlerApp.executable &&
+             aHandlerApp.executable.exists() &&
+             aHandlerApp.executable.isExecutable();
+
+    if (aHandlerApp instanceof Ci.nsIWebHandlerApp)
+      return aHandlerApp.uriTemplate;
+
+    if (aHandlerApp instanceof Ci.nsIWebContentHandlerInfo)
+      return aHandlerApp.uri;
+
+    return false;
+  },
+
+  /**
+   * Rebuild the actions menu for the selected entry.  Gets called by
+   * the richlistitem constructor when an entry in the list gets selected.
+   */
+  rebuildActionsMenu: function() {
+    var typeItem = this._list.selectedItem;
+    var handlerInfo = this._handledTypes[typeItem.type];
+    var menu =
+      document.getAnonymousElementByAttribute(typeItem, "class", "actionsMenu");
+    var menuPopup = menu.firstChild;
+
+    // Clear out existing items.
+    while (menuPopup.hasChildNodes())
+      menuPopup.removeChild(menuPopup.lastChild);
+
+    // If this is the feed type, add "always ask" and "live bookmarks" items.
+    if (handlerInfo.type == TYPE_MAYBE_FEED) {
+      let menuItem = document.createElementNS(kXULNS, "menuitem");
+      menuItem.setAttribute("alwaysAsk", "true");
+      menuItem.setAttribute("label", this._bundle.getString("alwaysAskAboutFeed"));
+      menuPopup.appendChild(menuItem);
+      if (handlerInfo.alwaysAskBeforeHandling)
+        menu.selectedItem = menuItem;
+
+      menuItem = document.createElementNS(kXULNS, "menuitem");
+      menuItem.setAttribute("action", Ci.nsIHandlerInfo.handleInternally);
+      menuItem.setAttribute("label", this._bundle.getString("liveBookmarks"));
+      menuItem.setAttribute("image", "chrome://browser/skin/page-livemarks.png");
+      menuPopup.appendChild(menuItem);
+      if (handlerInfo.preferredAction == Ci.nsIHandlerInfo.handleInternally)
+        menu.selectedItem = menuItem;
+    }
+
+    // Create a menu item for the OS default application, if any.
+    if (handlerInfo.hasDefaultHandler) {
+      let menuItem = document.createElementNS(kXULNS, "menuitem");
+      menuItem.setAttribute("action", Ci.nsIHandlerInfo.useSystemDefault);
+      menuItem.setAttribute("label", handlerInfo.defaultDescription);
+
+      if (handlerInfo.wrappedHandlerInfo) {
+        let iconURL =
+          this._getIconURLForSystemDefault(handlerInfo.wrappedHandlerInfo);
+        menuItem.setAttribute("image", iconURL);
+      }
+
+      menuPopup.appendChild(menuItem);
+      if (handlerInfo.preferredAction == Ci.nsIHandlerInfo.useSystemDefault)
+        menu.selectedItem = menuItem;
+    }
+
+    // Create menu items for possible handlers.
+    let preferredApp = handlerInfo.preferredApplicationHandler;
+    let possibleApps = handlerInfo.possibleApplicationHandlers.
+                       QueryInterface(Ci.nsIArray).enumerate();
+    while (possibleApps.hasMoreElements()) {
+      let possibleApp = possibleApps.getNext();
+      if (!this.isValidHandlerApp(possibleApp))
+        continue;
+
+      let menuItem = document.createElementNS(kXULNS, "menuitem");
+      menuItem.setAttribute("action", Ci.nsIHandlerInfo.useHelperApp);
+      menuItem.setAttribute("label", possibleApp.name);
+      menuItem.setAttribute("image", this._getIconURLForHandlerApp(possibleApp));
+
+      // Attach the handler app object to the menu item so we can use it
+      // to make changes to the datastore when the user selects the item.
+      menuItem.handlerApp = possibleApp;
+
+      menuPopup.appendChild(menuItem);
+
+      // Select this app if the preferred action is to use a helper app
+      // and this is the preferred app.
+      if (handlerInfo.preferredAction == Ci.nsIHandlerInfo.useHelperApp &&
+          preferredApp.equals(possibleApp))
+        menu.selectedItem = menuItem;
+    }
+
+    // Create a menu item for the plugin.
+    if (handlerInfo.plugin) {
+      let menuItem = document.createElementNS(kXULNS, "menuitem");
+      menuItem.setAttribute("action", kActionUsePlugin);
+      menuItem.setAttribute("label", handlerInfo.plugin.name);
+      menuPopup.appendChild(menuItem);
+      if (handlerInfo.preferredAction == kActionUsePlugin)
+        menu.selectedItem = menuItem;
+    }
+
+    // Create a menu item for saving to disk.
+    // Note: this option isn't available to protocol types, since we don't know
+    // what it means to save a URL having a certain scheme to disk, nor is it
+    // available to feeds, since the feed code doesn't implement the capability.
+    // And it's not available to types handled only by plugins either, although
+    // I would think we'd want to give users the ability to redirect that stuff
+    // to disk (so maybe we should revisit that decision).
+    if ((handlerInfo instanceof Ci.nsIMIMEInfo) &&
+        handlerInfo.type != TYPE_MAYBE_FEED &&
+        !handlerInfo.handledOnlyByPlugin) {
+      let menuItem = document.createElementNS(kXULNS, "menuitem");
+      menuItem.setAttribute("action", Ci.nsIHandlerInfo.saveToDisk);
+      menuItem.setAttribute("label", this._bundle.getString("saveToDisk"));
+      menuPopup.appendChild(menuItem);
+      if (handlerInfo.preferredAction == Ci.nsIHandlerInfo.saveToDisk)
+        menu.selectedItem = menuItem;
+    }
+
+    // Create a menu item for selecting a local application.
+    {
+      let menuItem = document.createElementNS(kXULNS, "menuitem");
+      menuItem.setAttribute("oncommand", "gApplicationsPane.chooseApp(event)");
+      menuItem.setAttribute("label", this._bundle.getString("chooseApp"));
+      menuPopup.appendChild(menuItem);
+    }
+
+    // Create a menu item for removing this entry unless it's a plugin
+    // or the feed type, which cannot be removed.
+    // XXX Should this perhaps be a button on the entry, or should we perhaps
+    // provide no UI for removing entries at all?
+    if (!handlerInfo.plugin && handlerInfo.type != TYPE_MAYBE_FEED) {
+      let menuItem = document.createElementNS(kXULNS, "menuitem");
+      menuItem.setAttribute("oncommand", "gApplicationsPane.removeType(event)");
+      menuItem.setAttribute("label", this._bundle.getString("removeType"));
+      menuPopup.appendChild(menuItem);
+    }
+  },
+
+
+  //**************************************************************************//
+  // Sorting & Filtering
+
+  _sortColumn: null,
+
+  /**
+   * Sort the list when the user clicks on a column header.
+   */
+  sort: function (event) {
+    var column = event.target;
+
+    // If the user clicked on a new sort column, remove the direction indicator
+    // from the old column.
+    if (this._sortColumn && this._sortColumn != column)
+      this._sortColumn.removeAttribute("sortDirection");
+
+    this._sortColumn = column;
+
+    // Set (or switch) the sort direction indicator.
+    if (column.getAttribute("sortDirection") == "ascending")
+      column.setAttribute("sortDirection", "descending");
+    else
+      column.setAttribute("sortDirection", "ascending");
+
+    this.rebuildView();
+  },
+
+  /**
+   * Given an array of HandlerInfoWrapper objects, sort them according to
+   * the current sort order.  Used by rebuildView to sort the set of visible
+   * types before building the list from them.
+   */
+  _sortTypes: function(aTypes) {
+    if (!this._sortColumn)
+      return;
+
+    function sortByType(a, b) {
+      return a.description.toLowerCase().localeCompare(b.description.toLowerCase());
+    }
+
+    var t = this;
+    function sortByAction(a, b) {
+      return t._describePreferredAction(a).toLowerCase().
+             localeCompare(t._describePreferredAction(b).toLowerCase());
+    }
+
+    switch (this._sortColumn.getAttribute("value")) {
+      case "type":
+        aTypes.sort(sortByType);
+        break;
+      case "action":
+        aTypes.sort(sortByAction);
+        break;
+    }
+
+    if (this._sortColumn.getAttribute("sortDirection") == "descending")
+      aTypes.reverse();
+  },
+
+  /**
+   * Filter the list when the user enters a filter term into the filter field.
+   */
+  filter: function() {
+    if (this._filter.value == "") {
+      this.clearFilter();
+      return;
+    }
+
+    this.rebuildView();
+
+    document.getElementById("filterActiveLabel").hidden = false;
+    document.getElementById("clearFilter").disabled = false;
+  },
+
+  _filterTimeout: null,
+
+  onFilterInput: function() {
+    if (this._filterTimeout)
+      clearTimeout(this._filterTimeout);
+   
+    this._filterTimeout = setTimeout("gApplicationsPane.filter()", 500);
+  },
+
+  onFilterKeyPress: function(aEvent) {
+    if (aEvent.keyCode == KeyEvent.DOM_VK_ESCAPE)
+      this.clearFilter();
+  },
+  
+  clearFilter: function() {
+    this._filter.value = "";
+    this.rebuildView();
+
+    this._filter.focus();
+    document.getElementById("filterActiveLabel").hidden = true;
+    document.getElementById("clearFilter").disabled = true;
+  },
+
+  focusFilterBox: function() {
+    this._filter.focus();
+    this._filter.select();
+  },
+
+
+  //**************************************************************************//
+  // Changes
+
+  onSelectAction: function(event) {
+    var actionItem = event.originalTarget;
+    var typeItem = this._list.selectedItem;
+    var handlerInfo = this._handledTypes[typeItem.type];
+
+    if (actionItem.hasAttribute("alwaysAsk")) {
+      handlerInfo.alwaysAskBeforeHandling = true;
+    }
+    else if (actionItem.hasAttribute("action")) {
+      let action = parseInt(actionItem.getAttribute("action"));
+
+      // Set the plugin state if we're enabling or disabling a plugin.
+      if (action == kActionUsePlugin)
+        handlerInfo.enablePluginType();
+      else if (handlerInfo.plugin && !handlerInfo.isDisabledPluginType)
+        handlerInfo.disablePluginType();
+
+      // Set the preferred application handler.
+      // FIXME: consider leaving the existing preferred app in the list
+      // when we set the preferred action to something other than useHelperApp
+      // so that legacy datastores that don't have the preferred app in the list
+      // of possible apps still include the preferred app in the list of apps
+      // the user can use to handle the type.  Filed as bug 395140.
+      if (action == Ci.nsIHandlerInfo.useHelperApp)
+        handlerInfo.preferredApplicationHandler = actionItem.handlerApp;
+      else
+        handlerInfo.preferredApplicationHandler = null;
+
+      // Set the "always ask" flag.
+      handlerInfo.alwaysAskBeforeHandling = false;
+
+      // Set the preferred action.
+      handlerInfo.preferredAction = action;
+    }
+
+    handlerInfo.store();
+
+    // Update the action label so it says the right thing once this type item
+    // is no longer selected.
+    typeItem.setAttribute("actionDescription",
+                          this._describePreferredAction(handlerInfo));
+  },
+
+  chooseApp: function(aEvent) {
+    // Don't let the normal "on select action" handler get this event,
+    // as we handle it specially ourselves.
+    aEvent.stopPropagation();
+
+    var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
+    var winTitle = this._bundle.getString("fpTitleChooseApp");
+    fp.init(window, winTitle, Ci.nsIFilePicker.modeOpen);
+    fp.appendFilters(Ci.nsIFilePicker.filterApps);
+
+    if (fp.show() == Ci.nsIFilePicker.returnOK && fp.file) {
+      // XXXben - we need to compare this with the running instance executable
+      //          just don't know how to do that via script...
+      // XXXmano TBD: can probably add this to nsIShellService
+#ifdef XP_WIN
+#expand      if (fp.file.leafName == "__MOZ_APP_NAME__.exe")
+#else
+#ifdef XP_MACOSX
+#expand      if (fp.file.leafName == "__MOZ_APP_DISPLAYNAME__.app")
+#else
+#expand      if (fp.file.leafName == "__MOZ_APP_NAME__-bin")
+#endif
+#endif
+        { this.rebuildActionsMenu(); return; }
+
+      let handlerApp = Cc["@mozilla.org/uriloader/local-handler-app;1"].
+                       createInstance(Ci.nsIHandlerApp);
+      handlerApp.name = getDisplayNameForFile(fp.file);
+      handlerApp.QueryInterface(Ci.nsILocalHandlerApp);
+      handlerApp.executable = fp.file;
+
+      var handlerInfo = this._handledTypes[this._list.selectedItem.type];
+
+      handlerInfo.preferredApplicationHandler = handlerApp;
+      handlerInfo.preferredAction = Ci.nsIHandlerInfo.useHelperApp;
+
+      handlerInfo.store();
+    }
+
+    // We rebuild the actions menu whether the user picked an app or canceled.
+    // If they picked an app, we want to add the app to the menu and select it.
+    // If they canceled, we want to go back to their previous selection.
+    this.rebuildActionsMenu();
+  },
+
+  removeType: function() {
+    var promptService = Cc["@mozilla.org/embedcomp/prompt-service;1"].
+                        getService(Ci.nsIPromptService);
+    var flags = Ci.nsIPromptService.BUTTON_TITLE_IS_STRING * Ci.nsIPromptService.BUTTON_POS_0;
+    flags += Ci.nsIPromptService.BUTTON_TITLE_CANCEL * Ci.nsIPromptService.BUTTON_POS_1;
+
+    var title = this._bundle.getString("removeTitle");
+    var message = this._bundle.getString("removeMessage");
+    var button = this._bundle.getString("removeButton");
+    var rv = promptService.confirmEx(window, title, message, flags, button, 
+                                     null, null, null, { value: 0 });
+
+    if (rv == 0) {
+      // Remove information about the type from the handlers datastore.
+      let listItem = this._list.selectedItem;
+      let handlerInfo = this._handledTypes[listItem.type];
+      handlerInfo.remove();
+
+      // Select the next item in the list (or the previous item if the item
+      // being removed is the last item).
+      if (this._list.selectedIndex == this._list.getRowCount() - 1)
+        this._list.selectedIndex = this._list.selectedIndex - 1;
+      else
+        this._list.selectedIndex = this._list.selectedIndex + 1;
+
+      // Remove the item from the list.
+      this._list.removeChild(listItem);
+    }
+    else {
+      // Rebuild the actions menu so we go back to their previous selection.
+      this.rebuildActionsMenu();
+    }
+  },
+
+  // Mark which item in the list was last selected so we can reselect it
+  // when we rebuild the list or when the user returns to the prefpane.
+  onSelectionChanged: function() {
+    this._list.setAttribute("lastSelectedType",
+                            this._list.selectedItem.getAttribute("type"));
+  },
+
+  _getIconURLForPreferredAction: function(aHandlerInfo) {
+    var preferredApp = aHandlerInfo.preferredApplicationHandler;
+
+    if (aHandlerInfo.preferredAction == Ci.nsIHandlerInfo.useHelperApp &&
+        this.isValidHandlerApp(preferredApp))
+      return this._getIconURLForHandlerApp(preferredApp);
+
+    if (aHandlerInfo.preferredAction == Ci.nsIHandlerInfo.useSystemDefault &&
+        aHandlerInfo.wrappedHandlerInfo)
+      return this._getIconURLForSystemDefault(aHandlerInfo.wrappedHandlerInfo);
+
+    // We don't know how to get an icon URL for any other actions.
+    return "";
+  },
+
+  _getIconURLForHandlerApp: function(aHandlerApp) {
+    if (aHandlerApp instanceof Ci.nsILocalHandlerApp)
+      return this._getIconURLForFile(aHandlerApp.executable);
+
+    if (aHandlerApp instanceof Ci.nsIWebHandlerApp)
+      return this._getIconURLForWebApp(aHandlerApp.uriTemplate);
+
+    if (aHandlerApp instanceof Ci.nsIWebContentHandlerInfo)
+      return this._getIconURLForWebApp(aHandlerApp.uri)
+
+    // We know nothing about other kinds of handler apps.
+    return "";
+  },
+
+  _getIconURLForFile: function(aFile) {
+    var fph = this._ioSvc.getProtocolHandler("file").
+              QueryInterface(Ci.nsIFileProtocolHandler);
+    var urlSpec = fph.getURLSpecFromFile(aFile);
+
+    return "moz-icon://" + urlSpec + "?size=16";
+  },
+
+  _getIconURLForWebApp: function(aWebAppURITemplate) {
+    var uri = this._ioSvc.newURI(aWebAppURITemplate, null, null);
+
+    // Unfortunately we can't use the favicon service to get the favicon,
+    // because the service looks in the annotations table for a record with
+    // the exact URL we give it, and users won't have such records for URLs
+    // they don't visit, and users won't visit the web app's URL template,
+    // they'll only visit URLs derived from that template (i.e. with %s
+    // in the template replaced by the URL of the content being handled).
+
+    if (/^https?/.test(uri.scheme))
+      return uri.prePath + "/favicon.ico";
+
+    return "";
+  },
+
+  _getIconURLForSystemDefault: function(aHandlerInfo) {
+    // Handler info objects for MIME types on Windows implement a property
+    // bag interface from which we can get an icon for the default app, so if
+    // we're dealing with a MIME type on Windows, then try to get the icon.
+    if (aHandlerInfo instanceof Ci.nsIMIMEInfo &&
+        aHandlerInfo instanceof Ci.nsIPropertyBag) {
+      try {
+        let url = aHandlerInfo.getProperty("defaultApplicationIconURL");
+        if (url)
+          return url + "?size=16";
+      }
+      catch(ex) {}
+    }
+
+    // We don't know how to get an icon URL on any other OSes or for any other
+    // classes of content type.
+    return "";
+  }
+
+};
new file mode 100755
--- /dev/null
+++ b/browser/components/preferences/applications.xul
@@ -0,0 +1,116 @@
+<?xml version="1.0"?>
+
+<!--
+# -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Firefox Preferences System.
+#
+# The Initial Developer of the Original Code is
+# Ben Goodger.
+# Portions created by the Initial Developer are Copyright (C) 2005
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Ben Goodger <ben@mozilla.org>
+#   Jeff Walden <jwalden+code@mit.edu>.
+#   Asaf Romano <mozilla.mano@sent.com>
+#   Myk Melez <myk@mozilla.org>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# 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 *****
+-->
+
+<!DOCTYPE overlay [
+  <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
+  <!ENTITY % applicationsDTD SYSTEM "chrome://browser/locale/preferences/applications.dtd">
+  %brandDTD;
+  %applicationsDTD;
+]>
+
+<overlay id="ApplicationsPaneOverlay"
+         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+  <prefpane id="paneApplications" onpaneload="gApplicationsPane.init();"
+            helpTopic="prefs-applications" helpURI="chrome://browser/locale/help/help.rdf">
+
+    <preferences id="feedsPreferences">
+      <preference id="browser.feeds.handler"
+                  name="browser.feeds.handler"
+                  type="string"/>
+      <preference id="browser.feeds.handler.default"
+                  name="browser.feeds.handler.default"
+                  type="string"/>
+      <preference id="browser.feeds.handlers.application"
+                  name="browser.feeds.handlers.application"
+                  type="file"/>
+      <preference id="browser.feeds.handlers.webservice"
+                  name="browser.feeds.handlers.webservice"
+                  type="string"/>
+    </preferences>
+
+    <script type="application/x-javascript" src="chrome://browser/content/preferences/applications.js"/>
+
+    <keyset>
+      <key key="&focusSearch1.key;" modifiers="accel" oncommand="gApplicationsPane.focusFilterBox();"/>
+      <key key="&focusSearch2.key;" modifiers="accel" oncommand="gApplicationsPane.focusFilterBox();"/>
+    </keyset>
+
+    <label>&prefpane.label;</label>
+
+    <vbox flex="1" class="contentPane">
+      <hbox align="center">
+        <label accesskey="&filter.accesskey;" control="filter">&filter.label;</label>
+        <textbox id="filter" flex="1" oninput="gApplicationsPane.onFilterInput();" 
+                onkeypress="gApplicationsPane.onFilterKeyPress(event);"/>
+        <button id="clearFilter" icon="clear" label="&clear.label;" accesskey="&clear.accesskey;" 
+                oncommand="gApplicationsPane.clearFilter();" disabled="true"/>
+      </hbox>
+
+      <separator class="thin"/>
+
+      <label id="filterActiveLabel" hidden="true">
+        &filterActive.label;
+      </label>
+
+      <separator class="thin"/>
+
+      <richlistbox id="handlersView" orient="vertical" style="height: 300px"
+                   onselect="gApplicationsPane.onSelectionChanged();"
+                   persist="lastSelectedType">
+        <listheader equalsize="always" style="border: 0; padding: 0;">
+          <treecol id="typeColumn" label="&typeColumn.label;" value="type"
+                   accesskey="&typeColumn.accesskey;" persist="sortDirection"
+                   flex="1" onclick="gApplicationsPane.sort(event);"
+                   sortDirection="ascending"/>
+          <treecol id="actionColumn" label="&actionColumn.label;" value="action"
+                   accesskey="&actionColumn.accesskey;" persist="sortDirection"
+                   flex="1" onclick="gApplicationsPane.sort(event);"/>
+        </listheader>
+      </richlistbox>
+    </vbox>
+
+  </prefpane>
+</overlay>
deleted file mode 100644
--- a/browser/components/preferences/changeaction.js
+++ /dev/null
@@ -1,255 +0,0 @@
-# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
-# ***** BEGIN LICENSE BLOCK *****
-# Version: MPL 1.1/GPL 2.0/LGPL 2.1
-#
-# The contents of this file are subject to the Mozilla Public License Version
-# 1.1 (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS IS" basis,
-# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-# for the specific language governing rights and limitations under the
-# License.
-#
-# The Original Code is the Download Actions Manager.
-#
-# The Initial Developer of the Original Code is
-# Ben Goodger.
-# Portions created by the Initial Developer are Copyright (C) 2000
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#   Ben Goodger <ben@mozilla.org>
-#
-# Alternatively, the contents of this file may be used under the terms of
-# either the GNU General Public License Version 2 or later (the "GPL"), or
-# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-# in which case the provisions of the GPL or the LGPL are applicable instead
-# of those above. If you wish to allow use of your version of this file only
-# under the terms of either the GPL or the LGPL, and not to allow others to
-# use your version of this file under the terms of the MPL, indicate your
-# 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 gChangeActionDialog = {
-  _item             : null,
-  _bundle           : null,
-  _lastSelectedMode : null,
-  _lastSelectedSave : null,
-
-  init: function ()
-  {
-    this._item = window.arguments[0];
-    this._bundle = document.getElementById("bundlePreferences");
-    dump("*** ir = " + this._item.toSource() + "\n");
-    
-    var typeField = document.getElementById("typeField");
-    typeField.value = this._item.typeName;
-    
-    var extensionField = document.getElementById("extensionField");
-    var ext = "." + this._item.extension.toLowerCase();
-    var contentType = this._item.type;
-    extensionField.value = this._bundle.getFormattedString("extensionStringFormat", [ext, contentType]);
-    
-    var typeIcon = document.getElementById("typeIcon");
-    typeIcon.src = this._item.bigIcon;
-
-    // Custom App Handler Path - this must be set before we set the selected
-    // radio button because the selection event handler for the radio group
-    // requires the extapp handler field to be non-empty for the extapp radio
-    // button to be selected. 
-    var customApp = document.getElementById("customApp");
-    if (this._item.customHandler)
-      customApp.file = this._item.customHandler;
-    else
-      customApp.file = null;
-
-    var defaultApp = document.getElementById("defaultApp");
-    var defaultAppIcon = null;
-    var fallbackIconURL = "moz-icon://goat?contentType=" + this._item.type + "&size=16";
-    if (this._item.mimeInfo instanceof Components.interfaces.nsIPropertyBag) {
-      try {
-        defaultAppIcon = this._item.mimeInfo.getProperty("defaultApplicationIconURL");
-      }
-      catch (e) { }
-      if (defaultAppIcon)
-        defaultAppIcon += "?size=16";
-    }
-    defaultApp.image = defaultAppIcon || fallbackIconURL;
-    defaultApp.label = this._item.mimeInfo.defaultDescription;
-
-    var pluginName = document.getElementById("pluginName");
-    var foundPlugin = false;
-    for (var i = 0; i < navigator.plugins.length; ++i) {
-      var plugin = navigator.plugins[i];
-      for (var j = 0; j < plugin.length; ++j) {
-        if (contentType == plugin[j].type) {
-          pluginName.label = plugin.name;
-          pluginName.image = "moz-icon://goat.goat?contentType=" + contentType + "&size=16";
-          foundPlugin = true;
-        }
-      }
-    }
-    if (!foundPlugin) {
-      pluginName.label = this._bundle.getString("pluginHelperNoneAvailable");
-      document.getElementById("plugin").disabled = true;
-    }
-      
-    // Selected Action Radiogroup
-    var handlerGroup = document.getElementById("handlerGroup");
-    if (this._item.handleMode == FILEACTION_OPEN_PLUGIN && this._item.pluginEnabled)
-      handlerGroup.selectedItem = document.getElementById("plugin");
-    else {
-      if (this._item.handleMode == FILEACTION_OPEN_DEFAULT)
-        handlerGroup.selectedItem = document.getElementById("openDefault");
-      else if (this._item.handleMode == FILEACTION_SAVE_TO_DISK)
-        handlerGroup.selectedItem = document.getElementById("saveToDisk");
-      else
-        handlerGroup.selectedItem = document.getElementById("openApplication");
-    }
-    this._lastSelectedMode = handlerGroup.selectedItem;
-    
-    // Figure out the last selected Save As mode
-    var saveToOptions = document.getElementById("saveToOptions");
-    this._lastSelectedSave = saveToOptions.selectedItem;
-
-    // We don't let users open .exe files or random binary data directly 
-    // from the browser at the moment because of security concerns. 
-    var mimeType = this._item.mimeInfo.MIMEType;
-    if (mimeType == "application/object-stream" ||
-        mimeType == "application/x-msdownload") {
-      document.getElementById("openApplication").disabled = true;
-      document.getElementById("openDefault").disabled = true;
-      handlerGroup.selectedItem = document.getElementById("saveToDisk");
-    }
-  },
-  
-  onAccept: function ()
-  {
-    var contentType = this._item.mimeInfo.MIMEType;
-    var handlerGroup = document.getElementById("handlerGroup");
-    switch (handlerGroup.selectedItem.value) {
-    case "plugin":
-      this._item.handleMode = FILEACTION_OPEN_PLUGIN;
-      var pluginName = document.getElementById("pluginName");
-      this._item.action = this._bundle.getFormattedString("openWith", [pluginName.label]);
-      this._item.pluginEnabled = true;
-      break;
-    case "system":
-      this._item.handledOnlyByPlugin = false;
-      this._item.handleMode = FILEACTION_OPEN_DEFAULT;
-      var defaultDescr = this._item.mimeInfo.defaultDescription;
-      this._item.action = this._bundle.getFormattedString("openWith", [defaultDescr]);
-      break;
-    case "app":
-      this._item.handledOnlyByPlugin = false;
-      this._item.handleMode = FILEACTION_OPEN_CUSTOM;
-      var customApp = document.getElementById("customApp");
-      this._item.action = this._bundle.getFormattedString("openWith", [customApp.label]);        
-      break;  
-    case "save":
-      this._item.handledOnlyByPlugin = false;
-      this._item.handleMode = FILEACTION_SAVE_TO_DISK;
-      this._item.action = this._bundle.getString("saveToDisk");
-      break;  
-    }
-    
-    // The opener uses the modifications to the FileAction item to update the
-    // datasource.
-    return true;
-  },
-  
-  doEnabling: function (aSelectedItem)
-  {
-    var defaultApp            = document.getElementById("defaultApp");
-    var saveToDefault         = document.getElementById("saveToDefault");
-    var saveToCustom          = document.getElementById("saveToCustom");
-    var customDownloadFolder  = document.getElementById("customDownloadFolder");
-    var chooseCustomDownloadFolder = document.getElementById("chooseCustomDownloadFolder");
-    var saveToAskMe           = document.getElementById("saveToAskMe");
-    var pluginName            = document.getElementById("pluginName");
-    var changeApp             = document.getElementById("changeApp");
-    var customApp             = document.getElementById("customApp");
-    
-    switch (aSelectedItem.id) {
-    case "openDefault":
-      changeApp.disabled = customApp.disabled = saveToDefault.disabled = saveToCustom.disabled = customDownloadFolder.disabled = chooseCustomDownloadFolder.disabled = saveToAskMe.disabled = pluginName.disabled = true;
-      defaultApp.disabled = false;
-      break;
-    case "openApplication":
-      defaultApp.disabled = saveToDefault.disabled = saveToCustom.disabled = customDownloadFolder.disabled = chooseCustomDownloadFolder.disabled = saveToAskMe.disabled = pluginName.disabled = true;
-      changeApp.disabled = customApp.disabled = false;
-      if (!customApp.file && !this.changeApp()) {
-        this._lastSelectedMode.click();
-        return;
-      }
-      break;
-    case "saveToDisk":
-      changeApp.disabled = customApp.disabled = defaultApp.disabled = pluginName.disabled = true;
-      var saveToOptions = document.getElementById("saveToOptions");
-      customDownloadFolder.disabled = chooseCustomDownloadFolder.disabled = !(saveToOptions.selectedItem.id == "saveToCustom");
-      saveToDefault.disabled = saveToCustom.disabled = saveToAskMe.disabled = false;
-      break;
-    case "plugin":
-      changeApp.disabled = customApp.disabled = defaultApp.disabled = saveToDefault.disabled = saveToCustom.disabled = customDownloadFolder.disabled = chooseCustomDownloadFolder.disabled = saveToAskMe.disabled = true;
-      pluginName.disabled = false;
-      break;
-    }
-    this._lastSelectedMode = aSelectedItem;
-  },
-  
-  doSaveToDiskEnabling: function (aSelectedItem)
-  {
-    var isSaveToCustom = aSelectedItem.id == "saveToCustom";
-    var customDownloadFolder = document.getElementById("customDownloadFolder");
-    var chooseCustomDownloadFolder = document.getElementById("chooseCustomDownloadFolder");
-    chooseCustomDownloadFolder.disabled = customDownloadFolder.disabled = !isSaveToCustom;
-    
-    if (isSaveToCustom && 
-        !customDownloadFolder.file && !this.changeCustomFolder()) {
-      this._lastSelectedSave.click();
-      return;
-    }
-    this._lastSelectedSave = aSelectedItem;
-  },
-  
-  changeApp: function ()
-  {
-    const nsIFilePicker = Components.interfaces.nsIFilePicker;
-    var fp = Components.classes["@mozilla.org/filepicker;1"]
-                       .createInstance(nsIFilePicker);
-    var winTitle = this._bundle.getString("fpTitleChooseApp");
-    fp.init(window, winTitle, nsIFilePicker.modeOpen);
-    fp.appendFilters(nsIFilePicker.filterApps);
-    if (fp.show() == nsIFilePicker.returnOK && fp.file) {
-      var customApp = document.getElementById("customApp");
-      customApp.file = fp.file;
-      this._item.customHandler = fp.file;      
-      return true;
-    }
-    return false;
-  },
-  
-  changeCustomFolder: function ()
-  {
-    const nsIFilePicker = Components.interfaces.nsIFilePicker;
-    var fp = Components.classes["@mozilla.org/filepicker;1"]
-                       .createInstance(nsIFilePicker);
-
-    // extract the window title
-    var winTitle = this._bundle.getString("fpTitleChooseDL");
-    fp.init(window, winTitle, nsIFilePicker.modeGetFolder);
-    if (fp.show() == nsIFilePicker.returnOK && fp.file) {
-      var customDownloadFolder = document.getElementById("customDownloadFolder");
-      customDownloadFolder.file = fp.file;
-      customDownloadFolder.label = fp.file.path;
-      return true;
-    }
-    return false;
-  }
-};
deleted file mode 100644
--- a/browser/components/preferences/changeaction.xul
+++ /dev/null
@@ -1,114 +0,0 @@
-<?xml version="1.0"?>
-
-# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
-# ***** BEGIN LICENSE BLOCK *****
-# Version: MPL 1.1/GPL 2.0/LGPL 2.1
-#
-# The contents of this file are subject to the Mozilla Public License Version
-# 1.1 (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS IS" basis,
-# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-# for the specific language governing rights and limitations under the
-# License.
-#
-# The Original Code is the Download Actions Manager.
-#
-# The Initial Developer of the Original Code is
-# Ben Goodger.
-# Portions created by the Initial Developer are Copyright (C) 2000
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#   Ben Goodger <ben@mozilla.org>
-#
-# Alternatively, the contents of this file may be used under the terms of
-# either the GNU General Public License Version 2 or later (the "GPL"), or
-# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-# in which case the provisions of the GPL or the LGPL are applicable instead
-# of those above. If you wish to allow use of your version of this file only
-# under the terms of either the GPL or the LGPL, and not to allow others to
-# use your version of this file under the terms of the MPL, indicate your
-# 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 *****
-
-<?xml-stylesheet href="chrome://global/skin/"?>
-<?xml-stylesheet href="chrome://mozapps/content/preferences/preferences.css" type="text/css"?>
-<?xml-stylesheet href="chrome://browser/skin/preferences/preferences.css" type="text/css"?>
-
-<!DOCTYPE window SYSTEM "chrome://browser/locale/preferences/changeaction.dtd">
-
-<dialog id="ChangeActionDialog" title="&changeAction.title;"
-        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-        onload="gChangeActionDialog.init();"
-        buttons="accept,cancel,help"
-        ondialogaccept="return gChangeActionDialog.onAccept();" 
-        ondialoghelp="openHelp('prefs-file-types', 'chrome://browser/locale/help/help.rdf');"
-        xmlns:aaa="http://www.w3.org/2005/07/aaa"
-        style="width: &window.width;;"
-        persist="screenX screenY">
-
-  <script type="application/x-javascript" src="chrome://mozapps/content/preferences/actionsshared.js"/>
-  <script type="application/x-javascript" src="chrome://browser/content/preferences/changeaction.js"/>
-  <script type="application/x-javascript" src="chrome://help/content/contextHelp.js"/>
-  
-  <stringbundle id="bundlePreferences" src="chrome://browser/locale/preferences/preferences.properties"/>
-
-  <hbox id="changeActionHeader" align="center" class="indent">
-    <image id="typeIcon"/>
-    <vbox flex="1">
-      <label id="typeField" crop="right"/>
-      <label id="extensionField" crop="right"/>
-    </vbox>
-  </hbox>
-  <vbox id="changeActionContent" flex="1">
-    <label control="handlerGroup">&whenDownloading.label;</label>
-    <radiogroup id="handlerGroup" onselect="gChangeActionDialog.doEnabling(this.selectedItem);" 
-                flex="1" aaa:describedby="changeActionHeader">
-      <separator class="thin"/>
-      <radio id="openDefault" value="system" 
-             label="&openDefault.label;" accesskey="&openDefault.accesskey;"
-             aaa:labelledby="openDefault defaultApp"/>
-      <filefield class="indent" id="defaultApp" disabled="true"/>
-      <separator class="thin"/>
-      <radio id="openApplication" value="app" 
-             label="&openApplication.label;" accesskey="&openApplication.accesskey;"
-             aaa:labelledby="openApplication customApp"/>
-      <hbox align="center">
-        <filefield id="customApp" class="indent" flex="1" disabled="true"/>
-        <button id="changeApp" oncommand="gChangeActionDialog.changeApp();" 
-                label="&changeApp.label;" accesskey="&changeApp.accesskey;"
-                disabled="true"/>
-      </hbox>
-      <separator class="thin"/>
-      <radio id="saveToDisk" value="save" 
-             label="&saveToDisk.label;" accesskey="&saveToDisk.accesskey;"/>
-      <radiogroup id="saveToOptions" class="indent" onselect="gChangeActionDialog.doSaveToDiskEnabling(this.selectedItem);"
-                  hidden="true">
-        <radio id="saveToDefault" value="default" selected="true"
-               label="&saveToDefaultFolder.label;" accesskey="&saveToDefaultFolder.accesskey;"/>
-        <radio id="saveToCustom" value="custom"
-               label="&saveToThisFolder.label;" accesskey="&saveToThisFolder.accesskey;"
-               aaa:labelledby="saveToCustom customDownloadFolder"/>
-        <hbox align="center" class="indent">
-          <filefield id="customDownloadFolder" flex="1"/>
-          <button id="chooseCustomDownloadFolder" oncommand="gChangeActionDialog.changeCustomFolder();"
-                  label="&chooseFolder.label;" accesskey="&chooseFolder.accesskey;"/>
-        </hbox>
-        <radio id="saveToAskMe" value="ask"
-               label="&saveToAskMe.label;" accesskey="&saveToAskMe.accesskey;"/>
-      </radiogroup>
-      <radio id="plugin" value="plugin" 
-             label="&usePlugin.label;" accesskey="&usePlugin.accesskey;"
-             aaa:labelledby="plugin pluginName"/>
-      <filefield class="indent" id="pluginName" disabled="true"/>
-    </radiogroup>
-  </vbox>
-</dialog>
-
--- a/browser/components/preferences/content.js
+++ b/browser/components/preferences/content.js
@@ -53,17 +53,17 @@ var gContentPane = {
     }
   },
 
   // UTILITY FUNCTIONS
 
   /**
    * Utility function to enable/disable the button specified by aButtonID based
    * on the value of the Boolean preference specified by aPreferenceID.
-   */  
+   */
   updateButtons: function (aButtonID, aPreferenceID)
   {
     var button = document.getElementById(aButtonID);
     var preference = document.getElementById(aPreferenceID);
     button.disabled = preference.value != true;
     return undefined;
   },
 
@@ -257,23 +257,11 @@ var gContentPane = {
   /**
    * Displays the colors dialog, where default web page/link/etc. colors can be
    * configured.
    */
   configureColors: function ()
   {
     document.documentElement.openSubDialog("chrome://browser/content/preferences/colors.xul",
                                            "", null);  
-  },
-
-  // FILE TYPES
-
-  /**
-   * Displays the file type configuration dialog.
-   */
-  configureFileTypes: function ()
-  {
-    document.documentElement.openWindow("Preferences:DownloadActions",
-                                        "chrome://browser/content/preferences/downloadactions.xul",
-                                        "", null);
   }
 
 };
--- a/browser/components/preferences/content.xul
+++ b/browser/components/preferences/content.xul
@@ -68,21 +68,16 @@
                   name="pref.advanced.javascript.disable_button.advanced"
                   type="bool"/>
 
       <!-- FONTS -->
       <preference id="font.language.group"
                   name="font.language.group"
                   type="wstring"
                   onchange="gContentPane._rebuildFonts();"/>
-
-      <!-- FILE TYPES -->
-      <preference id="pref.downloads.disable_button.edit_actions"
-                  name="pref.downloads.disable_button.edit_actions"
-                  type="bool"/>
     </preferences>
     
     <script type="application/x-javascript" src="chrome://mozapps/content/preferences/fontbuilder.js"/>
     <script type="application/x-javascript" src="chrome://browser/content/preferences/content.js"/>
 
     <stringbundle id="bundlePreferences" src="chrome://browser/locale/preferences/preferences.properties"/>
 
     <!-- various checkboxes, font-fu -->
@@ -202,25 +197,11 @@
                     label="&colors.label;"
                     accesskey="&colors.accesskey;"
                     oncommand="gContentPane.configureColors();"/>
           </row>
         </rows>
       </grid>
     </groupbox>
 
-    <!-- File Types -->
-    <groupbox id="fileTypesGroup">
-      <caption label="&fileTypes.label;"/>
-
-      <hbox id="configureFileTypesRow" align="center">
-        <description control="manageTypes" flex="1">&configureFileTypes.label;</description>
-        <button id="manageTypes"
-                label="&manage.label;"
-                accesskey="&manage.accesskey;"
-                oncommand="gContentPane.configureFileTypes();"
-                preference="pref.downloads.disable_button.edit_actions"/>
-      </hbox>
-    </groupbox>
-
   </prefpane>
 
 </overlay>
deleted file mode 100644
--- a/browser/components/preferences/downloadactions.js
+++ /dev/null
@@ -1,870 +0,0 @@
-# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
-# ***** BEGIN LICENSE BLOCK *****
-# Version: MPL 1.1/GPL 2.0/LGPL 2.1
-#
-# The contents of this file are subject to the Mozilla Public License Version
-# 1.1 (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS IS" basis,
-# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-# for the specific language governing rights and limitations under the
-# License.
-#
-# The Original Code is the Download Actions Manager.
-#
-# The Initial Developer of the Original Code is
-# Ben Goodger.
-# Portions created by the Initial Developer are Copyright (C) 2000
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#   Ben Goodger <ben@mozilla.org>
-#
-# Alternatively, the contents of this file may be used under the terms of
-# either the GNU General Public License Version 2 or later (the "GPL"), or
-# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-# in which case the provisions of the GPL or the LGPL are applicable instead
-# of those above. If you wish to allow use of your version of this file only
-# under the terms of either the GPL or the LGPL, and not to allow others to
-# use your version of this file under the terms of the MPL, indicate your
-# decision by deleting the provisions above and replace them with the notice
-# and other provisions required by the GPL or the LGPL. If you do not delete
-# the provisions above, a recipient may use your version of this file under
-# the terms of any one of the MPL, the GPL or the LGPL.
-#
-# ***** END LICENSE BLOCK *****
-
-const kPluginHandlerContractID = "@mozilla.org/content/plugin/document-loader-factory;1";
-const kDisabledPluginTypesPref = "plugin.disable_full_page_plugin_for_types";
-const kShowPluginsInList = "browser.download.show_plugins_in_list";
-const kHideTypesWithoutExtensions = "browser.download.hide_plugins_without_extensions";
-const kRootTypePrefix = "urn:mimetype:";
-
-///////////////////////////////////////////////////////////////////////////////
-// MIME Types Datasource RDF Utils
-function NC_URI(aProperty)
-{
-  return "http://home.netscape.com/NC-rdf#" + aProperty;
-}
-
-function MIME_URI(aType)
-{
-  return "urn:mimetype:" + aType;
-}
-
-function HANDLER_URI(aHandler)
-{
-  return "urn:mimetype:handler:" + aHandler;
-}
-
-function APP_URI(aType)
-{
-  return "urn:mimetype:externalApplication:" + aType;
-}
-
-var gDownloadActionsWindow = {  
-  _tree         : null,
-  _editButton   : null,
-  _removeButton : null,
-  _actions      : [],
-  _plugins      : {},
-  _bundle       : null,
-  _pref         : Components.classes["@mozilla.org/preferences-service;1"]
-                            .getService(Components.interfaces.nsIPrefBranch),
-  _mimeSvc      : Components.classes["@mozilla.org/uriloader/external-helper-app-service;1"]
-                            .getService(Components.interfaces.nsIMIMEService),
-  _excludingPlugins           : false,
-  _excludingMissingExtensions : false,
-  
-  init: function ()
-  {
-    (this._editButton = document.getElementById("editFileHandler")).disabled = true;
-    (this._removeButton = document.getElementById("removeFileHandler")).disabled = true;    
-
-    if (this._pref instanceof Components.interfaces.nsIPrefBranchInternal) {
-      this._pref.addObserver(kShowPluginsInList, this, false);
-      this._pref.addObserver(kHideTypesWithoutExtensions, this, false);
-    }
-    
-    // Initialize the File Type list
-    this._bundle = document.getElementById("bundlePreferences");
-    this._tree = document.getElementById("fileHandlersList");
-    this._loadView();
-    // Determine any exclusions being applied - e.g. don't show types for which
-    // only a plugin handler exists, don't show types lacking extensions, etc. 
-    this._view._rowCount = this._updateExclusions();    
-    this._tree.treeBoxObject.view = this._view;  
-
-    var indexToSelect = parseInt(this._tree.getAttribute("lastSelected"));
-    if (indexToSelect < this._tree.view.rowCount)
-      this._tree.view.selection.select(indexToSelect);
-    this._tree.focus();    
-  },
-  
-  _loadView: function ()
-  {
-    // Reset ALL the collections and state flags, because we can call this after
-    // the window has initially displayed by resetting the filter. 
-    this._actions = [];
-    this._plugins = {};
-    this._view._filtered = false;
-    this._view._filterSet = [];
-    this._view._usingExclusionSet = false;
-    this._view._exclusionSet = [];
-    this._view._filterValue = "";
-
-    this._loadPluginData();
-    this._loadMIMERegistryData();
-  },
-  
-  _updateRowCount: function (aNewRowCount)
-  {
-    var oldCount = this._view._rowCount;
-    this._view._rowCount = 0;
-    this._tree.treeBoxObject.rowCountChanged(0, -oldCount);
-    this._view._rowCount = aNewRowCount;
-    this._tree.treeBoxObject.rowCountChanged(0, aNewRowCount);
-  },
-  
-  uninit: function ()
-  {
-    if (this._pref instanceof Components.interfaces.nsIPrefBranchInternal) {
-      this._pref.removeObserver(kShowPluginsInList, this);
-      this._pref.removeObserver(kHideTypesWithoutExtensions, this);
-    }
-  },
-  
-  observe: function (aSubject, aTopic, aData)
-  {
-    if (aTopic == "nsPref:changed" &&
-        (aData == kShowPluginsInList || aData == kHideTypesWithoutExtensions))
-      this._updateRowCount(this._updateExclusions());
-  },
-  
-  _updateExclusions: function ()
-  {
-    this._excludingPlugins = !this._pref.getBoolPref(kShowPluginsInList);
-    this._excludingMissingExtensions = this._pref.getBoolPref(kHideTypesWithoutExtensions);    
-    this._view._exclusionSet = [].concat(this._actions);
-    if (this._excludingMissingExtensions) {
-      this._view._usingExclusionSet = true;
-      for (var i = 0; i < this._view._exclusionSet.length;) {
-        if (!this._view._exclusionSet[i].hasExtension)
-          this._view._exclusionSet.splice(i, 1);
-        else
-          ++i;
-      }
-    }
-    if (this._excludingPlugins) {
-      this._view._usingExclusionSet = true;
-      for (i = 0; i < this._view._exclusionSet.length;) {
-        if (this._view._exclusionSet[i].handledOnlyByPlugin)
-          this._view._exclusionSet.splice(i, 1);
-        else
-          ++i        
-      }      
-    }
-
-    return this._view._usingExclusionSet ? this._view._exclusionSet.length 
-                                         : this._view._filtered ? this._view._filterSet.length 
-                                                                : this._actions.length;
-  },
-  
-  _loadPluginData: function ()
-  {
-    // Read enabled plugin type information from the category manager
-    var disabled = "";
-    if (this._pref.prefHasUserValue(kDisabledPluginTypesPref)) 
-      disabled = this._pref.getCharPref(kDisabledPluginTypesPref);
-    
-    for (var i = 0; i < navigator.plugins.length; ++i) {
-      var plugin = navigator.plugins[i];
-      for (var j = 0; j < plugin.length; ++j) {
-        var actionName = this._bundle.getFormattedString("openWith", [plugin.name])
-        var type = plugin[j].type;
-        this._createAction(type, actionName, true, FILEACTION_OPEN_PLUGIN, 
-                           null, true, disabled.indexOf(type) == -1, true);
-      }
-    }
-  },
-
-  _createAction: function (aMIMEType, aActionName, 
-                           aIsEditable, aHandleMode, aCustomHandler,
-                           aPluginAvailable, aPluginEnabled, 
-                           aHandledOnlyByPlugin)
-  {
-    var newAction = !(aMIMEType in this._plugins);
-    var action = newAction ? new FileAction() : this._plugins[aMIMEType];
-    action.type = aMIMEType;
-    var info = this._mimeSvc.getFromTypeAndExtension(action.type, null);
-    
-    // File Extension
-    try {
-      action.extension = info.primaryExtension;
-    }
-    catch (e) {
-      action.extension = this._bundle.getString("extensionNone");
-      action.hasExtension = false;
-    }
-    
-    // Large and Small Icon
-    try {
-      action.smallIcon = "moz-icon://goat." + info.primaryExtension + "?size=16";
-      action.bigIcon = "moz-icon://goat." + info.primaryExtension + "?size=32";
-    }
-    catch (e) {
-      action.smallIcon = "moz-icon://goat?size=16&contentType=" + info.MIMEType;
-      action.bigIcon = "moz-icon://goat?contentType=" + info.MIMEType + "&size=32";
-    }
-
-    // Pretty Type Name
-    if (info.description == "") {
-      try {
-        action.typeName = this._bundle.getFormattedString("fileEnding", [info.primaryExtension.toUpperCase()]);
-      }
-      catch (e) { 
-        // Wow, this sucks, just show the MIME type as a last ditch effort to display
-        // the type of file that this is. 
-        action.typeName = info.MIMEType;
-      }
-    }
-    else
-      action.typeName = info.description;
-
-    // Pretty Action Name
-    if (aActionName)
-      action.action         = aActionName;
-    action.pluginAvailable  = aPluginAvailable;
-    action.pluginEnabled    = aPluginEnabled;
-    action.editable         = aIsEditable;
-    action.handleMode       = aHandleMode;
-    action.customHandler    = aCustomHandler;
-    action.mimeInfo         = info;
-    action.handledOnlyByPlugin  = aHandledOnlyByPlugin
-    
-    if (newAction && !(action.handledOnlyByPlugin && !action.pluginEnabled)) {
-      this._actions.push(action);
-      this._plugins[action.type] = action;
-    }      
-    return action;
-  },
-  
-  _loadMIMEDS: function ()
-  {
-    var fileLocator = Components.classes["@mozilla.org/file/directory_service;1"]
-                                .getService(Components.interfaces.nsIProperties);
-    
-    var file = fileLocator.get("UMimTyp", Components.interfaces.nsIFile);
-
-    var ioService = Components.classes["@mozilla.org/network/io-service;1"]
-                              .getService(Components.interfaces.nsIIOService);
-    var fileHandler = ioService.getProtocolHandler("file")
-                               .QueryInterface(Components.interfaces.nsIFileProtocolHandler);
-    this._mimeDS = this._rdf.GetDataSourceBlocking(fileHandler.getURLSpecFromFile(file));
-  },
-  
-  _getLiteralValue: function (aResource, aProperty)
-  {
-    var property = this._rdf.GetResource(NC_URI(aProperty));
-    var value = this._mimeDS.GetTarget(aResource, property, true);
-    if (value)
-      return value.QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
-    return "";
-  },
-  
-  _getChildResource: function (aResource, aProperty)
-  {
-    var property = this._rdf.GetResource(NC_URI(aProperty));
-    return this._mimeDS.GetTarget(aResource, property, true);
-  },
-  
-  _getDisplayNameForFile: function (aFile)
-  {
-#ifdef XP_WIN
-    if (aFile instanceof Components.interfaces.nsILocalFileWin) {
-      try {
-        return aFile.getVersionInfoField("FileDescription"); 
-      }
-      catch (e) {
-        // fall through to the filename
-      }
-    }
-#endif
-#ifdef XP_MACOSX
-    var lfm = aFile.QueryInterface(Components.interfaces.nsILocalFileMac);
-    try {
-      return lfm.bundleDisplayName;
-    }
-    catch (e) {
-      // fall through to the file name
-    }
-#endif
-    var ios = Components.classes["@mozilla.org/network/io-service;1"]
-                        .getService(Components.interfaces.nsIIOService);
-    var url = ios.newFileURI(aFile).QueryInterface(Components.interfaces.nsIURL);
-    return url.fileName;
-  },  
-  
-  _loadMIMERegistryData: function ()
-  {
-    this._rdf = Components.classes["@mozilla.org/rdf/rdf-service;1"]
-                          .getService(Components.interfaces.nsIRDFService);
-    this._loadMIMEDS();                          
-                          
-    var root = this._rdf.GetResource("urn:mimetypes:root");
-    var container = Components.classes["@mozilla.org/rdf/container;1"]
-                              .createInstance(Components.interfaces.nsIRDFContainer);
-    container.Init(this._mimeDS, root);
-    
-    var elements = container.GetElements();
-    while (elements.hasMoreElements()) {
-      var type = elements.getNext();
-      if (!(type instanceof Components.interfaces.nsIRDFResource))
-        break;
-      var editable = this._getLiteralValue(type, "editable") == "true";
-      if (!editable)
-        continue;
-      
-      var handler = this._getChildResource(type, "handlerProp");
-      var alwaysAsk = this._getLiteralValue(handler, "alwaysAsk") == "true";
-      if (alwaysAsk)
-        continue;
-      var saveToDisk        = this._getLiteralValue(handler, "saveToDisk") == "true";
-      var useSystemDefault  = this._getLiteralValue(handler, "useSystemDefault") == "true";
-      var editable          = this._getLiteralValue(type, "editable") == "true";
-      var handledInternally = this._getLiteralValue(handler, "handleInternal") == "true";
-      var externalApp       = this._getChildResource(handler, "externalApplication");
-      var externalAppPath   = this._getLiteralValue(externalApp, "path");
-      try {
-        var customHandler = Components.classes["@mozilla.org/file/local;1"]
-                                      .createInstance(Components.interfaces.nsILocalFile);
-        customHandler.initWithPath(externalAppPath);
-      }
-      catch (e) {
-        customHandler = null;
-      }      
-      if (customHandler && !customHandler.exists())
-        customHandler = null;
-      var mimeType = this._getLiteralValue(type, "value");
-      var typeInfo = this._mimeSvc.getFromTypeAndExtension(mimeType, null);
-
-      // Determine the pretty name of the associated action.
-      var actionName = "";
-      var handleMode = 0;
-      if (saveToDisk) {
-        // Save the file to disk
-        actionName = this._bundle.getString("saveToDisk");
-        handleMode = FILEACTION_SAVE_TO_DISK;
-      }
-      else if (useSystemDefault) {
-        // Use the System Default handler
-        actionName = this._bundle.getFormattedString("openWith", 
-                                                     [typeInfo.defaultDescription]);
-        handleMode = FILEACTION_OPEN_DEFAULT;
-      }
-      else {
-        // Custom Handler
-        if (customHandler) {
-          actionName = this._bundle.getFormattedString("openWith", 
-                                                       [this._getDisplayNameForFile(customHandler)]);
-          handleMode = FILEACTION_OPEN_CUSTOM;
-        }
-        else {
-          // Corrupt datasource, invalid custom handler path. Revert to default.
-          actionName = this._bundle.getFormattedString("openWith", 
-                                                       [typeInfo.defaultDescription]);
-          handleMode = FILEACTION_OPEN_DEFAULT;
-        }
-      }
-
-      if (handledInternally)
-        handleMode = FILEACTION_OPEN_INTERNALLY;
-      
-      var pluginAvailable = mimeType in this._plugins && this._plugins[mimeType].pluginAvailable;
-      var pluginEnabled = pluginAvailable && this._plugins[mimeType].pluginEnabled;
-      if (pluginEnabled) {
-        handleMode = FILEACTION_OPEN_PLUGIN;
-        actionName = null;
-      }
-      var action = this._createAction(mimeType, actionName, editable, handleMode, 
-                                      customHandler, pluginAvailable, pluginEnabled,
-                                      false);
-    }
-  },
-  
-  _view: {
-    _filtered           : false,
-    _filterSet          : [],
-    _usingExclusionSet  : false,
-    _exclusionSet       : [],
-    _filterValue        : "",
-
-    _rowCount: 0,
-    get rowCount() 
-    { 
-      return this._rowCount; 
-    },
-    
-    get activeCollection ()
-    {
-      return this._filtered ? this._filterSet 
-                            : this._usingExclusionSet ? this._exclusionSet 
-                                                      : gDownloadActionsWindow._actions;
-    },
-
-    getItemAtIndex: function (aIndex)
-    {
-      return this.activeCollection[aIndex];
-    },
-    
-    getCellText: function (aIndex, aColumn)
-    {
-      switch (aColumn.id) {
-      case "fileExtension":
-        return this.getItemAtIndex(aIndex).extension.toUpperCase();
-      case "fileType":
-        return this.getItemAtIndex(aIndex).typeName;
-      case "fileMIMEType":
-        return this.getItemAtIndex(aIndex).type;
-      case "fileHandler":
-        return this.getItemAtIndex(aIndex).action;
-      }
-      return "";
-    },
-    getImageSrc: function (aIndex, aColumn) 
-    {
-      if (aColumn.id == "fileExtension") 
-        return this.getItemAtIndex(aIndex).smallIcon;
-      return "";
-    },
-    _selection: null, 
-    get selection () { return this._selection; },
-    set selection (val) { this._selection = val; return val; },
-    getRowProperties: function (aIndex, aProperties) {},
-    getCellProperties: function (aIndex, aColumn, aProperties) {},
-    getColumnProperties: function (aColumn, aProperties) {},
-    isContainer: function (aIndex) { return false; },
-    isContainerOpen: function (aIndex) { return false; },
-    isContainerEmpty: function (aIndex) { return false; },
-    isSeparator: function (aIndex) { return false; },
-    isSorted: function (aIndex) { return false; },
-    canDrop: function (aIndex, aOrientation) { return false; },
-    drop: function (aIndex, aOrientation) {},
-    getParentIndex: function (aIndex) { return -1; },
-    hasNextSibling: function (aParentIndex, aIndex) { return false; },
-    getLevel: function (aIndex) { return 0; },
-    getProgressMode: function (aIndex, aColumn) {},    
-    getCellValue: function (aIndex, aColumn) {},
-    setTree: function (aTree) {},    
-    toggleOpenState: function (aIndex) { },
-    cycleHeader: function (aColumn) {},    
-    selectionChanged: function () {},    
-    cycleCell: function (aIndex, aColumn) {},    
-    isEditable: function (aIndex, aColumn) { return false; },
-    isSelectable: function (aIndex, aColumn) { return false; },
-    setCellValue: function (aIndex, aColumn, aValue) {},    
-    setCellText: function (aIndex, aColumn, aValue) {},    
-    performAction: function (aAction) {},  
-    performActionOnRow: function (aAction, aIndex) {},    
-    performActionOnCell: function (aAction, aindex, aColumn) {}
-  },
-
-  removeFileHandler: function ()
-  {
-    var selection = this._tree.view.selection; 
-    if (selection.count < 1)
-      return;
-      
-    var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
-                                  .getService(Components.interfaces.nsIPromptService);
-    var flags = promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_0;
-    flags += promptService.BUTTON_TITLE_CANCEL * promptService.BUTTON_POS_1;
-
-    var title = this._bundle.getString("removeTitle" + (selection.count > 1 ? "Multiple" : "Single"));
-    var message = this._bundle.getString("removeMessage" + (selection.count > 1 ? "Multiple" : "Single"));
-    var button = this._bundle.getString("removeButton" + (selection.count > 1 ? "Multiple" : "Single"));
-    var rv = promptService.confirmEx(window, title, message, flags, button, 
-                                     null, null, null, { value: 0 });
-    if (rv != 0)
-      return;     
-
-    var rangeCount = selection.getRangeCount();
-    var lastSelected = 0;
-    var mimeDSDirty = false;
-    for (var i = 0; i < rangeCount; ++i) {
-      var min = { }; var max = { };
-      selection.getRangeAt(i, min, max);
-      for (var j = min.value; j <= max.value; ++j) {
-        var item = this._view.getItemAtIndex(j);
-        if (!item.handledOnlyByPlugin) {
-          // There is data for this type in the MIME registry, so make sure we
-          // remove it from the MIME registry. We don't disable the plugin here because
-          // if we do there's currently no way through the UI to re-enable it. We may
-          // come up with some sort of solution for that at a later date. 
-          var typeRes = this._rdf.GetResource(MIME_URI(item.type));
-          var handlerRes = this._getChildResource(typeRes, "handlerProp");
-          var extAppRes = this._getChildResource(handlerRes, "externalApplication");
-          this._cleanResource(extAppRes);
-          this._cleanResource(handlerRes);
-          this._cleanResource(typeRes); 
-          mimeDSDirty = true;         
-        }
-        lastSelected = (j + 1) >= this._view.rowCount ? j-1 : j;
-      }
-    }
-    if (mimeDSDirty && 
-        this._mimeDS instanceof Components.interfaces.nsIRDFRemoteDataSource)
-      this._mimeDS.Flush();
-    
-    // Just reload the list to make sure deletions are respected
-    this._loadView();
-    this._updateRowCount(this._updateExclusions());
-
-    selection.select(lastSelected);
-  },
-  
-  _cleanResource: function (aResource)
-  {
-    var labels = this._mimeDS.ArcLabelsOut(aResource);
-    while (labels.hasMoreElements()) {
-      var arc = labels.getNext();
-      if (!(arc instanceof Components.interfaces.nsIRDFResource))
-        break;
-      var target = this._mimeDS.GetTarget(aResource, arc, true);
-      this._mimeDS.Unassert(aResource, arc, target);
-    }
-  },
-  
-  _disablePluginForItem: function (aItem)
-  {
-    if (aItem.pluginAvailable) {
-      // Since we're disabling the full page plugin for this content type, 
-      // we must add it to the disabled list if it's not in there already.
-      var prefs = Components.classes["@mozilla.org/preferences-service;1"]
-                            .getService(Components.interfaces.nsIPrefBranch);
-      var disabled = aItem.type;
-      if (prefs.prefHasUserValue(kDisabledPluginTypesPref)) {
-        disabled = prefs.getCharPref(kDisabledPluginTypesPref);
-        if (disabled.indexOf(aItem.type) == -1) 
-          disabled += "," + aItem.type;
-      }
-      prefs.setCharPref(kDisabledPluginTypesPref, disabled);   
-      
-      // Also, we update the category manager so that existing browser windows
-      // update.
-      var catman = Components.classes["@mozilla.org/categorymanager;1"]
-                             .getService(Components.interfaces.nsICategoryManager);
-      catman.deleteCategoryEntry("Gecko-Content-Viewers", aItem.type, false);     
-    }    
-  },
-  
-  _enablePluginForItem: function (aItem)
-  {
-    var prefs = Components.classes["@mozilla.org/preferences-service;1"]
-                          .getService(Components.interfaces.nsIPrefBranch);
-    // Since we're enabling the full page plugin for this content type, we must
-    // look at the disabled types list and ensure that this type isn't in it.
-    if (prefs.prefHasUserValue(kDisabledPluginTypesPref)) {
-      var disabledList = prefs.getCharPref(kDisabledPluginTypesPref);
-      if (disabledList == aItem.type)
-        prefs.clearUserPref(kDisabledPluginTypesPref);
-      else {
-        var disabledTypes = disabledList.split(",");
-        var disabled = "";
-        for (var i = 0; i < disabledTypes.length; ++i) {
-          if (aItem.type != disabledTypes[i])
-            disabled += disabledTypes[i] + (i == disabledTypes.length - 1 ? "" : ",");
-        }
-        prefs.setCharPref(kDisabledPluginTypesPref, disabled);
-      }
-    }
-
-    // Also, we update the category manager so that existing browser windows
-    // update.
-    var catman = Components.classes["@mozilla.org/categorymanager;1"]
-                           .getService(Components.interfaces.nsICategoryManager);
-    catman.addCategoryEntry("Gecko-Content-Viewers", aItem.type,
-                            kPluginHandlerContractID, false, true);
-  },
-  
-  _ensureMIMERegistryEntry: function (aItem)
-  {
-    var root = this._rdf.GetResource("urn:mimetypes:root");
-    var container = Components.classes["@mozilla.org/rdf/container;1"]
-                              .createInstance(Components.interfaces.nsIRDFContainer);
-    container.Init(this._mimeDS, root);
-    
-    var itemResource = this._rdf.GetResource(MIME_URI(aItem.type));
-    var handlerResource = null;
-    if (container.IndexOf(itemResource) == -1) {
-      container.AppendElement(itemResource);
-      this._setLiteralValue(itemResource, "editable", "true");
-      this._setLiteralValue(itemResource, "value", aItem.type);
-      
-      handlerResource = this._rdf.GetResource(HANDLER_URI(aItem.type));
-      this._setLiteralValue(handlerResource, "alwaysAsk", "false");
-      var handlerProp = this._rdf.GetResource(NC_URI("handlerProp"));
-      this._mimeDS.Assert(itemResource, handlerProp, handlerResource, true);
-      
-      var extAppResource = this._rdf.GetResource(APP_URI(aItem.type));
-      this._setLiteralValue(extAppResource, "path", "");
-      var extAppProp = this._rdf.GetResource(NC_URI("externalApplication"));
-      this._mimeDS.Assert(handlerResource, extAppProp, extAppResource, true);
-    }
-    else
-      handlerResource = this._getChildResource(itemResource, "handlerProp");
-        
-    return handlerResource;
-  },
-  
-  _setLiteralValue: function (aResource, aProperty, aValue)
-  {
-    var property = this._rdf.GetResource(NC_URI(aProperty));
-    var newValue = this._rdf.GetLiteral(aValue);
-    var oldValue = this._mimeDS.GetTarget(aResource, property, true);
-    if (oldValue)
-      this._mimeDS.Change(aResource, property, oldValue, newValue);
-    else
-      this._mimeDS.Assert(aResource, property, newValue, true);
-  },
-  
-  editFileHandler: function ()
-  {
-    var selection = this._tree.view.selection; 
-    if (selection.count != 1)
-      return;
-
-    var item = this._view.getItemAtIndex(selection.currentIndex);
-    openDialog("chrome://browser/content/preferences/changeaction.xul", 
-               "_blank", "modal,centerscreen", item);
-    
-    // Update the database
-    switch (item.handleMode) {
-    case FILEACTION_OPEN_PLUGIN:
-      this._enablePluginForItem(item);
-      // We don't need to adjust the database because plugin settings always
-      // supercede whatever is in the db, leaving it untouched allows the last
-      // user setting(s) to be preserved if they ever revert.
-      break;
-    case FILEACTION_OPEN_DEFAULT:
-      this._disablePluginForItem(item);
-      var handlerRes = this._ensureMIMERegistryEntry(item);
-      this._setLiteralValue(handlerRes, "useSystemDefault", "true");
-      this._setLiteralValue(handlerRes, "saveToDisk", "false");
-      break;
-    case FILEACTION_OPEN_CUSTOM:
-      this._disablePluginForItem(item);
-      var handlerRes = this._ensureMIMERegistryEntry(item);
-      this._setLiteralValue(handlerRes, "useSystemDefault", "false");
-      this._setLiteralValue(handlerRes, "saveToDisk", "false");
-      var extAppRes = this._getChildResource(handlerRes, "externalApplication");
-      this._setLiteralValue(extAppRes, "path", item.customHandler.path);
-      break;
-    case FILEACTION_SAVE_TO_DISK:
-      this._disablePluginForItem(item);
-      var handlerRes = this._ensureMIMERegistryEntry(item);
-      this._setLiteralValue(handlerRes, "useSystemDefault", "false");
-      this._setLiteralValue(handlerRes, "saveToDisk", "true");
-      break;
-    }
-    
-    if (this._mimeDS instanceof Components.interfaces.nsIRDFRemoteDataSource)
-      this._mimeDS.Flush();
-    
-    // Update the view
-    this._tree.treeBoxObject.invalidateRow(selection.currentIndex);    
-  },
-  
-  onSelectionChanged: function ()
-  {
-    if (this._tree.view.rowCount == 0) {
-      this._removeButton.disabled = true;
-      this._editButton.disabled = true;
-      return;
-    }
-      
-    var selection = this._tree.view.selection; 
-    var selected = selection.count;
-    this._removeButton.disabled = selected == 0;
-    this._editButton.disabled = selected != 1;
-    var stringKey = selected > 1 ? "removeButtonMultiple" : "removeButtonSingle";
-    this._removeButton.label = this._bundle.getString(stringKey);
-    
-    var canRemove = true;
-    var canEdit = true;
-    
-    var rangeCount = selection.getRangeCount();
-    var min = { }, max = { };
-    var setLastSelected = false;
-    for (var i = 0; i < rangeCount; ++i) {
-      selection.getRangeAt(i, min, max);
-      
-      for (var j = min.value; j <= max.value; ++j) {
-        if (!setLastSelected) {
-          // Set the last selected index to the first item in the selection
-          this._tree.setAttribute("lastSelected", j);
-          setLastSelected = true;
-        }
-
-        var item = this._view.getItemAtIndex(j);
-        if (item && 
-            (!item.editable || item.handleMode == FILEACTION_OPEN_INTERNALLY))
-          canEdit = false;
-        
-        if (item && 
-            (!item.editable || item.handleMode == FILEACTION_OPEN_INTERNALLY ||
-             item.handledOnlyByPlugin))
-          canRemove = false;
-      }
-    }
-    
-    if (!canRemove)
-      this._removeButton.disabled = true;
-    if (!canEdit)
-      this._editButton.disabled = true;
-  },
-  
-  _lastSortProperty : "",
-  _lastSortAscending: false,
-  sort: function (aProperty) 
-  {
-    var ascending = (aProperty == this._lastSortProperty) ? !this._lastSortAscending : true;
-    function sortByProperty(a, b) 
-    {
-      return a[aProperty].toLowerCase().localeCompare(b[aProperty].toLowerCase());
-    }
-    function sortByExtension(a, b)
-    {
-      if (!a.hasExtension && b.hasExtension)
-        return 1;
-      if (!b.hasExtension && a.hasExtension)
-        return -1;
-      return a.extension.toLowerCase().localeCompare(b.extension.toLowerCase());
-    }
-    // Sort the Filtered List, if in Filtered mode
-    if (!this._view._filtered) { 
-      this._view.activeCollection.sort(aProperty == "extension" ? sortByExtension : sortByProperty);
-      if (!ascending)
-        this._view.activeCollection.reverse();
-    }
-
-    this._view.selection.clearSelection();
-    this._view.selection.select(0);
-    this._tree.treeBoxObject.invalidate();
-    this._tree.treeBoxObject.ensureRowIsVisible(0);
-
-    this._lastSortAscending = ascending;
-    this._lastSortProperty = aProperty;
-  },
-  
-  clearFilter: function ()
-  {    
-    // Clear the Filter and the Tree Display
-    document.getElementById("filter").value = "";
-    this._view._filtered = false;
-    this._view._filterSet = [];
-
-    // Just reload the list to make sure deletions are respected
-    this._loadView();
-    this._updateRowCount(this._updateExclusions());
-
-    // Restore selection
-    this._view.selection.clearSelection();
-    for (var i = 0; i < this._lastSelectedRanges.length; ++i) {
-      var range = this._lastSelectedRanges[i];
-      this._view.selection.rangedSelect(range.min, range.max, true);
-    }
-    this._lastSelectedRanges = [];
-
-    document.getElementById("actionsIntro").value = this._bundle.getString("actionsAll");
-    document.getElementById("clearFilter").disabled = true;
-    document.getElementById("filter").focus();
-  },
-  
-  _actionMatchesFilter: function (aAction)
-  {
-    return aAction.extension.toLowerCase().indexOf(this._view._filterValue) != -1 ||
-           aAction.typeName.toLowerCase().indexOf(this._view._filterValue) != -1 || 
-           aAction.type.toLowerCase().indexOf(this._view._filterValue) != -1 ||
-           aAction.action.toLowerCase().indexOf(this._view._filterValue) != -1;
-  },
-  
-  _filterActions: function (aFilterValue)
-  {
-    this._view._filterValue = aFilterValue;
-    var actions = [];
-    var collection = this._view._usingExclusionSet ? this._view._exclusionSet : this._actions;
-    for (var i = 0; i < collection.length; ++i) {
-      var action = collection[i];
-      if (this._actionMatchesFilter(action)) 
-        actions.push(action);
-    }
-    return actions;
-  },
-  
-  _lastSelectedRanges: [],
-  _saveState: function ()
-  {
-    // Save selection
-    var seln = this._view.selection;
-    this._lastSelectedRanges = [];
-    var rangeCount = seln.getRangeCount();
-    for (var i = 0; i < rangeCount; ++i) {
-      var min = {}; var max = {};
-      seln.getRangeAt(i, min, max);
-      this._lastSelectedRanges.push({ min: min.value, max: max.value });
-    }
-  },
-  
-  _filterTimeout: -1,
-  onFilterInput: function ()
-  {
-    if (this._filterTimeout != -1)
-      clearTimeout(this._filterTimeout);
-   
-    function filterActions()
-    {
-      var filter = document.getElementById("filter").value.toLowerCase();
-      if (filter == "") {
-        gDownloadActionsWindow.clearFilter();
-        return;
-      }        
-      var view = gDownloadActionsWindow._view;
-      view._filterSet = gDownloadActionsWindow._filterActions(filter);
-      if (!view._filtered) {
-        // Save Display Info for the Non-Filtered mode when we first
-        // enter Filtered mode. 
-        gDownloadActionsWindow._saveState();
-        view._filtered = true;
-      }
-
-      // Clear the display
-      gDownloadActionsWindow._updateRowCount(view._filterSet.length);
-      
-      // if the view is not empty then select the first item
-      if (view.rowCount > 0)
-        view.selection.select(0);
-
-      document.getElementById("actionsIntro").value = gDownloadActionsWindow._bundle.getString("actionsFiltered");
-      document.getElementById("clearFilter").disabled = false;
-    }
-    window.filterActions = filterActions;
-    this._filterTimeout = setTimeout("filterActions();", 500);
-  },
-  
-  onFilterKeyPress: function (aEvent)
-  {
-    if (aEvent.keyCode == 27) // ESC key
-      this.clearFilter();
-  },
-  
-  focusFilterBox: function ()
-  { 
-    var filter = document.getElementById("filter");
-    filter.focus();
-    filter.select();
-  }  
-};
-
deleted file mode 100644
--- a/browser/components/preferences/downloadactions.xul
+++ /dev/null
@@ -1,129 +0,0 @@
-<?xml version="1.0"?>
-
-# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
-# ***** BEGIN LICENSE BLOCK *****
-# Version: MPL 1.1/GPL 2.0/LGPL 2.1
-#
-# The contents of this file are subject to the Mozilla Public License Version
-# 1.1 (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS IS" basis,
-# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-# for the specific language governing rights and limitations under the
-# License.
-#
-# The Original Code is the Firefox Preferences System.
-#
-# The Initial Developer of the Original Code is
-# Ben Goodger.
-# Portions created by the Initial Developer are Copyright (C) 2005
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#   Ben Goodger <ben@mozilla.org>
-#
-# Alternatively, the contents of this file may be used under the terms of
-# either the GNU General Public License Version 2 or later (the "GPL"), or
-# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-# in which case the provisions of the GPL or the LGPL are applicable instead
-# of those above. If you wish to allow use of your version of this file only
-# under the terms of either the GPL or the LGPL, and not to allow others to
-# use your version of this file under the terms of the MPL, indicate your
-# 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 *****
-
-<?xml-stylesheet href="chrome://global/skin/"?>
-<?xml-stylesheet href="chrome://browser/skin/preferences/preferences.css"?>
-
-<!DOCTYPE prefwindow [
-  <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
-  <!ENTITY % downloadactionsDTD SYSTEM "chrome://browser/locale/preferences/downloadactions.dtd">
-  %brandDTD;
-  %downloadactionsDTD;
-]>
-
-<window id="DownloadActionsWindow" class="windowDialog"
-        windowtype="Preferences:DownloadActions"
-        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-        onload="gDownloadActionsWindow.init();"
-        onunload="gDownloadActionsWindow.uninit();"
-        title="&downloadactionsWindow.title;"
-        width="&window.width;" height="&window.height;" persist="width height screenX screenY">
-
-  <script type="application/x-javascript" src="chrome://mozapps/content/preferences/actionsshared.js"/>
-  <script type="application/x-javascript" src="chrome://browser/content/preferences/downloadactions.js"/>
-
-  <stringbundle id="bundlePreferences" src="chrome://browser/locale/preferences/preferences.properties"/>
-
-  <keyset>
-    <key key="&windowClose.key;" modifiers="accel" oncommand="window.close();"/>
-    <key key="&focusSearch1.key;" modifiers="accel" oncommand="gDownloadActionsWindow.focusFilterBox();"/>
-    <key key="&focusSearch2.key;" modifiers="accel" oncommand="gDownloadActionsWindow.focusFilterBox();"/>
-  </keyset>
-           
-  <vbox flex="1" class="contentPane">
-    <hbox align="center">
-      <label accesskey="&filter.accesskey;" control="filter">&filter.label;</label>
-      <textbox id="filter" flex="1" oninput="gDownloadActionsWindow.onFilterInput();" 
-              onkeypress="gDownloadActionsWindow.onFilterKeyPress(event);"/>
-      <button id="clearFilter" icon="clear" label="&clear.label;" accesskey="&clear.accesskey;" 
-              oncommand="gDownloadActionsWindow.clearFilter();" disabled="true"/>
-    </hbox>
-    <separator class="thin"/>
-    <label id="actionsIntro" control="fileHandlersList">
-      &fileTypesDescription.label;
-    </label>
-    <separator class="thin"/>
-    <tree id="fileHandlersList" flex="1"
-          lastSelected="0" persist="lastSelected"
-          onselect="gDownloadActionsWindow.onSelectionChanged();"
-          ondblclick="gDownloadActionsWindow.editFileHandler();">
-      <treechildren id="extensionChildren"/>
-      <treecols>
-        <treecol id="fileExtension" ignoreincolumnpicker="true"
-                  class="sortDirectionIndicator" persist="width"
-                  label="&fileExtensionColumn.label;" accesskey="&fileExtensionColumn.accesskey;"
-                  onclick="gDownloadActionsWindow.sort('extension');"/>
-        <treecol id="fileType" flex="1"
-                  class="sortDirectionIndicator" persist="width"
-                  label="&fileTypeColumn.label;" accesskey="&fileTypeColumn.accesskey;"
-                  onclick="gDownloadActionsWindow.sort('typeName');"/>
-        <splitter class="tree-splitter" />
-        <treecol id="fileMIMEType" flex="1" hidden="true"
-                  class="sortDirectionIndicator" persist="width"
-                  label="&fileMIMETypeColumn.label;" accesskey="&fileMIMETypeColumn.accesskey;"
-                  onclick="gDownloadActionsWindow.sort('type');"/>
-        <splitter class="tree-splitter" />
-        <treecol id="fileHandler" flex="1"
-                  class="sortDirectionIndicator" persist="width"
-                  label="&fileHandlerColumn.label;" accesskey="&fileHandlerColumn.accesskey;"
-                  onclick="gDownloadActionsWindow.sort('action');"/>                
-        <splitter class="tree-splitter" />
-      </treecols>
-    </tree>
-  </vbox>
-  <separator class="thin"/>
-  <hbox>
-    <hbox flex="1" class="actionButtons">
-      <button id="removeFileHandler" icon="remove"
-              label="&remove.label;" accesskey="&remove.accesskey;"
-              oncommand="gDownloadActionsWindow.removeFileHandler();"/>
-      <button id="editFileHandler"
-              label="&edit.label;" accesskey="&edit.accesskey;"
-              oncommand="gDownloadActionsWindow.editFileHandler();"/>
-      <spacer flex="1"/>
-#ifndef XP_MACOSX
-      <button oncommand="close();" icon="close"
-              label="&button.close.label;" accesskey="&button.close.accesskey;"/>
-#endif
-    </hbox>
-    <resizer dir="bottomright"/>
-  </hbox>
-</window>
-
deleted file mode 100644
--- a/browser/components/preferences/feeds.js
+++ /dev/null
@@ -1,383 +0,0 @@
-# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
-# ***** BEGIN LICENSE BLOCK *****
-# Version: MPL 1.1/GPL 2.0/LGPL 2.1
-#
-# The contents of this file are subject to the Mozilla Public License Version
-# 1.1 (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS IS" basis,
-# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-# for the specific language governing rights and limitations under the
-# License.
-#
-# The Original Code is the Firefox Preferences System.
-#
-# The Initial Developer of the Original Code is
-# Jeff Walden <jwalden+code@mit.edu>.
-# Portions created by the Initial Developer are Copyright (C) 2006
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#   Asaf Romano <mozilla.mano@sent.com>
-#
-# Alternatively, the contents of this file may be used under the terms of
-# either the GNU General Public License Version 2 or later (the "GPL"), or
-# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-# in which case the provisions of the GPL or the LGPL are applicable instead
-# of those above. If you wish to allow use of your version of this file only
-# under the terms of either the GPL or the LGPL, and not to allow others to
-# use your version of this file under the terms of the MPL, indicate your
-# 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 *****
-
-#ifndef XP_MACOSX
-var Cc = Components.classes;
-var Ci = Components.interfaces;
-var Cr = Components.results;
-var TYPE_MAYBE_FEED = "application/vnd.mozilla.maybe.feed";
-const kXULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
-#endif
-
-/*
- * Preferences:
- *
- * browser.feeds.handler
- * - "bookmarks", "reader" (clarified further using the .default preference),
- *   or "ask" -- indicates the default handler being used to process feeds
- *
- * browser.feeds.handler.default
- * - "bookmarks", "client" or "web" -- indicates the chosen feed reader used
- *   to display feeds, either transiently (i.e., when the "use as default"
- *   checkbox is unchecked, corresponds to when browser.feeds.handler=="ask")
- *   or more permanently (i.e., the item displayed in the dropdown in Feeds
- *   preferences)
- *
- * browser.feeds.handler.webservice
- * - the URL of the currently selected web service used to read feeds
- *
- * browser.feeds.handlers.application
- * - nsILocalFile, stores the current client-side feed reading app if one has
- *   been chosen
- */
-   
-const PREF_SELECTED_APP    = "browser.feeds.handlers.application";
-const PREF_SELECTED_WEB    = "browser.feeds.handlers.webservice";
-const PREF_SELECTED_ACTION = "browser.feeds.handler";
-const PREF_SELECTED_READER = "browser.feeds.handler.default";
-
-var gFeedsPane = {
-  element: function(aID) {
-    return document.getElementById(aID);
-  },
-
-  /* ........ QueryInterface .............. */
-  QueryInterface: function(aIID) {
-    if (aIID.equals(Ci.nsISupports) ||
-        aIID.equals(Ci.nsIObserver) ||
-        aIID.equals(Ci.nsIDOMEventListener))
-      return this;
-      
-    throw Cr.NS_ERROR_NO_INTERFACE;
-  },
-
-  /**
-   * See nsIObserver
-   */
-  observe: function(aSubject, aTopic, aData) {
-    if (aTopic != "nsPref:changed" || aData != PREF_SELECTED_WEB)
-      return;
-
-    if (this.element(PREF_SELECTED_ACTION).value == "reader") {
-      var wccr = 
-        Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
-        getService(Ci.nsIWebContentConverterService);
-      var handlerURL = this.element(PREF_SELECTED_WEB).valueFromPreferences;
-      var handler =
-        wccr.getWebContentHandlerByURI(TYPE_MAYBE_FEED, handlerURL);
-      if (handler)
-        wccr.setAutoHandler(TYPE_MAYBE_FEED, handler);
-    }
-  },
-
-  /**
-   * See nsIDOMEventListener
-   */
-  handleEvent: function(aEvent) {
-    if (aEvent.type == "unload") {
-      var prefBranch = Cc["@mozilla.org/preferences-service;1"].
-        getService(Ci.nsIPrefBranch2);
-      prefBranch.removeObserver(PREF_SELECTED_WEB, this);
-      window.removeEventListener("unload", this, false);
-    }
-  },
-
-  /**
-   * Initializes this.
-   */
-  init: function () {
-    var _delayedPaneLoad = function(self) {
-      self._initFeedReaders();
-      self.updateSelectedReader();
-    }
-    setTimeout(_delayedPaneLoad, 0, this);
-
-    // For web readers, we need to call setAutoHandler if the
-    // preview page should be skipped (i.e. PREF_SELECTED_ACTION="reader")
-    // To do so, we've to add a pref-observer in order to be notified on
-    // actual pref-changes (i.e. not on pref changes which may not take
-    // affect when the prefwindow is closed)
-    var prefBranch = Cc["@mozilla.org/preferences-service;1"].
-      getService(Ci.nsIPrefBranch2);
-
-    prefBranch.addObserver(PREF_SELECTED_WEB, this, false);
-    window.addEventListener("unload", this, false);
-  },
-
-  /**
-   * Populates the UI list of available feed readers.
-   */
-  _initFeedReaders: function() {
-    this.updateSelectedApplicationInfo();
-
-    var readersList = this.element("readers");
-
-    // List the system default feed reader if it is
-    // not the last-selected application already
-    try {
-      var systemDefaultReader = Cc["@mozilla.org/browser/shell-service;1"].
-                                getService(Ci.nsIShellService).
-                                defaultFeedReader;
-
-      var defaultSystemReaderFilefield = this.element("defaultSystemReaderFilefield");
-      defaultSystemReaderFilefield.file = systemDefaultReader;
-      var selectedAppFile = this.element("selectedAppFilefield").file;
-      if (!selectedAppFile || defaultSystemReaderFilefield.file.path !=
-          selectedAppFile.path) {
-        var defaultReaderItem = document.createElementNS(kXULNS, "listitem");
-        defaultReaderItem.id = "defaultSystemReaderListitem";
-        defaultReaderItem.className = "listitem-iconic";
-        defaultReaderItem.setAttribute("label", defaultSystemReaderFilefield.label);
-        defaultReaderItem.setAttribute("image", defaultSystemReaderFilefield.image);
-        readersList.appendChild(defaultReaderItem);
-      }
-    }
-    catch(ex) { /* no default reader */ }
-
-    // List of web handlers
-    var wccr = 
-        Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
-        getService(Ci.nsIWebContentConverterService);
-    var handlers = wccr.getContentHandlers(TYPE_MAYBE_FEED, {});
-    if (handlers.length == 0)
-      return;
-
-    var ios = 
-        Cc["@mozilla.org/network/io-service;1"].
-        getService(Ci.nsIIOService);
-    for (var i = 0; i < handlers.length; ++i) {
-      var row = document.createElementNS(kXULNS, "listitem");
-      row.className = "listitem-iconic";
-      row.setAttribute("label", handlers[i].name);
-      row.setAttribute("webhandlerurl", handlers[i].uri);
-
-      var uri = ios.newURI(handlers[i].uri, null, null);
-      if (/^https?/.test(uri.scheme))
-        row.setAttribute("image", uri.prePath + "/favicon.ico");
-
-      readersList.appendChild(row);
-    }
-  },
-
-  /**
-   * Updates the label and image of the client feed reader listitem
-   */
-  updateSelectedApplicationInfo: function() {
-    var appItemCell = this.element("selectedApplicationCell");
-    var selectedAppFilefield = this.element("selectedAppFilefield");
-    selectedAppFilefield.file = this.element(PREF_SELECTED_APP).value;
-    if (selectedAppFilefield.file) {
-      appItemCell.setAttribute("label", selectedAppFilefield.label);
-      appItemCell.setAttribute("image", selectedAppFilefield.image);
-    }
-    else {
-      var noAppString =
-        this.element("stringbundle").getString("noApplicationSelected");
-      appItemCell.setAttribute("label", noAppString);
-      appItemCell.setAttribute("image", "");
-    }
-  },
-
-  /**
-   * Selects a item in the list without triggering a preference change.
-   *
-   * @param aItem
-   *        the listitem to be selected
-   */
-  _silentSelectReader: function(aItem) {
-    var readers = this.element("readers");
-    readers.setAttribute("suppressonselect", "true");
-    readers.selectItem(aItem);
-    readers.removeAttribute("suppressonselect");
-  },
-
-  /**
-   * Helper for updateSelectedReader. Syncs the selected item in the readers
-   * list with value stored invalues stored in PREF_SELECTED_WEB
-   */
-  _updateSelectedWebHandlerItem: function() {
-    // We should select the new web handler only if the default handler
-    // is "web"
-    var readers = this.element("readers")
-    var readerElts =
-        readers.getElementsByAttribute("webhandlerurl",
-                                       this.element(PREF_SELECTED_WEB).value);
-
-    // XXXmano: handle the addition of a new web handler
-    if (readerElts.length > 0)
-      this._silentSelectReader(readerElts[0]);
-  },
-
-  /**
-   * Syncs the selected item in the readers list with the values stored in
-   * preferences.
-   */
-  updateSelectedReader: function() {
-    var defaultReader = this.element(PREF_SELECTED_READER).value ||
-                        "bookmarks";
-    switch (defaultReader) {
-      case "bookmarks":
-        this._silentSelectReader(this.element("liveBookmarksListItem"));
-        break;
-      case "client":
-#ifdef XP_WIN
-        // Keep the system default feed reader item selected if the
-        // last-selected application is the the system default feed reader
-        // and if it is already selected
-        var currentItem = this.element("readers").currentItem;
-        if (currentItem && currentItem.id == "defaultSystemReaderListitem") {
-          var defaultSystemReaderFile = this.element("defaultSystemReaderFilefield").file;
-          var selectedAppFile = this.element("selectedAppFilefield").file;
-          if (selectedAppFile && defaultSystemReaderFile &&
-              defaultSystemReaderFile.path == selectedAppFile.path)
-            break;
-        }
-#endif
-
-        this._silentSelectReader(this.element("selectedApplicationListitem"));
-        break;
-      case "web":
-        this._updateSelectedWebHandlerItem();
-        break;
-    }
-  },
-
-  /**
-   * Displays a prompt from which the user may choose an a (client) feed reader.
-   */
-  chooseClientApp: function () {
-    var fp = Cc["@mozilla.org/filepicker;1"]
-               .createInstance(Ci.nsIFilePicker);
-    fp.init(window, document.title, Ci.nsIFilePicker.modeOpen);
-    fp.appendFilters(Ci.nsIFilePicker.filterApps);
-    if (fp.show() == Ci.nsIFilePicker.returnOK && fp.file) {
-      // XXXben - we need to compare this with the running instance executable
-      //          just don't know how to do that via script...
-      // XXXmano TBD: can probably add this to nsIShellService
-#ifdef XP_WIN
-#expand       if (fp.file.leafName == "__MOZ_APP_NAME__.exe")
-#else
-#ifdef XP_MACOSX
-#expand       if (fp.file.leafName == "__MOZ_APP_DISPLAYNAME__.app")
-#else
-#expand       if (fp.file.leafName == "__MOZ_APP_NAME__-bin")
-#endif
-#endif
-        return;
-
-      this.element(PREF_SELECTED_APP).value = fp.file;
-      this.element(PREF_SELECTED_READER).value = "client";
-    }
-  },
-
-  /**
-   * Disables the readers list if "Show preview..." is selected, enables
-   * it otherwise.
-   */
-  onReadingMethodSelect: function() {
-    var disableList = this.element("readingMethod").value == "ask";
-    this.element("readers").disabled = disableList;
-    this.element("chooseClientApp").disabled = disableList;
-  },
-
-  /**
-   * Maps the value of PREF_SELECTED_ACTION to the parallel
-   * value in the radiogroup
-   */
-  onReadingMethodSyncFromPreference: function() {
-    var pref = this.element(PREF_SELECTED_ACTION);
-    var newVal = pref.instantApply ? pref.valueFromPreferences : pref.value;
-    if (newVal != "ask")
-      return "reader";
-
-    return "ask";
-  },
-
-  /**
-   * Returns the value to be used for PREF_SELECTED_ACTION
-   * according to the current UI state.
-   */
-  onReadingMethodSyncToPreference: function() {
-    var readers = this.element("readers");
-
-    // A reader must be choosed in order to skip the preview page
-    if (this.element("readingMethod").value == "ask" ||
-        !readers.currentItem)
-      return "ask";
-
-    if (readers.currentItem.id == "liveBookmarksListItem")
-      return "bookmarks";
-
-    return "reader";
-  },
-
-  /**
-   * Syncs PREF_SELECTED_READER with the selected item in the readers list
-   * Also updates PREF_SELECTED_ACTION if necessary
-   */
-  writeSelectedFeedReader: function() {
-    // Force update of the action pref. This is needed for the case in which
-    // the user flipped from a reader to live bookmarks or vice-versa
-    this.element(PREF_SELECTED_ACTION).value =
-      this.onReadingMethodSyncToPreference();
-
-    var currentItem = this.element("readers").currentItem;
-    if (currentItem.hasAttribute("webhandlerurl")) {
-      this.element(PREF_SELECTED_WEB).value =
-        currentItem.getAttribute("webhandlerurl");
-      this.element(PREF_SELECTED_READER).value = "web";
-    }
-    else {
-      switch (currentItem.id) {
-        case "liveBookmarksListItem":
-          this.element(PREF_SELECTED_READER).value = "bookmarks";
-          break;
-        case "selectedApplicationListitem":
-          // PREF_SELECTED_APP is saved in chooseClientApp
-          this.element(PREF_SELECTED_READER).value = "client";
-          break;
-#ifdef XP_WIN
-        case "defaultSystemReaderListitem":
-          this.element(PREF_SELECTED_APP).value = this.element("defaultSystemReaderFilefield").file;
-          this.element(PREF_SELECTED_READER).value = "client";
-          break;
-#endif
-      }
-    }
-  }
-};
deleted file mode 100644
--- a/browser/components/preferences/feeds.xul
+++ /dev/null
@@ -1,121 +0,0 @@
-<?xml version="1.0"?>
-
-# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
-# ***** BEGIN LICENSE BLOCK *****
-# Version: MPL 1.1/GPL 2.0/LGPL 2.1
-#
-# The contents of this file are subject to the Mozilla Public License Version
-# 1.1 (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS IS" basis,
-# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-# for the specific language governing rights and limitations under the
-# License.
-#
-# The Original Code is the Firefox Preferences System.
-#
-# The Initial Developer of the Original Code is
-# Jeff Walden <jwalden+code@mit.edu>.
-# Portions created by the Initial Developer are Copyright (C) 2006
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#   Asaf Romano <mozilla.mano@sent.com>
-#
-# Alternatively, the contents of this file may be used under the terms of
-# either the GNU General Public License Version 2 or later (the "GPL"), or
-# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-# in which case the provisions of the GPL or the LGPL are applicable instead
-# of those above. If you wish to allow use of your version of this file only
-# under the terms of either the GPL or the LGPL, and not to allow others to
-# use your version of this file under the terms of the MPL, indicate your
-# 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 *****
-
-<!DOCTYPE overlay [
-  <!ENTITY % feedsDTD SYSTEM "chrome://browser/locale/preferences/feeds.dtd">
-  %feedsDTD;
-]>
-
-<overlay id="FeedsPaneOverlay"
-         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-         xmlns:aaa="http://www.w3.org/2005/07/aaa">
-
-  <prefpane id="paneFeeds"
-            onpaneload="gFeedsPane.init();"
-            helpTopic="prefs-feeds"
-            helpURI="chrome://browser/locale/help/help.rdf">
-
-    <preferences id="feedsPreferences">
-      <preference id="browser.feeds.handler"
-                  name="browser.feeds.handler"
-                  type="string"/>
-      <preference id="browser.feeds.handler.default"
-                  name="browser.feeds.handler.default"
-                  onchange="gFeedsPane.updateSelectedReader();"
-                  type="string"/>
-      <preference id="browser.feeds.handlers.application"
-                  name="browser.feeds.handlers.application"
-                  onchange="gFeedsPane.updateSelectedApplicationInfo();"
-                  type="file"/>
-      <preference id="browser.feeds.handlers.webservice"
-                  name="browser.feeds.handlers.webservice"
-                  onchange="gFeedsPane.updateSelectedReader();"
-                  type="string"/>
-    </preferences>
-    
-    <script type="application/x-javascript" src="chrome://browser/content/preferences/feeds.js"/>
-
-    <filefield class="indent" id="selectedAppFilefield" disabled="true" hidden="true"/>
-#ifdef XP_WIN
-    <filefield class="indent" id="defaultSystemReaderFilefield" disabled="true" hidden="true"/>
-#endif
-
-    <stringbundle id="stringbundle" src="chrome://browser/locale/preferences/feeds.properties"/>
-
-    <label value="&feedClick.label;"/>
-    <radiogroup id="readingMethod"
-                class="indent"
-                preference="browser.feeds.handler"
-                onsyncfrompreference="return gFeedsPane.onReadingMethodSyncFromPreference();"
-                onsynctopreference="return gFeedsPane.onReadingMethodSyncToPreference();"
-                onselect="gFeedsPane.onReadingMethodSelect();">
-      <radio value="ask"
-             label="&showPreview.label;"
-             accesskey="&showPreview.accesskey;"/>
-      <radio value="reader" id="useReader"
-             label="&subscribeUsing.label;"
-             accesskey="&subscribeUsing.accesskey;"
-             aaa:labelledby="useReader readers"/>
-      <hbox id="readerContainer" class="indent" flex="1">
-        <listbox id="readers" rows="5" flex="1"
-                 aaa:labelledby="useReader"
-                 onselect="gFeedsPane.writeSelectedFeedReader(); event.stopPropagation();">
-          <listcols>
-            <listcol flex="1"/>
-            <listcol/>
-          </listcols>
-          <listitem id="liveBookmarksListItem"
-                    label="&liveBookmarks.label;"
-                    class="listitem-iconic"
-                    image="chrome://browser/skin/page-livemarks.png"/>
-          <listitem id="selectedApplicationListitem" allowevents="true">
-            <listcell id="selectedApplicationCell" class="listcell-iconic"/>
-            <listcell id="chooseClientAppCell">
-              <button id="chooseClientApp"
-                      label="&chooseApplication.label;"
-                      accesskey="&chooseApplication.accesskey;"
-                      oncommand="gFeedsPane.chooseClientApp();"/>
-            </listcell>
-          </listitem>
-        </listbox>
-      </hbox>
-    </radiogroup>
-  </prefpane>
-</overlay>
new file mode 100755
--- /dev/null
+++ b/browser/components/preferences/handlers.css
@@ -0,0 +1,66 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla browser.
+ *
+ * The Initial Developer of the Original Code is Mozilla.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Myk Melez <myk@mozilla.org>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * 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 ***** */
+
+richlistitem {
+  -moz-binding: url("chrome://browser/content/preferences/handlers.xml#handler");
+}
+
+richlistitem[selected="true"] {
+  -moz-binding: url("chrome://browser/content/preferences/handlers.xml#handler-selected");
+}
+
+/**
+ * Somewhat line up the actions menu with action labels above and below it.
+ * FIXME: to really line this up, equalize the distance from the left side
+ * of the action box to the left side of the icon for both the menu and the
+ * non-menu versions of the action box.  Also make sure the labels are the
+ * same distance away from the icons.
+ */
+.actionsMenu {
+  margin-left: 0;
+}
+
+/**
+ * Make the icons appear and pad them a bit.
+ * Note: we display the icon box for every item whether or not it has an icon
+ * so the labels of all the items align vertically.
+ */
+.actionsMenu > menupopup > menuitem > .menu-iconic-left {
+  display: -moz-box;
+  min-width: 16px;
+  -moz-padding-start: 2px;
+  -moz-padding-end: 2px;
+}
new file mode 100755
--- /dev/null
+++ b/browser/components/preferences/handlers.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0"?>
+
+<!-- ***** BEGIN LICENSE BLOCK *****
+   - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+   -
+   - The contents of this file are subject to the Mozilla Public License Version
+   - 1.1 (the "License"); you may not use this file except in compliance with
+   - the License. You may obtain a copy of the License at
+   - http://www.mozilla.org/MPL/
+   -
+   - Software distributed under the License is distributed on an "AS IS" basis,
+   - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+   - for the specific language governing rights and limitations under the
+   - License.
+   -
+   - The Original Code is the Mozilla browser.
+   -
+   - The Initial Developer of the Original Code is Mozilla.
+   - Portions created by the Initial Developer are Copyright (C) 2007
+   - the Initial Developer. All Rights Reserved.
+   -
+   - Contributor(s):
+   -   Myk Melez <myk@mozilla.org>
+   -
+   - Alternatively, the contents of this file may be used under the terms of
+   - either the GNU General Public License Version 2 or later (the "GPL"), or
+   - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+   - in which case the provisions of the GPL or the LGPL are applicable instead
+   - of those above. If you wish to allow use of your version of this file only
+   - under the terms of either the GPL or the LGPL, and not to allow others to
+   - use your version of this file under the terms of the MPL, indicate your
+   - decision by deleting the provisions above and replace them with the notice
+   - and other provisions required by the LGPL or the GPL. 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 ***** -->
+
+<!DOCTYPE overlay [
+  <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
+  <!ENTITY % applicationsDTD SYSTEM "chrome://browser/locale/preferences/applications.dtd">
+  %brandDTD;
+  %applicationsDTD;
+]>
+
+<bindings id="handlerBindings"
+          xmlns="http://www.mozilla.org/xbl"
+          xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+          xmlns:xbl="http://www.mozilla.org/xbl">
+
+  <binding id="handler-base" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
+    <implementation>
+      <property name="type" readonly="true">
+        <getter>
+          return this.getAttribute("type");
+        </getter>
+      </property>
+    </implementation>
+  </binding>
+
+  <binding id="handler" extends="chrome://browser/content/preferences/handlers.xml#handler-base">
+    <content>
+      <xul:hbox flex="1" equalsize="always">
+        <xul:hbox flex="1" align="center">
+          <xul:image xbl:inherits="src=typeIcon" height="16" width="16"/>
+          <xul:label flex="1" crop="end" xbl:inherits="value=typeDescription"/>
+        </xul:hbox>
+        <xul:hbox flex="1" align="center">
+          <xul:image xbl:inherits="src=actionIcon" height="16" width="16"/>
+          <xul:label flex="1" crop="end" xbl:inherits="value=actionDescription"/>
+        </xul:hbox>
+      </xul:hbox>
+    </content>
+  </binding>
+
+  <binding id="handler-selected" extends="chrome://browser/content/preferences/handlers.xml#handler-base">
+    <content>
+      <xul:hbox flex="1" equalsize="always">
+        <xul:hbox flex="1" align="center">
+          <xul:image xbl:inherits="src=typeIcon" height="16" width="16"/>
+          <xul:label flex="1" crop="end" xbl:inherits="value=typeDescription"/>
+        </xul:hbox>
+        <xul:hbox flex="1">
+          <xul:menulist class="actionsMenu" flex="1" crop="end" selectedIndex="1"
+                        oncommand="gApplicationsPane.onSelectAction(event)">
+            <xul:menupopup/>
+          </xul:menulist>
+        </xul:hbox>
+      </xul:hbox>
+    </content>
+
+    <implementation>
+      <constructor>
+        gApplicationsPane.rebuildActionsMenu();
+      </constructor>
+    </implementation>
+
+  </binding>
+
+</bindings>
--- a/browser/components/preferences/jar.mn
+++ b/browser/components/preferences/jar.mn
@@ -1,28 +1,26 @@
 browser.jar:
 *   content/browser/preferences/advanced.xul
 *   content/browser/preferences/advanced.js
 *   content/browser/preferences/advanced-scripts.xul
-*   content/browser/preferences/changeaction.xul
-*   content/browser/preferences/changeaction.js
+*   content/browser/preferences/applications.xul
+*   content/browser/preferences/applications.js
 *   content/browser/preferences/colors.xul
 *   content/browser/preferences/cookies.xul
 *   content/browser/preferences/cookies.js
 *   content/browser/preferences/content.xul
 *   content/browser/preferences/content.js
 *   content/browser/preferences/connection.xul
 *   content/browser/preferences/connection.js
-*   content/browser/preferences/downloadactions.xul
-*   content/browser/preferences/downloadactions.js
 *   content/browser/preferences/fallbackEULA.xhtml
-*   content/browser/preferences/feeds.xul
-*   content/browser/preferences/feeds.js
 *   content/browser/preferences/fonts.xul
 *   content/browser/preferences/fonts.js
+*   content/browser/preferences/handlers.xml
+*   content/browser/preferences/handlers.css
 *   content/browser/preferences/languages.xul
 *   content/browser/preferences/languages.js
 *   content/browser/preferences/main.xul
 *   content/browser/preferences/main.js
 *   content/browser/preferences/permissions.xul
 *   content/browser/preferences/permissions.js
 *   content/browser/preferences/permissionsutils.js
 *   content/browser/preferences/phishEULA.xul
--- a/browser/components/preferences/preferences.xul
+++ b/browser/components/preferences/preferences.xul
@@ -38,16 +38,23 @@
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
 <?xml-stylesheet href="chrome://global/skin/global.css"?>
 <?xml-stylesheet href="chrome://mozapps/content/preferences/preferences.css"?>
 <?xml-stylesheet href="chrome://browser/skin/preferences/preferences.css"?>
 
+<!-- XXX This should be in applications.xul, but bug 393953 means putting it
+   - there causes the Applications pane not to work the first time you open
+   - the Preferences dialog in a browsing session, so we work around the problem
+   - by putting it here instead.
+   -->
+<?xml-stylesheet href="chrome://browser/content/preferences/handlers.css"?>
+
 <!DOCTYPE prefwindow [
 <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
 <!ENTITY % preferencesDTD SYSTEM "chrome://browser/locale/preferences/preferences.dtd">
 %brandDTD;
 %preferencesDTD;
 ]>
 
 #ifdef XP_WIN
@@ -88,18 +95,18 @@
                   src="chrome://browser/locale/preferences/preferences.properties"/>
 
     <prefpane id="paneMain" label="&paneMain.title;"
               src="chrome://browser/content/preferences/main.xul"/>
     <prefpane id="paneTabs" label="&paneTabs.title;"
               src="chrome://browser/content/preferences/tabs.xul"/>
     <prefpane id="paneContent" label="&paneContent.title;"
               src="chrome://browser/content/preferences/content.xul"/>
-    <prefpane id="paneFeeds" label="&paneFeeds.title;"
-              src="chrome://browser/content/preferences/feeds.xul"/>
+    <prefpane id="paneApplications" label="&paneApplications.title;"
+              src="chrome://browser/content/preferences/applications.xul"/>
     <prefpane id="panePrivacy" label="&panePrivacy.title;"
               src="chrome://browser/content/preferences/privacy.xul"/>
     <prefpane id="paneSecurity" label="&paneSecurity.title;"
               src="chrome://browser/content/preferences/security.xul"/>
     <prefpane id="paneAdvanced" label="&paneAdvanced.title;"
               src="chrome://browser/content/preferences/advanced.xul"/>
 
 #ifdef XP_MACOSX
--- a/browser/components/safebrowsing/content/phishing-afterload-displayer.js
+++ b/browser/components/safebrowsing/content/phishing-afterload-displayer.js
@@ -203,17 +203,16 @@ PROT_PhishMsgDisplayerBase.prototype.bro
 
   // If messageshowing hasn't been set, then this is the first time this
   // problematic browser tab has been on top, so do our setup and show
   // the warning.
   if (this.messageShowing_ === undefined) {
     this.messageShouldShow_ = true;
   }
 
-  this.hideLockIcon_();        // Comes back when we are unselected or unloaded
   this.addWarningInUrlbar_();  // Goes away when we are unselected or unloaded
 
   // messageShouldShow might be false if the user dismissed the warning, 
   // switched tabs, and then switched back. We're still active, but don't
   // want to show the warning again. The user can cause it to show by
   // clicking our icon in the urlbar.
   if (this.messageShouldShow_)
     this.showMessage_();
@@ -229,17 +228,16 @@ PROT_PhishMsgDisplayerBase.prototype.exp
     this.showMessage_();
 }
 
 /** 
  * Invoked by the browser view when our browser is switched away from
  */
 PROT_PhishMsgDisplayerBase.prototype.browserUnselected = function() {
   this.removeWarningInUrlbar_();
-  this.unhideLockIcon_();
   if (this.messageShowing_)
     this.hideMessage_();
 }
 
 /**
  * Invoked to make this displayer active. The displayer will now start
  * responding to notifications such as commands and resize events. We
  * can't do this in the constructor because there might be many 
@@ -285,17 +283,16 @@ PROT_PhishMsgDisplayerBase.prototype.don
 
   // If the Document we're showing the warning for was nav'd away from
   // before we had a chance to get started, we have nothing to do.
   if (this.started_) {
 
     // If we were started, we must be the current problem, so these things
     // must be showing
     this.removeWarningInUrlbar_();
-    this.unhideLockIcon_();
 
     // Could be though that they've closed the warning dialog
     if (this.messageShowing_)
       this.hideMessage_();
 
     if (this.resizeHandler_) {
       this.browser_.removeEventListener("resize", 
                                         this.resizeHandler_, 
@@ -323,38 +320,16 @@ PROT_PhishMsgDisplayerBase.prototype.rem
   var pos = orig.indexOf(toRemove);
   if (pos != -1)
     orig = orig.substring(0, pos) + orig.substring(pos + toRemove.length);
 
   return orig;
 }
 
 /**
- * We don't want to confuse users if they land on a phishy page that uses
- * SSL, so ensure that the lock icon never shows when we're showing our 
- * warning.
- */
-PROT_PhishMsgDisplayerBase.prototype.hideLockIcon_ = function() {
-  var lockIcon = this.doc_.getElementById("lock-icon");
-  if (!lockIcon)
-    return;
-  lockIcon.hidden = true;
-}
-
-/**
- * Ensure they can see it after our warning is finished.
- */
-PROT_PhishMsgDisplayerBase.prototype.unhideLockIcon_ = function() {
-  var lockIcon = this.doc_.getElementById("lock-icon");
-  if (!lockIcon)
-    return;
-  lockIcon.hidden = false;
-}
-
-/**
  * This method makes our warning icon visible in the location bar. It will
  * be removed only when the problematic document is navigated awy from 
  * (i.e., when done() is called), and not when the warning is dismissed.
  */
 PROT_PhishMsgDisplayerBase.prototype.addWarningInUrlbar_ = function() {
   var urlbarIcon = this.doc_.getElementById(this.urlbarIconId_);
   if (!urlbarIcon)
     return;
--- a/browser/components/search/nsSearchService.js
+++ b/browser/components/search/nsSearchService.js
@@ -200,29 +200,31 @@ function isUsefulLine(aLine) {
  */
 const SEARCH_LOG_PREFIX = "*** Search: ";
 
 /**
  * Outputs aText to the JavaScript console as well as to stdout, if the search
  * logging pref (browser.search.log) is set to true.
  */
 function LOG(aText) {
+#ifdef DEBUG
   var prefB = Cc["@mozilla.org/preferences-service;1"].
               getService(Ci.nsIPrefBranch);
   var shouldLog = false;
   try {
     shouldLog = prefB.getBoolPref(BROWSER_SEARCH_PREF + "log");
   } catch (ex) {}
 
   if (shouldLog) {
     dump(SEARCH_LOG_PREFIX + aText + "\n");
     var consoleService = Cc["@mozilla.org/consoleservice;1"].
                          getService(Ci.nsIConsoleService);
     consoleService.logStringMessage(aText);
   }
+#endif
 }
 
 function ERROR(message, resultCode) {
   NS_ASSERT(false, SEARCH_LOG_PREFIX + message);
   throw resultCode;
 }
 
 /**
--- a/browser/installer/unix/packages-static
+++ b/browser/installer/unix/packages-static
@@ -169,17 +169,16 @@ bin/components/unicharutil.xpt
 bin/components/uriloader.xpt
 bin/components/webBrowser_core.xpt
 bin/components/webbrowserpersist.xpt
 bin/components/webshell_idls.xpt
 bin/components/websrvcs.xpt
 bin/components/widget.xpt
 bin/components/windowds.xpt
 bin/components/windowwatcher.xpt
-bin/components/xml-rpc.xpt
 bin/components/xpcom_base.xpt
 bin/components/xpcom_system.xpt
 bin/components/xpcom_components.xpt
 bin/components/xpcom_ds.xpt
 bin/components/xpcom_io.xpt
 bin/components/xpcom_threads.xpt
 bin/components/xpcom_xpti.xpt
 bin/components/xpconnect.xpt
@@ -213,17 +212,16 @@ bin/components/nsFilePicker.js
 bin/components/nsHelperAppDlg.js
 bin/components/nsDownloadManagerUI.js
 bin/components/nsInterfaceInfoToIDL.js
 ; bin/components/nsProgressDialog.js   not needed for firefox
 bin/components/nsProxyAutoConfig.js
 ; bin/components/nsResetPref.js    not needed for firefox
 bin/components/nsSidebar.js
 ; bin/components/nsUpdateNotifier.js not needed for firefox
-bin/components/nsXmlRpcClient.js
 bin/components/nsExtensionManager.js
 bin/components/nsBlocklistService.js
 bin/components/nsUpdateService.js
 bin/components/pluginGlue.js
 bin/components/extensions.xpt
 bin/components/update.xpt
 bin/components/nsSessionStartup.js
 bin/components/nsSessionStore.js
--- a/browser/installer/windows/packages-static
+++ b/browser/installer/windows/packages-static
@@ -175,17 +175,16 @@ bin\components\walletpreview.xpt
 bin\components\webBrowser_core.xpt
 bin\components\webbrowserpersist.xpt
 bin\components\webshell_idls.xpt
 bin\components\websrvcs.xpt
 bin\components\widget.xpt
 bin\components\windowds.xpt
 bin\components\windowwatcher.xpt
 bin\components\shellservice.xpt
-bin\components\xml-rpc.xpt
 bin\components\xpcom_base.xpt
 bin\components\xpcom_system.xpt
 bin\components\xpcom_components.xpt
 bin\components\xpcom_ds.xpt
 bin\components\xpcom_io.xpt
 bin\components\xpcom_thread.xpt
 bin\components\xpcom_xpti.xpt
 bin\components\xpconnect.xpt
@@ -205,17 +204,16 @@ bin\components\nsSetDefaultBrowser.js
 bin\components\nsTryToClose.js
 bin\components\nsDictionary.js
 bin\components\nsHelperAppDlg.js
 bin\components\nsDownloadManagerUI.js
 bin\components\nsProxyAutoConfig.js
 bin\components\nsSearchService.js
 bin\components\nsSearchSuggestions.js
 bin\components\nsSidebar.js
-bin\components\nsXmlRpcClient.js
 bin\components\nsExtensionManager.js
 bin\components\nsBlocklistService.js
 bin\components\nsUpdateService.js
 bin\components\nsMicrosummaryService.js
 bin\components\nsPlacesTransactionsService.js
 bin\components\nsPostUpdateWin.js
 bin\components\nsLoginInfo.js
 bin\components\nsLoginManager.js
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -345,8 +345,10 @@
 <!ENTITY findAgainCmd.commandkey "g">
 <!ENTITY findAgainCmd.commandkey2 "VK_F3">
 
 <!ENTITY spellAddDictionaries.label "Add dictionaries...">
 <!ENTITY spellAddDictionaries.accesskey "A">
 
 <!ENTITY editBookmark.done.label                      "Done">
 <!ENTITY editBookmark.delete.label                    "Delete">
+
+<!ENTITY identity.moreInfoLinkText "Tell me more about this web site...">
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -92,8 +92,25 @@ refreshBlocked.goButton.accesskey=A
 refreshBlocked.refreshLabel=%S prevented this page from automatically reloading.
 refreshBlocked.redirectLabel=%S prevented this page from automatically redirecting to another page.
 
 # Chromeless popup handling
 chromelessWindow.warningMessage=The web site at %S has hidden your toolbars.
 chromelessWindow.warningNoLocation=This web site has hidden your toolbars.
 chromelessWindow.showToolbarsButton=Show Toolbars
 chromelessWindow.accessKey=S
+
+# Identity information
+identity.domainverified.title=Location Verified
+identity.domainverified.body=You are currently visiting:
+identity.domainverified.supplemental=Information identifying the owner of this site may not have been validated.
+
+identity.identified.title=Identity Verified
+identity.identified.body=This website is owned by:
+identity.identified.verifier=Verified by: %S
+identity.identified.state_and_country=%S, %S
+identity.identified.title_with_country=%S (%S)
+
+identity.unknown.title=Identity Unknown
+identity.unknown.body=This web site does not supply identity information.
+
+identity.encrypted=Your connection to this web site is encrypted to prevent eavesdropping.
+identity.unencrypted=Your connection to this web site is not encrypted.
--- a/browser/locales/en-US/chrome/browser/places/places.dtd
+++ b/browser/locales/en-US/chrome/browser/places/places.dtd
@@ -62,16 +62,28 @@
 <!ENTITY cmd.export.label
   "Export...">
 <!ENTITY cmd.export.accesskey
   "E">
 <!ENTITY cmd.import.label
   "Import...">
 <!ENTITY cmd.import.accesskey
   "I">
+<!ENTITY cmd.backup.label
+  "Backup...">
+<!ENTITY cmd.backup.accesskey
+  "B">
+<!ENTITY cmd.restore.label
+  "Restore...">
+<!ENTITY cmd.restore.accesskey
+  "R">
+<!ENTITY cmd.restoreFromFile.label
+  "Choose File...">
+<!ENTITY cmd.restoreFromFile.accesskey
+  "C">
 <!ENTITY cmd.select_all.label
   "Select All">
 <!ENTITY cmd.select_all.accesskey
   "A">
 <!ENTITY cmd.select_all.key
   "a">
 <!ENTITY cmd.edit_cut.label
   "Cut">
--- a/browser/locales/en-US/chrome/browser/places/places.properties
+++ b/browser/locales/en-US/chrome/browser/places/places.properties
@@ -15,16 +15,23 @@ noTitle=(no title)
 localhost=(local files)
 
 bookmarksMenuName=Bookmarks Menu
 bookmarksToolbarName=Bookmarks Toolbar
 bookmarksMenuEmptyFolder=(Empty)
 bookmarksLivemarkLoading=Live Bookmark loading...
 bookmarksLivemarkFailed=Live Bookmark feed failed to load.
 
+bookmarksBackupFilename=Bookmarks %1$S.html
+bookmarksBackupTitle=Bookmarks backup filename
+
+bookmarksRestoreAlertTitle=Revert Bookmarks
+bookmarksRestoreAlert=This will replace all of your current bookmarks with the backup. Are you sure?
+bookmarksRestoreTitle=Select a bookmarks backup
+
 headerTextPrefix1=Showing 
 headerTextPrefix2=Search Results for 
 headerTextPrefix3=Advanced Search
 
 lessCriteria.label=-
 moreCriteria.label=+
 
 menuOpenLivemarkOrigin.label=Open "%S"
new file mode 100755
--- /dev/null
+++ b/browser/locales/en-US/chrome/browser/preferences/applications.dtd
@@ -0,0 +1,17 @@
+<!ENTITY  prefpane.label          "Here you can configure &brandShortName; to let your favorite applications handle different types of content.">
+<!ENTITY  filterActive.label      "The following entries match your search:">
+
+<!ENTITY  typeColumn.label        "Content Type">
+<!ENTITY  typeColumn.accesskey    "T">
+
+<!ENTITY  actionColumn.label      "Application">
+<!ENTITY  actionColumn.accesskey  "A">
+
+<!ENTITY  focusSearch1.key        "f">
+<!ENTITY  focusSearch2.key        "k">
+
+<!ENTITY  filter.label            "Search:">
+<!ENTITY  filter.accesskey        "S">
+
+<!ENTITY  clear.label             "Clear">
+<!ENTITY  clear.accesskey         "l">
deleted file mode 100644
--- a/browser/locales/en-US/chrome/browser/preferences/changeaction.dtd
+++ /dev/null
@@ -1,23 +0,0 @@
-<!ENTITY  changeAction.title                  "Change Action">
-<!ENTITY window.width                         "36em">
-
-<!ENTITY  whenDownloading.label               "When downloading files like this:">
-
-<!ENTITY  openDefault.label                   "Open them with the default application:">
-<!ENTITY  openDefault.accesskey               "O">
-<!ENTITY  openApplication.label               "Open them with this application:">
-<!ENTITY  openApplication.accesskey           "e">
-<!ENTITY  changeApp.label                     "Browse...">
-<!ENTITY  changeApp.accesskey                 "B">
-<!ENTITY  saveToDisk.label                    "Save them on my computer">
-<!ENTITY  saveToDisk.accesskey                "S">
-<!ENTITY  saveToDefaultFolder.label           "in the default download folder">
-<!ENTITY  saveToDefaultFolder.accesskey       "d">
-<!ENTITY  saveToThisFolder.label              "in this folder:">
-<!ENTITY  saveToThisFolder.accesskey          "h">
-<!ENTITY  chooseFolder.label                  "Browse...">
-<!ENTITY  chooseFolder.accesskey              "w">
-<!ENTITY  saveToAskMe.label                   "ask me where to save the file">
-<!ENTITY  saveToAskMe.accesskey               "a">
-<!ENTITY  usePlugin.label                     "Use this Plugin:">
-<!ENTITY  usePlugin.accesskey                 "P">
--- a/browser/locales/en-US/chrome/browser/preferences/connection.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/connection.dtd
@@ -6,17 +6,17 @@
 <!ENTITY  proxyTitle.label              "Configure Proxies to Access the Internet">
 <!ENTITY  directTypeRadio.label         "Direct connection to the Internet">
 <!ENTITY  directTypeRadio.accesskey     "d">
 <!ENTITY  WPADTypeRadio.label           "Auto-detect proxy settings for this network">
 <!ENTITY  WPADTypeRadio.accesskey       "w">
 <!ENTITY  manualTypeRadio.label         "Manual proxy configuration:">
 <!ENTITY  manualTypeRadio.accesskey     "m">
 <!ENTITY  autoTypeRadio.label           "Automatic proxy configuration URL:">
-<!ENTITY  autoTypeRadio.accesskey       "a">
+<!ENTITY  autoTypeRadio.accesskey       "A">
 <!ENTITY  reload.label                  "Reload">
 <!ENTITY  reload.accesskey              "e">
 <!ENTITY  ftp.label                     "FTP Proxy:">
 <!ENTITY  ftp.accesskey                 "F">
 <!ENTITY  gopher.label                  "Gopher Proxy:">
 <!ENTITY  gopher.accesskey              "G">
 <!ENTITY  http.label                    "HTTP Proxy:">
 <!ENTITY  http.accesskey                "y">
--- a/browser/locales/en-US/chrome/browser/preferences/content.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/content.dtd
@@ -24,14 +24,8 @@
 <!ENTITY  defaultSize.label           "Size:">
 <!ENTITY  defaultSize.accesskey       "S">
 
 <!ENTITY  advancedFonts.label         "Advanced...">
 <!ENTITY  advancedFonts.accesskey     "A">
 
 <!ENTITY  colors.label                "Colors...">
 <!ENTITY  colors.accesskey            "C">
-
-<!ENTITY fileTypes.label              "File Types">
-
-<!ENTITY configureFileTypes.label     "Configure how &brandShortName; handles certain types of files">
-<!ENTITY manage.label                 "Manage...">
-<!ENTITY manage.accesskey             "M">
deleted file mode 100644
--- a/browser/locales/en-US/chrome/browser/preferences/downloadactions.dtd
+++ /dev/null
@@ -1,32 +0,0 @@
-<!ENTITY  downloadactionsWindow.title         "Download Actions">
-<!ENTITY window.width                         "480">
-<!ENTITY window.height                        "310">
-
-<!ENTITY  fileTypesDescription.label          "Automatically perform the associated Action with each of the following file types:">
-
-<!ENTITY  fileHandlerColumn.label             "Action">
-<!ENTITY  fileHandlerColumn.accesskey         "A">
-<!ENTITY  fileTypeColumn.label                "File Type">
-<!ENTITY  fileTypeColumn.accesskey            "T">
-<!ENTITY  fileMIMETypeColumn.label            "MIME Type">
-<!ENTITY  fileMIMETypeColumn.accesskey        "M">
-<!ENTITY  fileExtensionColumn.label           "Extension">
-<!ENTITY  fileExtensionColumn.accesskey       "E">
-
-<!ENTITY  remove.label                        "Remove Action">
-<!ENTITY  remove.accesskey                    "R">
-<!ENTITY  edit.label                          "Change Action...">
-<!ENTITY  edit.accesskey                      "C">
-
-<!ENTITY  windowClose.key                     "w">
-<!ENTITY  focusSearch1.key                    "f">
-<!ENTITY  focusSearch2.key                    "k">
-
-<!ENTITY  filter.label                        "Search:">
-<!ENTITY  filter.accesskey                    "S">
-<!ENTITY  clear.label                         "Clear">
-<!ENTITY  clear.accesskey                     "l">
-
-<!ENTITY  button.close.label                  "Close">
-<!ENTITY  button.close.accesskey              "o">
-
deleted file mode 100644
--- a/browser/locales/en-US/chrome/browser/preferences/feeds.dtd
+++ /dev/null
@@ -1,8 +0,0 @@
-<!ENTITY  feedClick.label             "When I click on a web feed:">
-<!ENTITY  showPreview.label           "Show me a preview and ask me which Feed Reader to use">
-<!ENTITY  showPreview.accesskey       "S">
-<!ENTITY  subscribeUsing.label        "Subscribe to the feed using:">
-<!ENTITY  subscribeUsing.accesskey    "u">
-<!ENTITY  liveBookmarks.label         "Live Bookmarks">
-<!ENTITY  chooseApplication.label     "Choose Application...">
-<!ENTITY  chooseApplication.accesskey     "C">
deleted file mode 100644
--- a/browser/locales/en-US/chrome/browser/preferences/feeds.properties
+++ /dev/null
@@ -1,1 +0,0 @@
-noApplicationSelected=No Application Selected
--- a/browser/locales/en-US/chrome/browser/preferences/preferences.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/preferences.dtd
@@ -5,12 +5,12 @@
      Luna since widget heights are different based on the OS theme -->
 <!ENTITY  prefWin.styleWin        "width: 42em; min-height: 44em;">
 <!ENTITY  prefWindow.styleMac     "width: 47em;">
 <!ENTITY  prefWin.styleGNOME      "width: 42em; min-height: 44.5em;">
 
 <!ENTITY  paneMain.title          "Main">
 <!ENTITY  paneTabs.title          "Tabs">
 <!ENTITY  paneContent.title       "Content">
-<!ENTITY  paneFeeds.title         "Feeds">
+<!ENTITY  paneApplications.title  "Applications">
 <!ENTITY  panePrivacy.title       "Privacy">
 <!ENTITY  paneSecurity.title      "Security">
 <!ENTITY  paneAdvanced.title      "Advanced">
--- a/browser/locales/en-US/chrome/browser/preferences/preferences.properties
+++ b/browser/locales/en-US/chrome/browser/preferences/preferences.properties
@@ -38,39 +38,29 @@ languageRegionCodeFormat=%1$S/%2$S  [%3$
 languageCodeFormat=%1$S  [%2$S]
 
 #### Downloads
 
 desktopFolderName=Desktop
 downloadsFolderName=Downloads
 chooseDownloadFolderTitle=Choose Download Folder:
 
-#### Download Actions
+#### Applications
 
-extensionNone=(NONE)
-removeButtonSingle=Remove Action
-removeButtonMultiple=Remove Actions
-removeTitleSingle=Remove Action
-removeTitleMultiple=Remove Actions
-removeMessageSingle=The selected Action will no longer be performed when files of the affected types are downloaded. Are you sure you want to remove this Action?
-removeMessageMultiple=The selected Actions will no longer be performed when files of the affected types are downloaded. Are you sure you want to remove these Actions?
+removeType=Remove this entry...
+removeButton=Remove Entry
+removeTitle=Remove Entry
+removeMessage=If you remove this entry, Firefox will ask you what to do next time you access content of this type.  Are you sure you want to remove this entry?
 fileEnding=%S file
 saveToDisk=Save to Disk
-openWith=Open with %S
-actionsFiltered=The following Actions match your search:
-actionsAll=Automatically perform the associated Action with each of the following file types:
-
-
-#### Change Action
-
-extensionStringFormat=%S, %S
-downloadHelperNoneSelected=None Selected
-pluginHelperNoneAvailable=None Available
+chooseApp=Choose application...
 fpTitleChooseApp=Select Helper Application
-fpTitleChooseDL=Select Download Folder
+webFeed=Web Feed
+alwaysAskAboutFeed=Show me a preview and ask me which Feed Reader to use
+liveBookmarks=Live Bookmarks
 
 #### Cookie Viewer
 
 hostColon=Host:
 domainColon=Domain:
 forSecureOnly=Encrypted connections only
 forAnyConnection=Any type of connection
 AtEndOfSession = at end of session
--- a/browser/locales/jar.mn
+++ b/browser/locales/jar.mn
@@ -40,25 +40,22 @@
 #endif
     locale/browser/feeds/subscribe.dtd              (%chrome/browser/feeds/subscribe.dtd)
     locale/browser/feeds/subscribe.properties       (%chrome/browser/feeds/subscribe.properties)
     locale/browser/history/history.dtd             (%chrome/browser/history/history.dtd)
     locale/browser/migration/migration.dtd         (%chrome/browser/migration/migration.dtd)
     locale/browser/migration/migration.properties  (%chrome/browser/migration/migration.properties)
     locale/browser/preferences/advanced.dtd           (%chrome/browser/preferences/advanced.dtd)
 *   locale/browser/preferences/advanced-scripts.dtd   (%chrome/browser/preferences/advanced-scripts.dtd)
-    locale/browser/preferences/changeaction.dtd       (%chrome/browser/preferences/changeaction.dtd)
     locale/browser/preferences/colors.dtd             (%chrome/browser/preferences/colors.dtd)
     locale/browser/preferences/cookies.dtd            (%chrome/browser/preferences/cookies.dtd)
     locale/browser/preferences/content.dtd            (%chrome/browser/preferences/content.dtd)
     locale/browser/preferences/connection.dtd         (%chrome/browser/preferences/connection.dtd)
-    locale/browser/preferences/downloadactions.dtd    (%chrome/browser/preferences/downloadactions.dtd)
+    locale/browser/preferences/applications.dtd       (%chrome/browser/preferences/applications.dtd)
     locale/browser/preferences/fallbackEULA.dtd       (%chrome/browser/preferences/fallbackEULA.dtd)
-    locale/browser/preferences/feeds.dtd              (%chrome/browser/preferences/feeds.dtd)
-    locale/browser/preferences/feeds.properties       (%chrome/browser/preferences/feeds.properties)
     locale/browser/preferences/fonts.dtd              (%chrome/browser/preferences/fonts.dtd)
     locale/browser/preferences/main.dtd               (%chrome/browser/preferences/main.dtd)
     locale/browser/preferences/languages.dtd          (%chrome/browser/preferences/languages.dtd)
     locale/browser/preferences/permissions.dtd        (%chrome/browser/preferences/permissions.dtd)
     locale/browser/preferences/phishEULA.dtd          (%chrome/browser/preferences/phishEULA.dtd)
     locale/browser/preferences/preferences.dtd        (%chrome/browser/preferences/preferences.dtd)
     locale/browser/preferences/preferences.properties (%chrome/browser/preferences/preferences.properties)
     locale/browser/preferences/privacy.dtd            (%chrome/browser/preferences/privacy.dtd)
--- a/browser/themes/pinstripe/browser/browser.css
+++ b/browser/themes/pinstripe/browser/browser.css
@@ -822,17 +822,17 @@ toolbar[iconsize="small"] #paste-button:
   list-style-image: url("chrome://global/skin/icons/close.gif");
 }
 
 /* ::::: nav-bar-inner ::::: */
 
 #urlbar {
   margin-top: 5px;
   margin-bottom: 5px;
-  -moz-margin-start: 4px;
+  -moz-margin-start: 0px;
   -moz-margin-end: 0px;
   width: 7em;
   min-width: 7em;
   padding: 0px;
   font: icon !important;
 }
 
 .formatted-url {
@@ -874,56 +874,16 @@ toolbar[iconsize="small"] #paste-button:
 #urlbar[level="high"] > .autocomplete-history-dropmarker,
 #urlbar[level="low"] > .autocomplete-history-dropmarker
  {
   margin: -2px;
   padding: 2px 6px;
   background: url("chrome://browser/skin/Secure-background.gif") #FFFED8 repeat-x;
 }
 
-#urlbar #lock-icon {
-  height: 18px;
-  margin: -1px;
-}
-
-#urlbar[level="high"] #lock-icon {
-  list-style-image: url("chrome://browser/skin/Secure.png");
-  -moz-image-region: rect(0px, 18px, 18px, 0px);
-}
-#urlbar[level="high"] #lock-icon:hover {
-  -moz-image-region: rect(18px, 18px, 36px, 0px);
-}
-#urlbar[level="high"] #lock-icon:active {
-  -moz-image-region: rect(36px, 18px, 54px, 0px);
-}
-
-#urlbar[level="low"] #lock-icon {
-  list-style-image: url("chrome://browser/skin/Secure.png");
-  -moz-image-region: rect(0px, 18px, 18px, 0px);
-}
-#urlbar[level="low"] #lock-icon:hover {
-  -moz-image-region: rect(18px, 18px, 36px, 0px);
-}
-#urlbar[level="low"] #lock-icon:active {
-  -moz-image-region: rect(36px, 18px, 54px, 0px);
-}
-
-#urlbar[level="broken"] #lock-icon {
-  list-style-image: url("chrome://browser/skin/Security-broken.png");
-  -moz-image-region: rect(0px, 18px, 18px, 0px);
-}
-
-#urlbar[level="broken"] #lock-icon:hover {
-  -moz-image-region: rect(18px, 18px, 36px, 0px);
-}
-
-#urlbar[level="broken"] #lock-icon:active {
-  -moz-image-region: rect(36px, 18px, 54px, 0px);
-}
-
 #urlbar-container {
   -moz-padding-end: 5px;
 }
 
 #wrapper-urlbar-container #urlbar {
   -moz-user-input: disabled;
   cursor: -moz-grab;
 }
@@ -974,27 +934,26 @@ statusbarpanel#statusbar-display {
 
 .autocomplete-treebody::-moz-tree-image(bookmark, treecolAutoCompleteValue) {
   width: 16px;
   height: 16px;
 }
 
 #treecolAutoCompleteImage {
  max-width : 36px; 
- padding-end: 18px;
 }
 
-.autocomplete-treebody::-moz-tree-image(favicon, treecolAutoCompleteImage) {
-  list-style-image: url("chrome://browser/skin/places/starPage.png");
+.autocomplete-treebody::-moz-tree-image(bookmark, treecolAutoCompleteImage) {
+  list-style-image: url("chrome://browser/skin/places/pageStarred.png");
   width: 16px;
   height: 16px;
 }
 
-.autocomplete-treebody::-moz-tree-image(bookmark, treecolAutoCompleteImage) {
-  list-style-image: url("chrome://browser/skin/places/pageStarred.png");
+.autocomplete-treebody::-moz-tree-image(tag, treecolAutoCompleteImage) {
+  list-style-image: url("chrome://browser/skin/places/tag.png");
   width: 16px;
   height: 16px;
 }
 
 .autocomplete-treebody::-moz-tree-cell-text(treecolAutoCompleteComment) {
   color: #555566;
 }
 
@@ -1698,8 +1657,121 @@ toolbarbutton.bookmark-item[dragover="tr
   border-left: 2px solid;
   border-right: 2px solid;
   border-bottom: 3px solid;
   -moz-border-right-colors: -moz-mac-menushadow ThreeDLightShadow  !important;
   -moz-border-bottom-colors: -moz-mac-menushadow -moz-mac-menushadow ThreeDShadow  !important;
   -moz-border-left-colors: ThreeDLightShadow ThreeDHighlight !important;
 }
 
+/* ::::: Identity Indicator Styling ::::: */
+/* Location bar visuals*/
+#identity-box {
+  /* Extend our margins out so that our highlight/separator bar covers the
+    location bar properly */
+  margin: -1px 0 -2px;
+  padding: 1px 2px 2px 0;
+  border-right: 1px solid #888;
+  background-color: white;
+  opacity: 0.9;
+}
+
+#identity-box:hover {
+  opacity: 1.0;
+}
+
+#identity-box.verifiedIdentity {
+  background-color: #BFA;
+}
+
+#urlbar[level="high"] > #identity-box,
+#urlbar[level="low"] > #identity-box {
+  /* urlbar adds padding when security level is set, which we need to
+  counteract here so that we still fill the background.  */
+  margin: -2px;
+  padding: 1px 2px;
+}
+
+#identity-icon-label {
+    padding: 1px 2px 2px;
+    margin: 0;
+    color: black;
+    vertical-align: middle;
+}
+
+.unknownIdentity > #identity-icon-label {
+    display: none;
+}
+
+/* Popup Icons */
+#identity-popup-icon {
+    height: 64px;
+    width: 64px;
+    padding: 0;
+    margin: 10px 0 0;
+    list-style-image: url("chrome://browser/skin/identity.png");
+    -moz-image-region: rect(0px, 64px, 64px, 0px);
+}
+
+.verifiedDomain > #identity-popup-container > #identity-popup-icon {
+    -moz-image-region: rect(64px, 64px, 128px, 0px);
+}
+
+.verifiedIdentity > #identity-popup-container > #identity-popup-icon {
+    -moz-image-region: rect(128px, 64px, 192px, 0px);
+}
+
+/* Popup Title */
+#identity-popup-title {
+    font-size: 120%;
+    font-weight: bold;
+}
+
+.verifiedIdentity > #identity-popup-title {
+    color: #6A6;
+}
+
+.unknownIdentity > #identity-popup-title {
+    color: #999;
+}
+
+.verifiedDomain > #identity-popup-title {
+    color: black;
+}
+
+/* Popup Body Text */
+#identity-popup-content-box > description,
+#identity-popup-encryption-label {
+    white-space: -moz-pre-wrap;
+    color: black;
+    padding-left: 10px;
+}
+
+#identity-popup-content {
+    padding-top: 5px;
+    margin-bottom: 0;
+    max-width: 200px;
+}
+
+.verifiedIdentity > #identity-popup-content,
+.verifiedDomain > #identity-popup-content {
+   font-size: 140%;
+   font-weight: bold;
+   max-width: 300px;
+}
+
+#identity-popup-encryption {
+  margin: 10px 0;
+}
+
+.verifiedIdentity > #identity-popup-encryption > * > #identity-popup-encryption-icon,
+.verifiedDomain > #identity-popup-encryption > * >#identity-popup-encryption-icon {
+  list-style-image: url("chrome://browser/skin/Secure.png");
+  -moz-image-region: rect(0px, 18px, 18px, 0px);
+}
+
+/* Popup Bounding Box */
+#identity-popup-container {
+    background-image: none;
+    background-color: white;
+    min-width: 280px;
+    padding: 10px;
+}
--- a/browser/themes/pinstripe/browser/jar.mn
+++ b/browser/themes/pinstripe/browser/jar.mn
@@ -5,16 +5,17 @@ classic.jar:
   skin/classic/browser/bookmark-open-mid.png
   skin/classic/browser/bookmark-open-right.png
 * skin/classic/browser/browser.css                          (browser.css)
   skin/classic/browser/browser.xml
 * skin/classic/browser/engineManager.css                    (engineManager.css)
   skin/classic/browser/find.png
   skin/classic/browser/find-bar-background.png
   skin/classic/browser/Go.png
+  skin/classic/browser/identity.png
   skin/classic/browser/Info.png
   skin/classic/browser/page-livemarks.png
   skin/classic/browser/livemark-item.png
   skin/classic/browser/pageInfo.css
   skin/classic/browser/pageInfo.png
   skin/classic/browser/Popup-blocked.png
   skin/classic/browser/searchbar.css
   skin/classic/browser/search-bar-background-mid.png
@@ -43,16 +44,17 @@ classic.jar:
   skin/classic/browser/places/folderDropArrow.png           (places/folderDropArrow.png)
   skin/classic/browser/places/folderDropHoverArrow.png      (places/folderDropHoverArrow.png)
   skin/classic/browser/places/livemarkFolder.png            (places/livemarkFolder.png)
   skin/classic/browser/places/livemarkFolderHover.png       (places/livemarkFolderHover.png)
   skin/classic/browser/places/bookmarkProperties.css        (places/bookmarkProperties.css)
   skin/classic/browser/places/editBookmarkOverlay.css       (places/editBookmarkOverlay.css)
   skin/classic/browser/places/starPage.png                  (places/starPage.png)
   skin/classic/browser/places/pageStarred.png               (places/pageStarred.png)
+  skin/classic/browser/places/tag.png                       (places/tag.png)
   skin/classic/browser/places/organizer-toolbar.png         (bookmarks/Bookmarks-toolbar.png)
   skin/classic/browser/places/expander-closed-active.png    (bookmarks/expander-closed-active.png)
   skin/classic/browser/places/expander-closed.png           (bookmarks/expander-closed.png)
   skin/classic/browser/places/expander-open-active.png      (bookmarks/expander-open-active.png)
   skin/classic/browser/places/expander-open.png             (bookmarks/expander-open.png)
 #ifdef MOZ_SAFE_BROWSING
   skin/classic/browser/safebrowsing/browser-protection.css  (safebrowsing/browser-protection.css)
   skin/classic/browser/safebrowsing/close16x16.png          (safebrowsing/close16x16.png)
new file mode 100755
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..9757fc6ed6597438eb8e5a70a1ab2402cdebd5d1
GIT binary patch
literal 586
zc$@)B0=4~#P)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004XF*Lt006JZ
zHwB960000PbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUz+(|@1R5;6p
zli7+IK@^7TCFVB4w-A~<T_9wVOfEA+67m49DDEgIDsIy~ZaprDn2w^x+%>6YY<vFH
zDX|@K$;G*;I{)|or}{M0bsgPq7wvW%tyT-oW)qsGK~+^W8jULe>{78#rvt}vj%qrc
zN=UU@y$E6COaj9&r1NAlaUpajQlL~SorN%pOwHs*2laYgHBA$?ZOd~4Rw@<b^ZAny
zMy|U?A$}5(4a>5yFm2?1ZIg`0V-$-;<Z`(q2qWiR<jrOS694||;KRc+-rfUQV|zCm
zjVJ}u>GT1Fi5dB7wUSNi^%`^Ge62m>OBeX610Nsukl}DhDG-mxT?nhyYH!4he7Ri8
zrq0Ti&UXUvqX&F@JcJAe14@BNBqAY_QZAPjF(Y3r7P9H_kB#@LgFAf>xz>Qp&n=|a
z>ro1XLZK^nmO`PRh#C2OK0ktd7l6-A;O5?fz1gNnCX)yR0<RBVRLrMjvspfy&0NSk
z0r@0GxNWUrT2C*<9(RP7mC0n3R4T=36A7XV$Zgw!W$&H+e!s_k#8b<WNF<b4EXHXQ
zcb}NV;`~5-7C;q^M!n*tIW1Vf-#;n72%rjw!`@&p$Vu$;`8+3A`G3EwaP<oDt8@4N
Y09wpC?6mZIDF6Tf07*qoM6N<$f_O;+EC2ui
--- a/browser/themes/pinstripe/browser/preferences/preferences.css
+++ b/browser/themes/pinstripe/browser/preferences/preferences.css
@@ -109,24 +109,24 @@ radio[pane=paneContent] {
 }
 
 radio[pane=paneContent]:hover,
 radio[pane=paneContent]:active,
 radio[pane=paneContent][selected="true"] {
 	-moz-image-region: rect(32px, 96px, 64px, 64px);
 }
 
-/* ----- FEEDS BUTTON ----- */
+/* ----- APPLICATIONS BUTTON ----- */
 
-radio[pane=paneFeeds] {
+radio[pane=paneApplications] {
 	-moz-image-region: rect(0px, 128px, 32px, 96px);
 }
-radio[pane=paneFeeds]:hover,
-radio[pane=paneFeeds]:active,
-radio[pane=paneFeeds][selected="true"] {
+radio[pane=paneApplications]:hover,
+radio[pane=paneApplications]:active,
+radio[pane=paneApplications][selected="true"] {
 	-moz-image-region: rect(32px, 128px, 64px, 96px);
 }
 
 /* ----- PRIVACY BUTTON ----- */
 
 radio[pane=panePrivacy] {
 	-moz-image-region: rect(0px, 160px, 32px, 128px);
 }
@@ -271,16 +271,8 @@ caption {
  */
 #autoInstallOptions {
   -moz-margin-start: 20px;
 }
 
 .updateControls {
   -moz-margin-start: 10px;
 }
-
-
-/**
- * Feeds pane
- */
-#chooseClientAppCell {
-  -moz-padding-end: 12px;
-}
--- a/browser/themes/winstripe/browser/browser.css
+++ b/browser/themes/winstripe/browser/browser.css
@@ -845,17 +845,17 @@ toolbar[iconsize="small"] #paste-button:
 }
 
 /* ::::: nav-bar-inner ::::: */
 
 #urlbar {
   margin-bottom: 2px;
   margin-top: 2px;
   -moz-margin-end: 0px;
-  -moz-margin-start: 3px;
+  -moz-margin-start: 0px;
   width: 7em;
   min-width: 7em;
 
   -moz-appearance: none;
   -moz-border-top-colors: #96969D;
   -moz-border-bottom-colors: #96969D;
   -moz-border-right-colors: #96969D;
   -moz-border-left-colors: #96969D;
@@ -967,27 +967,26 @@ statusbarpanel#statusbar-display {
 
 .autocomplete-treebody::-moz-tree-image(bookmark, treecolAutoCompleteValue) {
   width: 16px;
   height: 16px;
 }
 
 #treecolAutoCompleteImage {
  max-width : 36px; 
- padding-end: 18px;
 }
 
-.autocomplete-treebody::-moz-tree-image(favicon, treecolAutoCompleteImage) {
-  list-style-image: url("chrome://browser/skin/places/starPage.png");
+.autocomplete-treebody::-moz-tree-image(bookmark, treecolAutoCompleteImage) {
+  list-style-image: url("chrome://browser/skin/places/pageStarred.png");
   width: 16px;
   height: 16px;
 }
 
-.autocomplete-treebody::-moz-tree-image(bookmark, treecolAutoCompleteImage) {
-  list-style-image: url("chrome://browser/skin/places/pageStarred.png");
+.autocomplete-treebody::-moz-tree-image(tag, treecolAutoCompleteImage) {
+  list-style-image: url("chrome://browser/skin/places/tag.png");
   width: 16px;
   height: 16px;
 }
 
 .autocomplete-treebody::-moz-tree-cell-text(treecolAutoCompleteComment) {
   color: #555566;
 }
 
@@ -1805,53 +1804,16 @@ toolbar[mode="text"] > #window-controls 
 }
 
 #urlbar[level="high"] > .autocomplete-textbox-container,
 #urlbar[level="low"] > .autocomplete-textbox-container {
   background-color: #F5F6BE; /* #F7F898; */
   color: #000000;
 }
 
-#urlbar[level="high"] #lock-icon {
-  -moz-image-region: rect(0px, 18px, 18px, 0px);
-  list-style-image: url("chrome://browser/skin/Secure.png");
-}
-#urlbar[level="high"] #lock-icon:hover {
-  -moz-image-region: rect(18px, 18px, 36px, 0px);
-  list-style-image: url("chrome://browser/skin/Secure.png");
-}
-#urlbar[level="high"] #lock-icon:active {
-  -moz-image-region: rect(36px, 18px, 54px, 0px);
-  list-style-image: url("chrome://browser/skin/Secure.png");
-}
-#urlbar[level="low"] #lock-icon {
-  -moz-image-region: rect(0px, 18px, 18px, 0px);
-  list-style-image: url("chrome://browser/skin/Secure.png");
-}
-#urlbar[level="low"] #lock-icon:hover {
-  -moz-image-region: rect(18px, 18px, 36px, 0px);
-  list-style-image: url("chrome://browser/skin/Secure.png");
-}
-#urlbar[level="low"] #lock-icon:active {
-  -moz-image-region: rect(36px, 18px, 54px, 0px);
-  list-style-image: url("chrome://browser/skin/Secure.png");
-}
-#urlbar[level="broken"] #lock-icon {
-  -moz-image-region: rect(0px, 18px, 18px, 0px);
-  list-style-image: url("chrome://browser/skin/Security-broken.png");
-}
-#urlbar[level="broken"] #lock-icon:hover {
-  -moz-image-region: rect(18px, 18px, 36px, 0px);
-  list-style-image: url("chrome://browser/skin/Security-broken.png");
-}
-#urlbar[level="broken"] #lock-icon:active {
-  -moz-image-region: rect(36px, 18px, 54px, 0px);
-  list-style-image: url("chrome://browser/skin/Security-broken.png");
-}
-
 %ifdef MOZ_WIDGET_GTK2
 #urlbar > .autocomplete-textbox-container {
   -moz-binding: url(chrome://browser/skin/browser.xml#autocomplete-security-wrapper);
 }
 
 #autocomplete-security-wrapper {
   -moz-box-align: center;
 }
@@ -1954,8 +1916,110 @@ toolbarbutton.bookmark-item[dragover="tr
 
 .bookmark-item[dragover-top="true"] {
   -moz-border-top-colors: #000000;
 }
 
 .bookmark-item[dragover-bottom="true"] {
   -moz-border-bottom-colors: #000000;
 }
+
+/* ::::: Identity Indicator Styling ::::: */
+/* Location bar visuals*/
+#identity-box {
+  border-right: 1px solid #888;
+  background-color: white;
+  opacity: 0.9;
+}
+
+#identity-box:hover {
+  opacity: 1.0;
+}
+
+#identity-box.verifiedIdentity {
+  background-color: #BFA;
+}
+
+#identity-icon-label {
+    padding: 1px 2px 2px;
+    margin: 0;
+    color: black;
+    vertical-align: middle;
+}
+
+.unknownIdentity > #identity-icon-label {
+    display: none;
+}
+
+/* Popup Icons */
+#identity-popup-icon {
+    height: 64px;
+    width: 64px;
+    padding: 0;
+    margin: 10px 0 0;
+    list-style-image: url("chrome://browser/skin/identity.png");
+    -moz-image-region: rect(0px, 64px, 64px, 0px);
+}
+
+.verifiedDomain > #identity-popup-container > #identity-popup-icon {
+    -moz-image-region: rect(64px, 64px, 128px, 0px);
+}
+
+.verifiedIdentity > #identity-popup-container > #identity-popup-icon {
+    -moz-image-region: rect(128px, 64px, 192px, 0px);
+}
+
+/* Popup Title */
+#identity-popup-title {
+    font-size: 120%;
+    font-weight: bold;
+}
+
+.verifiedIdentity > #identity-popup-title {
+    color: #6A6;
+}
+
+.unknownIdentity > #identity-popup-title {
+    color: #999;
+}
+
+.verifiedDomain > #identity-popup-title {
+    color: black;
+}
+
+/* Popup Body Text */
+#identity-popup-content-box > description,
+#identity-popup-encryption-label {
+    white-space: -moz-pre-wrap;
+    color: black;
+    padding-left: 10px;
+}
+
+#identity-popup-content {
+    padding-top: 5px;
+    margin-bottom: 0;
+    max-width: 200px;
+}
+
+.verifiedIdentity > #identity-popup-content,
+.verifiedDomain > #identity-popup-content {
+   font-size: 140%;
+   font-weight: bold;
+   max-width: 300px;
+}
+
+#identity-popup-encryption {
+  margin: 10px 0;
+}
+
+.verifiedIdentity > #identity-popup-encryption > * > #identity-popup-encryption-icon,
+.verifiedDomain > #identity-popup-encryption > * >#identity-popup-encryption-icon {
+  list-style-image: url("chrome://browser/skin/Secure.png");
+  -moz-image-region: rect(0px, 18px, 18px, 0px);
+}
+
+/* Popup Bounding Box */
+#identity-popup-container {
+    background-image: none;
+    background-color: white;
+    min-width: 280px;
+    padding: 10px;
+}
--- a/browser/themes/winstripe/browser/jar.mn
+++ b/browser/themes/winstripe/browser/jar.mn
@@ -1,14 +1,15 @@
 classic.jar:
 % skin browser classic/1.0 %skin/classic/browser/
 *       skin/classic/browser/browser.css                        (browser.css)
         skin/classic/browser/browser.xml
 *       skin/classic/browser/engineManager.css                  (engineManager.css)
         skin/classic/browser/Info.png
+        skin/classic/browser/identity.png
         skin/classic/browser/pageInfo.css
         skin/classic/browser/pageInfo.png
         skin/classic/browser/page-livemarks.png
         skin/classic/browser/livemark-item.png
         skin/classic/browser/livemark-item-rtl.png
         skin/classic/browser/livemark-folder.png
         skin/classic/browser/livemark-folder-rtl.png
         skin/classic/browser/Secure.png
@@ -49,16 +50,17 @@ classic.jar:
         skin/classic/browser/places/livemarkItem.png            (places/livemarkItem.png)
         skin/classic/browser/places/bookmarksMenu.png           (places/bookmarksMenu.png)
         skin/classic/browser/places/bookmarksToolbar.png        (places/bookmarksToolbar.png)
         skin/classic/browser/places/toolbarDropMarker.png       (places/toolbarDropMarker.png)
         skin/classic/browser/places/folderDragOver.png          (places/folderDragOver.png)
         skin/classic/browser/places/editBookmarkOverlay.css     (places/editBookmarkOverlay.css)
         skin/classic/browser/places/starPage.png                (places/starPage.png)
         skin/classic/browser/places/pageStarred.png             (places/pageStarred.png)
+        skin/classic/browser/places/tag.png                     (places/tag.png)
         skin/classic/browser/places/bookmarkProperties.css      (places/bookmarkProperties.css)
         skin/classic/browser/places/organizer-toolbar.png       (bookmarks/Bookmarks-toolbar.png)
 #ifdef MOZ_SAFE_BROWSING
         skin/classic/browser/safebrowsing/browser-protection.css      (safebrowsing/browser-protection.css)
         skin/classic/browser/safebrowsing/close16x16.png              (safebrowsing/close16x16.png)
         skin/classic/browser/safebrowsing/dim.png                     (safebrowsing/dim.png)
         skin/classic/browser/safebrowsing/tail.png                    (safebrowsing/tail.png)
         skin/classic/browser/safebrowsing/warning16x16.png            (safebrowsing/warning16x16.png)
new file mode 100755
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..9757fc6ed6597438eb8e5a70a1ab2402cdebd5d1
GIT binary patch
literal 586
zc$@)B0=4~#P)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004XF*Lt006JZ
zHwB960000PbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUz+(|@1R5;6p
zli7+IK@^7TCFVB4w-A~<T_9wVOfEA+67m49DDEgIDsIy~ZaprDn2w^x+%>6YY<vFH
zDX|@K$;G*;I{)|or}{M0bsgPq7wvW%tyT-oW)qsGK~+^W8jULe>{78#rvt}vj%qrc
zN=UU@y$E6COaj9&r1NAlaUpajQlL~SorN%pOwHs*2laYgHBA$?ZOd~4Rw@<b^ZAny
zMy|U?A$}5(4a>5yFm2?1ZIg`0V-$-;<Z`(q2qWiR<jrOS694||;KRc+-rfUQV|zCm
zjVJ}u>GT1Fi5dB7wUSNi^%`^Ge62m>OBeX610Nsukl}DhDG-mxT?nhyYH!4he7Ri8
zrq0Ti&UXUvqX&F@JcJAe14@BNBqAY_QZAPjF(Y3r7P9H_kB#@LgFAf>xz>Qp&n=|a
z>ro1XLZK^nmO`PRh#C2OK0ktd7l6-A;O5?fz1gNnCX)yR0<RBVRLrMjvspfy&0NSk
z0r@0GxNWUrT2C*<9(RP7mC0n3R4T=36A7XV$Zgw!W$&H+e!s_k#8b<WNF<b4EXHXQ
zcb}NV;`~5-7C;q^M!n*tIW1Vf-#;n72%rjw!`@&p$Vu$;`8+3A`G3EwaP<oDt8@4N
Y09wpC?6mZIDF6Tf07*qoM6N<$f_O;+EC2ui
--- a/browser/themes/winstripe/browser/preferences/preferences.css
+++ b/browser/themes/winstripe/browser/preferences/preferences.css
@@ -62,21 +62,21 @@ radio[pane=paneTabs][selected="true"] {
 radio[pane=paneContent] {
 	-moz-image-region: rect(0px, 96px,  32px, 64px)
 }
 radio[pane=paneContent]:hover, 
 radio[pane=paneContent][selected="true"]  {
 	-moz-image-region: rect(32px, 96px,  64px, 64px)
 }
 
-radio[pane=paneFeeds] {
+radio[pane=paneApplications] {
 	-moz-image-region: rect(0px, 128px,  32px, 96px)
 }
-radio[pane=paneFeeds]:hover, 
-radio[pane=paneFeeds][selected="true"]  {
+radio[pane=paneApplications]:hover, 
+radio[pane=paneApplications][selected="true"]  {
 	-moz-image-region: rect(32px, 128px,  64px, 96px)
 }
 
 radio[pane=panePrivacy] {
 	-moz-image-region: rect(0px, 160px,  32px, 128px)
 }
 radio[pane=panePrivacy]:hover, 
 radio[pane=panePrivacy][selected="true"]  {
@@ -186,87 +186,13 @@ filefield[disabled="true"] .fileFieldIco
 #cookieInfoBox textbox {
   background-color: transparent;
 }
 
 #cookieInfoGrid {
   background-color: #E9E7E3; 
 }
 
-/* Download Actions Manager */
-#fileExtension {
-  width: 5em; 
-}
-
-#extensionChildren::-moz-tree-image(fileExtension) {
-  margin: 0px 5px 0px 0px;
-}
-
-#typeField {
-  font-weight: bold; 
-}
-
-/* Change Action Dialog */
-#typeIcon {
-  width: 32px;
-  height: 32px;
-  -moz-margin-end: 3px;
-}
-
-#typeField {
-  background-color: transparent;
-  margin-top: 1px !important;
-  margin-bottom: 2px !important;
-  -moz-margin-start: 6px !important;
-  -moz-margin-end: 5px !important;
-}
-
-#extensionField {
-  color: GrayText;
-  font-weight: bold;
-}
-#ChangeActionDialog {
-  padding: 0px;
-}
-
-#ChangeActionDialog .dialog-button-box {
-  padding-top: 8px;
-  padding-bottom: 10px;
-  -moz-padding-start: 8px;
-  -moz-padding-end: 10px;  
-}
-
-#changeActionHeader {
-  border-bottom: 2px groove ThreeDFace;
-  margin: 0px;
-  padding: 10px;
-  background-color: -moz-Field;
-  color: -moz-FieldText;  
-}
-
-#changeActionContent {
-  padding-top: 8px;
-  padding-bottom: 10px;
-  -moz-padding-start: 9px;
-  -moz-padding-end: 10px;
-}
-
-#defaultAppIcon {
-  width: 16px;
-  height: 16px;
-  -moz-margin-start: 2px;
-}
-
-#defaultAppName {
-  -moz-margin-start: 6px !important; 
-  font-weight: bold;
-}
-
-/* Feeds pane */
-#chooseClientAppCell {
-  -moz-padding-end: 12px;
-}
-
 /* bottom-most box containing a groupbox in a prefpane. Prevents the bottom
    of the groupbox from being cutoff */
 .bottomBox {
   padding-bottom: 4px;
 }
--- a/caps/include/nsScriptSecurityManager.h
+++ b/caps/include/nsScriptSecurityManager.h
@@ -540,35 +540,39 @@ private:
     /**
      * Utility method for comparing two URIs.  For security purposes, two URIs
      * are equivalent if their schemes, hosts, and ports (if any) match.  This
      * method returns true if aSubjectURI and aObjectURI have the same origin,
      * false otherwise.
      */
     PRBool SecurityCompareURIs(nsIURI* aSourceURI, nsIURI* aTargetURI);
 
+    /* encapsulate the file comparison rules */
+    PRBool SecurityCompareFileURIs(nsIURI* aSourceURI, nsIURI* aTargetURI);
+
 #ifdef XPC_IDISPATCH_SUPPORT
     // While this header is included outside of caps, this class isn't 
     // referenced so this should be fine.
     nsresult
     CheckComponentPermissions(JSContext *cx, const nsCID &aCID);
 #endif
 #ifdef DEBUG_CAPS_HACKER
     void
     PrintPolicyDB();
 #endif
 
     // JS strings we need to clean up on shutdown
     static jsval sEnabledID;
 
     inline void
-    JSEnabledPrefChanged(nsISecurityPref* aSecurityPref);
+    ScriptSecurityPrefChanged();
 
     static const char sJSEnabledPrefName[];
     static const char sJSMailEnabledPrefName[];
+    static const char sFileOriginPolicyPrefName[];
 
     nsObjectHashtable* mOriginToPolicyMap;
     DomainPolicy* mDefaultPolicy;
     nsObjectHashtable* mCapabilities;
 
     nsCOMPtr<nsIPrefBranch> mPrefBranch;
     nsCOMPtr<nsISecurityPref> mSecurityPref;
     nsCOMPtr<nsIPrincipal> mSystemPrincipal;
@@ -578,16 +582,29 @@ private:
     PRPackedBool mIsJavaScriptEnabled;
     PRPackedBool mIsMailJavaScriptEnabled;
     PRPackedBool mIsWritingPrefs;
     PRPackedBool mPolicyPrefsChanged;
 #ifdef XPC_IDISPATCH_SUPPORT    
     PRPackedBool mXPCDefaultGrantAll;
     static const char sXPCDefaultGrantAllName[];
 #endif
+    PRInt32 mFileURIOriginPolicy;
 
     static nsIIOService    *sIOService;
     static nsIXPConnect    *sXPConnect;
     static nsIStringBundle *sStrBundle;
     static JSRuntime       *sRuntime;
 };
 
+// Levels for file: URI same-origin policy:
+//   self:        same-origin only with itself
+//   samedir:     same-origin with files having the same path
+//   subdir:      same-origin with files having longer paths (asymetric)
+//   anyfile:     same-origin with any other file: URI (but not directories)
+//   traditional: any local file, any directory
+#define FILEURI_SOP_SELF        0
+#define FILEURI_SOP_SAMEDIR     1
+#define FILEURI_SOP_SUBDIR      2
+#define FILEURI_SOP_ANYFILE     3
+#define FILEURI_SOP_TRADITIONAL 4
+
 #endif // nsScriptSecurityManager_h__
--- a/caps/src/nsScriptSecurityManager.cpp
+++ b/caps/src/nsScriptSecurityManager.cpp
@@ -60,16 +60,17 @@
 #include "nsIXPConnect.h"
 #include "nsIXPCSecurityManager.h"
 #include "nsTextFormatter.h"
 #include "nsIStringBundle.h"
 #include "nsNetUtil.h"
 #include "nsIProperties.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsIFile.h"
+#include "nsIFileURL.h"
 #include "nsIZipReader.h"
 #include "nsIJAR.h"
 #include "nsIPluginInstance.h"
 #include "nsIXPConnect.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsPIDOMWindow.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeItem.h"
@@ -263,105 +264,176 @@ nsScriptSecurityManager::SecurityCompare
 
     if (!aTargetURI || !aSourceURI) 
     {
         return PR_FALSE;
     }
 
     // If either URI is a nested URI, get the base URI
     nsCOMPtr<nsIURI> sourceBaseURI = NS_GetInnermostURI(aSourceURI);
-    
     nsCOMPtr<nsIURI> targetBaseURI = NS_GetInnermostURI(aTargetURI);
 
     if (!sourceBaseURI || !targetBaseURI)
         return PR_FALSE;
 
     // Compare schemes
     nsCAutoString targetScheme;
-    nsresult rv = targetBaseURI->GetScheme(targetScheme);
-    nsCAutoString sourceScheme;
-    if (NS_SUCCEEDED(rv))
-        rv = sourceBaseURI->GetScheme(sourceScheme);
-    if (NS_FAILED(rv) || !targetScheme.Equals(sourceScheme)) {
+    PRBool sameScheme = PR_FALSE;
+    if (NS_FAILED( targetBaseURI->GetScheme(targetScheme) ) ||
+        NS_FAILED( sourceBaseURI->SchemeIs(targetScheme.get(), &sameScheme) ) ||
+        !sameScheme)
+    {
+        // Not same-origin if schemes differ
         return PR_FALSE;
     }
-    
+
+    // special handling for file: URIs
     if (targetScheme.EqualsLiteral("file"))
-    {
-        // All file: urls are considered to have the same origin.
-        return  PR_TRUE;
-    }
-
+        return SecurityCompareFileURIs( sourceBaseURI, targetBaseURI );
+
+    // Special handling for mailnews schemes
     if (targetScheme.EqualsLiteral("imap") ||
         targetScheme.EqualsLiteral("mailbox") ||
         targetScheme.EqualsLiteral("news"))
     {
         // Each message is a distinct trust domain; use the 
         // whole spec for comparison
         nsCAutoString targetSpec;
-        if (NS_FAILED(targetBaseURI->GetSpec(targetSpec)))
-            return PR_FALSE;
         nsCAutoString sourceSpec;
-        if (NS_FAILED(sourceBaseURI->GetSpec(sourceSpec)))
-            return PR_FALSE;
-        return targetSpec.Equals(sourceSpec);
+        return ( NS_SUCCEEDED( targetBaseURI->GetSpec(targetSpec) ) &&
+                 NS_SUCCEEDED( sourceBaseURI->GetSpec(sourceSpec) ) &&
+                 targetSpec.Equals(sourceSpec) );
     }
 
     // Compare hosts
     nsCAutoString targetHost;
-    rv = targetBaseURI->GetHost(targetHost);
     nsCAutoString sourceHost;
-    if (NS_SUCCEEDED(rv))
-        rv = sourceBaseURI->GetHost(sourceHost);
-    if (NS_FAILED(rv) ||
-        !targetHost.Equals(sourceHost, nsCaseInsensitiveCStringComparator())) {
+    if (NS_FAILED( targetBaseURI->GetHost(targetHost) ) ||
+        NS_FAILED( sourceBaseURI->GetHost(sourceHost) ) ||
+        !targetHost.Equals(sourceHost, nsCaseInsensitiveCStringComparator()))
+    {
+        // Not same-origin if hosts differ
         return PR_FALSE;
     }
-    
+
     // Compare ports
     PRInt32 targetPort;
-    rv = targetBaseURI->GetPort(&targetPort);
+    nsresult rv = targetBaseURI->GetPort(&targetPort);
     PRInt32 sourcePort;
     if (