merge with m-c. resolved conflicts in:
authorDoug Turner <dougt@dougt.org>
Tue, 11 May 2010 11:09:54 -0700
changeset 46846 22343803fc8448a8e06d3ccdc1602315e4e99bb1
parent 46845 31d2d548061a057a164fc8270b97fab32be005ef (current diff)
parent 42156 d67ddb92a98c53fd5d41515030ce2ff799e62334 (diff)
child 46847 af5bfcdaba4e25dede848f5ff63d795e5092c0c8
push idunknown
push userunknown
push dateunknown
milestone1.9.3a5pre
merge with m-c. resolved conflicts in: U chrome/src/nsChromeRegistry.cpp U content/base/src/Makefile.in U dom/base/nsDOMClassInfo.cpp U toolkit/toolkit-tiers.mk
browser/app/profile/firefox.js
browser/components/places/content/toolbar.xml
browser/fuel/test/browser_Extensions.js
build/automation.py.in
caps/src/nsScriptSecurityManager.cpp
chrome/src/nsChromeRegistry.cpp
configure.in
content/base/public/Makefile.in
content/base/public/nsContentUtils.h
content/base/src/Makefile.in
content/base/src/nsContentUtils.cpp
content/base/src/nsObjectLoadingContent.cpp
content/base/src/nsScriptLoader.cpp
content/canvas/src/nsCanvasRenderingContext2D.cpp
content/html/content/src/nsGenericHTMLElement.cpp
content/media/ogg/nsOggDecoder.cpp
content/media/ogg/nsOggPlayStateMachine.cpp
content/media/ogg/nsOggPlayStateMachine.h
content/media/ogg/nsOggReader.cpp
content/media/ogg/nsOggReader.h
content/xul/content/src/nsXULElement.cpp
content/xul/content/src/nsXULElement.h
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfoID.h
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
dom/base/nsJSEnvironment.cpp
dom/plugins/PPluginInstance.ipdl
dom/plugins/PluginInstanceChild.cpp
dom/plugins/PluginInstanceParent.cpp
dom/plugins/PluginInstanceParent.h
dom/plugins/PluginModuleChild.cpp
dom/plugins/PluginModuleChild.h
dom/plugins/PluginModuleParent.cpp
embedding/components/windowwatcher/public/nsINonBlockingAlertService.idl
gfx/cairo/libpixman/src/pixman-arm-neon.h
gfx/cairo/libpixman/src/pixman-arm-simd-asm.c
gfx/cairo/libpixman/src/pixman-arm-simd-asm.h
gfx/cairo/libpixman/src/pixman-arm-simd.h
gfx/cairo/libpixman/src/pixman-compose-accessors.c
gfx/cairo/libpixman/src/pixman-compose.c
gfx/cairo/libpixman/src/pixman-compute-region.c
gfx/cairo/libpixman/src/pixman-mmx.h
gfx/cairo/libpixman/src/pixman-pict.c
gfx/cairo/libpixman/src/pixman-source.c
gfx/cairo/libpixman/src/pixman-sse2.h
gfx/cairo/libpixman/src/pixman-transformed-accessors.c
gfx/cairo/libpixman/src/pixman-transformed.c
gfx/cairo/libpixman/src/pixman-vmx.h
gfx/cairo/libpixman/src/pixman-wce-arm-simd.asm
gfx/src/thebes/nsThebesDeviceContext.cpp
ipc/glue/RPCChannel.h
ipc/ipdl/ipdl/lower.py
js/src/jsapi.cpp
js/src/jsapi.h
js/src/tests/js1_5/extensions/regress-220584.js
js/src/tests/js1_5/extensions/regress-312278.js
js/src/tests/js1_5/extensions/regress-452372.js
js/src/tests/js1_7/extensions/regress-355578.js
js/src/trace-test/tests/basic/bug533705.js
js/src/trace-test/tests/basic/testBug532363.js
js/src/xpconnect/shell/xpcshell.cpp
js/src/xpconnect/src/xpcthreadcontext.cpp
js/src/xpconnect/tests/js/old/threads.js
layout/base/nsPresContext.cpp
layout/mathml/mathml-css.pl
modules/plugin/base/src/nsPluginHost.cpp
modules/plugin/default/mac/DefaultPlugin.mm
modules/plugin/default/mac/DefaultPlugin.xcodeproj/project.pbxproj
modules/plugin/default/mac/English.lproj/InfoPlist.strings
modules/plugin/default/mac/Makefile.in
modules/plugin/default/os2/Makefile.in
modules/plugin/default/os2/dbg.cpp
modules/plugin/default/os2/dbg.h
modules/plugin/default/os2/dialogs.cpp
modules/plugin/default/os2/dialogs.h
modules/plugin/default/os2/maindll.cpp
modules/plugin/default/os2/npnulos2.h
modules/plugin/default/os2/npnulos2.ico
modules/plugin/default/os2/npnulos2.rc
modules/plugin/default/os2/npos2.cpp
modules/plugin/default/os2/npshell.cpp
modules/plugin/default/os2/plugin.cpp
modules/plugin/default/os2/plugin.h
modules/plugin/default/os2/utils.cpp
modules/plugin/default/os2/utils.h
modules/plugin/default/unix/Makefile.in
modules/plugin/default/unix/npshell.c
modules/plugin/default/unix/npunix.c
modules/plugin/default/unix/nullplugin.c
modules/plugin/default/unix/nullplugin.h
modules/plugin/default/windows/Makefile.in
modules/plugin/default/windows/Npnul32.dsp
modules/plugin/default/windows/dbg.cpp
modules/plugin/default/windows/dbg.h
modules/plugin/default/windows/dialogs.cpp
modules/plugin/default/windows/dialogs.h
modules/plugin/default/windows/maindll.cpp
modules/plugin/default/windows/npnul32.def
modules/plugin/default/windows/npnul32.dsw
modules/plugin/default/windows/npnul32.rc
modules/plugin/default/windows/npshell.cpp
modules/plugin/default/windows/npwin.cpp
modules/plugin/default/windows/plugicon.ico
modules/plugin/default/windows/plugin.cpp
modules/plugin/default/windows/plugin.h
modules/plugin/default/windows/resource.h
modules/plugin/default/windows/utils.cpp
modules/plugin/default/windows/utils.h
modules/plugin/test/mochitest/Makefile.in
modules/plugin/test/testplugin/nptest.cpp
modules/plugin/test/testplugin/nptest_gtk2.cpp
netwerk/base/src/nsIOService.cpp
netwerk/cookie/src/nsCookieService.cpp
netwerk/protocol/http/src/nsHttpChannel.cpp
netwerk/protocol/http/src/nsHttpHandler.cpp
netwerk/protocol/http/src/nsHttpHeaderArray.h
netwerk/protocol/http/src/nsHttpResponseHead.h
testing/mochitest/tests/FakeJSAN.js
testing/mochitest/tests/cli.js
testing/mochitest/tests/standalone.js
testing/mochitest/tests/test_Base.js
testing/mochitest/tests/test_Color.js
testing/mochitest/tests/test_DateTime.js
testing/mochitest/tests/test_DragAndDrop.js
testing/mochitest/tests/test_Format.js
testing/mochitest/tests/test_Iter.js
testing/mochitest/tests/test_Logging.js
testing/mochitest/tests/test_MochiKit-Async.html
testing/mochitest/tests/test_MochiKit-Async.json
testing/mochitest/tests/test_MochiKit-Base.html
testing/mochitest/tests/test_MochiKit-Color.html
testing/mochitest/tests/test_MochiKit-DOM.html
testing/mochitest/tests/test_MochiKit-DateTime.html
testing/mochitest/tests/test_MochiKit-DragAndDrop.html
testing/mochitest/tests/test_MochiKit-Format.html
testing/mochitest/tests/test_MochiKit-Iter.html
testing/mochitest/tests/test_MochiKit-JSAN.html
testing/mochitest/tests/test_MochiKit-Logging.html
testing/mochitest/tests/test_MochiKit-MochiKit.html
testing/mochitest/tests/test_MochiKit-Signal.html
testing/mochitest/tests/test_MochiKit-Style.html
testing/mochitest/tests/test_MochiKit-Visual.html
testing/mochitest/tests/test_Signal.js
toolkit/crashreporter/nsExceptionHandler.cpp
toolkit/library/libxul-config.mk
toolkit/mozapps/extensions/nsExtensionManager.js
toolkit/mozapps/extensions/nsIExtensionManager.idl
toolkit/mozapps/extensions/test/addons/test_bug257155/install.rdf
toolkit/mozapps/extensions/test/addons/test_bug378216_1/install.rdf
toolkit/mozapps/extensions/test/addons/test_bug378216_10/install.rdf
toolkit/mozapps/extensions/test/addons/test_bug378216_11/install.rdf
toolkit/mozapps/extensions/test/addons/test_bug378216_12/install.rdf
toolkit/mozapps/extensions/test/addons/test_bug378216_13/install.rdf
toolkit/mozapps/extensions/test/addons/test_bug378216_2/install.rdf
toolkit/mozapps/extensions/test/addons/test_bug378216_3/install.rdf
toolkit/mozapps/extensions/test/addons/test_bug378216_4/install.rdf
toolkit/mozapps/extensions/test/addons/test_bug378216_5/install.rdf
toolkit/mozapps/extensions/test/addons/test_bug378216_6/install.rdf
toolkit/mozapps/extensions/test/addons/test_bug378216_7/install.rdf
toolkit/mozapps/extensions/test/addons/test_bug378216_8/install.rdf
toolkit/mozapps/extensions/test/addons/test_bug378216_9/install.rdf
toolkit/mozapps/extensions/test/addons/test_bug392180/install.rdf
toolkit/mozapps/extensions/test/addons/test_bug396129_a_1/install.rdf
toolkit/mozapps/extensions/test/addons/test_bug396129_a_2/install.rdf
toolkit/mozapps/extensions/test/addons/test_bug396129_b_1/install.rdf
toolkit/mozapps/extensions/test/addons/test_bug396129_b_2/install.rdf
toolkit/mozapps/extensions/test/addons/test_bug396129_c_1/install.rdf
toolkit/mozapps/extensions/test/addons/test_bug396129_c_2/install.rdf
toolkit/mozapps/extensions/test/addons/test_bug396129_d_1/install.rdf
toolkit/mozapps/extensions/test/addons/test_bug396129_d_2/install.rdf
toolkit/mozapps/extensions/test/addons/test_bug428341_1/README
toolkit/mozapps/extensions/test/addons/test_bug428341_2/install.rdf
toolkit/mozapps/extensions/test/addons/test_bug428341_3/install.rdf
toolkit/mozapps/extensions/test/addons/test_bug428341_4/install.rdf
toolkit/mozapps/extensions/test/addons/test_bug428341_5/install.rdf
toolkit/mozapps/extensions/test/addons/test_bug428341_6/install.rdf
toolkit/mozapps/extensions/test/addons/test_bug428341_7/install.rdf
toolkit/mozapps/extensions/test/addons/test_bug428341_8/install.rdf
toolkit/mozapps/extensions/test/addons/test_bug428341_9/install.rdf
toolkit/mozapps/extensions/test/addons/test_bug436207/install.js
toolkit/mozapps/extensions/test/browser/browser_bug510909.js
toolkit/mozapps/extensions/test/bug435743.rdf
toolkit/mozapps/extensions/test/bug435743.sjs
toolkit/mozapps/extensions/test/bug435743.xpi
toolkit/mozapps/extensions/test/test_bug435743_1.xul
toolkit/mozapps/extensions/test/test_bug435743_2.xul
toolkit/mozapps/extensions/test/unit/data/bug455906_block.xml
toolkit/mozapps/extensions/test/unit/data/bug455906_empty.xml
toolkit/mozapps/extensions/test/unit/data/bug455906_start.xml
toolkit/mozapps/extensions/test/unit/data/bug455906_warn.xml
toolkit/mozapps/extensions/test/unit/data/cert8.db
toolkit/mozapps/extensions/test/unit/data/key3.db
toolkit/mozapps/extensions/test/unit/data/secmod.db
toolkit/mozapps/extensions/test/unit/data/signed-no-cn.xpi
toolkit/mozapps/extensions/test/unit/data/signed-no-o.xpi
toolkit/mozapps/extensions/test/unit/data/signed-tampered.xpi
toolkit/mozapps/extensions/test/unit/data/signed-untrusted.xpi
toolkit/mozapps/extensions/test/unit/data/signed.xpi
toolkit/mozapps/extensions/test/unit/data/test_bug299716.rdf
toolkit/mozapps/extensions/test/unit/data/test_bug299716_2.rdf
toolkit/mozapps/extensions/test/unit/data/test_bug324121.rdf
toolkit/mozapps/extensions/test/unit/data/test_bug378216.rdf
toolkit/mozapps/extensions/test/unit/data/test_bug393285.xml
toolkit/mozapps/extensions/test/unit/data/test_bug394300.rdf
toolkit/mozapps/extensions/test/unit/data/test_bug396129.rdf
toolkit/mozapps/extensions/test/unit/data/test_bug404024.xml
toolkit/mozapps/extensions/test/unit/data/test_bug417606.xml
toolkit/mozapps/extensions/test/unit/data/test_bug424107_1.rdf
toolkit/mozapps/extensions/test/unit/data/test_bug424107_2.rdf
toolkit/mozapps/extensions/test/unit/data/test_bug424262.xml
toolkit/mozapps/extensions/test/unit/data/test_bug449027_app.xml
toolkit/mozapps/extensions/test/unit/data/test_bug449027_toolkit.xml
toolkit/mozapps/extensions/test/unit/data/test_bug468528.xml
toolkit/mozapps/extensions/test/unit/data/test_bug470377/install_1.rdf
toolkit/mozapps/extensions/test/unit/data/test_bug470377/install_2.rdf
toolkit/mozapps/extensions/test/unit/data/test_bug470377/install_3.rdf
toolkit/mozapps/extensions/test/unit/data/test_bug470377/install_4.rdf
toolkit/mozapps/extensions/test/unit/data/test_bug470377/install_5.rdf
toolkit/mozapps/extensions/test/unit/data/test_bug470377/update_1.rdf
toolkit/mozapps/extensions/test/unit/data/test_bug470377/update_2.rdf
toolkit/mozapps/extensions/test/unit/data/test_bug470377/update_3.rdf
toolkit/mozapps/extensions/test/unit/data/test_bug470377/update_4.rdf
toolkit/mozapps/extensions/test/unit/data/test_bug470377/update_5.rdf
toolkit/mozapps/extensions/test/unit/data/test_bug486195/install.rdf
toolkit/mozapps/extensions/test/unit/data/test_bug514327_1.xml
toolkit/mozapps/extensions/test/unit/data/test_bug514327_2.xml
toolkit/mozapps/extensions/test/unit/data/test_bug514327_3_empty.xml
toolkit/mozapps/extensions/test/unit/data/test_bug514327_3_outdated_1.xml
toolkit/mozapps/extensions/test/unit/data/test_bug514327_3_outdated_2.xml
toolkit/mozapps/extensions/test/unit/data/test_bug526598_1.xpi
toolkit/mozapps/extensions/test/unit/data/test_bug526598_2.xpi
toolkit/mozapps/extensions/test/unit/data/test_bug541420.xpi
toolkit/mozapps/extensions/test/unit/data/unsigned.xpi
toolkit/mozapps/extensions/test/unit/test_LightweightThemeManager.js
toolkit/mozapps/extensions/test/unit/test_bug257155.js
toolkit/mozapps/extensions/test/unit/test_bug299716.js
toolkit/mozapps/extensions/test/unit/test_bug299716_2.js
toolkit/mozapps/extensions/test/unit/test_bug324121.js
toolkit/mozapps/extensions/test/unit/test_bug335238.js
toolkit/mozapps/extensions/test/unit/test_bug371495.js
toolkit/mozapps/extensions/test/unit/test_bug378216.js
toolkit/mozapps/extensions/test/unit/test_bug384052.js
toolkit/mozapps/extensions/test/unit/test_bug386153.js
toolkit/mozapps/extensions/test/unit/test_bug391899.js
toolkit/mozapps/extensions/test/unit/test_bug392180.js
toolkit/mozapps/extensions/test/unit/test_bug393285.js
toolkit/mozapps/extensions/test/unit/test_bug394300.js
toolkit/mozapps/extensions/test/unit/test_bug394717.js
toolkit/mozapps/extensions/test/unit/test_bug396129.js
toolkit/mozapps/extensions/test/unit/test_bug397778.js
toolkit/mozapps/extensions/test/unit/test_bug404024.js
toolkit/mozapps/extensions/test/unit/test_bug406118.js
toolkit/mozapps/extensions/test/unit/test_bug417606.js
toolkit/mozapps/extensions/test/unit/test_bug424107.js
toolkit/mozapps/extensions/test/unit/test_bug424262.js
toolkit/mozapps/extensions/test/unit/test_bug425657.js
toolkit/mozapps/extensions/test/unit/test_bug428341.js
toolkit/mozapps/extensions/test/unit/test_bug430120.js
toolkit/mozapps/extensions/test/unit/test_bug436207.js
toolkit/mozapps/extensions/test/unit/test_bug449027.js
toolkit/mozapps/extensions/test/unit/test_bug455906.js
toolkit/mozapps/extensions/test/unit/test_bug465190.js
toolkit/mozapps/extensions/test/unit/test_bug468528.js
toolkit/mozapps/extensions/test/unit/test_bug470377_1.js
toolkit/mozapps/extensions/test/unit/test_bug470377_2.js
toolkit/mozapps/extensions/test/unit/test_bug470377_3.js
toolkit/mozapps/extensions/test/unit/test_bug470377_4.js
toolkit/mozapps/extensions/test/unit/test_bug474988.js
toolkit/mozapps/extensions/test/unit/test_bug486195.js
toolkit/mozapps/extensions/test/unit/test_bug509194.js
toolkit/mozapps/extensions/test/unit/test_bug514327_1.js
toolkit/mozapps/extensions/test/unit/test_bug514327_2.js
toolkit/mozapps/extensions/test/unit/test_bug514327_3.js
toolkit/mozapps/extensions/test/unit/test_bug521905.js
toolkit/mozapps/extensions/test/unit/test_bug526598.js
toolkit/mozapps/extensions/test/unit/test_bug541420.js
toolkit/mozapps/extensions/test/xpcshell/test_bug541420.js
toolkit/themes/gnomestripe/mozapps/extensions/extensionIcons.png
toolkit/themes/gnomestripe/mozapps/extensions/notifyBadges.png
toolkit/themes/gnomestripe/mozapps/extensions/ratings.png
toolkit/themes/gnomestripe/mozapps/extensions/viewButtons.png
toolkit/themes/pinstripe/mozapps/extensions/extensionIcons.png
toolkit/themes/pinstripe/mozapps/extensions/extensionItem.png
toolkit/themes/pinstripe/mozapps/extensions/itemDisabledFader.png
toolkit/themes/pinstripe/mozapps/extensions/itemEnabledFader.png
toolkit/themes/pinstripe/mozapps/extensions/notifyBadges.png
toolkit/themes/pinstripe/mozapps/extensions/question.png
toolkit/themes/pinstripe/mozapps/extensions/ratings.png
toolkit/themes/pinstripe/mozapps/extensions/viewButtons.png
toolkit/themes/winstripe/mozapps/extensions/extensionIcons-aero.png
toolkit/themes/winstripe/mozapps/extensions/extensionIcons.png
toolkit/themes/winstripe/mozapps/extensions/itemDisabledFader.png
toolkit/themes/winstripe/mozapps/extensions/itemEnabledFader.png
toolkit/themes/winstripe/mozapps/extensions/notifyBadges-aero.png
toolkit/themes/winstripe/mozapps/extensions/notifyBadges.png
toolkit/themes/winstripe/mozapps/extensions/question-aero.png
toolkit/themes/winstripe/mozapps/extensions/question.png
toolkit/themes/winstripe/mozapps/extensions/ratings-aero.png
toolkit/themes/winstripe/mozapps/extensions/ratings.png
toolkit/themes/winstripe/mozapps/extensions/viewButtons-aero.png
toolkit/themes/winstripe/mozapps/extensions/viewButtons.png
toolkit/toolkit-makefiles.sh
toolkit/toolkit-tiers.mk
toolkit/xre/nsAppRunner.cpp
widget/src/windows/nsWindow.cpp
xpcom/ds/nsCommaSeparatedTokenizer.h
xpfe/components/find/Makefile.in
xpfe/components/find/public/Makefile.in
xpfe/components/find/public/nsIFindService.idl
xpfe/components/find/src/Makefile.in
xpfe/components/find/src/nsFindModule.cpp
xpfe/components/find/src/nsFindService.cpp
xpfe/components/find/src/nsFindService.h
xpfe/components/intl/Makefile.in
xpfe/components/intl/nsCharsetMenu.cpp
xpfe/components/intl/nsCharsetMenu.h
--- a/accessible/public/nsIAccessibleProvider.idl
+++ b/accessible/public/nsIAccessibleProvider.idl
@@ -93,17 +93,17 @@ interface nsIAccessibleProvider : nsISup
   const long XULRadioGroup = 0x00001016;
 
   /** The single tab in a dialog or tabbrowser/editor interface */
   const long XULTab = 0x00001017;
 
   /** A combination of a tabs object and a tabpanels object */
   const long XULTabBox = 0x00001018;
 
-  /** The collection of tab objects, useable in the TabBox and independant of
+  /** The collection of tab objects, usable in the TabBox and independent of it
    as well */
   const long XULTabs = 0x00001019;
 
   const long XULText             = 0x0000101A;
   const long XULTextBox          = 0x0000101B;
   const long XULThumb            = 0x0000101C;
   const long XULTree             = 0x0000101D;
   const long XULTreeColumns      = 0x0000101E;
--- a/accessible/src/base/nsAccUtils.cpp
+++ b/accessible/src/base/nsAccUtils.cpp
@@ -118,17 +118,17 @@ nsAccUtils::GetDefaultLevel(nsAccessible
   }
 
   return 0;
 }
 
 PRInt32
 nsAccUtils::GetARIAOrDefaultLevel(nsIAccessible *aAcc)
 {
-  nsRefPtr<nsAccessible> acc = nsAccUtils::QueryObject<nsAccessible>(aAcc);
+  nsRefPtr<nsAccessible> acc = do_QueryObject(aAcc);
   NS_ENSURE_TRUE(acc, 0);
 
   nsCOMPtr<nsIDOMNode> node;
   acc->GetDOMNode(getter_AddRefs(node));
   nsCOMPtr<nsIContent> content(do_QueryInterface(node));
   NS_ENSURE_TRUE(content, 0);
 
   PRInt32 level = 0;
--- a/accessible/src/base/nsAccUtils.h
+++ b/accessible/src/base/nsAccUtils.h
@@ -314,47 +314,16 @@ public:
    *
    * @param  aRule   [in] rule constant (see ELiveAttrRule in nsAccMap.h)
    * @param  aValue  [out] object attribute value
    *
    * @return         true if object attribute should be exposed
    */
   static PRBool GetLiveAttrValue(PRUint32 aRule, nsAString& aValue);
 
-  /**
-   * Query DestinationType from the given SourceType.
-   */
-  template<class DestinationType, class SourceType> static inline
-    already_AddRefed<DestinationType> QueryObject(SourceType *aObject)
-  {
-    DestinationType* object = nsnull;
-    if (aObject)
-      CallQueryInterface(aObject, &object);
-
-    return object;
-  }
-  template<class DestinationType, class SourceType> static inline
-    already_AddRefed<DestinationType> QueryObject(nsCOMPtr<SourceType>& aObject)
-  {
-    DestinationType* object = nsnull;
-    if (aObject)
-      CallQueryInterface(aObject, &object);
-
-    return object;
-  }
-  template<class DestinationType, class SourceType> static inline
-  already_AddRefed<DestinationType> QueryObject(nsRefPtr<SourceType>& aObject)
-  {
-    DestinationType* object = nsnull;
-    if (aObject)
-      CallQueryInterface(aObject.get(), &object);
-    
-    return object;
-  }
-
 #ifdef DEBUG_A11Y
   /**
    * Detect whether the given accessible object implements nsIAccessibleText,
    * when it is text or has text child node.
    */
   static PRBool IsTextInterfaceSupportCorrect(nsIAccessible *aAccessible);
 #endif
 
--- a/accessible/src/base/nsAccessNode.cpp
+++ b/accessible/src/base/nsAccessNode.cpp
@@ -67,16 +67,17 @@
 #include "nsIPrefBranch.h"
 #include "nsPresContext.h"
 #include "nsIPresShell.h"
 #include "nsIServiceManager.h"
 #include "nsIStringBundle.h"
 #include "nsRootAccessible.h"
 #include "nsFocusManager.h"
 #include "nsIObserverService.h"
+#include "mozilla/Services.h"
 
 /* For documentation of the accessibility architecture, 
  * see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
  */
 
 nsIStringBundle *nsAccessNode::gStringBundle = 0;
 nsIStringBundle *nsAccessNode::gKeyStringBundle = 0;
 nsIDOMNode *nsAccessNode::gLastFocusedNode = 0;
@@ -276,24 +277,25 @@ void nsAccessNode::InitXPAccessibility()
 
   NotifyA11yInitOrShutdown(PR_TRUE);
 }
 
 // nsAccessNode protected static
 void nsAccessNode::NotifyA11yInitOrShutdown(PRBool aIsInit)
 {
   nsCOMPtr<nsIObserverService> obsService =
-    do_GetService("@mozilla.org/observer-service;1");
+    mozilla::services::GetObserverService();
   NS_ASSERTION(obsService, "No observer service to notify of a11y init/shutdown");
-  if (obsService) {
-    static const PRUnichar kInitIndicator[] = { '1', 0 };
-    static const PRUnichar kShutdownIndicator[] = { '0', 0 }; 
-    obsService->NotifyObservers(nsnull, "a11y-init-or-shutdown",
-                                aIsInit ? kInitIndicator  : kShutdownIndicator);
-  }
+  if (!obsService)
+    return;
+
+  static const PRUnichar kInitIndicator[] = { '1', 0 };
+  static const PRUnichar kShutdownIndicator[] = { '0', 0 }; 
+  obsService->NotifyObservers(nsnull, "a11y-init-or-shutdown",
+                              aIsInit ? kInitIndicator  : kShutdownIndicator);
 }
 
 void nsAccessNode::ShutdownXPAccessibility()
 {
   // Called by nsAccessibilityService::Shutdown()
   // which happens when xpcom is shutting down
   // at exit of program
 
@@ -394,18 +396,17 @@ nsAccessNode::IsInCache()
     nsAccessNode::GetDocAccessibleFor(mWeakShell);
 
   if (!accessibleDoc)
     return nsnull;
 
   void* uniqueID = nsnull;
   GetUniqueID(&uniqueID);
 
-  nsRefPtr<nsDocAccessible> docAccessible =
-    nsAccUtils::QueryObject<nsDocAccessible>(accessibleDoc);
+  nsRefPtr<nsDocAccessible> docAccessible = do_QueryObject(accessibleDoc);
   return docAccessible->GetCachedAccessNode(uniqueID) ? PR_TRUE : PR_FALSE;
 }
 #endif
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIAccessNode
 
 NS_IMETHODIMP
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -80,16 +80,17 @@
 #include "nsOuterDocAccessible.h"
 #include "nsRootAccessibleWrap.h"
 #include "nsTextFragment.h"
 #include "nsServiceManagerUtils.h"
 #include "nsUnicharUtils.h"
 #include "nsIWebProgress.h"
 #include "nsNetError.h"
 #include "nsDocShellLoadTypes.h"
+#include "mozilla/Services.h"
 
 #ifdef MOZ_XUL
 #include "nsXULAlertAccessible.h"
 #include "nsXULColorPickerAccessible.h"
 #include "nsXULComboboxAccessible.h"
 #include "nsXULFormControlAccessible.h"
 #include "nsXULListboxAccessibleWrap.h"
 #include "nsXULMenuAccessibleWrap.h"
@@ -114,18 +115,18 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 nsAccessibilityService *nsAccessibilityService::gAccessibilityService = nsnull;
 PRBool nsAccessibilityService::gIsShutdown = PR_TRUE;
 
 nsAccessibilityService::nsAccessibilityService()
 {
   // Add observers.
-  nsCOMPtr<nsIObserverService> observerService = 
-    do_GetService("@mozilla.org/observer-service;1");
+  nsCOMPtr<nsIObserverService> observerService =
+    mozilla::services::GetObserverService();
   if (!observerService)
     return;
 
   observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_FALSE);
   nsCOMPtr<nsIWebProgress> progress(do_GetService(NS_DOCUMENTLOADER_SERVICE_CONTRACTID));
   if (progress) {
     progress->AddProgressListener(static_cast<nsIWebProgressListener*>(this),
                                   nsIWebProgress::NOTIFY_STATE_DOCUMENT);
@@ -150,21 +151,21 @@ NS_IMPL_THREADSAFE_ISUPPORTS5(nsAccessib
 
 NS_IMETHODIMP
 nsAccessibilityService::Observe(nsISupports *aSubject, const char *aTopic,
                          const PRUnichar *aData)
 {
   if (!nsCRT::strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
 
     // Remove observers.
-    nsCOMPtr<nsIObserverService> observerService = 
-      do_GetService("@mozilla.org/observer-service;1");
-    if (observerService) {
+    nsCOMPtr<nsIObserverService> observerService =
+      mozilla::services::GetObserverService();
+    if (observerService)
       observerService->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
-    }
+
     nsCOMPtr<nsIWebProgress> progress(do_GetService(NS_DOCUMENTLOADER_SERVICE_CONTRACTID));
     if (progress)
       progress->RemoveProgressListener(static_cast<nsIWebProgressListener*>(this));
 
     // Application is going to be closed, shutdown accessibility and mark
     // accessibility service as shutdown to prevent calls of its methods.
     // Don't null accessibility service static member at this point to be safe
     // if someone will try to operate with it.
@@ -981,18 +982,17 @@ nsAccessibilityService::GetCachedAccessN
                                             nsIWeakReference *aWeakShell)
 {
   nsCOMPtr<nsIAccessibleDocument> accessibleDoc =
     nsAccessNode::GetDocAccessibleFor(aWeakShell);
 
   if (!accessibleDoc)
     return nsnull;
 
-  nsRefPtr<nsDocAccessible> docAccessible =
-    nsAccUtils::QueryObject<nsDocAccessible>(accessibleDoc);
+  nsRefPtr<nsDocAccessible> docAccessible = do_QueryObject(accessibleDoc);
   return docAccessible->GetCachedAccessNode(static_cast<void*>(aNode));
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIAccessibleRetrieval
 
 NS_IMETHODIMP
 nsAccessibilityService::GetApplicationAccessible(nsIAccessible **aAccessibleApplication)
@@ -1340,18 +1340,17 @@ nsAccessibilityService::GetAccessible(ns
 #endif
 
   // Check to see if we already have an accessible for this node in the cache.
   nsAccessNode* cachedAccessNode = GetCachedAccessNode(aNode, aWeakShell);
   if (cachedAccessNode) {
     // XXX: the cache might contain the access node for the DOM node that is not
     // accessible because of wrong cache update. In this case try to create new
     // accessible.
-    nsRefPtr<nsAccessible> cachedAccessible =
-      nsAccUtils::QueryObject<nsAccessible>(cachedAccessNode);
+    nsRefPtr<nsAccessible> cachedAccessible = do_QueryObject(cachedAccessNode);
 
     if (cachedAccessible)
       return cachedAccessible.forget();
   }
 
   // No cache entry, so we must create the accessible.
   nsRefPtr<nsAccessible> newAcc;
 
@@ -1425,17 +1424,17 @@ nsAccessibilityService::GetAccessible(ns
 
         return nsnull;
       }
     }
     if (weakFrame.IsAlive()) {
       nsCOMPtr<nsIAccessible> newAccessible;
       weakFrame.GetFrame()->GetAccessible(getter_AddRefs(newAccessible));
       if (newAccessible) {
-        newAcc = nsAccUtils::QueryObject<nsAccessible>(newAccessible);
+        newAcc = do_QueryObject(newAccessible);
         if (InitAccessible(newAcc, nsnull))
           return newAcc.forget();
         return nsnull;
       }
     }
 
     return nsnull;
   }
@@ -1593,17 +1592,17 @@ nsAccessibilityService::GetAccessible(ns
             *aIsHidden = PR_TRUE;
 
           return nsnull;
         }
 
         // Try using frame to do it.
         nsCOMPtr<nsIAccessible> newAccessible;
         f->GetAccessible(getter_AddRefs(newAccessible));
-        newAcc = nsAccUtils::QueryObject<nsAccessible>(newAccessible);
+        newAcc = do_QueryObject(newAccessible);
       }
     }
   }
 
   if (!newAcc) {
     // Elements may implement nsIAccessibleProvider via XBL. This allows them to
     // say what kind of accessible to create.
     newAcc = CreateAccessibleByType(aNode, aWeakShell);
@@ -1762,38 +1761,37 @@ nsAccessibilityService::GetAreaAccessibl
 
   // Try to get image map accessible from the global cache or create it
   // if failed.
   nsRefPtr<nsAccessible> imageAcc;
 
   nsCOMPtr<nsIDOMNode> imageNode(do_QueryInterface(aImageFrame->GetContent()));
   nsAccessNode *cachedImgAcc = GetCachedAccessNode(imageNode, aWeakShell);
   if (cachedImgAcc)
-    imageAcc = nsAccUtils::QueryObject<nsAccessible>(cachedImgAcc);
+    imageAcc = do_QueryObject(cachedImgAcc);
 
   if (!imageAcc) {
     nsCOMPtr<nsIAccessible> imageAccessible;
     CreateHTMLImageAccessible(aImageFrame,
                               getter_AddRefs(imageAccessible));
 
-    imageAcc = nsAccUtils::QueryObject<nsAccessible>(imageAccessible);
+    imageAcc = do_QueryObject(imageAccessible);
     if (!InitAccessible(imageAcc, nsnull))
       return nsnull;
   }
 
   // Make sure <area> accessible children of the image map are cached so
   // that they should be available in global cache.
   imageAcc->EnsureChildren();
 
   nsAccessNode *cachedAreaAcc = GetCachedAccessNode(aAreaNode, aWeakShell);
   if (!cachedAreaAcc)
     return nsnull;
 
-  nsRefPtr<nsAccessible> areaAcc =
-    nsAccUtils::QueryObject<nsAccessible>(cachedAreaAcc);
+  nsRefPtr<nsAccessible> areaAcc = do_QueryObject(cachedAreaAcc);
   return areaAcc.forget();
 }
 
 already_AddRefed<nsAccessible>
 nsAccessibilityService::CreateAccessibleByType(nsIDOMNode *aNode,
                                                nsIWeakReference *aWeakShell)
 {
   nsCOMPtr<nsIAccessibleProvider> accessibleProvider(do_QueryInterface(aNode));
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -170,18 +170,17 @@ nsresult nsAccessible::QueryInterface(RE
     if (mRoleMapEntry && mRoleMapEntry->valueRule != eNoValue) {
       *aInstancePtr = static_cast<nsIAccessibleValue*>(this);
       NS_ADDREF_THIS();
       return NS_OK;
     }
   }                       
 
   if (aIID.Equals(NS_GET_IID(nsIAccessibleHyperLink))) {
-    nsCOMPtr<nsIAccessibleHyperText> hyperTextParent =
-      nsAccUtils::QueryObject<nsIAccessibleHyperText>(GetParent());
+    nsCOMPtr<nsIAccessibleHyperText> hyperTextParent = do_QueryObject(GetParent());
 
     if (hyperTextParent) {
       *aInstancePtr = static_cast<nsIAccessibleHyperLink*>(this);
       NS_ADDREF_THIS();
       return NS_OK;
     }
     return NS_ERROR_NO_INTERFACE;
   }
@@ -400,17 +399,17 @@ nsAccessible::GetKeyboardShortcut(nsAStr
 {
   aAccessKey.Truncate();
 
   nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
   if (!content)
     return NS_ERROR_FAILURE;
 
   PRUint32 key = nsCoreUtils::GetAccessKeyFor(content);
-  if (!key && content->IsNodeOfType(nsIContent::eELEMENT)) {
+  if (!key && content->IsElement()) {
     // Copy access key from label node unless it is labeled
     // via an ancestor <label>, in which case that would be redundant
     nsCOMPtr<nsIContent> labelContent(nsCoreUtils::GetLabelContent(content));
     nsCOMPtr<nsINode> thisNode = do_QueryInterface(mDOMNode);
     if (labelContent && !nsCoreUtils::IsAncestorOf(labelContent, thisNode))
       key = nsCoreUtils::GetAccessKeyFor(labelContent);
   }
 
@@ -736,17 +735,17 @@ nsAccessible::GetStateInternal(PRUint32 
     isDisabled = content->AttrValueIs(kNameSpaceID_None,
                                       nsAccessibilityAtoms::disabled,
                                       nsAccessibilityAtoms::_true,
                                       eCaseMatters);
   }
   if (isDisabled) {
     *aState |= nsIAccessibleStates::STATE_UNAVAILABLE;
   }
-  else if (content->IsNodeOfType(nsINode::eELEMENT)) {
+  else if (content->IsElement()) {
     nsIFrame *frame = GetFrame();
     if (frame && frame->IsFocusable()) {
       *aState |= nsIAccessibleStates::STATE_FOCUSABLE;
     }
 
     if (gLastFocusedNode == mDOMNode) {
       *aState |= nsIAccessibleStates::STATE_FOCUSED;
     }
@@ -1300,17 +1299,17 @@ nsresult
 nsAccessible::HandleAccEvent(nsAccEvent *aEvent)
 {
   NS_ENSURE_ARG_POINTER(aEvent);
   nsCOMPtr<nsIDOMNode> eventNode;
   aEvent->GetDOMNode(getter_AddRefs(eventNode));
   NS_ENSURE_TRUE(nsAccUtils::IsNodeRelevant(eventNode), NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIObserverService> obsService =
-    do_GetService("@mozilla.org/observer-service;1");
+    mozilla::services::GetObserverService();
   NS_ENSURE_TRUE(obsService, NS_ERROR_FAILURE);
 
   return obsService->NotifyObservers(aEvent, NS_ACCESSIBLE_EVENT_TOPIC, nsnull);
 }
 
 NS_IMETHODIMP
 nsAccessible::GetRole(PRUint32 *aRole)
 {
--- a/accessible/src/base/nsApplicationAccessible.cpp
+++ b/accessible/src/base/nsApplicationAccessible.cpp
@@ -319,18 +319,17 @@ nsApplicationAccessible::GetSiblingAtOff
 ////////////////////////////////////////////////////////////////////////////////
 // Public methods
 
 nsresult
 nsApplicationAccessible::AddRootAccessible(nsIAccessible *aRootAccessible)
 {
   NS_ENSURE_ARG_POINTER(aRootAccessible);
 
-  nsRefPtr<nsAccessible> rootAcc =
-    nsAccUtils::QueryObject<nsAccessible>(aRootAccessible);
+  nsRefPtr<nsAccessible> rootAcc = do_QueryObject(aRootAccessible);
 
   if (!mChildren.AppendElement(rootAcc))
     return NS_ERROR_FAILURE;
 
   rootAcc->SetParent(this);
 
   return NS_OK;
 }
--- a/accessible/src/base/nsBaseWidgetAccessible.cpp
+++ b/accessible/src/base/nsBaseWidgetAccessible.cpp
@@ -207,18 +207,17 @@ nsLinkableAccessible::GetKeyboardShortcu
 // nsLinkableAccessible. nsIAccessibleHyperLink
 
 NS_IMETHODIMP
 nsLinkableAccessible::GetURI(PRInt32 aIndex, nsIURI **aURI)
 {
   if (mIsLink) {
     nsRefPtr<nsAccessible> actionAcc = GetActionAccessible();
     if (actionAcc) {
-      nsCOMPtr<nsIAccessibleHyperLink> hyperLinkAcc =
-        nsAccUtils::QueryObject<nsIAccessibleHyperLink>(actionAcc);
+      nsCOMPtr<nsIAccessibleHyperLink> hyperLinkAcc = do_QueryObject(actionAcc);
       NS_ASSERTION(hyperLinkAcc,
                    "nsIAccessibleHyperLink isn't implemented.");
 
       if (hyperLinkAcc)
         return hyperLinkAcc->GetURI(aIndex, aURI);
     }
   }
   
--- a/accessible/src/base/nsCoreUtils.cpp
+++ b/accessible/src/base/nsCoreUtils.cpp
@@ -237,17 +237,17 @@ nsCoreUtils::GetAccessKeyFor(nsIContent 
 }
 
 already_AddRefed<nsIDOMElement>
 nsCoreUtils::GetDOMElementFor(nsIDOMNode *aNode)
 {
   nsCOMPtr<nsINode> node(do_QueryInterface(aNode));
   nsIDOMElement *element = nsnull;
 
-  if (node->IsNodeOfType(nsINode::eELEMENT))
+  if (node->IsElement())
     CallQueryInterface(node, &element);
 
   else if (node->IsNodeOfType(nsINode::eTEXT)) {
     nsCOMPtr<nsINode> nodeParent = node->GetNodeParent();
     NS_ASSERTION(nodeParent, "Text node has no parent!");
     if (nodeParent)
       CallQueryInterface(nodeParent, &element);
   }
@@ -271,17 +271,17 @@ nsCoreUtils::GetDOMElementFor(nsIDOMNode
 }
 
 already_AddRefed<nsIDOMNode>
 nsCoreUtils::GetDOMNodeFromDOMPoint(nsIDOMNode *aNode, PRUint32 aOffset)
 {
   nsIDOMNode *resultNode = nsnull;
 
   nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
-  if (content && content->IsNodeOfType(nsINode::eELEMENT)) {
+  if (content && content->IsElement()) {
 
     PRUint32 childCount = content->GetChildCount();
     NS_ASSERTION(aOffset >= 0 && aOffset <= childCount,
                  "Wrong offset of the DOM point!");
 
     // The offset can be after last child of container node that means DOM point
     // is placed immediately after the last child. In this case use the DOM node
     // from the given DOM point is used as result node.
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -544,18 +544,17 @@ nsDocAccessible::GetCachedAccessNode(voi
       accessNode = this;
   }
 
 #ifdef DEBUG
   // All cached accessible nodes should be in the parent
   // It will assert if not all the children were created
   // when they were first cached, and no invalidation
   // ever corrected parent accessible's child cache.
-  nsRefPtr<nsAccessible> acc =
-    nsAccUtils::QueryObject<nsAccessible>(accessNode);
+  nsRefPtr<nsAccessible> acc = do_QueryObject(accessNode);
 
   if (acc) {
     nsAccessible* parent(acc->GetCachedParent());
     if (parent)
       parent->TestChildCache(acc);
   }
 #endif
 
@@ -1304,32 +1303,32 @@ nsDocAccessible::ARIAAttributeChanged(ns
     InvalidateCacheSubtree(aContent,
                            nsIAccessibilityService::NODE_SIGNIFICANT_CHANGE);
     return;
   }
 }
 
 void nsDocAccessible::ContentAppended(nsIDocument *aDocument,
                                       nsIContent* aContainer,
-                                      PRInt32 aNewIndexInContainer)
+                                      nsIContent* aFirstNewContent,
+                                      PRInt32 /* unused */)
 {
   if ((!mIsContentLoaded || !mDocument) && mAccessNodeCache.Count() <= 1) {
     // See comments in nsDocAccessible::InvalidateCacheSubtree
     InvalidateChildren();
     return;
   }
 
-  PRUint32 childCount = aContainer->GetChildCount();
-  for (PRUint32 index = aNewIndexInContainer; index < childCount; index ++) {
-    nsCOMPtr<nsIContent> child(aContainer->GetChildAt(index));
+  // Does this need to be a strong ref?  If so, why?
+  for (nsIContent* cur = aFirstNewContent; cur; cur = cur->GetNextSibling()) {
     // InvalidateCacheSubtree will not fire the EVENT_SHOW for the new node
     // unless an accessible can be created for the passed in node, which it
     // can't do unless the node is visible. The right thing happens there so
     // no need for an extra visibility check here.
-    InvalidateCacheSubtree(child, nsIAccessibilityService::NODE_APPEND);
+    InvalidateCacheSubtree(cur, nsIAccessibilityService::NODE_APPEND);
   }
 }
 
 
 void nsDocAccessible::ContentStatesChanged(nsIDocument* aDocument,
                                            nsIContent* aContent1,
                                            nsIContent* aContent2,
                                            PRInt32 aStateMask)
@@ -1358,28 +1357,28 @@ void nsDocAccessible::CharacterDataChang
                                            nsIContent* aContent,
                                            CharacterDataChangeInfo* aInfo)
 {
   FireTextChangeEventForText(aContent, aInfo, PR_TRUE);
 }
 
 void
 nsDocAccessible::ContentInserted(nsIDocument *aDocument, nsIContent* aContainer,
-                                 nsIContent* aChild, PRInt32 aIndexInContainer)
+                                 nsIContent* aChild, PRInt32 /* unused */)
 {
   // InvalidateCacheSubtree will not fire the EVENT_SHOW for the new node
   // unless an accessible can be created for the passed in node, which it
   // can't do unless the node is visible. The right thing happens there so
   // no need for an extra visibility check here.
   InvalidateCacheSubtree(aChild, nsIAccessibilityService::NODE_APPEND);
 }
 
 void
 nsDocAccessible::ContentRemoved(nsIDocument *aDocument, nsIContent* aContainer,
-                                nsIContent* aChild, PRInt32 aIndexInContainer)
+                                nsIContent* aChild, PRInt32 /* unused */)
 {
   // It's no needed to invalidate the subtree of the removed element,
   // because we get notifications directly from content (see
   // nsGenericElement::doRemoveChildAt) *before* the frame for the content is
   // destroyed, or any other side effects occur . That allows us to correctly
   // calculate the TEXT_REMOVED event if there is one and coalesce events from
   // the same subtree.
 }
@@ -1413,17 +1412,17 @@ nsDocAccessible::GetParent()
     if (accService) {
       // XXX aaronl: ideally we would traverse the presshell chain. Since
       // there's no easy way to do that, we cheat and use the document
       // hierarchy. GetAccessibleFor() is bad because it doesn't support our
       // concept of multiple presshells per doc.
       // It should be changed to use GetAccessibleInWeakShell()
       nsCOMPtr<nsIAccessible> parent;
       accService->GetAccessibleFor(ownerNode, getter_AddRefs(parent));
-      mParent = nsAccUtils::QueryObject<nsAccessible>(parent);
+      mParent = do_QueryObject(parent);
     }
   }
 
   NS_ASSERTION(mParent, "No parent for not root document accessible!");
   return mParent;
 }
 
 
@@ -1766,18 +1765,17 @@ nsDocAccessible::ProcessPendingEvent(nsA
         }
       }
     }
   }
 }
 
 void nsDocAccessible::InvalidateChildrenInSubtree(nsIDOMNode *aStartNode)
 {
-  nsRefPtr<nsAccessible> acc =
-    nsAccUtils::QueryObject<nsAccessible>(GetCachedAccessNode(aStartNode));
+  nsRefPtr<nsAccessible> acc = do_QueryObject(GetCachedAccessNode(aStartNode));
   if (acc)
     acc->InvalidateChildren();
 
   // Invalidate accessible children in the DOM subtree 
   nsCOMPtr<nsINode> node = do_QueryInterface(aStartNode);
   PRInt32 index, numChildren = node->GetChildCount();
   for (index = 0; index < numChildren; index ++) {
     nsCOMPtr<nsIDOMNode> childNode = do_QueryInterface(node->GetChildAt(index));
@@ -1791,18 +1789,17 @@ void nsDocAccessible::RefreshNodes(nsIDO
   if (mAccessNodeCache.Count() <= 1) {
     return; // All we have is a doc accessible. There is nothing to invalidate, quit early
   }
 
   nsRefPtr<nsAccessNode> accessNode = GetCachedAccessNode(aStartNode);
 
   // Shut down accessible subtree, which may have been created for
   // anonymous content subtree
-  nsRefPtr<nsAccessible> accessible =
-    nsAccUtils::QueryObject<nsAccessible>(accessNode);
+  nsRefPtr<nsAccessible> accessible = do_QueryObject(accessNode);
   if (accessible) {
     // Fire menupopup end if a menu goes away
     PRUint32 role = nsAccUtils::Role(accessible);
     if (role == nsIAccessibleRole::ROLE_MENUPOPUP) {
       nsCOMPtr<nsIDOMNode> domNode;
       accessNode->GetDOMNode(getter_AddRefs(domNode));
       nsCOMPtr<nsIDOMXULPopupElement> popup(do_QueryInterface(domNode));
       if (!popup) {
--- a/accessible/src/base/nsEventShell.cpp
+++ b/accessible/src/base/nsEventShell.cpp
@@ -47,18 +47,17 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 void
 nsEventShell::FireEvent(nsAccEvent *aEvent)
 {
   if (!aEvent)
     return;
 
-  nsRefPtr<nsAccessible> acc =
-    nsAccUtils::QueryObject<nsAccessible>(aEvent->GetAccessible());
+  nsRefPtr<nsAccessible> acc = do_QueryObject(aEvent->GetAccessible());
   NS_ENSURE_TRUE(acc,);
 
   nsCOMPtr<nsIDOMNode> node;
   aEvent->GetDOMNode(getter_AddRefs(node));
   if (node) {
     sEventTargetNode = node;
     sEventFromUserInput = aEvent->IsFromUserInput();
   }
--- a/accessible/src/base/nsRootAccessible.cpp
+++ b/accessible/src/base/nsRootAccessible.cpp
@@ -71,23 +71,27 @@
 #include "nsIServiceManager.h"
 #include "nsPIDOMWindow.h"
 #include "nsIWebBrowserChrome.h"
 #include "nsReadableUtils.h"
 #include "nsRootAccessible.h"
 #include "nsIDOMNSEventTarget.h"
 #include "nsIDOMDocumentEvent.h"
 #include "nsFocusManager.h"
+#include "mozilla/dom/Element.h"
+
 
 #ifdef MOZ_XUL
 #include "nsXULTreeAccessible.h"
 #include "nsIXULDocument.h"
 #include "nsIXULWindow.h"
 #endif
 
+using namespace mozilla;
+
 ////////////////////////////////////////////////////////////////////////////////
 // nsISupports
 
 // Expanded version of NS_IMPL_ISUPPORTS_INHERITED2 
 // so we can QI directly to concrete nsRootAccessible
 NS_IMPL_QUERY_HEAD(nsRootAccessible)
 NS_IMPL_QUERY_BODY(nsIDOMEventListener)
 if (aIID.Equals(NS_GET_IID(nsRootAccessible)))
@@ -138,19 +142,19 @@ nsRootAccessible::GetName(nsAString& aNa
 nsresult
 nsRootAccessible::GetRoleInternal(PRUint32 *aRole) 
 { 
   if (!mDocument) {
     return NS_ERROR_FAILURE;
   }
 
   // If it's a <dialog> or <wizard>, use nsIAccessibleRole::ROLE_DIALOG instead
-  nsIContent *rootContent = mDocument->GetRootContent();
-  if (rootContent) {
-    nsCOMPtr<nsIDOMElement> rootElement(do_QueryInterface(rootContent));
+  dom::Element *root = mDocument->GetRootElement();
+  if (root) {
+    nsCOMPtr<nsIDOMElement> rootElement(do_QueryInterface(root));
     if (rootElement) {
       nsAutoString name;
       rootElement->GetLocalName(name);
       if (name.EqualsLiteral("dialog") || name.EqualsLiteral("wizard")) {
         *aRole = nsIAccessibleRole::ROLE_DIALOG; // Always at the root
         return NS_OK;
       }
     }
--- a/accessible/src/base/nsTextAccessible.cpp
+++ b/accessible/src/base/nsTextAccessible.cpp
@@ -56,17 +56,17 @@ nsTextAccessible::GetRoleInternal(PRUint
   *aRole = nsIAccessibleRole::ROLE_TEXT_LEAF;
   return NS_OK;
 }
 
 nsresult
 nsTextAccessible::AppendTextTo(nsAString& aText, PRUint32 aStartOffset, PRUint32 aLength)
 {
   nsIFrame *frame = GetFrame();
-  NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
+  if (!frame) return NS_ERROR_FAILURE;//NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
 
   return frame->GetRenderedText(&aText, nsnull, nsnull, aStartOffset, aLength);
 }
 
 void
 nsTextAccessible::CacheChildren()
 {
   // No children for text accessible.
--- a/accessible/src/html/nsHTMLTableAccessible.cpp
+++ b/accessible/src/html/nsHTMLTableAccessible.cpp
@@ -402,30 +402,30 @@ nsHTMLTableHeaderCellAccessible::GetRole
   // rowheader.
   nsIContent* parent = content->GetParent();
   NS_ENSURE_STATE(parent);
 
   PRInt32 indexInParent = parent->IndexOf(content);
 
   for (PRInt32 idx = indexInParent - 1; idx >= 0; idx--) {
     nsIContent* sibling = parent->GetChildAt(idx);
-    if (sibling && sibling->IsNodeOfType(nsINode::eELEMENT)) {
+    if (sibling && sibling->IsElement()) {
       if (nsCoreUtils::IsHTMLTableHeader(sibling))
         *aRole = nsIAccessibleRole::ROLE_COLUMNHEADER;
       else
         *aRole = nsIAccessibleRole::ROLE_ROWHEADER;
 
       return NS_OK;
     }
   }
 
   PRInt32 childCount = parent->GetChildCount();
   for (PRInt32 idx = indexInParent + 1; idx < childCount; idx++) {
     nsIContent* sibling = parent->GetChildAt(idx);
-    if (sibling && sibling->IsNodeOfType(nsINode::eELEMENT)) {
+    if (sibling && sibling->IsElement()) {
       if (nsCoreUtils::IsHTMLTableHeader(sibling))
         *aRole = nsIAccessibleRole::ROLE_COLUMNHEADER;
       else
         *aRole = nsIAccessibleRole::ROLE_ROWHEADER;
       
       return NS_OK;
     }
   }
--- a/accessible/src/html/nsHyperTextAccessible.cpp
+++ b/accessible/src/html/nsHyperTextAccessible.cpp
@@ -1128,17 +1128,17 @@ nsHyperTextAccessible::GetTextAttributes
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Set 'misspelled' text attribute.
   rv = GetSpellTextAttribute(node, nodeOffset, aStartOffset, aEndOffset,
                              aAttributes ? *aAttributes : nsnull);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIContent> content(do_QueryInterface(node));
-  if (content && content->IsNodeOfType(nsINode::eELEMENT))
+  if (content && content->IsElement())
     node = do_QueryInterface(content->GetChildAt(nodeOffset));
 
   if (!node)
     return NS_OK;
 
   nsTextAttrsMgr textAttrsMgr(this, mDOMNode, aIncludeDefAttrs, node);
   return textAttrsMgr.GetAttributes(*aAttributes, aStartOffset, aEndOffset);
 }
--- a/accessible/src/msaa/nsAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsAccessibleWrap.cpp
@@ -496,17 +496,17 @@ STDMETHODIMP nsAccessibleWrap::get_accRo
   if (!accessNode)
     return E_FAIL;
 
   accessNode->GetDOMNode(getter_AddRefs(domNode));
   nsIContent *content = nsCoreUtils::GetRoleContent(domNode);
   if (!content)
     return E_FAIL;
 
-  if (content->IsNodeOfType(nsINode::eELEMENT)) {
+  if (content->IsElement()) {
     nsAutoString roleString;
     if (msaaRole != ROLE_SYSTEM_CLIENT &&
         !content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::role, roleString)) {
       nsIDocument * document = content->GetCurrentDoc();
       if (!document)
         return E_FAIL;
 
       nsINodeInfo *nodeInfo = content->NodeInfo();
--- a/accessible/src/xforms/nsXFormsAccessible.cpp
+++ b/accessible/src/xforms/nsXFormsAccessible.cpp
@@ -131,17 +131,17 @@ nsXFormsAccessible::CacheSelectChildren(
     if (!child)
       continue;
 
     GetAccService()->GetAttachedAccessibleFor(child,
                                               getter_AddRefs(accessible));
     if (!accessible)
       continue;
 
-    acc = nsAccUtils::QueryObject<nsAccessible>(accessible);
+    acc = do_QueryObject(accessible);
     mChildren.AppendElement(acc);
     acc->SetParent(this);
   }
 }
 
 // nsIAccessible
 
 NS_IMETHODIMP
--- a/accessible/src/xul/nsXULTreeAccessible.cpp
+++ b/accessible/src/xul/nsXULTreeAccessible.cpp
@@ -264,18 +264,17 @@ nsXULTreeAccessible::GetChildAtPoint(PRI
   // tree columns.
   if (row == -1 || !column)
     return nsXULSelectableAccessible::
       GetChildAtPoint(aX, aY, aDeepestChild, aChild);
 
   nsAccessible *child = GetTreeItemAccessible(row);
   if (aDeepestChild && child) {
     // Look for accessible cell for the found item accessible.
-    nsRefPtr<nsXULTreeItemAccessibleBase> treeitem =
-      nsAccUtils::QueryObject<nsXULTreeItemAccessibleBase>(child);
+    nsRefPtr<nsXULTreeItemAccessibleBase> treeitem = do_QueryObject(child);
 
     nsAccessible *cell = treeitem->GetCellAccessible(column);
     if (cell)
       child = cell;
   }
 
   NS_IF_ADDREF(*aChild = child);
   return NS_OK;
@@ -476,18 +475,17 @@ nsXULTreeAccessible::GetChildCount()
 }
 
 PRInt32
 nsXULTreeAccessible::GetIndexOf(nsIAccessible *aChild)
 {
   if (IsDefunct())
     return -1;
 
-  nsRefPtr<nsXULTreeItemAccessibleBase> item =
-    nsAccUtils::QueryObject<nsXULTreeItemAccessibleBase>(aChild);
+  nsRefPtr<nsXULTreeItemAccessibleBase> item = do_QueryObject(aChild);
 
   // If the given child is not treeitem then it should be treecols accessible.
   if (!item)
     return nsAccessible::GetIndexOf(aChild);
 
   return nsAccessible::GetChildCount() + item->GetRowIndex();
 }
 
@@ -627,18 +625,17 @@ nsXULTreeAccessible::TreeViewInvalidated
   }
 
   for (PRInt32 rowIdx = aStartRow; rowIdx <= endRow; ++rowIdx) {
 
     void *key = reinterpret_cast<void*>(rowIdx);
     nsAccessible *accessible = mAccessibleCache.GetWeak(key);
 
     if (accessible) {
-      nsRefPtr<nsXULTreeItemAccessibleBase> treeitemAcc =
-        nsAccUtils::QueryObject<nsXULTreeItemAccessibleBase>(accessible);
+      nsRefPtr<nsXULTreeItemAccessibleBase> treeitemAcc = do_QueryObject(accessible);
       NS_ASSERTION(treeitemAcc, "Wrong accessible at the given key!");
 
       treeitemAcc->RowInvalidated(aStartCol, endCol);
     }
   }
 }
 
 void
--- a/accessible/src/xul/nsXULTreeGridAccessible.cpp
+++ b/accessible/src/xul/nsXULTreeGridAccessible.cpp
@@ -353,18 +353,17 @@ nsXULTreeGridAccessible::GetCellAt(PRInt
   if (!rowAccessible)
     return NS_ERROR_INVALID_ARG;
 
   nsCOMPtr<nsITreeColumn> column =
   nsCoreUtils::GetSensibleColumnAt(mTree, aColumnIndex);
   if (!column)
     return NS_ERROR_INVALID_ARG;
 
-  nsRefPtr<nsXULTreeItemAccessibleBase> rowAcc =
-    nsAccUtils::QueryObject<nsXULTreeItemAccessibleBase>(rowAccessible);
+  nsRefPtr<nsXULTreeItemAccessibleBase> rowAcc = do_QueryObject(rowAccessible);
 
   NS_IF_ADDREF(*aCell = rowAcc->GetCellAccessible(column));
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULTreeGridAccessible::GetCellIndexAt(PRInt32 aRowIndex, PRInt32 aColumnIndex,
                                         PRInt32 *aCellIndex)
@@ -700,18 +699,17 @@ nsXULTreeGridRowAccessible::GetChildCoun
 }
 
 PRInt32
 nsXULTreeGridRowAccessible::GetIndexOf(nsIAccessible *aChild)
 {
   if (IsDefunct())
     return -1;
 
-  nsRefPtr<nsXULTreeGridCellAccessible> cell =
-    nsAccUtils::QueryObject<nsXULTreeGridCellAccessible>(aChild);
+  nsRefPtr<nsXULTreeGridCellAccessible> cell = do_QueryObject(aChild);
 
   return cell ? cell->GetColumnIndex() : -1;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeGridRowAccessible: nsXULTreeItemAccessibleBase implementation
 
 nsAccessible*
@@ -752,18 +750,17 @@ nsXULTreeGridRowAccessible::RowInvalidat
     return;
 
   for (PRInt32 colIdx = aStartColIdx; colIdx <= aEndColIdx; ++colIdx) {
     nsCOMPtr<nsITreeColumn> column;
     treeColumns->GetColumnAt(colIdx, getter_AddRefs(column));
     if (column && !nsCoreUtils::IsColumnHidden(column)) {
       nsAccessible *cellAccessible = GetCellAccessible(column);
       if (cellAccessible) {
-        nsRefPtr<nsXULTreeGridCellAccessible> cellAcc =
-          nsAccUtils::QueryObject<nsXULTreeGridCellAccessible>(cellAccessible);
+        nsRefPtr<nsXULTreeGridCellAccessible> cellAcc = do_QueryObject(cellAccessible);
 
         cellAcc->CellInvalidated();
       }
     }
   }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -1282,18 +1279,17 @@ nsXULTreeGridCellAccessible::GetSiblingA
       column = nsCoreUtils::GetNextSensibleColumn(columnAtOffset);
       column.swap(columnAtOffset);
     }
   }
 
   if (!columnAtOffset)
     return nsnull;
 
-  nsRefPtr<nsXULTreeItemAccessibleBase> rowAcc =
-    nsAccUtils::QueryObject<nsXULTreeItemAccessibleBase>(mParent);
+  nsRefPtr<nsXULTreeItemAccessibleBase> rowAcc = do_QueryObject(mParent);
 
   return rowAcc->GetCellAccessible(columnAtOffset);
 }
 
 void
 nsXULTreeGridCellAccessible::DispatchClickEvent(nsIContent *aContent,
                                                 PRUint32 aActionIndex)
 {
--- a/accessible/tests/mochitest/states/Makefile.in
+++ b/accessible/tests/mochitest/states/Makefile.in
@@ -40,23 +40,25 @@ DEPTH		= ../../../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = accessible/states
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
+# temporarily disabled test (bug 562328)
+#  test_frames.html \
+
 _TEST_FILES =\
 		test_aria.html \
 		test_aria_imgmap.html \
 		test_doc.html \
 		test_docarticle.html \
 		test_editablebody.html \
-		test_frames.html \
 		test_link.html \
 		test_popup.xul \
 		test_tree.xul \
 		z_frames.html \
 		z_frames_article.html \
 		z_frames_checkbox.html \
 		z_frames_textbox.html \
 		$(NULL)
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -47,40 +47,22 @@
 #define UNIX_BUT_NOT_MAC
 #endif
 #endif
 
 pref("general.startup.browser", true);
 
 pref("browser.chromeURL","chrome://browser/content/");
 pref("browser.hiddenWindowChromeURL", "chrome://browser/content/hiddenWindow.xul");
-pref("xpinstall.dialog.confirm", "chrome://mozapps/content/xpinstall/xpinstallConfirm.xul");
-pref("xpinstall.dialog.progress.skin", "chrome://mozapps/content/extensions/extensions.xul");
-pref("xpinstall.dialog.progress.chrome", "chrome://mozapps/content/extensions/extensions.xul");
-pref("xpinstall.dialog.progress.type.skin", "Extension:Manager");
-pref("xpinstall.dialog.progress.type.chrome", "Extension:Manager");
 
-// Developers can set this to |true| if they are constantly changing files in their 
-// extensions directory so that the extension system does not constantly think that
-// their extensions are being updated and thus reregistered every time the app is
-// started.
-pref("extensions.ignoreMTimeChanges", false);
 // Enables some extra Extension System Logging (can reduce performance)
 pref("extensions.logging.enabled", false);
-// Hides the install button in the add-ons mgr
-pref("extensions.hideInstallButton", true);
 
-// Preferences for the Get Add-ons pane
-pref("extensions.getAddons.showPane", true);
-pref("extensions.getAddons.browseAddons", "https://addons.mozilla.org/%LOCALE%/%APP%");
-pref("extensions.getAddons.maxResults", 5);
-pref("extensions.getAddons.recommended.browseURL", "https://addons.mozilla.org/%LOCALE%/%APP%/recommended");
-pref("extensions.getAddons.recommended.url", "https://services.addons.mozilla.org/%LOCALE%/%APP%/api/%API_VERSION%/list/featured/all/10/%OS%/%VERSION%");
-pref("extensions.getAddons.search.browseURL", "https://addons.mozilla.org/%LOCALE%/%APP%/search?q=%TERMS%");
-pref("extensions.getAddons.search.url", "https://services.addons.mozilla.org/%LOCALE%/%APP%/api/%API_VERSION%/search/%TERMS%/all/10/%OS%/%VERSION%");
+// Preferences for AMO integration
+pref("extensions.webservice.discoverURL", "https://services.addons.mozilla.org/%LOCALE%/%APP%/discovery/%VERSION%/%OS%");
 
 // Blocklist preferences
 pref("extensions.blocklist.enabled", true);
 pref("extensions.blocklist.interval", 86400);
 // Controls what level the blocklist switches from warning about items to forcibly
 // blocking them.
 pref("extensions.blocklist.level", 2);
 pref("extensions.blocklist.url", "https://addons.mozilla.org/blocklist/3/%APP_ID%/%APP_VERSION%/%PRODUCT%/%BUILD_ID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/");
@@ -899,23 +881,31 @@ pref("browser.sessionstore.interval", 60
 
 // Whether to use a panel that looks like an OS X sheet for customization
 #ifdef XP_MACOSX
 pref("toolbar.customization.usesheet", true);
 #else
 pref("toolbar.customization.usesheet", false);
 #endif
 
+// The default for this pref reflects whether the build is capable of IPC.
+// (Turning it on in a no-IPC build will have no effect.)
 #ifdef XP_MACOSX
+// OSX still has only partial support for IPC.  Note that the PowerPC
+// and x86 builds must generate identical copies of this file, so we
+// can't make the prefs indicate that IPC is not available at all in
+// PowerPC builds.
 pref("dom.ipc.plugins.enabled", false);
 // These plug-ins will run OOP by default
 pref("dom.ipc.plugins.enabled.flash player.plugin", true);
 pref("dom.ipc.plugins.enabled.javaplugin2_npapi.plugin", true);
+#elifdef MOZ_IPC
+pref("dom.ipc.plugins.enabled", true);
 #else
-pref("dom.ipc.plugins.enabled", true);
+pref("dom.ipc.plugins.enabled", false);
 #endif
 
 #ifdef XP_WIN
 #ifndef WINCE
 pref("browser.taskbar.previews.enable", true);
 pref("browser.taskbar.previews.max", 20);
 pref("browser.taskbar.previews.cachetime", 20);
 pref("browser.taskbar.lists.enabled", true);
--- a/browser/base/content/aboutDialog.js
+++ b/browser/base/content/aboutDialog.js
@@ -32,17 +32,17 @@
 # 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 ***** -->
 
 var gSelectedPage = 0;
 
-function init(aEvent) 
+function init(aEvent)
 {
   if (aEvent.target != document)
     return;
 
   var prefs = Components.classes["@mozilla.org/preferences-service;1"]
                         .getService(Components.interfaces.nsIPrefBranch);
 
   try {
@@ -96,17 +96,17 @@ function uninit(aEvent)
 
 function switchPage(aEvent)
 {
   var button = aEvent.target;
   if (button.localName != "button")
     return;
 
   var iframe = document.getElementById("creditsIframe");
-  if (gSelectedPage == 0) { 
+  if (gSelectedPage == 0) {
     iframe.setAttribute("src", "chrome://browser/content/credits.xhtml");
     button.setAttribute("label", document.documentElement.getAttribute("aboutlabel"));
     button.setAttribute("accesskey", document.documentElement.getAttribute("aboutaccesskey"));
     gSelectedPage = 1;
   }
   else {
     iframe.setAttribute("src", ""); 
     button.setAttribute("label", document.documentElement.getAttribute("creditslabel"));
--- a/browser/base/content/aboutDialog.xul
+++ b/browser/base/content/aboutDialog.xul
@@ -32,18 +32,18 @@
 # 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 ***** -->
 
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> 
-<?xml-stylesheet href="chrome://browser/content/aboutDialog.css" type="text/css"?> 
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+<?xml-stylesheet href="chrome://browser/content/aboutDialog.css" type="text/css"?>
 
 <!DOCTYPE window [
 <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
 %brandDTD;
 <!ENTITY % aboutDialogDTD SYSTEM "chrome://browser/locale/aboutDialog.dtd" >
 %aboutDialogDTD;
 ]>
 
--- a/browser/base/content/browser-context.inc
+++ b/browser/base/content/browser-context.inc
@@ -139,19 +139,19 @@
                 label="&copyAudioURLCmd.label;"
                 accesskey="&copyAudioURLCmd.accesskey;"
                 oncommand="gContextMenu.copyMediaLocation();"/>
       <menuseparator id="context-sep-copyimage"/>
       <menuitem id="context-saveimage"
                 label="&saveImageCmd.label;"
                 accesskey="&saveImageCmd.accesskey;"
                 oncommand="gContextMenu.saveMedia();"/>
-      <menuitem id="context-sendimage"  
-                label="&sendImageCmd.label;" 
-                accesskey="&sendImageCmd.accesskey;" 
+      <menuitem id="context-sendimage" 
+                label="&sendImageCmd.label;"
+                accesskey="&sendImageCmd.accesskey;"
                 oncommand="gContextMenu.sendMedia();"/>
       <menuitem id="context-setDesktopBackground"
                 label="&setDesktopBackgroundCmd.label;"
                 accesskey="&setDesktopBackgroundCmd.accesskey;"
                 oncommand="gContextMenu.setDesktopBackground();"/>
       <menuitem id="context-blockimage"
                 type="checkbox"
                 accesskey="&blockImageCmd.accesskey;"
@@ -199,21 +199,21 @@
       <menuitem id="context-bookmarkpage"
                 label="&bookmarkPageCmd2.label;"
                 accesskey="&bookmarkPageCmd2.accesskey;"
                 oncommand="gContextMenu.bookmarkThisPage();"/>
       <menuitem id="context-savepage"
                 label="&savePageCmd.label;"
                 accesskey="&savePageCmd.accesskey2;"
                 oncommand="gContextMenu.savePageAs();"/>
-      <menuitem id="context-sendpage"  
-                label="&sendPageCmd.label;" 
-                accesskey="&sendPageCmd.accesskey;" 
+      <menuitem id="context-sendpage"
+                label="&sendPageCmd.label;"
+                accesskey="&sendPageCmd.accesskey;"
                 oncommand="gContextMenu.sendPage();"/>
-      <menuseparator id="context-sep-viewbgimage"/>  
+      <menuseparator id="context-sep-viewbgimage"/>
       <menuitem id="context-viewbgimage"
                 label="&viewBGImageCmd.label;"
                 accesskey="&viewBGImageCmd.accesskey;"
                 oncommand="gContextMenu.viewBGImage(event);"
                 onclick="checkForMiddleClick(this, event);"/>
       <menuitem id="context-undo"
                 label="&undoCmd.label;"
                 accesskey="&undoCmd.accesskey;"
@@ -234,17 +234,17 @@
       <menuitem id="context-delete"
                 label="&deleteCmd.label;"
                 accesskey="&deleteCmd.accesskey;"
                 command="cmd_delete"/>
       <menuseparator id="context-sep-paste"/>
       <menuitem id="context-selectall"
                 label="&selectAllCmd.label;"
                 accesskey="&selectAllCmd.accesskey;"
-                command="cmd_selectAll"/>      
+                command="cmd_selectAll"/>
       <menuseparator id="context-sep-selectall"/>
       <menuitem id="context-keywordfield"
                 label="&keywordfield.label;"
                 accesskey="&keywordfield.accesskey;"
                 oncommand="AddKeywordForSearchField();"/>
       <menuitem id="context-searchselect"
                 oncommand="BrowserSearch.loadSearch(getBrowserSelection(), true);"/>
       <menuseparator id="frame-sep"/>
--- a/browser/base/content/browser-menubar.inc
+++ b/browser/base/content/browser-menubar.inc
@@ -450,26 +450,28 @@
                           hidden="true"
                           label="&bidiSwitchPageDirectionItem.label;"
                           accesskey="&bidiSwitchPageDirectionItem.accesskey;"
                           oncommand="SwitchDocumentDirection(window.content)"/>
               </menupopup>
             </menu>
 
             <menu id="history-menu"
-                  oncommand="var node = event.target.node; if (node) { PlacesUIUtils.markPageAsTyped(node.uri); openUILink(node.uri, event, false, true); }"
+                  oncommand="this._placesView._onCommand(event);"
                   onclick="checkForMiddleClick(this, event);"
                   label="&historyMenu.label;"
                   accesskey="&historyMenu.accesskey;">
               <menupopup id="goPopup"
-                         type="places"
-                         onpopupshowing="HistoryMenu.onPopupShowing(event);"
-                         onpopuphidden="HistoryMenu.onPopupHidden(event);"
-                         place="place:redirectsMode=2&amp;sort=4&amp;maxResults=10"
-                         tooltip="bhTooltip" popupsinherittooltip="true">
+#ifndef XP_MACOSX
+                         placespopup="true"
+#endif
+                         onpopupshowing="if (!document.getElementById('history-menu')._placesView)
+                                           new HistoryMenu(event);"
+                         tooltip="bhTooltip"
+                         popupsinherittooltip="true">
                 <menuitem id="historyMenuBack"
                           label="&backCmd.label;"
 #ifdef XP_MACOSX
                           key="goBackKb2"
 #else
                           key="goBackKb"
 #endif
                           command="Browser:BackOrBackDuplicate"
@@ -494,42 +496,50 @@
                           key="showAllHistoryKb"
 #endif
                           command="Browser:ShowAllHistory"/>
                 <menuseparator id="startHistorySeparator"/>
                 <menuseparator id="endHistorySeparator" builder="end"/>
                 <menu id="historyUndoMenu"
                       label="&historyUndoMenu.label;"
                       disabled="true">
-                  <menupopup id="historyUndoPopup" placespopup="true"
-                             onpopupshowing="HistoryMenu.populateUndoSubmenu();"/>
+                  <menupopup id="historyUndoPopup"
+#ifndef XP_MACOSX
+                             placespopup="true"
+#endif
+                             onpopupshowing="document.getElementById('history-menu')._placesView.populateUndoSubmenu();"/>
                 </menu>
                 <menu id="historyUndoWindowMenu"
                       label="&historyUndoWindowMenu.label;"
                       disabled="true">
-                  <menupopup id="historyUndoWindowPopup" placespopup="true"
-                             onpopupshowing="HistoryMenu.populateUndoWindowSubmenu();"/>
+                  <menupopup id="historyUndoWindowPopup"
+#ifndef XP_MACOSX
+                             placespopup="true"
+#endif
+                             onpopupshowing="document.getElementById('history-menu')._placesView.populateUndoWindowSubmenu();"/>
                 </menu>
               </menupopup>
             </menu>
 
   <menu id="bookmarksMenu"
         label="&bookmarksMenu.label;"
         accesskey="&bookmarksMenu.accesskey;"
         ondragenter="PlacesMenuDNDController.onBookmarksMenuDragEnter(event);"
         ondragover="BookmarksMenuDropHandler.onDragOver(event);"
         ondrop="BookmarksMenuDropHandler.onDrop(event);">
     <menupopup id="bookmarksMenuPopup"
-               type="places"
-               place="place:folder=BOOKMARKS_MENU"
+#ifndef XP_MACOSX
+               placespopup="true"
+#endif
                context="placesContext"
                openInTabs="children"
                oncommand="BookmarksEventHandler.onCommand(event);"
                onclick="BookmarksEventHandler.onClick(event);"
-               onpopupshowing="BookmarksEventHandler.onPopupShowing(event);"
+               onpopupshowing="if (!document.getElementById('bookmarksMenu')._placesView)
+                                 new PlacesMenu(event, 'place:folder=BOOKMARKS_MENU');"
                tooltip="bhTooltip" popupsinherittooltip="true">
       <menuitem id="menu_bookmarkThisPage"
                 label="&bookmarkThisPageCmd.label;"
                 command="Browser:AddBookmarkAs"
                 key="addBookmarkAsKb"/>
       <menuitem id="subscribeToPageMenuitem"
                 label="&subscribeToPageMenuitem.label;"
                 oncommand="return FeedHandler.subscribeToFeed(null, event);"
@@ -551,21 +561,23 @@
                 label="&organizeBookmarks.label;"
                 command="Browser:ShowAllBookmarks"
                 key="manBookmarkKb"/>
       <menuseparator id="organizeBookmarksSeparator"/>
       <menu id="bookmarksToolbarFolderMenu"
             class="menu-iconic bookmark-item"
             label="&personalbarCmd.label;"
             container="true">
-        <menupopup id="bookmarksToolbarFolderPopup"
-                   type="places"
-                   place="place:folder=TOOLBAR"
+        <menupopup id="bookmarksToolbarFolderPopup"  
+#ifndef XP_MACOSX
+                   placespopup="true"
+#endif
                    context="placesContext"
-                   onpopupshowing="BookmarksEventHandler.onPopupShowing(event);"/>
+                   onpopupshowing="if (!this.parentNode._placesView)
+                                     new PlacesMenu(event, 'place:folder=TOOLBAR');"/>
       </menu>
       <menuseparator/>
     </menupopup>
   </menu>
 
             <menu id="tools-menu"
                   label="&toolsMenu.label;"
                   accesskey="&toolsMenu.accesskey;">
--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -563,25 +563,29 @@ var PlacesCommandHook = {
 
     // remove all tags for the associated url
     PlacesUtils.tagging.untagURI(gEditItemOverlay._uri, null);
 
     this.panel.hidePopup();
   }
 };
 
-// Helper object for the history menu.
-var HistoryMenu = {
-  get _ss() {
-    delete this._ss;
-    return this._ss = Cc["@mozilla.org/browser/sessionstore;1"].
-                      getService(Ci.nsISessionStore);
-  },
+// View for the history menu.
+function HistoryMenu(aPopupShowingEvent) {
+  XPCOMUtils.defineLazyServiceGetter(this, "_ss",
+                                     "@mozilla.org/browser/sessionstore;1",
+                                     "nsISessionStore");
+  PlacesMenu.call(this, aPopupShowingEvent,
+                  "place:redirectsMode=2&sort=4&maxResults=10");
+}
 
-  toggleRecentlyClosedTabs: function PHM_toggleRecentlyClosedTabs() {
+HistoryMenu.prototype = {
+  __proto__: PlacesMenu.prototype,
+
+  toggleRecentlyClosedTabs: function HM_toggleRecentlyClosedTabs() {
     // enable/disable the Recently Closed Tabs sub menu
     var undoPopup = document.getElementById("historyUndoPopup");
 
     // no restorable tabs, so disable menu
     if (this._ss.getClosedTabCount(window) == 0)
       undoPopup.parentNode.setAttribute("disabled", true);
     else
       undoPopup.parentNode.removeAttribute("disabled");
@@ -733,50 +737,38 @@ var HistoryMenu = {
     let m = undoPopup.appendChild(document.createElement("menuitem"));
     m.id = "menu_restoreAllWindows";
     m.setAttribute("label", gNavigatorBundle.getString("menuRestoreAllWindows.label"));
     m.setAttribute("accesskey", gNavigatorBundle.getString("menuRestoreAllWindows.accesskey"));
     m.setAttribute("oncommand",
       "for (var i = 0; i < " + undoItems.length + "; i++) undoCloseWindow();");
   },
 
-  /**
-   * popupshowing handler for the history menu.
-   * @param aEvent
-   *        The popupshowing event.
-   */
-  onPopupShowing: function PHM_onPopupShowing(aEvent) {
+  _onPopupShowing: function HM__onPopupShowing(aEvent) {
+    PlacesMenu.prototype._onPopupShowing.apply(this, arguments);
+
     // Don't handle events for submenus.
     if (aEvent.target != aEvent.currentTarget)
       return;
 
-    var menuPopup = aEvent.target;
-    var resultNode = menuPopup.getResultNode();
+    let resultNode = this.result.root;
     resultNode.containerOpen = true;
     document.getElementById("endHistorySeparator").hidden =
       resultNode.childCount == 0;
 
     this.toggleRecentlyClosedTabs();
     this.toggleRecentlyClosedWindows();
   },
 
-  /**
-   * popuphidden handler for the history menu.
-   * @param aEvent
-   *        The popuphidden event.
-   */
-  onPopupHidden: function PHM_onPopupHidden(aEvent) {
-    // Don't handle events for submenus.
-    if (aEvent.target != aEvent.currentTarget)
-      return;
-
-    var menuPopup = aEvent.target;
-    var resultNode = menuPopup.getResultNode();
-    if (resultNode.containerOpen)
-      resultNode.containerOpen = false;
+  _onCommand: function HM__onCommand(aEvent) {
+    let placesNode = aEvent.target._placesNode;
+    if (placesNode) {
+      PlacesUIUtils.markPageAsTyped(placesNode.uri);
+      openUILink(placesNode.uri, aEvent, false, true);
+    }
   }
 };
 
 /**
  * Functions for handling events in the Bookmarks Toolbar and menu.
  */
 var BookmarksEventHandler = {  
   /**
@@ -805,136 +797,40 @@ var BookmarksEventHandler = {
       for (node = target.parentNode; node; node = node.parentNode) {
         if (node.localName == "menupopup")
           node.hidePopup();
         else if (node.localName != "menu")
           break;
       }
     }
 
-    if (target.node && PlacesUtils.nodeIsContainer(target.node)) {
+    if (target._placesNode && PlacesUtils.nodeIsContainer(target._placesNode)) {
       // Don't open the root folder in tabs when the empty area on the toolbar
       // is middle-clicked or when a non-bookmark item except for Open in Tabs)
       // in a bookmarks menupopup is middle-clicked.
       if (target.localName == "menu" || target.localName == "toolbarbutton")
-        PlacesUIUtils.openContainerNodeInTabs(target.node, aEvent);
+        PlacesUIUtils.openContainerNodeInTabs(target._placesNode, aEvent);
     }
     else if (aEvent.button == 1) {
       // left-clicks with modifier are already served by onCommand
       this.onCommand(aEvent);
     }
   },
 
   /**
    * Handler for command event for an item in the bookmarks toolbar.
    * Menus and submenus from the folder buttons bubble up to this handler.
    * Opens the item.
    * @param aEvent 
    *        DOMEvent for the command
    */
   onCommand: function BM_onCommand(aEvent) {
     var target = aEvent.originalTarget;
-    if (target.node)
-      PlacesUIUtils.openNodeWithEvent(target.node, aEvent);
-  },
-
-  /**
-   * Handler for popupshowing event for an item in bookmarks toolbar or menu.
-   * If the item isn't the main bookmarks menu, add an "Open All in Tabs"
-   * menuitem to the bottom of the popup.
-   * @param event 
-   *        DOMEvent for popupshowing
-   */
-  onPopupShowing: function BM_onPopupShowing(event) {
-    var target = event.originalTarget;
-    if (!target.hasAttribute("placespopup"))
-      return;
-
-    // Check if the popup contains at least 2 menuitems with places nodes
-    var numNodes = 0;
-    var hasMultipleURIs = false;
-    var currentChild = target.firstChild;
-    while (currentChild) {
-      if (currentChild.localName == "menuitem" && currentChild.node) {
-        if (++numNodes == 2) {
-          hasMultipleURIs = true;
-          break;
-        }
-      }
-      currentChild = currentChild.nextSibling;
-    }
-
-    var itemId = target._resultNode.itemId;
-    var siteURIString = "";
-    if (itemId != -1 && PlacesUtils.itemIsLivemark(itemId)) {
-      var siteURI = PlacesUtils.livemarks.getSiteURI(itemId);
-      if (siteURI)
-        siteURIString = siteURI.spec;
-    }
-
-    if (!siteURIString && target._endOptOpenSiteURI) {
-        target.removeChild(target._endOptOpenSiteURI);
-        target._endOptOpenSiteURI = null;
-    }
-
-    if (!hasMultipleURIs && target._endOptOpenAllInTabs) {
-      target.removeChild(target._endOptOpenAllInTabs);
-      target._endOptOpenAllInTabs = null;
-    }
-
-    if (!(hasMultipleURIs || siteURIString)) {
-      // we don't have to show any option
-      if (target._endOptSeparator) {
-        target.removeChild(target._endOptSeparator);
-        target._endOptSeparator = null;
-        target._endMarker = -1;
-      }
-      return;
-    }
-
-    if (!target._endOptSeparator) {
-      // create a separator before options
-      target._endOptSeparator = document.createElement("menuseparator");
-      target._endOptSeparator.className = "bookmarks-actions-menuseparator";
-      target._endMarker = target.childNodes.length;
-      target.appendChild(target._endOptSeparator);
-    }
-
-    if (siteURIString && !target._endOptOpenSiteURI) {
-      // Add "Open (Feed Name)" menuitem if it's a livemark with a siteURI
-      target._endOptOpenSiteURI = document.createElement("menuitem");
-      target._endOptOpenSiteURI.className = "openlivemarksite-menuitem";
-      target._endOptOpenSiteURI.setAttribute("targetURI", siteURIString);
-      target._endOptOpenSiteURI.setAttribute("oncommand",
-          "openUILink(this.getAttribute('targetURI'), event);");
-      // If a user middle-clicks this item we serve the oncommand event
-      // We are using checkForMiddleClick because of Bug 246720
-      // Note: stopPropagation is needed to avoid serving middle-click
-      // with BT_onClick that would open all items in tabs
-      target._endOptOpenSiteURI.setAttribute("onclick",
-          "checkForMiddleClick(this, event); event.stopPropagation();");
-      target._endOptOpenSiteURI.setAttribute("label",
-          PlacesUIUtils.getFormattedString("menuOpenLivemarkOrigin.label",
-          [target.parentNode.getAttribute("label")]));
-      target.appendChild(target._endOptOpenSiteURI);
-    }
-
-    if (hasMultipleURIs && !target._endOptOpenAllInTabs) {
-        // Add the "Open All in Tabs" menuitem if there are
-        // at least two menuitems with places result nodes.
-        target._endOptOpenAllInTabs = document.createElement("menuitem");
-        target._endOptOpenAllInTabs.className = "openintabs-menuitem";
-        target._endOptOpenAllInTabs.setAttribute("oncommand",
-            "PlacesUIUtils.openContainerNodeInTabs(this.parentNode._resultNode, event);");
-        target._endOptOpenAllInTabs.setAttribute("onclick",
-            "checkForMiddleClick(this, event); event.stopPropagation();");
-        target._endOptOpenAllInTabs.setAttribute("label",
-            gNavigatorBundle.getString("menuOpenAllInTabs.label"));
-        target.appendChild(target._endOptOpenAllInTabs);
-    }
+    if (target._placesNode)
+      PlacesUIUtils.openNodeWithEvent(target._placesNode, aEvent);
   },
 
   fillInBHTooltip: function(aDocument, aEvent) {
     var node;
     var cropped = false;
     var targetURI;
 
     if (aDocument.tooltipNode.localName == "treechildren") {
@@ -946,18 +842,18 @@ var BookmarksEventHandler = {
         return false;
       node = tree.view.nodeForTreeIndex(row.value);
       cropped = tbo.isCellCropped(row.value, column.value);
     }
     else {
       // Check whether the tooltipNode is a Places node.
       // In such a case use it, otherwise check for targetURI attribute.
       var tooltipNode = aDocument.tooltipNode;
-      if (tooltipNode.node)
-        node = tooltipNode.node;
+      if (tooltipNode._placesNode)
+        node = tooltipNode._placesNode;
       else {
         // This is a static non-Places node.
         targetURI = tooltipNode.getAttribute("targetURI");
       }
     }
 
     if (!node && !targetURI)
       return false;
@@ -1193,8 +1089,40 @@ var PlacesStarButton = {
                                             aLastModified, aItemType) {
     if (!this._batching && aProperty == "uri")
       this.updateState();
   },
 
   onItemVisited: function() { },
   onItemMoved: function() { }
 };
+
+// This object handles the initlization and uninitlization of the bookmarks
+// toolbar.  updateState is called when the browser window is opened and
+// after closing the toolbar customization dialog.
+let PlacesToolbarHelper = {
+  _place: "place:folder=TOOLBAR",
+  _cachedElt: null,
+
+  onBrowserWindowClose: function PTH_onBrowserWindowClose() {
+    if (this._cachedElt)
+      this._cachedElt._placesView.uninit();
+  },
+
+  updateState: function PTH_updateState() {
+    let currentElt = document.getElementById("PlacesToolbar");
+
+    // Bail out if the state has not changed.
+    if (currentElt == this._cachedElt)
+      return;
+
+    if (!this._cachedElt) {
+      // The toolbar has been added.
+      new PlacesToolbar(this._place);
+      this._cachedElt = currentElt;
+    }
+    else {
+      // The toolbar has been removed.
+      this._cachedElt._placesView.uninit();
+      this._cachedElt = null;
+    }
+  }
+};
--- a/browser/base/content/browser-tabPreviews.js
+++ b/browser/base/content/browser-tabPreviews.js
@@ -305,22 +305,24 @@ var ctrlTab = {
       aPreview.hidden = true;
       aPreview.removeAttribute("label");
       aPreview.removeAttribute("tooltiptext");
       aPreview.removeAttribute("image");
     }
   },
 
   advanceFocus: function ctrlTab_advanceFocus(aForward) {
-    if (this.panel.state == "open") {
+    if (this._selectedIndex == -1) {
+      // No virtual selectedIndex, focus must be in the panel already.
       if (aForward)
         document.commandDispatcher.advanceFocus();
       else
         document.commandDispatcher.rewindFocus();
     } else {
+      // Focus isn't in the panel yet, so we maintain a virtual selectedIndex.
       do {
         this._selectedIndex += aForward ? 1 : -1;
         if (this._selectedIndex < 0)
           this._selectedIndex = this.previews.length - 1;
         else if (this._selectedIndex >= this.previews.length)
           this._selectedIndex = 0;
       } while (this.selected.hidden);
     }
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -592,28 +592,34 @@ const gXPInstallObserver = {
     }
     return null;
   },
 
   observe: function (aSubject, aTopic, aData)
   {
     var brandBundle = document.getElementById("bundle_brand");
     switch (aTopic) {
-    case "xpinstall-install-blocked":
-      var installInfo = aSubject.QueryInterface(Components.interfaces.nsIXPIInstallInfo);
+    case "addon-install-blocked":
+      var installInfo = aSubject.QueryInterface(Components.interfaces.amIWebInstallInfo);
       var win = installInfo.originatingWindow;
       var shell = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                      .getInterface(Components.interfaces.nsIWebNavigation)
                      .QueryInterface(Components.interfaces.nsIDocShell);
       var browser = this._getBrowser(shell);
       if (browser) {
         var host = installInfo.originatingURI.host;
         var brandShortName = brandBundle.getString("brandShortName");
         var notificationName, messageString, buttons;
-        if (!gPrefService.getBoolPref("xpinstall.enabled")) {
+        var enabled = true;
+        try {
+          enabled = gPrefService.getBoolPref("xpinstall.enabled");
+        }
+        catch (e) {
+        }
+        if (!enabled) {
           notificationName = "xpinstall-disabled"
           if (gPrefService.prefIsLocked("xpinstall.enabled")) {
             messageString = gNavigatorBundle.getString("xpinstallDisabledMessageLocked");
             buttons = [];
           }
           else {
             messageString = gNavigatorBundle.getFormattedString("xpinstallDisabledMessage",
                                                                 [brandShortName, host]);
@@ -634,19 +640,17 @@ const gXPInstallObserver = {
           messageString = gNavigatorBundle.getFormattedString("xpinstallPromptWarning",
                                                               [brandShortName, host]);
 
           buttons = [{
             label: gNavigatorBundle.getString("xpinstallPromptAllowButton"),
             accessKey: gNavigatorBundle.getString("xpinstallPromptAllowButton.accesskey"),
             popup: null,
             callback: function() {
-              var mgr = Components.classes["@mozilla.org/xpinstall/install-manager;1"]
-                                  .createInstance(Components.interfaces.nsIXPInstallManager);
-              mgr.initManagerWithInstallInfo(installInfo);
+              installInfo.install();
               return false;
             }
           }];
         }
 
         var notificationBox = gBrowser.getNotificationBox(browser);
         if (!notificationBox.getNotificationWithValue(notificationName)) {
           const priority = notificationBox.PRIORITY_WARNING_MEDIUM;
@@ -1178,17 +1182,17 @@ function prepareForStartup() {
                             OfflineApps, false);
 
   // setup simple gestures support
   gGestureSupport.init(true);
 }
 
 function delayedStartup(isLoadingBlank, mustLoadSidebar) {
   Services.obs.addObserver(gSessionHistoryObserver, "browser:purge-session-history", false);
-  Services.obs.addObserver(gXPInstallObserver, "xpinstall-install-blocked", false);
+  Services.obs.addObserver(gXPInstallObserver, "addon-install-blocked", false);
 
   BrowserOffline.init();
   OfflineApps.init();
 
   gBrowser.addEventListener("pageshow", function(evt) { setTimeout(pageShowEventHandlers, 0, evt); }, true);
 
   // Ensure login manager is up and running.
   Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager);
@@ -1296,16 +1300,18 @@ function delayedStartup(isLoadingBlank, 
   try {
     Cc["@mozilla.org/browser/sessionstore;1"]
       .getService(Ci.nsISessionStore)
       .init(window);
   } catch (ex) {
     dump("nsSessionStore could not be initialized: " + ex + "\n");
   }
 
+  PlacesToolbarHelper.updateState();
+
   // bookmark-all-tabs command
   gBookmarkAllTabsHandler.init();
 
   // Attach a listener to watch for "command" events bubbling up from error
   // pages.  This lets us fix bugs like 401575 which require error page UI to
   // do privileged things, without letting error pages have any privilege
   // themselves.
   gBrowser.addEventListener("command", BrowserOnCommand, false);
@@ -1396,17 +1402,17 @@ function BrowserShutdown()
   try {
     FullZoom.destroy();
   }
   catch(ex) {
     Components.utils.reportError(ex);
   }
 
   Services.obs.removeObserver(gSessionHistoryObserver, "browser:purge-session-history");
-  Services.obs.removeObserver(gXPInstallObserver, "xpinstall-install-blocked");
+  Services.obs.removeObserver(gXPInstallObserver, "addon-install-blocked");
   Services.obs.removeObserver(gPluginHandler.pluginCrashed, "plugin-crashed");
 
   try {
     gBrowser.removeProgressListener(window.XULBrowserWindow);
     gBrowser.removeTabsProgressListener(window.TabsProgressListener);
   } catch (ex) {
   }
 
@@ -3346,16 +3352,18 @@ function BrowserToolboxCustomizeDone(aTo
         document.getElementById('Browser:Back').hasAttribute('disabled') &&
         document.getElementById('Browser:Forward').hasAttribute('disabled');
 
 #ifndef XP_MACOSX
     updateEditUIVisibility();
 #endif
   }
 
+  PlacesToolbarHelper.updateState();
+
   UpdateUrlbarSearchSplitterState();
 
   CombinedStopReload.init();
 
   // Update the urlbar
   if (gURLBar) {
     URLBarSetURI();
     XULBrowserWindow.asyncUpdateUI();
@@ -5714,31 +5722,18 @@ var MailIntegration = {
        Cc["@mozilla.org/uriloader/external-protocol-service;1"]
          .getService(Ci.nsIExternalProtocolService);
     if (extProtocolSvc)
       extProtocolSvc.loadUrl(aURL);
   }
 };
 
 function BrowserOpenAddonsMgr(aPane) {
-  const EMTYPE = "Extension:Manager";
-  var theEM = Services.wm.getMostRecentWindow(EMTYPE);
-  if (theEM) {
-    theEM.focus();
-    if (aPane)
-      theEM.showView(aPane);
-    return;
-  }
-
-  const EMURL = "chrome://mozapps/content/extensions/extensions.xul";
-  const EMFEATURES = "chrome,menubar,extra-chrome,toolbar,dialog=no,resizable";
-  if (aPane)
-    window.openDialog(EMURL, "", EMFEATURES, aPane);
-  else
-    window.openDialog(EMURL, "", EMFEATURES);
+  // TODO need to implement switching to the relevant view - see bug 560449
+  switchToTabHavingURI("about:addons", true);
 }
 
 function AddKeywordForSearchField() {
   var node = document.popupNode;
 
   var charset = node.ownerDocument.characterSet;
 
   var docURI = makeURI(node.ownerDocument.URL,
@@ -7511,44 +7506,38 @@ var LightWeightThemeWebInstaller = {
     gBrowser.tabContainer.removeEventListener("TabSelect", this, false);
 
     this._manager.resetPreview();
   },
 
   _isAllowed: function (node) {
     var pm = Services.perms;
 
-    var prefs = [["xpinstall.whitelist.add", pm.ALLOW_ACTION],
-                 ["xpinstall.whitelist.add.36", pm.ALLOW_ACTION],
-                 ["xpinstall.blacklist.add", pm.DENY_ACTION]];
-    prefs.forEach(function ([pref, permission]) {
-      try {
-        var hosts = gPrefService.getCharPref(pref);
-      } catch (e) {}
-
-      if (hosts) {
-        hosts.split(",").forEach(function (host) {
-          pm.add(makeURI("http://" + host), "install", permission);
-        });
-
-        gPrefService.setCharPref(pref, "");
-      }
-    });
-
     var uri = node.ownerDocument.documentURIObject;
     return pm.testPermission(uri, "install") == pm.ALLOW_ACTION;
   },
 
   _getThemeFromNode: function (node) {
     return this._manager.parseTheme(node.getAttribute("data-browsertheme"),
                                     node.baseURI);
   }
 }
 
-function switchToTabHavingURI(aURI) {
+/**
+ * Switch to a tab that has a given URI, and focusses its browser window.
+ * If a matching tab is in this window, it will be switched to. Otherwise, other
+ * windows will be searched.
+ *
+ * @param aURI
+ *        URI to search for
+ * @param aOpenNew
+ *        True to open a new tab and switch to it, if no existing tab is found
+ * @return True if a tab was switched to (or opened), false otherwise
+ */
+function switchToTabHavingURI(aURI, aOpenNew) {
   function switchIfURIInWindow(aWindow) {
     if (!("gBrowser" in aWindow))
       return false;
     let browsers = aWindow.gBrowser.browsers;
     for (let i = 0; i < browsers.length; i++) {
       let browser = browsers[i];
       if (browser.currentURI.equals(aURI)) {
         gURLBar.handleRevert();
@@ -7573,17 +7562,23 @@ function switchToTabHavingURI(aURI) {
     let browserWin = winEnum.getNext();
     // Skip closed (but not yet destroyed) windows,
     // and the current window (which was checked earlier).
     if (browserWin.closed || browserWin == window)
       continue;
     if (switchIfURIInWindow(browserWin))
       return true;
   }
+
   // No opened tab has that url.
+  if (aOpenNew) {
+    gBrowser.selectedTab = gBrowser.addTab(aURI.spec);
+    return true;
+  }
+
   return false;
 }
 
 var TabContextMenu = {
   contextTab: null,
   updateContextMenu: function updateContextMenu(aPopupMenu) {
     this.contextTab = document.popupNode.localName == "tab" ?
                       document.popupNode : gBrowser.selectedTab;
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -545,24 +545,50 @@
              defaultset="personal-bookmarks"
              toolbarname="&personalbarCmd.label;" accesskey="&personalbarCmd.accesskey;"
 #ifdef WINCE
              collapsed="true"
 #endif
              customizable="true">
       <toolbaritem flex="1" id="personal-bookmarks" title="&bookmarksItem.title;"
                    removable="true">
-         <hbox id="bookmarksBarContent" flex="1"
-               type="places"
-               place="place:folder=TOOLBAR"
-               context="placesContext"
-               onclick="BookmarksEventHandler.onClick(event);"
-               oncommand="BookmarksEventHandler.onCommand(event);"
-               onpopupshowing="BookmarksEventHandler.onPopupShowing(event);"
-               tooltip="bhTooltip" popupsinherittooltip="true"/>
+        <hbox flex="1"
+              id="PlacesToolbar"
+              context="placesContext"
+              onclick="BookmarksEventHandler.onClick(event);"
+              oncommand="BookmarksEventHandler.onCommand(event);"
+              tooltip="bhTooltip"
+              popupsinherittooltip="true">
+          <toolbarbutton class="bookmark-item bookmarks-toolbar-customize"
+                         mousethrough="never"
+                         label="&bookmarksToolbarItem.label;"/>
+          <hbox flex="1">
+            <hbox align="center">
+              <image id="PlacesToolbarDropIndicator"
+                     mousethrough="always"
+                     collapsed="true"/>
+            </hbox>
+            <scrollbox orient="horizontal"
+                       id="PlacesToolbarItems"
+                       flex="1"/>
+            <toolbarbutton type="menu"
+                           id="PlacesChevron"
+                           class="chevron"
+                           mousethrough="never"
+                           collapsed="true"
+                           tooltiptext="&bookmarksToolbarChevron.tooltip;"
+                           onpopupshowing="document.getElementById('PlacesToolbar')
+                                                   ._placesView._onChevronPopupShowing(event);">
+              <menupopup id="PlacesChevronPopup"
+                         placespopup="true"
+                         popupsinherittooltip="true"
+                         context="placesContext"/>
+            </toolbarbutton>
+          </hbox>
+        </hbox>
       </toolbaritem>
     </toolbar>
 
     <toolbar id="TabsToolbar"
              fullscreentoolbar="true"
              customizable="true"
              mode="icons" lockmode="true"
              iconsize="small" defaulticonsize="small" lockiconsize="true"
--- a/browser/base/content/global-scripts.inc
+++ b/browser/base/content/global-scripts.inc
@@ -34,11 +34,12 @@
 # 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 *****
 
 <script type="application/javascript" src="chrome://global/content/printUtils.js"/>
 <script type="application/javascript" src="chrome://global/content/viewZoomOverlay.js"/>
+<script type="application/javascript" src="chrome://browser/content/places/browserPlacesViews.js"/>
 <script type="application/javascript" src="chrome://browser/content/browser.js"/>
 <script type="application/javascript" src="chrome://global/content/inlineSpellCheckUI.js"/>
 <script type="application/javascript" src="chrome://global/content/viewSourceUtils.js"/>
--- a/browser/base/content/pageinfo/pageInfo.css
+++ b/browser/base/content/pageinfo/pageInfo.css
@@ -1,11 +1,11 @@
 
 #viewGroup > radio {
-  -moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#viewbutton");
+  -moz-binding: url("chrome://browser/content/pageinfo/pageInfo.xml#viewbutton");
 }
 
 richlistitem[feed] {
   -moz-binding: url("chrome://browser/content/pageinfo/feeds.xml#feed");
 }
 
 richlistitem[feed]:not([selected="true"]) .feed-subscribe {
   display: none;
new file mode 100644
--- /dev/null
+++ b/browser/base/content/pageinfo/pageInfo.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+
+<bindings id="pageInfoBindings"
+          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">
+
+  <!-- based on preferences.xml paneButton -->
+  <binding id="viewbutton" extends="chrome://global/content/bindings/radio.xml#radio">
+    <content>
+      <xul:image class="viewButtonIcon" xbl:inherits="src"/>
+      <xul:label class="viewButtonLabel" xbl:inherits="value=label"/>
+    </content>
+    <implementation implements="nsIAccessibleProvider">
+      <property name="accessibleType" readonly="true">
+        <getter>
+          <![CDATA[
+            return Components.interfaces.nsIAccessibleProvider.XULListitem;
+          ]]>
+        </getter>
+      </property>
+    </implementation>
+  </binding>
+
+</bindings>
--- a/browser/base/content/pageinfo/permissions.js
+++ b/browser/base/content/pageinfo/permissions.js
@@ -58,19 +58,23 @@ var gPermObj = {
   popup: function getPopupDefaultPermission()
   {
     if (gPrefs.getBoolPref("dom.disable_open_during_load"))
       return BLOCK;
     return ALLOW;
   },
   install: function getInstallDefaultPermission()
   {
-    if (gPrefs.getBoolPref("xpinstall.whitelist.required"))
-      return BLOCK;
-    return ALLOW;
+    try {
+      if (!gPrefs.getBoolPref("xpinstall.whitelist.required"))
+        return ALLOW;
+    }
+    catch (e) {
+    }
+    return BLOCK;
   },
   geo: function getGeoDefaultPermissions()
   {
       return BLOCK;
   }
 };
 
 var permissionObserver = {
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -2197,17 +2197,17 @@
                 this.mTabBox.handleCtrlPageUpDown) {
               this.removeCurrentTab();
 
               aEvent.stopPropagation();
               aEvent.preventDefault();
               return;
             }
 #endif
-            if (aEvent.target == this) {
+            if (aEvent.target.parentNode == this.tabContainer) {
               switch (aEvent.keyCode) {
                 case KeyEvent.DOM_VK_UP:
                   this.moveTabBackward();
                   break;
                 case KeyEvent.DOM_VK_DOWN:
                   this.moveTabForward();
                   break;
                 case KeyEvent.DOM_VK_RIGHT:
--- a/browser/base/content/test/browser_customize.js
+++ b/browser/base/content/test/browser_customize.js
@@ -18,18 +18,20 @@ function testCustomizeFrameLoadedPre(){
 function testCustomizeFrameLoaded()
 {
   var panel = document.getElementById("customizeToolbarSheetPopup");
   panel.addEventListener("popuphidden", testCustomizePopupHidden, false);
 
   var frame = document.getElementById("customizeToolbarSheetIFrame");
   frame.removeEventListener("load", testCustomizeFrameLoadedPre, true);
 
-  var menu = document.getElementById("bookmarksMenuPopup");
-  ok("getResult" in menu, "menu has binding");
+  if (navigator.platform.indexOf("Mac") == -1) {
+    var menu = document.getElementById("bookmarksMenuPopup");
+    ok("result" in menu, "menu has binding");
+  }
 
   var framedoc = document.getElementById("customizeToolbarSheetIFrame").contentDocument;
   var b = framedoc.getElementById("donebutton");
 
   b.focus();
   framedoc.getElementById("donebutton").doCommand();
 }
   
--- a/browser/base/content/test/browser_pluginnotification.js
+++ b/browser/base/content/test/browser_pluginnotification.js
@@ -1,76 +1,67 @@
 const gTestRoot = "chrome://mochikit/content/browser/browser/base/content/test/";
 
 var gTestBrowser = null;
 var gNextTest = null;
 
 function get_test_plugin() {
   var ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
   var tags = ph.getPluginTags();
-  
+
   // Find the test plugin
   for (var i = 0; i < tags.length; i++) {
     if (tags[i].name == "Test Plug-in")
       return tags[i];
   }
 }
 
-// This listens for the next opened window and checks it is of the right url.
-// opencallback is called when the new window is fully loaded
-// closecallback is called when the window is closed
-function WindowOpenListener(url, opencallback, closecallback) {
+// This listens for the next opened tab and checks it is of the right url.
+// opencallback is called when the new tab is fully loaded
+// closecallback is called when the tab is closed
+function TabOpenListener(url, opencallback, closecallback) {
   this.url = url;
   this.opencallback = opencallback;
   this.closecallback = closecallback;
 
-  Services.wm.addListener(this);
+  gBrowser.tabContainer.addEventListener("TabOpen", this, false);
 }
 
-WindowOpenListener.prototype = {
+TabOpenListener.prototype = {
   url: null,
   opencallback: null,
   closecallback: null,
-  window: null,
-  domwindow: null,
+  tab: null,
+  browser: null,
 
   handleEvent: function(event) {
-    is(this.domwindow.document.location.href, this.url, "Should have opened the correct window");
-
-    this.domwindow.removeEventListener("load", this, false);
-    // Allow any other load handlers to execute
-    var self = this;
-    executeSoon(function() { self.opencallback(self.domwindow); } );
-  },
-
-  onWindowTitleChange: function(window, title) {
-  },
-
-  onOpenWindow: function(window) {
-    if (this.window)
-      return;
-
-    this.window = window;
-    this.domwindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
-                           .getInterface(Components.interfaces.nsIDOMWindowInternal);
-    this.domwindow.addEventListener("load", this, false);
-  },
-
-  onCloseWindow: function(window) {
-    if (this.window != window)
-      return;
-
-    Services.wm.removeListener(this);
-    this.opencallback = null;
-    this.window = null;
-    this.domwindow = null;
-
-    // Let the window close complete
-    executeSoon(this.closecallback);
-    this.closecallback = null;
+    if (event.type == "TabOpen") {
+      gBrowser.tabContainer.removeEventListener("TabOpen", this, false);
+      this.tab = event.originalTarget;
+      this.browser = this.tab.linkedBrowser;
+      gBrowser.addEventListener("load", this, true);
+    } else if (event.type == "load") {
+      gBrowser.removeEventListener("load", this, true);
+      this.tab.addEventListener("TabClose", this, false);
+      var url = this.browser.contentDocument.location.href;
+      is(url, this.url, "Should have opened the correct tab");
+      // Allow any other load handlers to execute
+      var self = this;
+      executeSoon(function() { self.opencallback(self.tab, self.browser.contentWindow); } );
+    } else if (event.type == "TabClose") {
+      if (event.originalTarget != this.tab)
+        return;
+      this.tab.removeEventListener("TabClose", this, false);
+      this.opencallback = null;
+      this.tab = null;
+      this.browser = null;
+      // Let the window close complete
+      executeSoon(this.closecallback);
+      this.closecallback = null;
+    }
   }
 };
 
 function test() {
   waitForExplicitFinish();
 
   var newTab = gBrowser.addTab();
   gBrowser.selectedTab = newTab;
@@ -128,25 +119,25 @@ function test2() {
 
 // Tests a page with a disabled plugin in it.
 function test3() {
   var notificationBox = gBrowser.getNotificationBox(gTestBrowser);
   ok(!notificationBox.getNotificationWithValue("missing-plugins"), "Test 3, Should not have displayed the missing plugin notification");
   ok(!notificationBox.getNotificationWithValue("blocked-plugins"), "Test 3, Should not have displayed the blocked plugin notification");
   ok(!gTestBrowser.missingPlugins, "Test 3, Should not be a missing plugin list");
 
-  new WindowOpenListener("chrome://mozapps/content/extensions/extensions.xul", test4, prepareTest5);
+  new TabOpenListener("about:addons", test4, prepareTest5);
 
   EventUtils.synthesizeMouse(gTestBrowser.contentDocument.getElementById("test"),
                              0, 0, {}, gTestBrowser.contentWindow);
 }
 
-function test4(win) {
-  is(win.gView, "plugins", "Should have displayed the plugins pane");
-  win.close();
+function test4(tab, win) {
+  todo_is(win.gView, "plugins", "Should have displayed the plugins pane");
+  gBrowser.removeTab(tab);
 }
 
 function prepareTest5() {
   var plugin = get_test_plugin();
   plugin.disabled = false;
   plugin.blocklisted = true;
   prepareTest(test5, gTestRoot + "plugin_test.html");
 }
--- a/browser/base/jar.mn
+++ b/browser/base/jar.mn
@@ -22,16 +22,17 @@ browser.jar:
 *       content/browser/browser.js                    (content/browser.js)
 *       content/browser/browser.xul                   (content/browser.xul)
 *       content/browser/browser-tabPreviews.xml       (content/browser-tabPreviews.xml)
 *       content/browser/credits.xhtml                 (content/credits.xhtml)
 *       content/browser/fullscreen-video.xhtml        (content/fullscreen-video.xhtml)
 *       content/browser/pageinfo/pageInfo.xul         (content/pageinfo/pageInfo.xul)
 *       content/browser/pageinfo/pageInfo.js          (content/pageinfo/pageInfo.js)
 *       content/browser/pageinfo/pageInfo.css         (content/pageinfo/pageInfo.css)
+*       content/browser/pageinfo/pageInfo.xml         (content/pageinfo/pageInfo.xml)
 *       content/browser/pageinfo/feeds.js             (content/pageinfo/feeds.js)
 *       content/browser/pageinfo/feeds.xml            (content/pageinfo/feeds.xml)
 *       content/browser/pageinfo/permissions.js       (content/pageinfo/permissions.js)
 *       content/browser/pageinfo/security.js          (content/pageinfo/security.js)
 *       content/browser/openLocation.js               (content/openLocation.js)
 *       content/browser/openLocation.xul              (content/openLocation.xul)
 *       content/browser/pageReportFirstTime.xul       (content/pageReportFirstTime.xul)
 *       content/browser/safeMode.js                   (content/safeMode.js)
new file mode 100644
--- /dev/null
+++ b/browser/components/places/content/browserPlacesViews.js
@@ -0,0 +1,1701 @@
+/* -*- Mode: C++; tab-width: 8; 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 Places Frontend Code.
+ *
+ * The Initial Developer of the Original Code is
+ * Google Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2005
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Annie Sullivan <annie.sullivan@gmail.com>
+ *   Ben Goodger <beng@google.com>
+ *   Myk Melez <myk@mozilla.org>
+ *   Marco Bonardo <mak77@bonardo.net>
+ *   Asaf Romano <mano@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 ***** */
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+/**
+ * The base view implements everything that's common to the toolbar and
+ * menu views.
+ */
+function PlacesViewBase(aPlace) {
+  this.place = aPlace;
+  this._controller = new PlacesController(this);
+  this._viewElt.controllers.appendController(this._controller);
+}
+
+PlacesViewBase.prototype = {
+  // The xul element that holds the entire view.
+  _viewElt: null,
+  get viewElt() this._viewElt,
+
+  // The xul element that represents the root container.
+  _rootElt: null,
+
+  // Set to true for views that are represented by native widgets (i.e.
+  // the native mac menu).
+  _nativeView: false,
+
+  QueryInterface: XPCOMUtils.generateQI(
+    [Components.interfaces.nsINavHistoryResultObserver,
+     Components.interfaces.nsISupportsWeakReference]),
+
+  _place: "",
+  get place() this._place,
+  set place(val) {
+    this._place = val;
+
+    let history = PlacesUtils.history;
+    let queries = { }, options = { };
+    history.queryStringToQueries(val, queries, { }, options);
+    if (!queries.value.length)
+      queries.value = [history.getNewQuery()];
+
+    let result = history.executeQueries(queries.value, queries.value.length,
+                                        options.value);
+    result.addObserver(this, false);
+    return val;
+  },
+
+  _result: null,
+  get result() this._result,
+  set result(val) {
+    if (this._result == val)
+      return;
+
+    if (this._result) {
+      this._result.removeObserver(this);
+      this._resultNode.containerOpen = false;
+    }
+
+    if (this._rootElt.localName == "menupopup")
+      this._rootElt._built = false;
+
+    this._result = val;
+    if (val) {
+      this._resultNode = val.root;
+      this._rootElt._placesNode = this._resultNode;
+      this._resultNode._DOMElement = this._rootElt;
+
+      // This calls _rebuild through invalidateContainer.
+      this._resultNode.containerOpen = true;
+    }
+    else {
+      this._resultNode = null;
+    }
+
+    return val;
+  },
+
+  get controller() this._controller,
+
+  get selType() "single",
+  selectItems: function() { },
+  selectAll: function() { },
+
+  get selectedNode() {
+    if (this._contextMenuShown) {
+      let popup = document.popupNode;
+      return popup._placesNode || popup.parentNode._placesNode || null;
+    }
+    return null;
+  },
+
+  get hasSelection() this.selectedNode != null,
+
+  get selectedNodes() {
+    let selectedNode = this.selectedNode;
+    return selectedNode ? [selectedNode] : [];
+  },
+
+  get removableSelectionRanges() {
+    // On static content the current selectedNode would be the selection's
+    // parent node. We don't want to allow removing a node when the
+    // selection is not explicit.
+    if (document.popupNode &&
+        (document.popupNode == "menupopup" || !document.popupNode._placesNode))
+      return [];
+
+    return [this.selectedNodes];
+  },
+
+  get draggableSelection() [this._draggedElt],
+
+  get insertionPoint() {
+    // There is no insertion point for history queries, so bail out now and
+    // save a lot of work when updating commands.
+    let resultNode = this._resultNode;
+    if (PlacesUtils.nodeIsQuery(resultNode) &&
+        PlacesUtils.asQuery(resultNode).queryOptions.queryType ==
+          Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY)
+      return null;
+
+    // By default, the insertion point is at the top level, at the end.
+    let index = PlacesUtils.bookmarks.DEFAULT_INDEX;
+    let container = this._resultNode;
+    let orientation = Ci.nsITreeView.DROP_BEFORE;
+    let isTag = false;
+
+    let selectedNode = this.selectedNode;
+    if (selectedNode) {
+      let popup = document.popupNode;
+      if (!popup._placesNode || popup._placesNode == this._resultNode) {
+        // If a static menuitem is selected, or if the root node is selected,
+        // the insertion point is inside the folder, at the end.
+        container = selectedNode;
+        orientation = Ci.nsITreeView.DROP_ON;
+      }
+      else {
+        // In all other cases the insertion point is before that node.
+        container = selectedNode.parent;
+        index = container.getChildIndex(selectedNode);
+        isTag = PlacesUtils.nodeIsTagQuery(container);
+      }
+    }
+
+    if (PlacesControllerDragHelper.disallowInsertion(container))
+      return null;
+
+    return new InsertionPoint(PlacesUtils.getConcreteItemId(container),
+                              index, orientation, isTag);
+  },
+
+  buildContextMenu: function PVB_buildContextMenu(aPopup) {
+    this._contextMenuShown = true;
+    window.updateCommands("places");
+    return this.controller.buildContextMenu(aPopup);
+  },
+
+  destroyContextMenu: function PVB_destroyContextMenu(aPopup) {
+    this._contextMenuShown = false;
+    if (window.content)
+      window.content.focus();
+  },
+
+  _cleanPopup: function PVB_cleanPopup(aPopup) {
+    // Remove places popup children and update markers to keep track of
+    // their indices.
+    let start = aPopup._startMarker != -1 ? aPopup._startMarker + 1 : 0;
+    let end = aPopup._endMarker != -1 ? aPopup._endMarker :
+                                        aPopup.childNodes.length;
+    let items = [];
+    let placesNodeFound = false;
+    for (let i = start; i < end; ++i) {
+      let item = aPopup.childNodes[i];
+      if (item.getAttribute("builder") == "end") {
+        // we need to do this for menus that have static content at the end but
+        // are initially empty, eg. the history menu, we need to know where to
+        // start inserting new items.
+        aPopup._endMarker = i;
+        break;
+      }
+      if (item._placesNode) {
+        items.push(item);
+        placesNodeFound = true;
+      }
+      else {
+        // This is static content...
+        if (!placesNodeFound)
+          // ...at the start of the popup
+          // Initialized in menu.xml, in the base binding
+          aPopup._startMarker++;
+        else {
+          // ...after places nodes
+          aPopup._endMarker = i;
+          break;
+        }
+      }
+    }
+
+    for (let i = 0; i < items.length; ++i) {
+      aPopup.removeChild(items[i]);
+      if (aPopup._endMarker != -1)
+        aPopup._endMarker--;
+    }
+  },
+
+  _rebuildPopup: function PVB__rebuildPopup(aPopup) {
+    this._cleanPopup(aPopup);
+
+    // If this is a livemark container check if the status menuitem has
+    // to be added or removed.
+    if (PlacesUtils.nodeIsLivemarkContainer(aPopup._placesNode))
+      this._ensureLivemarkStatusMenuItem(aPopup);
+
+    let resultNode = aPopup._placesNode;
+    if (!resultNode.containerOpen)
+      return;
+
+    let cc = resultNode.childCount;
+    if (cc > 0) {
+      if (aPopup._emptyMenuItem)
+        aPopup._emptyMenuItem.hidden = true;
+
+      for (let i = 0; i < cc; ++i) {
+        let child = resultNode.getChild(i);
+        this._insertNewItemToPopup(child, aPopup, null);
+      }
+    }
+    else {
+      // This menu is empty.  If there is no static content, add
+      // an element to show it is empty.
+      if (aPopup._startMarker == -1 && aPopup._endMarker == -1)
+        this._showEmptyMenuItem(aPopup);
+    }
+    aPopup._built = true;
+  },
+
+  _removeChild: function PVB__removeChild(aChild) {
+    // If document.popupNode pointed to this child, null it out,
+    // otherwise controller's command-updating may rely on the removed
+    // item still being "selected".
+    if (document.popupNode == aChild)
+      document.popupNode = null;
+
+    aChild.parentNode.removeChild(aChild);
+  },
+
+  _showEmptyMenuItem: function PVB__showEmptyMenuItem(aPopup) {
+    if (aPopup._emptyMenuItem) {
+      aPopup._emptyMenuItem.hidden = false;
+      return;
+    }
+
+    let label = PlacesUIUtils.getString("bookmarksMenuEmptyFolder");
+    aPopup._emptyMenuItem = document.createElement("menuitem");
+    aPopup._emptyMenuItem.setAttribute("label", label);
+    aPopup._emptyMenuItem.setAttribute("disabled", true);
+    aPopup.appendChild(aPopup._emptyMenuItem);
+  },
+
+  _createMenuItemForPlacesNode:
+  function PVB__createMenuItemForPlacesNode(aPlacesNode) {
+    let element;
+    let type = aPlacesNode.type;
+    if (type == Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR)
+      element = document.createElement("menuseparator");
+    else {
+      if (PlacesUtils.uriTypes.indexOf(type) != -1) {
+        element = document.createElement("menuitem");
+        element.className = "menuitem-iconic bookmark-item menuitem-with-favicon";
+        element.setAttribute("scheme",
+                             PlacesUIUtils.guessUrlSchemeForUI(aPlacesNode.uri));
+      }
+      else if (PlacesUtils.containerTypes.indexOf(type) != -1) {
+        element = document.createElement("menu");
+        element.setAttribute("container", "true");
+
+        if (aPlacesNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY) {
+          element.setAttribute("query", "true");
+          if (PlacesUtils.nodeIsTagQuery(aPlacesNode))
+            element.setAttribute("tagContainer", "true");
+          else if (PlacesUtils.nodeIsDay(aPlacesNode))
+            element.setAttribute("dayContainer", "true");
+          else if (PlacesUtils.nodeIsHost(aPlacesNode))
+            element.setAttribute("hostContainer", "true");
+        }
+        else if (aPlacesNode.itemId != -1) {
+          if (PlacesUtils.nodeIsLivemarkContainer(aPlacesNode))
+            element.setAttribute("livemark", "true");
+        }
+
+        let popup = document.createElement("menupopup");
+        popup._placesNode = PlacesUtils.asContainer(aPlacesNode);
+        if (this._nativeView) {
+          popup._startMarker = -1;
+          popup._endMarker = -1;
+        }
+        else
+          popup.setAttribute("placespopup", "true");
+#ifdef XP_MACOSX
+        // No context menu on mac.
+        popup.setAttribute("context", "placesContext");
+#endif
+        element.appendChild(popup);
+        element.className = "menu-iconic bookmark-item";
+
+        aPlacesNode._DOMElement = popup;
+      }
+      else
+        throw "Unexpected node";
+
+      element.setAttribute("label", PlacesUIUtils.getBestTitle(aPlacesNode));
+
+      let icon = aPlacesNode.icon;
+      if (icon)
+        element.setAttribute("image", icon);
+    }
+
+    element._placesNode = aPlacesNode;
+    if (!aPlacesNode._DOMElement)
+      aPlacesNode._DOMElement = element;
+
+    return element;
+  },
+
+  _insertNewItemToPopup:
+  function PVB__insertNewItemToPopup(aNewChild, aPopup, aBefore) {
+    let element = this._createMenuItemForPlacesNode(aNewChild);
+
+    if (aBefore) {
+      aPopup.insertBefore(element, aBefore);
+    }
+    else {
+      // Add the new element to the menu.  If there is static content at
+      // the end of the menu, add the element before that.  Otherwise,
+      // just add to the end.
+      if (aPopup._endMarker != -1) {
+        let lastElt = aPopup.childNodes[aPopup._endMarker];
+        aPopup.insertBefore(element, lastElt);
+      }
+      else {
+        aPopup.appendChild(element);
+      }
+    }
+
+    if (aPopup._endMarker != -1)
+      aPopup._endMarker++;
+
+    return element;
+  },
+
+  /**
+   * Add, update or remove the livemark status menuitem.
+   * @param aPopup
+   *        The livemark container popup
+   */
+  _ensureLivemarkStatusMenuItem:
+  function PVB_ensureLivemarkStatusMenuItem(aPopup) {
+    let itemId = aPopup._placesNode.itemId;
+    let as = PlacesUtils.annotations;
+
+    let lmStatus = null;
+    if (as.itemHasAnnotation(itemId, "livemark/loadfailed"))
+      lmStatus = "bookmarksLivemarkFailed";
+    else if (as.itemHasAnnotation(itemId, "livemark/loading"))
+      lmStatus = "bookmarksLivemarkLoading";
+
+    let lmStatusElt = aPopup._lmStatusMenuItem;
+    if (lmStatus && !lmStatusElt) {
+      // Create the status menuitem and cache it in the popup object.
+      lmStatusElt = document.createElement("menuitem");
+      lmStatusElt.setAttribute("lmStatus", lmStatus);
+      lmStatusElt.setAttribute("label", PlacesUIUtils.getString(lmStatus));
+      lmStatusElt.setAttribute("disabled", true);
+      aPopup.insertBefore(lmStatusElt,
+                          aPopup.childNodes.item(aPopup._startMarker + 1));
+      aPopup._lmStatusMenuItem = lmStatusElt;
+      aPopup._startMarker++;
+    }
+    else if (lmStatus && lmStatusElt.getAttribute("lmStatus") != lmStatus) {
+      // Status has changed, update the cached status menuitem.
+      lmStatusElt.setAttribute("label", this.getString(lmStatus));
+    }
+    else if (!lmStatus && lmStatusElt) {
+      // No status, remove the cached menuitem.
+      aPopup.removeChild(aPopup._lmStatusMenuItem);
+      aPopup._lmStatusMenuItem = null;
+      aPopup._startMarker--;
+    }
+  },
+
+  nodeURIChanged: function PVB_nodeURIChanged(aPlacesNode, aURIString) {
+    let elt = aPlacesNode._DOMElement;
+    if (!elt)
+      throw "aPlacesNode must have _DOMElement set";
+
+    // Here we need the <menu>.
+    if (elt.localName == "menupopup")
+      elt = elt.parentNode;
+
+    elt.setAttribute("scheme", PlacesUIUtils.guessUrlSchemeForUI(aURIString));
+  },
+
+  nodeIconChanged: function PT_nodeIconChanged(aPlacesNode) {
+    let elt = aPlacesNode._DOMElement;
+    if (!elt)
+      throw "aPlacesNode must have _DOMElement set";
+
+    // There's no UI representation for the root node, thus there's nothing to
+    // be done when the icon changes.
+    if (elt == this._rootElt)
+      return;
+
+    // Here we need the <menu>.
+    if (elt.localName == "menupopup")
+      elt = elt.parentNode;
+
+    let icon = aPlacesNode.icon;
+    if (!icon)
+      elt.removeAttribute("image");
+    else if (icon != elt.getAttribute("image"))
+      elt.setAttribute("image", icon);
+  },
+
+  nodeAnnotationChanged:
+  function PVB_nodeAnnotationChanged(aPlacesNode, aAnno) {
+    // Ensure the changed annotation is a livemark one.
+    if (/^livemark\//.test(aAnno) &&
+        PlacesUtils.nodeIsLivemarkContainer(aPlacesNode)) {
+      let elt = aPlacesNode._DOMElement;
+      if (!elt)
+        throw "aPlacesNode must have _DOMElement set";
+
+      let menu = elt.parentNode;
+      if (!menu.hasAttribute("livemark"))
+        menu.setAttribute("livemark", "true");
+
+      // Add or remove the livemark status menuitem.
+      this._ensureLivemarkStatusMenuItem(elt);
+    }
+  },
+
+  nodeRemoved:
+  function PVB_nodeRemoved(aParentPlacesNode, aPlacesNode, aIndex) {
+    let parentElt = aParentPlacesNode._DOMElement;
+    let elt = aPlacesNode._DOMElement;
+
+    if (!parentElt)
+      throw "aParentPlacesNode must have _DOMElement set";
+    if (!elt)
+      throw "aPlacesNode must have _DOMElement set";
+
+    // Here we need the <menu>.
+    if (elt.localName == "menupopup")
+      elt = elt.parentNode;
+
+    if (parentElt._built) {
+      parentElt.removeChild(elt);
+
+      // Figure out if we need to show the "<Empty>" menu-item.
+      // TODO Bug 517701: This doesn't seem to handle the case of an empty
+      // root.
+      if (!parentElt.hasChildNodes() ||
+          (parentElt.childNodes.length == 1 &&
+          parentElt.firstChild == parentElt._emptyMenuItem))
+        this._showEmptyMenuItem(parentElt);
+
+      if (parentElt._endMarker != -1)
+        parentElt._endMarker--;
+    }
+  },
+
+  nodeReplaced:
+  function PBV_nodeReplaced(aParentPlacesNode, aOldPlacesNode, aNewPlacesNode, aIndex) {
+    let parentElt = aParentPlacesNode._DOMElement;
+    if (!parentElt)
+      throw "aParentPlacesNode node must have _DOMElement set";
+
+    if (parentElt._built) {
+      let elt = aOldPlacesNode._DOMElement;
+      if (!elt)
+        throw "aOldPlacesNode must have _DOMElement set";
+
+      // Here we need the <menu>.
+      if (elt.localName == "menupopup")
+        elt = elt.parentNode;
+
+      parentElt.removeChild(elt);
+
+      // No worries: If elt is the last item (i.e. no nextSibling),
+      // _insertNewItem/_insertNewItemToPopup will insert the new element as
+      // the last item.
+      let nextElt = elt.nextSibling;
+      this._insertNewItemToPopup(aNewPlacesNode, parentElt, nextElt);
+    }
+  },
+
+  nodeHistoryDetailsChanged: function() { },
+  nodeTagsChanged: function() { },
+  nodeDateAddedChanged: function() { },
+  nodeLastModifiedChanged: function() { },
+  nodeKeywordChanged: function() { },
+  sortingChanged: function() { },
+  // Replaced by containerStateChanged.
+  containerOpened: function() { },
+  containerClosed: function() { },
+
+  nodeInserted:
+  function PVB_nodeInserted(aParentPlacesNode, aPlacesNode, aIndex) {
+    let parentElt = aParentPlacesNode._DOMElement;
+    if (!parentElt)
+      throw "aParentPlacesNode node must have _DOMElement set";
+
+    if (!parentElt._built)
+      return;
+
+    let index = parentElt._startMarker + 1 + aIndex;
+    this._insertNewItemToPopup(aPlacesNode, parentElt,
+                               parentElt.childNodes[index]);
+    if (parentElt._emptyMenuItem)
+      parentElt._emptyMenuItem.hidden = true;
+  },
+
+  nodeMoved:
+  function PBV_nodeMoved(aPlacesNode,
+                         aOldParentPlacesNode, aOldIndex,
+                         aNewParentPlacesNode, aNewIndex) {
+    // Note: the current implementation of moveItem does not actually
+    // use this notification when the item in question is moved from one
+    // folder to another.  Instead, it calls nodeRemoved and nodeInserted
+    // for the two folders.  Thus, we can assume old-parent == new-parent.
+    let elt = aPlacesNode._DOMElement;
+    if (!elt)
+      throw "aPlacesNode must have _DOMElement set";
+
+    // Here we need the <menu>.
+    if (elt.localName == "menupopup")
+      elt = elt.parentNode;
+
+    // If our root node is a folder, it might be moved. There's nothing
+    // we need to do in that case.
+    if (elt == this._rootElt)
+      return;
+
+    let parentElt = aNewParentPlacesNode._DOMElement;
+    if (!parentElt)
+      throw "aNewParentPlacesNode node must have _DOMElement set";
+
+    if (parentElt._built) {
+      // Move the node.
+      parentElt.removeChild(elt);
+      let index = parentElt._startMarker + 1 + aNewIndex;
+      parentElt.insertBefore(elt, parentElt.childNodes[index]);
+    }
+  },
+
+  containerStateChanged:
+  function PVB_containerStateChanged(aPlacesNode, aOldState, aNewState) {
+    if (aNewState == Ci.nsINavHistoryContainerResultNode.STATE_OPENED ||
+        aNewState == Ci.nsINavHistoryContainerResultNode.STATE_CLOSED) {
+      this.invalidateContainer(aPlacesNode);
+    }
+    else {
+      throw "Unexpected state passed to containerStateChanged";
+    }
+  },
+
+  invalidateContainer: function PVB_invalidateContainer(aPlacesNode) {
+    let elt = aPlacesNode._DOMElement;
+    if (!elt)
+      throw "aPlacesNode must have _DOMElement set";
+
+    elt._built = false;
+
+    // If the menupopup is open we should live-update it.
+    if (elt.parentNode.open)
+      this._rebuildPopup(elt);
+  },
+
+  uninit: function PVB_uninit() {
+    if (this._result) {
+      this._result.removeObserver(this);
+      this._resultNode.containerOpen = false;
+      this._resultNode = null;
+      this._result = null;
+    }
+
+    delete this._viewElt._placesView;
+  },
+
+  get isRTL() {
+    if ("_isRTL" in this)
+      return this._isRTL;
+
+    return this._isRTL = document.defaultView.getComputedStyle(this, "")
+                                 .direction == "rtl"
+  },
+
+  /**
+   * Adds an "Open All in Tabs" menuitem to the bottom of the popup.
+   * @param aPopup
+   *        a Places popup.
+   */
+  _mayAddCommandsItems: function PVB__mayAddCommandsItems(aPopup) {
+    // The command items are never added to the root popup.
+    if (aPopup == this._rootElt)
+      return;
+
+    // Check if the popup contains at least 2 menuitems with places nodes
+    let numURINodes = 0;
+    let currentChild = aPopup.firstChild;
+    while (currentChild) {
+      if (currentChild.localName == "menuitem" && currentChild._placesNode) {
+        if (++numURINodes == 2)
+          break;
+      }
+      currentChild = currentChild.nextSibling;
+    }
+
+    let hasMultipleURIs = numURINodes > 1;
+    let itemId = aPopup._placesNode.itemId;
+    let siteURIString = "";
+    if (itemId != -1 && PlacesUtils.itemIsLivemark(itemId)) {
+      let siteURI = PlacesUtils.livemarks.getSiteURI(itemId);
+      if (siteURI)
+        siteURIString = siteURI.spec;
+    }
+
+    if (!siteURIString && aPopup._endOptOpenSiteURI) {
+      aPopup.removeChild(aPopup._endOptOpenSiteURI);
+      aPopup._endOptOpenSiteURI = null;
+    }
+
+    if (!hasMultipleURIs && aPopup._endOptOpenAllInTabs) {
+      aPopup.removeChild(aPopup._endOptOpenAllInTabs);
+      aPopup._endOptOpenAllInTabs = null;
+    }
+
+    if (!(hasMultipleURIs || siteURIString)) {
+      // We don't have to show any option.
+      if (aPopup._endOptSeparator) {
+        aPopup.removeChild(aPopup._endOptSeparator);
+        aPopup._endOptSeparator = null;
+        aPopup._endMarker = -1;
+      }
+      return;
+    }
+
+    if (!aPopup._endOptSeparator) {
+      // Create a separator before options.
+      aPopup._endOptSeparator = document.createElement("menuseparator");
+      aPopup._endOptSeparator.className = "bookmarks-actions-menuseparator";
+      aPopup._endMarker = aPopup.childNodes.length;
+      aPopup.appendChild(aPopup._endOptSeparator);
+    }
+
+    if (siteURIString && !aPopup._endOptOpenSiteURI) {
+      // Add "Open (Feed Name)" menuitem if it's a livemark with a siteURI.
+      aPopup._endOptOpenSiteURI = document.createElement("menuitem");
+      aPopup._endOptOpenSiteURI.className = "openlivemarksite-menuitem";
+      aPopup._endOptOpenSiteURI.setAttribute("targetURI", siteURIString);
+      aPopup._endOptOpenSiteURI.setAttribute("oncommand",
+          "openUILink(this.getAttribute('targetURI'), event);");
+
+      // If a user middle-clicks this item we serve the oncommand event
+      // We are using checkForMiddleClick because of Bug 246720
+      // Note: stopPropagation is needed to avoid serving middle-click
+      // with BT_onClick that would open all items in tabs.
+      aPopup._endOptOpenSiteURI.setAttribute("onclick",
+          "checkForMiddleClick(this, event); event.stopPropagation();");
+      aPopup._endOptOpenSiteURI.setAttribute("label",
+          PlacesUIUtils.getFormattedString("menuOpenLivemarkOrigin.label",
+          [aPopup.parentNode.getAttribute("label")]));
+      aPopup.appendChild(aPopup._endOptOpenSiteURI);
+    }
+
+    if (hasMultipleURIs && !aPopup._endOptOpenAllInTabs) {
+      // Add the "Open All in Tabs" menuitem if there are
+      // at least two menuitems with places result nodes.
+      aPopup._endOptOpenAllInTabs = document.createElement("menuitem");
+      aPopup._endOptOpenAllInTabs.className = "openintabs-menuitem";
+      aPopup._endOptOpenAllInTabs.setAttribute("oncommand",
+        "PlacesUIUtils.openContainerNodeInTabs(this.parentNode._placesNode, event);");
+      aPopup._endOptOpenAllInTabs.setAttribute("onclick",
+        "checkForMiddleClick(this, event); event.stopPropagation();");
+      aPopup._endOptOpenAllInTabs.setAttribute("label",
+        gNavigatorBundle.getString("menuOpenAllInTabs.label"));
+      aPopup.appendChild(aPopup._endOptOpenAllInTabs);
+    }
+  },
+
+  _onPopupShowing: function PVB__onPopupShowing(aEvent) {
+    // Avoid handling popupshowing of inner views.
+    let popup = aEvent.originalTarget;
+    if (popup._placesNode && PlacesUIUtils.getViewForNode(popup) == this) {
+      if (!popup._placesNode.containerOpen)
+        popup._placesNode.containerOpen = true;
+      if (!popup._built)
+        this._rebuildPopup(popup);
+
+      this._mayAddCommandsItems(popup);
+    }
+  },
+
+  _addEventListeners:
+  function PVB__addEventListeners(aObject, aEventNames, aCapturing) {
+    for (let i = 0; i < aEventNames.length; i++) {
+      aObject.addEventListener(aEventNames[i], this, aCapturing);
+    }
+  },
+
+  _removeEventListeners:
+  function PVB__removeEventListeners(aObject, aEventNames, aCapturing) {
+    for (let i = 0; i < aEventNames.length; i++) {
+      aObject.removeEventListener(aEventNames[i], this, aCapturing);
+    }
+  },
+};
+
+function PlacesToolbar(aPlace) {
+  // Add some smart getters for our elements.
+  let thisView = this;
+  [
+    ["_viewElt",              "PlacesToolbar"],
+    ["_rootElt",              "PlacesToolbarItems"],
+    ["_dropIndicator",        "PlacesToolbarDropIndicator"],
+    ["_chevron",              "PlacesChevron"],
+    ["_chevronPopup",         "PlacesChevronPopup"]
+  ].forEach(function (elementGlobal) {
+    let [name, id] = elementGlobal;
+    thisView.__defineGetter__(name, function () {
+      let element = document.getElementById(id);
+      if (!element)
+        return null;
+
+      delete thisView[name];
+      return thisView[name] = element;
+    });
+  });
+
+  this._viewElt._placesView = this;
+
+  this._addEventListeners(this._viewElt, this._cbEvents, false);
+  this._addEventListeners(this._rootElt, ["popupshowing", "popuphidden"], true);
+  this._addEventListeners(this._rootElt, ["overflow", "underflow"], true);
+  this._addEventListeners(window, ["resize", "unload"], false);
+
+  PlacesViewBase.call(this, aPlace);
+}
+
+PlacesToolbar.prototype = {
+  __proto__: PlacesViewBase.prototype,
+
+  _cbEvents: ["dragstart", "dragover", "dragleave", "dragend", "drop",
+#ifdef XP_UNIX
+#ifndef XP_MACOSX
+              "mousedown",
+#endif
+#endif
+              "mousemove", "mouseover", "mouseout"],
+
+  QueryInterface: function PT_QueryInterface(aIID) {
+    if (aIID.equals(Ci.nsIDOMEventListener) ||
+        aIID.equals(Ci.nsITimerCallback))
+      return this;
+
+    return PlacesViewBase.prototype.QueryInterface.apply(this, arguments);
+  },
+
+  uninit: function PT_uninit() {
+    this._removeEventListeners(this._viewElt, this._cbEvents, false);
+    this._removeEventListeners(this._rootElt, ["popupshowing", "popuphidden"],
+                               true);
+    this._removeEventListeners(this._rootElt, ["overflow", "underflow"], true);
+    this._removeEventListeners(window, ["resize", "unload"], false);
+
+    PlacesViewBase.prototype.uninit.apply(this, arguments);
+  },
+
+  _openedMenuButton: null,
+  _allowPopupShowing: true,
+
+  _rebuild: function PT__rebuild() {
+    // Clear out references to existing nodes, since they will be removed
+    // and re-added.
+    if (this._overFolder.elt)
+      this._clearOverFolder();
+
+    this._openedMenuButton = null;
+    while (this._rootElt.hasChildNodes()) {
+      this._rootElt.removeChild(this._rootElt.firstChild);
+    }
+
+    let cc = this._resultNode.childCount;
+    for (let i = 0; i < cc; ++i) {
+      this._insertNewItem(this._resultNode.getChild(i), null);
+    }
+
+    if (this._chevronPopup.hasAttribute("type")) {
+      // Chevron has already been initialized, but since we are forcing
+      // a rebuild of the toolbar, it has to be rebuilt.
+      // Otherwise, it will be initialized when the toolbar overflows.
+      this._chevronPopup.place = this.place;
+    }
+  },
+
+  _insertNewItem:
+  function PT__insertNewItem(aChild, aBefore) {
+    let type = aChild.type;
+    let button;
+    if (type == Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR) {
+      button = document.createElement("toolbarseparator");
+    }
+    else {
+      button = document.createElement("toolbarbutton");
+      button.className = "bookmark-item";
+      button.setAttribute("label", aChild.title);
+      let icon = aChild.icon;
+      if (icon)
+        button.setAttribute("image", icon);
+
+      if (PlacesUtils.containerTypes.indexOf(type) != -1) {
+        button.setAttribute("type", "menu");
+        button.setAttribute("container", "true");
+
+        if (PlacesUtils.nodeIsQuery(aChild)) {
+          button.setAttribute("query", "true");
+          if (PlacesUtils.nodeIsTagQuery(aChild))
+            button.setAttribute("tagContainer", "true");
+        }
+        else if (PlacesUtils.nodeIsLivemarkContainer(aChild)) {
+          button.setAttribute("livemark", "true");
+        }
+
+        let popup = document.createElement("menupopup");
+        popup.setAttribute("placespopup", "true");
+        button.appendChild(popup);
+        popup._placesNode = PlacesUtils.asContainer(aChild);
+#ifndef XP_MACOSX
+        popup.setAttribute("context", "placesContext");
+#endif
+
+        aChild._DOMElement = popup;
+      }
+      else if (PlacesUtils.nodeIsURI(aChild)) {
+        button.setAttribute("scheme",
+                            PlacesUIUtils.guessUrlSchemeForUI(aChild.uri));
+      }
+    }
+
+    button._placesNode = aChild;
+    if (!aChild._DOMElement)
+      aChild._DOMElement = button;
+
+    if (aBefore)
+      this._rootElt.insertBefore(button, aBefore);
+    else
+      this._rootElt.appendChild(button);
+  },
+
+  _updateChevronPopupNodesVisibility:
+  function PT__updateChevronPopupNodesVisibility() {
+    for (let i = 0; i < this._chevronPopup.childNodes.length; i++) {
+      this._chevronPopup.childNodes[i].hidden =
+        this._rootElt.childNodes[i].style.visibility != "hidden";
+    }
+  },
+
+  _onChevronPopupShowing:
+  function PT__onChevronPopupShowing(aEvent) {
+    // Handle popupshowing only for the chevron popup, not for nested ones.
+    if (aEvent.target != this._chevronPopup)
+      return;
+
+    if (!this._chevron._placesView)
+      this._chevron._placesView = new PlacesMenu(aEvent, this.place);
+
+    this._updateChevronPopupNodesVisibility();
+  },
+
+  handleEvent: function PT_handleEvent(aEvent) {
+    switch (aEvent.type) {
+      case "unload":
+        this.uninit();
+        break;
+      case "resize":
+        // This handler updates nodes visibility in both the toolbar
+        // and the chevron popup when a window resize does not change
+        // the overflow status of the toolbar.
+        this.updateChevron();
+        break;
+      case "overflow":
+        if (aEvent.target != aEvent.currentTarget)
+          return;
+
+        // Ignore purely vertical overflows.
+        if (aEvent.detail == 0)
+          return;
+
+        // Attach the popup binding to the chevron popup if it has not yet
+        // been initialized.
+        if (!this._chevronPopup.hasAttribute("type")) {
+          this._chevronPopup.setAttribute("place", this.place);
+          this._chevronPopup.setAttribute("type", "places");
+        }
+        this._chevron.collapsed = false;
+        this.updateChevron();
+        break;
+      case "underflow":
+        if (aEvent.target != aEvent.currentTarget)
+          return;
+
+        // Ignore purely vertical underflows.
+        if (aEvent.detail == 0)
+          return;
+
+        this._chevron.collapsed = true;
+        this.updateChevron();
+        break;
+      case "dragstart":
+        this._onDragStart(aEvent);
+        break;
+      case "dragover":
+        this._onDragOver(aEvent);
+        break;
+      case "dragleave":
+        this._onDragLeave(aEvent);
+        break;
+      case "dragend":
+        this._onDragEnd(aEvent);
+        break;
+      case "drop":
+        this._onDrop(aEvent);
+        break;
+      case "mouseover":
+        this._onMouseOver(aEvent);
+        break;
+      case "mousemove":
+        this._onMouseMove(aEvent);
+        break;
+      case "mouseout":
+        this._onMouseOut(aEvent);
+        break;
+      case "mousedown":
+        this._onMouseDown(aEvent);
+        break;
+      case "popupshowing":
+        this._onPopupShowing(aEvent);
+        break;
+      case "popuphidden":
+        this._onPopupHidden(aEvent);
+        break;
+    }
+  },
+
+  updateChevron: function PT_updateChevron() {
+    // If the chevron is collapsed there's nothing to update.
+    if (this._chevron.collapsed)
+      return;
+
+    // XXX (bug 508816) Scrollbox does not handle correctly RTL mode.
+    // This workarounds the issue scrolling the box to the right.
+    if (this._isRTL)
+      this._rootElt.scrollLeft = this._rootElt.scrollWidth;
+
+    // Update the chevron on a timer.  This will avoid repeated work when
+    // lot of changes happen in a small timeframe.
+    if (this._updateChevronTimer)
+      this._updateChevronTimer.cancel();
+
+    this._updateChevronTimer = this._setTimer(100);
+  },
+
+  _updateChevronTimerCallback: function PT__updateChevronTimerCallback() {
+    let scrollRect = this._rootElt.getBoundingClientRect();
+    let childOverflowed = false;
+    for (let i = 0; i < this._rootElt.childNodes.length; i++) {
+      let child = this._rootElt.childNodes[i];
+      // Once a child overflows, all the next ones will.
+      if (!childOverflowed) {
+        let childRect = child.getBoundingClientRect();
+        childOverflowed = this._isRTL ? (childRect.left < scrollRect.left)
+                                      : (childRect.right > scrollRect.right);
+      }
+      child.style.visibility = childOverflowed ? "hidden" : "visible";
+    }
+
+    // We rebuild the chevron on popupShowing, so if it is open
+    // we must update it.
+    if (this._chevron.open)
+      this._updateChevronPopupNodesVisibility();
+  },
+
+  nodeInserted:
+  function PT_nodeInserted(aParentPlacesNode, aPlacesNode, aIndex) {
+    let parentElt = aParentPlacesNode._DOMElement;
+    if (!parentElt) 
+      throw "aParentPlacesNode node must have _DOMElement set";
+
+    if (parentElt == this._rootElt) {
+      let children = this._rootElt.childNodes;
+      this._insertNewItem(aPlacesNode,
+        aIndex < children.length ? children[aIndex] : null);
+      this.updateChevron();
+      return;
+    }
+
+    PlacesViewBase.prototype.nodeInserted.apply(this, arguments);
+  },
+
+  nodeRemoved:
+  function PT_nodeRemoved(aParentPlacesNode, aPlacesNode, aIndex) {
+    let parentElt = aParentPlacesNode._DOMElement;
+    let elt = aPlacesNode._DOMElement;
+
+    if (!parentElt)
+      throw "aParentPlacesNode node must have _DOMElement set";
+    if (!elt)
+      throw "aPlacesNode must have _DOMElement set";
+
+    // Here we need the <menu>.
+    if (elt.localName == "menupopup")
+      elt = elt.parentNode;
+
+    if (parentElt == this._rootElt) {
+      this._removeChild(elt);
+      this.updateChevron();
+      return;
+    }
+
+    PlacesViewBase.prototype.nodeRemoved.apply(this, arguments);
+  },
+
+  nodeMoved:
+  function PT_nodeMoved(aPlacesNode,
+                        aOldParentPlacesNode, aOldIndex,
+                        aNewParentPlacesNode, aNewIndex) {
+    let parentElt = aNewParentPlacesNode._DOMElement;
+    if (!parentElt) 
+      throw "aNewParentPlacesNode node must have _DOMElement set";
+
+    if (parentElt == this._rootElt) {
+      // Container is on the toolbar.
+
+      // Move the element.
+      let elt = aPlacesNode._DOMElement;
+      if (!elt)
+        throw "aPlacesNode must have _DOMElement set";
+
+      // Here we need the <menu>.
+      if (elt.localName == "menupopup")
+        elt = elt.parentNode;
+
+      this._removeChild(elt);
+      this._rootElt.insertBefore(elt, this._rootElt.childNodes[aNewIndex]);
+
+      // If the chevron popup is open, keep it in sync.
+      if (this._chevron.open) {
+        let chevronPopup = this._chevronPopup;
+        let menuitem = chevronPopup.childNodes[aOldIndex];
+        chevronPopup.removeChild(menuitem);
+        chevronPopup.insertBefore(menuitem,
+                                  chevronPopup.childNodes[aNewIndex]);
+      }
+      this.updateChevron();
+      return;
+    }
+
+    PlacesViewBase.prototype.nodeMoved.apply(this, arguments);
+  },
+
+  nodeTitleChanged: function PT_nodeTitleChanged(aPlacesNode, aNewTitle) {
+    let elt = aPlacesNode._DOMElement;
+    if (!elt)
+      throw "aPlacesNode must have _DOMElement set";
+
+    // There's no UI representation for the root node, thus there's
+    // nothing to be done when the title changes.
+    if (elt == this._rootElt)
+      return;
+
+    // Here we need the <menu>.
+    if (elt.localName == "menupopup")
+      elt = elt.parentNode;
+
+    if (elt.parentNode == this._rootElt) {
+      // Node is on the toolbar
+      elt.label = aNewTitle;
+      this.updateChevron();
+    }
+    else {
+      // Node is within a built menu.
+      elt.label = aNewTitle || PlacesUIUtils.getBestTitle(aPlacesNode);
+    }
+  },
+
+  nodeReplaced:
+  function PT_nodeReplaced(aParentPlacesNode,
+                           aOldPlacesNode, aNewPlacesNode, aIndex) {
+    let parentElt = aParentPlacesNode._DOMElement;
+    if (!parentElt) 
+      throw "aParentPlacesNode node must have _DOMElement set";
+
+    if (parentElt == this._rootElt) {
+      let elt = aOldPlacesNode._DOMElement;
+      if (!elt)
+        throw "aOldPlacesNode must have _DOMElement set";
+
+      // Here we need the <menu>.
+      if (elt.localName == "menupopup")
+        elt = elt.parentNode;
+
+      this._removeChild(elt);
+
+      // No worries: If elt is the last item (i.e. no nextSibling),
+      // _insertNewItem/_insertNewItemToPopup will insert the new element as
+      // the last item.
+      let next = elt.nextSibling;
+      this._insertNewItem(aNewPlacesNode, next);
+      this.updateChevron();
+      return;
+    }
+
+    PlacesViewBase.prototype.nodeReplaced.apply(this, arguments);
+  },
+
+  invalidateContainer: function PT_invalidateContainer(aPlacesNode) {
+    let elt = aPlacesNode._DOMElement;
+    if (!elt)
+      throw "aPlacesNode must have _DOMElement set";
+
+    if (elt == this._rootElt) {
+      // Container is the toolbar itself.
+      this._rebuild();
+      return;
+    }
+
+    PlacesViewBase.prototype.invalidateContainer.apply(this, arguments);
+  },
+
+  _overFolder: { elt: null,
+                 openTimer: null,
+                 hoverTime: 350,
+                 closeTimer: null },
+
+  _clearOverFolder: function PT__clearOverFolder() {
+    // The mouse is no longer dragging over the stored menubutton.
+    // Close the menubutton, clear out drag styles, and clear all
+    // timers for opening/closing it.
+    if (this._overFolder.elt && this._overFolder.elt.lastChild) {
+      if (!this._overFolder.elt.lastChild.hasAttribute("dragover")) {
+        this._overFolder.elt.lastChild.hidePopup();
+      }
+      this._overFolder.elt.removeAttribute("dragover");
+      this._overFolder.elt = null;
+    }
+    if (this._overFolder.openTimer) {
+      this._overFolder.openTimer.cancel();
+      this._overFolder.openTimer = null;
+    }
+    if (this._overFolder.closeTimer) {
+      this._overFolder.closeTimer.cancel();
+      this._overFolder.closeTimer = null;
+    }
+  },
+
+  /**
+   * This function returns information about where to drop when dragging over
+   * the toolbar.  The returned object has the following properties:
+   * - ip: the insertion point for the bookmarks service.
+   * - beforeIndex: child index to drop before, for the drop indicator.
+   * - folderElt: the folder to drop into, if applicable.
+   */
+  _getDropPoint: function PT__getDropPoint(aEvent) {
+    let result = this.result;
+    if (!PlacesUtils.nodeIsFolder(this._resultNode))
+      return null;
+
+    let dropPoint = { ip: null, beforeIndex: null, folderElt: null };
+    let elt = aEvent.target;
+    if (elt._placesNode && elt != this._rootElt &&
+        elt.localName != "menupopup") {
+      let eltRect = elt.getBoundingClientRect();
+      let eltIndex = Array.indexOf(this._rootElt.childNodes, elt);
+      if (PlacesUtils.nodeIsFolder(elt._placesNode) &&
+          !PlacesUtils.nodeIsReadOnly(elt._placesNode)) {
+        // This is a folder.
+        // If we are in the middle of it, drop inside it.
+        // Otherwise, drop before it, with regards to RTL mode.
+        let threshold = eltRect.width * 0.25;
+        if (this._isRTL ? (aEvent.clientX > eltRect.right - threshold)
+                        : (aEvent.clientX < eltRect.left + threshold)) {
+          // Drop before this folder.
+          dropPoint.ip =
+            new InsertionPoint(PlacesUtils.getConcreteItemId(this._resultNode),
+                               eltIndex, Ci.nsITreeView.DROP_BEFORE);
+          dropPoint.beforeIndex = eltIndex;
+        }
+        else if (this._isRTL ? (aEvent.clientX > eltRect.left + threshold)
+                             : (aEvent.clientX < eltRect.right - threshold)) {
+          // Drop inside this folder.
+          dropPoint.ip =
+            new InsertionPoint(PlacesUtils.getConcreteItemId(elt._placesNode),
+                               -1, Ci.nsITreeView.DROP_ON,
+                               PlacesUtils.nodeIsTagQuery(elt._placesNode));
+          dropPoint.beforeIndex = eltIndex;
+          dropPoint.folderElt = elt;
+        }
+        else {
+          // Drop after this folder.
+          let beforeIndex =
+            (eltIndex == this._rootElt.childNodes.length - 1) ?
+            -1 : eltIndex + 1;
+
+          dropPoint.ip =
+            new InsertionPoint(PlacesUtils.getConcreteItemId(this._resultNode),
+                               beforeIndex, Ci.nsITreeView.DROP_BEFORE);
+          dropPoint.beforeIndex = beforeIndex;
+        }
+      }
+      else {
+        // This is a non-folder node or a read-only folder.
+        // Drop before it with regards to RTL mode.
+        let threshold = eltRect.width * 0.5;
+        if (this._isRTL ? (aEvent.clientX > eltRect.left + threshold)
+                        : (aEvent.clientX < eltRect.left + threshold)) {
+          // Drop before this bookmark.
+          dropPoint.ip =
+            new InsertionPoint(PlacesUtils.getConcreteItemId(this._resultNode),
+                               eltIndex, Ci.nsITreeView.DROP_BEFORE);
+          dropPoint.beforeIndex = eltIndex;
+        }
+        else {
+          // Drop after this bookmark.
+          let beforeIndex =
+            eltIndex == this._rootElt.childNodes.length - 1 ?
+            -1 : eltIndex + 1;
+          dropPoint.ip =
+            new InsertionPoint(PlacesUtils.getConcreteItemId(this._resultNode),
+                               beforeIndex, Ci.nsITreeView.DROP_BEFORE);
+          dropPoint.beforeIndex = beforeIndex;
+        }
+      }
+    }
+    else {
+      // We are most likely dragging on the empty area of the
+      // toolbar, we should drop after the last node.
+      dropPoint.ip =
+        new InsertionPoint(PlacesUtils.getConcreteItemId(this._resultNode),
+                           -1, Ci.nsITreeView.DROP_BEFORE);
+      dropPoint.beforeIndex = -1;
+    }
+
+    return dropPoint;
+  },
+
+  _setTimer: function PT_setTimer(aTime) {
+    let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+    timer.initWithCallback(this, aTime, timer.TYPE_ONE_SHOT);
+    return timer;
+  },
+
+  notify: function PT_notify(aTimer) {
+    if (aTimer == this._updateChevronTimer) {
+      this._updateChevronTimer = null;
+      this._updateChevronTimerCallback();
+    }
+
+    // * Timer to turn off indicator bar.
+    else if (aTimer == this._ibTimer) {
+      this._dropIndicator.collapsed = true;
+      this._ibTimer = null;
+    }
+
+    // * Timer to open a menubutton that's being dragged over.
+    else if (aTimer == this._overFolder.openTimer) {
+      // Set the autoopen attribute on the folder's menupopup so that
+      // the menu will automatically close when the mouse drags off of it.
+      this._overFolder.elt.lastChild.setAttribute("autoopened", "true");
+      this._overFolder.elt.open = true;
+      this._overFolder.openTimer = null;
+    }
+
+    // * Timer to close a menubutton that's been dragged off of.
+    else if (aTimer == this._overFolder.closeTimer) {
+      // Close the menubutton if we are not dragging over it or one of
+      // its children.  The autoopened attribute will let the menu know to
+      // close later if the menu is still being dragged over.
+      let currentPlacesNode = PlacesControllerDragHelper.currentDropTarget;
+      let inHierarchy = false;
+      while (currentPlacesNode) {
+        if (currentPlacesNode == this._rootElt) {
+          inHierarchy = true;
+          break;
+        }
+        currentPlacesNode = currentPlacesNode.parentNode;
+      }
+      // The _clearOverFolder() function will close the menu for
+      // _overFolder.elt.  So null it out if we don't want to close it.
+      if (inHierarchy)
+        this._overFolder.elt = null;
+
+      // Clear out the folder and all associated timers.
+      this._clearOverFolder();
+    }
+  },
+
+  _onMouseOver: function PT__onMouseOver(aEvent) {
+    let button = aEvent.target;
+    if (button.parentNode == this._rootElt && button._placesNode &&
+        PlacesUtils.nodeIsURI(button._placesNode))
+      window.XULBrowserWindow.setOverLink(aEvent.target._placesNode.uri, null);
+  },
+
+  _onMouseOut: function PT__onMouseOut(aEvent) {
+    window.XULBrowserWindow.setOverLink("", null);
+  },
+
+  _cleanupDragDetails: function PT__cleanupDragDetails() {
+    // Called on dragend and drop.
+    PlacesControllerDragHelper.currentDropTarget = null;
+    this._draggedElt = null;
+    if (this._ibTimer)
+      this._ibTimer.cancel();
+
+    this._dropIndicator.collapsed = true;
+  },
+
+  _onDragStart: function PT__onDragStart(aEvent) {
+    // Sub menus have their own d&d handlers.
+    let draggedElt = aEvent.target;
+    if (draggedElt.parentNode != this._rootElt || !draggedElt._placesNode)
+      return;
+
+    if (draggedElt.localName == "toolbarbutton" &&
+        draggedElt.getAttribute("type") == "menu") {
+      // If the drag gesture on a container is toward down we open instead
+      // of dragging.
+      if (this._mouseDownTimer) {
+        this._mouseDownTimer.cancel();
+        this._mouseDownTimer = null;
+      }
+      let translateY = this._cachedMouseMoveEvent.clientY - aEvent.clientY;
+      let translateX = this._cachedMouseMoveEvent.clientX - aEvent.clientX;
+      if ((translateY) >= Math.abs(translateX/2)) {
+        // Don't start the drag.
+        aEvent.preventDefault();
+        // Open the menu.
+        draggedElt.open = true;
+        return;
+      }
+
+      // If the menu is open, close it.
+      if (draggedElt.open) {
+        draggedElt.firstChild.hidePopup();
+        draggedElt.open = false;
+      }
+    }
+
+    // Activate the view and cache the dragged element.
+    this._draggedElt = draggedElt._placesNode;
+    this._rootElt.focus();
+
+    this._controller.setDataTransfer(aEvent);
+    aEvent.stopPropagation();
+  },
+
+  _onDragOver: function PT__onDragOver(aEvent) {
+    // Cache the dataTransfer
+    PlacesControllerDragHelper.currentDropTarget = aEvent.target;
+    let dt = aEvent.dataTransfer;
+
+    let dropPoint = this._getDropPoint(aEvent);
+    if (!dropPoint || !dropPoint.ip ||
+        !PlacesControllerDragHelper.canDrop(dropPoint.ip, dt)) {
+      this._dropIndicator.collapsed = true;
+      aEvent.stopPropagation();
+      return;
+    }
+
+    if (this._ibTimer) {
+      this._ibTimer.cancel();
+      this._ibTimer = null;
+    }
+
+    if (dropPoint.folderElt || aEvent.originalTarget == this._chevron) {
+      // Dropping over a menubutton or chevron button.
+      // Set styles and timer to open relative menupopup.
+      let overElt = dropPoint.folderElt || this._chevron;
+      if (this._overFolder.elt != overElt) {
+        this._clearOverFolder();
+        this._overFolder.elt = overElt;
+        this._overFolder.openTimer = this._setTimer(this._overFolder.hoverTime);
+      }
+      if (!this._overFolder.elt.hasAttribute("dragover"))
+        this._overFolder.elt.setAttribute("dragover", "true");
+
+      this._dropIndicator.collapsed = true;
+    }
+    else {
+      // Dragging over a normal toolbarbutton,
+      // show indicator bar and move it to the appropriate drop point.
+      let ind = this._dropIndicator;
+      let halfInd = ind.clientWidth / 2;
+      let translateX;
+      if (this._isRTL) {
+        halfInd = Math.ceil(halfInd);
+        translateX = 0 - this._rootElt.getBoundingClientRect().right - halfInd;
+        if (this._rootElt.firstChild) {
+          if (dropPoint.beforeIndex == -1)
+            translateX += this._rootElt.lastChild.getBoundingClientRect().left;
+          else {
+            translateX += this._rootElt.childNodes[dropPoint.beforeIndex]
+                              .getBoundingClientRect().right;
+          }
+        }
+      }
+      else {
+        halfInd = Math.floor(halfInd);
+        translateX = 0 - this._rootElt.getBoundingClientRect().left +
+                     halfInd;
+        if (this._rootElt.firstChild) {
+          if (dropPoint.beforeIndex == -1)
+            translateX += this._rootElt.lastChild.getBoundingClientRect().right;
+          else {
+            translateX += this._rootElt.childNodes[dropPoint.beforeIndex]
+                              .getBoundingClientRect().left;
+          }
+        }
+      }
+
+      ind.style.MozTransform = "translate(" + Math.round(translateX) + "px)";
+      ind.style.MozMarginStart = (-ind.clientWidth) + "px";
+      ind.collapsed = false;
+
+      // Clear out old folder information.
+      this._clearOverFolder();
+    }
+
+    aEvent.preventDefault();
+    aEvent.stopPropagation();
+  },
+
+  _onDrop: function PT__onDrop(aEvent) {
+    PlacesControllerDragHelper.currentDropTarget = aEvent.target;
+
+    let dropPoint = this._getDropPoint(aEvent);
+    if (dropPoint && dropPoint.ip) {
+      PlacesControllerDragHelper.onDrop(dropPoint.ip, aEvent.dataTransfer)
+      aEvent.preventDefault();
+    }
+
+    this._cleanupDragDetails();
+    aEvent.stopPropagation();
+  },
+
+  _onDragLeave: function PT__onDragLeave(aEvent) {
+    PlacesControllerDragHelper.currentDropTarget = null;
+
+    // Set timer to turn off indicator bar (if we turn it off
+    // here, dragenter might be called immediately after, creating
+    // flicker).
+    if (this._ibTimer)
+      this._ibTimer.cancel();
+    this._ibTimer = this._setTimer(10);
+
+    // If we hovered over a folder, close it now.
+    if (this._overFolder.elt)
+        this._overFolder.closeTimer = this._setTimer(this._overFolder.hoverTime);
+  },
+
+  _onDragEnd: function PT_onDragEnd(aEvent) {
+    this._cleanupDragDetails();
+  },
+
+  _onPopupShowing: function PT__onPopupShowing(aEvent) {
+    if (!this._allowPopupShowing) {
+      this._allowPopupShowing = true;
+      aEvent.preventDefault();
+      return;
+    }
+
+    let parent = aEvent.target.parentNode;
+    if (parent.localName == "toolbarbutton")
+      this._openedMenuButton = parent;
+
+    return PlacesViewBase.prototype._onPopupShowing.apply(this, arguments);
+  },
+
+  _onPopupHidden: function PT__onPopupHidden(aEvent) {
+    let popup = aEvent.target;
+
+    // Avoid handling popuphidden of inner views
+    if (popup._placesNode && PlacesUIUtils.getViewForNode(popup) == this) {
+      // UI performance: folder queries are cheap, keep the resultnode open
+      // so we don't rebuild its contents whenever the popup is reopened.
+      if (!PlacesUtils.nodeIsFolder(popup._placesNode))
+        popup._placesNode.containerOpen = false;
+    }
+
+    let parent = popup.parentNode;
+    if (parent.localName == "toolbarbutton") {
+      this._openedMenuButton = null;
+      // Clear the dragover attribute if present, if we are dragging into a
+      // folder in the hierachy of current opened popup we don't clear
+      // this attribute on clearOverFolder.  See Notify for closeTimer.
+      if (parent.hasAttribute("dragover"))
+        parent.removeAttribute("dragover");
+    }
+  },
+
+  _onMouseDown: function PT__onMouseDown(aEvent) {
+#ifdef XP_UNIX
+#ifndef XP_MACOSX
+    let target = aEvent.target;
+    if (aEvent.button == 0 &&
+        target.localName == "toolbarbutton" &&
+        target.getAttribute("type") == "menu") {
+      this._allowPopupShowing = false;
+      // On Linux we can open the popup only after a delay.
+      // Indeed as soon as the menupopup opens we are unable to start a
+      // drag aEvent.  See bug 500081 for details.
+      this._mouseDownTimer = Cc["@mozilla.org/timer;1"].
+                             createInstance(Ci.nsITimer);
+      let callback = {
+        _self: this,
+        _target: target,
+        notify: function(timer) {
+          this._target.open = true;
+          this._mouseDownTimer = null;
+        }
+      };
+
+      this._mouseDownTimer.initWithCallback(callback, 300,
+                                            Ci.nsITimer.TYPE_ONE_SHOT);
+    }
+#endif
+#endif
+  },
+
+  _onMouseUp: function PT__onMouseUp(aEvent) {
+    if (aEvent.button != 0)
+      return;
+
+    if (this._mouseDownTimer) {
+      // On a click (down/up), we should open the menu popup.
+      this._mouseDownTimer.cancel();
+      this._mouseDownTimer = null;
+      aEvent.target.open = true;
+    }
+  },
+
+  _onMouseMove: function PT__onMouseMove(aEvent) {
+    // Used in dragStart to prevent dragging folders when dragging down.
+    this._cachedMouseMoveEvent = aEvent;
+
+    if (this._openedMenuButton == null ||
+        PlacesControllerDragHelper.getSession())
+      return;
+
+    let target = aEvent.originalTarget;
+    if (this._openedMenuButton != target &&
+        target.localName == "toolbarbutton" &&
+        target.type == "menu") {
+      this._openedMenuButton.open = false;
+      target.open = true;
+    }
+  }
+};
+
+/**
+ * View for Places menus.  This object should be created during the first
+ * popupshowing that's dispatched on the menu.
+ */
+function PlacesMenu(aPopupShowingEvent, aPlace) {
+  this._rootElt = aPopupShowingEvent.target; // <menupopup>
+  this._viewElt = this._rootElt.parentNode;   // <menu>
+  this._viewElt._placesView = this;
+  this._addEventListeners(this._rootElt, ["popupshowing", "popuphidden"], true);
+  this._addEventListeners(window, ["unload"], false);
+
+#ifdef XP_MACOSX
+  if (this._viewElt.parentNode.localName == "menubar") {
+    this._nativeView = true;
+    this._rootElt._startMarker = -1;
+    this._rootElt._endMarker = -1;
+  }
+#endif
+
+  PlacesViewBase.call(this, aPlace);
+  this._onPopupShowing(aPopupShowingEvent);
+}
+
+PlacesMenu.prototype = {
+  __proto__: PlacesViewBase.prototype,
+
+  QueryInterface: function PM_QueryInterface(aIID) {
+    if (aIID.equals(Ci.nsIDOMEventListener))
+      return this;
+
+    return PlacesViewBase.prototype.QueryInterface.apply(this, arguments);
+  },
+
+  _removeChild: function PM_removeChild(aChild) {
+    PlacesViewBase.prototype._removeChild.apply(this, arguments);
+    if (this._endMarker != -1)
+      this._endMarker--;
+  },
+
+  nodeTitleChanged: function PM_nodeTitleChanged(aPlacesNode, aNewTitle) {
+    let elt = aPlacesNode._DOMElement;
+    if (!elt)
+      throw "aPlacesNode must have _DOMElement set";
+
+    // There's no UI representation for the root node, thus there's
+    // nothing to be done when the title changes.
+    if (elt == this._rootElt)
+      return;
+
+    elt.label = aNewTitle || PlacesUIUtils.getBestTitle(aPlacesNode);
+  },
+
+  uninit: function PM_uninit() {
+    this._removeEventListeners(this._rootElt, ["popupshowing", "popuphidden"],
+                               true);
+    this._removeEventListeners(window, ["unload"], false);
+
+    PlacesViewBase.prototype.uninit.apply(this, arguments);
+  },
+
+  handleEvent: function PM_handleEvent(aEvent) {
+    switch (aEvent.type) {
+      case "unload":
+        this.uninit();
+        break;
+      case "popupshowing":
+        this._onPopupShowing(aEvent);
+        break;
+      case "popuphidden":
+        this._onPopupHidden(aEvent);
+        break;
+    }
+  },
+
+  _onPopupHidden: function PM__onPopupHidden(aEvent) {
+    // Avoid handling popuphidden of inner views.
+    let popup = aEvent.originalTarget;
+    if (!popup._placesNode || PlacesUIUtils.getViewForNode(popup) != this)
+      return;
+
+    // UI performance: folder queries are cheap, keep the resultnode open
+    // so we don't rebuild its contents whenever the popup is reopened.
+    if (!PlacesUtils.nodeIsFolder(popup._placesNode))
+      popup._placesNode.containerOpen = false;
+
+    // The autoopened attribute is set for folders which have been
+    // automatically opened when dragged over.  Turn off this attribute
+    // when the folder closes because it is no longer applicable.
+    popup.removeAttribute("autoopened");
+    popup.removeAttribute("dragstart");
+  }
+};
+
--- a/browser/components/places/content/controller.js
+++ b/browser/components/places/content/controller.js
@@ -128,17 +128,17 @@ PlacesController.prototype = {
   isCommandEnabled: function PC_isCommandEnabled(aCommand) {
     switch (aCommand) {
     case "cmd_undo":
       return PlacesUIUtils.ptm.numberOfUndoItems > 0;
     case "cmd_redo":
       return PlacesUIUtils.ptm.numberOfRedoItems > 0;
     case "cmd_cut":
     case "placesCmd_cut":
-      var nodes = this._view.getSelectionNodes();
+      var nodes = this._view.selectedNodes;
       // If selection includes history nodes there's no reason to allow cut.
       for (var i = 0; i < nodes.length; i++) {
         if (nodes[i].itemId == -1)
           return false;
       }
       // Otherwise fallback to cmd_delete check.
     case "cmd_delete":
     case "placesCmd_delete":
@@ -151,35 +151,35 @@ PlacesController.prototype = {
     case "cmd_copy":
     case "placesCmd_copy":
       return this._view.hasSelection;
     case "cmd_paste":
     case "placesCmd_paste":
       return this._canInsert(true) && this._isClipboardDataPasteable();
     case "cmd_selectAll":
       if (this._view.selType != "single") {
-        var rootNode = this._view.getResultNode();
+        let rootNode = this._view.result.root;
         if (rootNode.containerOpen && rootNode.childCount > 0)
             return true;
       }
       return false;
     case "placesCmd_open":
     case "placesCmd_open:window":
     case "placesCmd_open:tab":
       var selectedNode = this._view.selectedNode;
       return selectedNode && PlacesUtils.nodeIsURI(selectedNode);
     case "placesCmd_new:folder":
     case "placesCmd_new:livemark":
       return this._canInsert();
     case "placesCmd_new:bookmark":
       return this._canInsert();
     case "placesCmd_new:separator":
       return this._canInsert() &&
-             !PlacesUtils.asQuery(this._view.getResultNode()).queryOptions.excludeItems &&
-             this._view.getResult().sortingMode ==
+             !PlacesUtils.asQuery(this._view.result.root).queryOptions.excludeItems &&
+             this._view.result.sortingMode ==
                  Ci.nsINavHistoryQueryOptions.SORT_BY_NONE;
     case "placesCmd_show:info":
       var selectedNode = this._view.selectedNode;
       if (selectedNode &&
           PlacesUtils.getConcreteItemId(selectedNode) != -1  &&
           !PlacesUtils.nodeIsLivemarkItem(selectedNode))
         return true;
       return false;
@@ -191,17 +191,17 @@ PlacesController.prototype = {
       // Livemark containers
       var selectedNode = this._view.selectedNode;
       return selectedNode && PlacesUtils.nodeIsLivemarkContainer(selectedNode);
     case "placesCmd_sortBy:name":
       var selectedNode = this._view.selectedNode;
       return selectedNode &&
              PlacesUtils.nodeIsFolder(selectedNode) &&
              !PlacesUtils.nodeIsReadOnly(selectedNode) &&
-             this._view.getResult().sortingMode ==
+             this._view.result.sortingMode ==
                  Ci.nsINavHistoryQueryOptions.SORT_BY_NONE;
     case "placesCmd_createBookmark":
       var node = this._view.selectedNode;
       return node && PlacesUtils.nodeIsURI(node) && node.itemId == -1;
     default:
       return false;
     }
   },
@@ -317,21 +317,21 @@ PlacesController.prototype = {
    * removable item.
    * @param aIsMoveCommand
    *        True if the command for which this method is called only moves the
    *        selected items to another container, false otherwise.
    * @returns true if all nodes in the selection can be removed,
    *          false otherwise.
    */
   _hasRemovableSelection: function PC__hasRemovableSelection(aIsMoveCommand) {
-    var ranges = this._view.getRemovableSelectionRanges();
+    var ranges = this._view.removableSelectionRanges;
     if (!ranges.length)
       return false;
 
-    var root = this._view.getResultNode();
+    var root = this._view.result.root;
 
     for (var j = 0; j < ranges.length; j++) {
       var nodes = ranges[j];
       for (var i = 0; i < nodes.length; ++i) {
         // Disallow removing the view's root node
         if (nodes[i] == root)
           return false;
 
@@ -364,18 +364,18 @@ PlacesController.prototype = {
     var ip = this._view.insertionPoint;
     return ip != null && (isPaste || ip.isTag != true);
   },
 
   /**
    * Determines whether or not the root node for the view is selected
    */
   rootNodeIsSelected: function PC_rootNodeIsSelected() {
-    var nodes = this._view.getSelectionNodes();
-    var root = this._view.getResultNode();
+    var nodes = this._view.selectedNodes;
+    var root = this._view.result.root;
     for (var i = 0; i < nodes.length; ++i) {
       if (nodes[i] == root)
         return true;      
     }
 
     return false;
   },
 
@@ -446,18 +446,18 @@ PlacesController.prototype = {
    *          node are set on its corresponding object as properties.
    * Notes:
    *   1) This can be slow, so don't call it anywhere performance critical!
    *   2) A single-object array corresponding the root node is returned if
    *      there's no selection.
    */
   _buildSelectionMetadata: function PC__buildSelectionMetadata() {
     var metadata = [];
-    var root = this._view.getResultNode();
-    var nodes = this._view.getSelectionNodes();
+    var root = this._view.result.root;
+    var nodes = this._view.selectedNodes;
     if (nodes.length == 0)
       nodes.push(root); // See the second note above
 
     for (var i=0; i < nodes.length; i++) {
       var nodeData = {};
       var node = nodes[i];
       var nodeType = node.type;
       var uri = null;
@@ -790,17 +790,17 @@ PlacesController.prototype = {
   /**
    * Opens the links in the selected folder, or the selected links in new tabs. 
    */
   openSelectionInTabs: function PC_openLinksInTabs(aEvent) {
     var node = this._view.selectedNode;
     if (node && PlacesUtils.nodeIsContainer(node))
       PlacesUIUtils.openContainerNodeInTabs(this._view.selectedNode, aEvent);
     else
-      PlacesUIUtils.openURINodesInTabs(this._view.getSelectionNodes(), aEvent);
+      PlacesUIUtils.openURINodesInTabs(this._view.selectedNodes, aEvent);
   },
 
   /**
    * Shows the Add Bookmark UI for the current insertion point.
    *
    * @param aType
    *        the type of the new item (bookmark/livemark/folder)
    */
@@ -861,17 +861,17 @@ PlacesController.prototype = {
   },
 
   /**
    * Opens a dialog for moving the selected nodes.
    */
   moveSelectedBookmarks: function PC_moveBookmarks() {
     window.openDialog("chrome://browser/content/places/moveBookmarks.xul",
                       "", "chrome, modal",
-                      this._view.getSelectionNodes());
+                      this._view.selectedNodes);
   },
 
   /**
    * Sort the selected folder by name
    */
   sortFolderByName: function PC_sortFolderByName() {
     var itemId = PlacesUtils.getConcreteItemId(this._view.selectedNode);
     var txn = PlacesUIUtils.ptm.sortFolderByName(itemId);
@@ -986,17 +986,17 @@ PlacesController.prototype = {
   },
 
   /**
    * Removes the set of selected ranges from bookmarks.
    * @param   txnName
    *          See |remove|.
    */
   _removeRowsFromBookmarks: function PC__removeRowsFromBookmarks(txnName) {
-    var ranges = this._view.getRemovableSelectionRanges();
+    var ranges = this._view.removableSelectionRanges;
     var transactions = [];
     var removedFolders = [];
 
     for (var i = 0; i < ranges.length; i++)
       this._removeRange(ranges[i], transactions, removedFolders);
 
     if (transactions.length > 0) {
       var txn = PlacesUIUtils.ptm.aggregateTransactions(txnName, transactions);
@@ -1005,20 +1005,20 @@ PlacesController.prototype = {
   },
 
   /**
    * Removes the set of selected ranges from history.
    */
   _removeRowsFromHistory: function PC__removeRowsFromHistory() {
     // Other containers are history queries, just delete from history
     // history deletes are not undoable.
-    var nodes = this._view.getSelectionNodes();
+    var nodes = this._view.selectedNodes;
     var URIs = [];
     var bhist = PlacesUtils.history.QueryInterface(Ci.nsIBrowserHistory);
-    var root = this._view.getResultNode();
+    var root = this._view.result.root;
 
     for (var i = 0; i < nodes.length; ++i) {
       var node = nodes[i];
       if (PlacesUtils.nodeIsURI(node)) {
         var uri = PlacesUtils._uri(node.uri);
         // avoid trying to delete the same url twice
         if (URIs.indexOf(uri) < 0) {
           URIs.push(uri);
@@ -1083,17 +1083,17 @@ PlacesController.prototype = {
    *          as part of another operation.
    */
   remove: function PC_remove(aTxnName) {
     if (!this._hasRemovableSelection(false))
       return;
 
     NS_ASSERT(aTxnName !== undefined, "Must supply Transaction Name");
 
-    var root = this._view.getResultNode();
+    var root = this._view.result.root;
 
     if (PlacesUtils.nodeIsFolder(root)) 
       this._removeRowsFromBookmarks(aTxnName);
     else if (PlacesUtils.nodeIsQuery(root)) {
       var queryType = PlacesUtils.asQuery(root).queryOptions.queryType;
       if (queryType == Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS)
         this._removeRowsFromBookmarks(aTxnName);
       else if (queryType == Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY)
@@ -1110,23 +1110,23 @@ PlacesController.prototype = {
    * dropped elsewhere.
    * @param   aEvent
    *          The dragstart event.
    */
   setDataTransfer: function PC_setDataTransfer(aEvent) {
     let dt = aEvent.dataTransfer;
     let doCopy = ["copyLink", "copy", "link"].indexOf(dt.effectAllowed) != -1;
 
-    let result = this._view.getResult();
+    let result = this._view.result;
     let didSuppressNotifications = result.suppressNotifications;
     if (!didSuppressNotifications)
       result.suppressNotifications = true;
 
     try {
-      let nodes = this._view.getDraggableSelection();
+      let nodes = this._view.draggableSelection;
       for (let i = 0; i < nodes.length; ++i) {
         var node = nodes[i];
 
         function addData(type, index, overrideURI) {
           let wrapNode = PlacesUtils.wrapNode(node, type, overrideURI, doCopy);
           dt.mozSetDataAt(type, wrapNode, index);
         }
 
@@ -1152,24 +1152,24 @@ PlacesController.prototype = {
         result.suppressNotifications = false;
     }
   },
 
   /**
    * Copy Bookmarks and Folders to the clipboard
    */
   copy: function PC_copy() {
-    let result = this._view.getResult();
+    let result = this._view.result;
 
     let didSuppressNotifications = result.suppressNotifications;
     if (!didSuppressNotifications)
       result.suppressNotifications = true;
 
     try {
-      let nodes = this._view.getSelectionNodes();
+      let nodes = this._view.selectedNodes;
 
       let xferable =  Cc["@mozilla.org/widget/transferable;1"].
                       createInstance(Ci.nsITransferable);
       let foundFolder = false, foundLink = false;
       let copiedFolders = [];
       let placeString, mozURLString, htmlString, unicodeString;
       placeString = mozURLString = htmlString = unicodeString = "";
 
@@ -1626,36 +1626,32 @@ function goUpdatePlacesCommands() {
   updatePlacesCommand("placesCmd_cut");
   updatePlacesCommand("placesCmd_copy");
   updatePlacesCommand("placesCmd_paste");
   updatePlacesCommand("placesCmd_delete");
 }
 
 function doGetPlacesControllerForCommand(aCommand)
 {
-  var placesController = top.document.commandDispatcher
-                            .getControllerForCommand(aCommand);
-  if (!placesController) {
-    // If building commands for a context menu, look for an element in the
-    // current popup.
-    var element = document.popupNode;
-    while (element) {
-      var isContextMenuShown = ("_contextMenuShown" in element) && element._contextMenuShown;
-      // Check for the parent menupopup or the hbox used for toolbars
-      if ((element.localName == "menupopup" || element.localName == "hbox") &&
-          isContextMenuShown) {
-        placesController = element.controllers.getControllerForCommand(aCommand);
-        break;
-      }
-      element = element.parentNode;
-    }
+  let controller = top.document.commandDispatcher
+                      .getControllerForCommand(aCommand);
+  if (controller)
+    return controller;
+
+  // If building commands for a context menu, look for an element in the
+  // current popup.
+  let element = document.popupNode;
+  if (element) {
+    let view = PlacesUIUtils.getViewForNode(element);
+    if (view && view._contextMenuShown)
+      return view.viewElt.controllers.getControllerForCommand(aCommand);
   }
 
-  return placesController;
+  return null;
 }
 
 function goDoPlacesCommand(aCommand)
 {
-  var controller = doGetPlacesControllerForCommand(aCommand);
+  let controller = doGetPlacesControllerForCommand(aCommand);
   if (controller && controller.isCommandEnabled(aCommand))
     controller.doCommand(aCommand);
 }
 
--- a/browser/components/places/content/menu.xml
+++ b/browser/components/places/content/menu.xml
@@ -91,118 +91,118 @@
           if (this._startMarker != -1 &&
               target.boxObject.y <= this.childNodes[this._startMarker].boxObject.y)
             betweenMarkers = false;
           if (this._endMarker != -1 &&
               target.boxObject.y >= this.childNodes[this._endMarker].boxObject.y)
             betweenMarkers = false;
 
           // Hide the dropmarker if current node is not a Places node.
-          return !(target && target.node && betweenMarkers);
+          return !(target && target._placesNode && betweenMarkers);
         ]]></body>
       </method>
 
       <!-- This function returns information about where to drop when
            dragging over this popup insertion point -->
       <method name="_getDropPoint">
         <parameter name="aEvent"/>
           <body><![CDATA[
             // Can't drop if the menu isn't a folder
-            var resultNode = this._resultNode;
+            let resultNode = this._placesNode;
 
             if (!PlacesUtils.nodeIsFolder(resultNode) ||
                 PlacesControllerDragHelper.disallowInsertion(resultNode)) {
               return null;
             }
 
-            var dropPoint = { ip: null, folderNode: null };
+            var dropPoint = { ip: null, folderElt: null };
 
-            // The node we are dragging over
-            var xulNode = aEvent.target;
+            // The element we are dragging over
+            let elt = aEvent.target;
 
             // Calculate positions taking care of arrowscrollbox
-            var eventY = aEvent.layerY;
-            var scrollbox = this._scrollBox;
-            var scrollboxOffset = scrollbox.scrollBoxObject.y -
+            let eventY = aEvent.layerY;
+            let scrollbox = this._scrollBox;
+            let scrollboxOffset = scrollbox.scrollBoxObject.y -
                                   (scrollbox.boxObject.y - this.boxObject.y);
-            var nodeY = xulNode.boxObject.y - scrollboxOffset;
-            var nodeHeight = xulNode.boxObject.height;
+            let eltY = elt.boxObject.y - scrollboxOffset;
+            let eltHeight = elt.boxObject.height;
 
-            if (!xulNode.node) {
-              // if we are dragging over a non places node drop at the end
+            if (!elt._placesNode) {
+              // If we are dragging over a non places node drop at the end.
               dropPoint.ip = new InsertionPoint(
                                   PlacesUtils.getConcreteItemId(resultNode),
                                   -1,
                                   Ci.nsITreeView.DROP_ON);
               return dropPoint;
             }
-            else if ((PlacesUtils.nodeIsFolder(xulNode.node) ||
-                      PlacesUtils.nodeIsTagQuery(xulNode.node)) &&
-                     !PlacesUtils.nodeIsReadOnly(xulNode.node)) {
+            else if ((PlacesUtils.nodeIsFolder(elt._placesNode) ||
+                      PlacesUtils.nodeIsTagQuery(elt._placesNode)) &&
+                     !PlacesUtils.nodeIsReadOnly(elt._placesNode)) {
               // This is a folder or a tag container.
-              if (eventY - nodeY < nodeHeight * 0.20) {
-                // If mouse is in the top part of the node, drop above folder.
+              if (eventY - eltY < eltHeight * 0.20) {
+                // If mouse is in the top part of the element, drop above folder.
                 dropPoint.ip = new InsertionPoint(
                                     PlacesUtils.getConcreteItemId(resultNode),
                                     -1,
                                     Ci.nsITreeView.DROP_BEFORE,
-                                    PlacesUtils.nodeIsTagQuery(xulNode.node),
-                                    xulNode.node.itemId);
+                                    PlacesUtils.nodeIsTagQuery(elt._placesNode),
+                                    elt._placesNode.itemId);
                 return dropPoint;
               }
-              else if (eventY - nodeY < nodeHeight * 0.80) {
-                // If mouse is in the middle of the node, drop inside folder.
+              else if (eventY - eltY < eltHeight * 0.80) {
+                // If mouse is in the middle of the element, drop inside folder.
                 dropPoint.ip = new InsertionPoint(
-                                    PlacesUtils.getConcreteItemId(xulNode.node),
+                                    PlacesUtils.getConcreteItemId(elt._placesNode),
                                     -1,
                                     Ci.nsITreeView.DROP_ON,
-                                    PlacesUtils.nodeIsTagQuery(xulNode.node));
-                dropPoint.folderNode = xulNode;
+                                    PlacesUtils.nodeIsTagQuery(elt._placesNode));
+                dropPoint.folderElt = elt;
                 return dropPoint;
               }
             }
-            else if (eventY - nodeY <= nodeHeight / 2) {
+            else if (eventY - eltY <= eltHeight / 2) {
               // This is a non-folder node or a readonly folder.
               // If the mouse is above the middle, drop above this item.
               dropPoint.ip = new InsertionPoint(
                                   PlacesUtils.getConcreteItemId(resultNode),
                                   -1,
                                   Ci.nsITreeView.DROP_BEFORE,
-                                  PlacesUtils.nodeIsTagQuery(xulNode.node),
-                                  xulNode.node.itemId);
+                                  PlacesUtils.nodeIsTagQuery(elt._placesNode),
+                                  elt._placesNode.itemId);
               return dropPoint;
             }
 
             // Drop below the item.
             dropPoint.ip = new InsertionPoint(
                                 PlacesUtils.getConcreteItemId(resultNode),
                                 -1,
                                 Ci.nsITreeView.DROP_AFTER,
-                                PlacesUtils.nodeIsTagQuery(xulNode.node),
-                                xulNode.node.itemId);
+                                PlacesUtils.nodeIsTagQuery(elt._placesNode),
+                                elt._placesNode.itemId);
             return dropPoint;
         ]]></body>
       </method>
 
       <!-- Sub-menus should be opened when the mouse drags over them, and closed
            when the mouse drags off.  The overFolder object manages opening and
            closing of folders when the mouse hovers. -->
       <field name="_overFolder"><![CDATA[({
         _self: this,
-        _folder: {node: null,
+        _folder: {elt: null,
                   openTimer: null,
                   hoverTime: 350,
                   closeTimer: null},
         _closeMenuTimer: null,
 
-        get node() {
-          return this._folder.node;
+        get elt() {
+          return this._folder.elt;
         },
-        set node(val) {
-          return this._folder.node = val;
+        set elt(val) {
+          return this._folder.elt = val;
         },
 
         get openTimer() {
           return this._folder.openTimer;
         },
         set openTimer(val) {
           return this._folder.openTimer = val;
         },
@@ -234,29 +234,29 @@
           return timer;
         },
 
         notify: function OF__notify(aTimer) {
           // Function to process all timer notifications.
 
           if (aTimer == this._folder.openTimer) {
             // Timer to open a submenu that's being dragged over.
-            this._folder.node.lastChild.setAttribute("autoopened", "true");
-            this._folder.node.lastChild.showPopup(this._folder.node);
+            this._folder.elt.lastChild.setAttribute("autoopened", "true");
+            this._folder.elt.lastChild.showPopup(this._folder.elt);
             this._folder.openTimer = null;
           }
 
           else if (aTimer == this._folder.closeTimer) {
             // Timer to close a submenu that's been dragged off of.
             // Only close the submenu if the mouse isn't being dragged over any
             // of its child menus.
             var draggingOverChild = PlacesControllerDragHelper
-                                    .draggingOverChildNode(this._folder.node);
+                                    .draggingOverChildNode(this._folder.elt);
             if (draggingOverChild)
-              this._folder.node = null;
+              this._folder.elt = null;
             this.clear();
 
             // Close any parent folders which aren't being dragged over.
             // (This is necessary because of the above code that keeps a folder
             // open while its children are being dragged over.)
             if (!draggingOverChild)
               this.closeParentMenus();
           }
@@ -280,117 +280,117 @@
 
         //  Helper function to close all parent menus of this menu,
         //  as long as none of the parent's children are currently being
         //  dragged over.
         closeParentMenus: function OF__closeParentMenus() {
           var popup = this._self;
           var parent = popup.parentNode;
           while (parent) {
-            if (parent.nodeName == "menupopup" && parent._resultNode) {
+            if (parent.localName == "menupopup" && parent._placesNode) {
               if (PlacesControllerDragHelper.draggingOverChildNode(parent.parentNode))
                 break;
               parent.hidePopup();
             }
             parent = parent.parentNode;
           }
         },
 
         //  The mouse is no longer dragging over the stored menubutton.
         //  Close the menubutton, clear out drag styles, and clear all
         //  timers for opening/closing it.
         clear: function OF__clear() {
-          if (this._folder.node && this._folder.node.lastChild) {
-            if (!this._folder.node.lastChild.hasAttribute("dragover"))
-              this._folder.node.lastChild.hidePopup();
+          if (this._folder.elt && this._folder.elt.lastChild) {
+            if (!this._folder.elt.lastChild.hasAttribute("dragover"))
+              this._folder.elt.lastChild.hidePopup();
             // remove menuactive style
-            this._folder.node.removeAttribute("_moz-menuactive");
-            this._folder.node = null;
+            this._folder.elt.removeAttribute("_moz-menuactive");
+            this._folder.elt = null;
           }
           if (this._folder.openTimer) {
             this._folder.openTimer.cancel();
             this._folder.openTimer = null;
           }
           if (this._folder.closeTimer) {
             this._folder.closeTimer.cancel();
             this._folder.closeTimer = null;
           }
         }
       })]]></field>
 
       <method name="_cleanupDragDetails">
         <body><![CDATA[
           // Called on dragend and drop.
           PlacesControllerDragHelper.currentDropTarget = null;
-          this._rootView._draggedNode = null;
+          this._rootView._draggedElt = null;
           this.removeAttribute("dragover");
           this.removeAttribute("dragstart");
           this._indicatorBar.hidden = true;
         ]]></body>
       </method>
 
     </implementation>
 
     <handlers>
       <handler event="DOMMenuItemActive"><![CDATA[
-        var node = event.target;
-        if (node.parentNode != this)
+        let elt = event.target;
+        if (elt.parentNode != this)
           return;
 
 #ifdef XP_MACOSX
-        // XXXschonfeld: The following check is a temporary hack
-        // until bug 420033 is resolved.
-        while (node) {
-          if (node.id == "bookmarksMenuPopup" || node.id == "goPopup")
+        // XXX: The following check is a temporary hack until bug 420033 is
+        // resolved.
+        let parentElt = elt.parent;
+        while (parentElt) {
+          if (parentElt.id == "bookmarksMenuPopup" ||
+              parentElt.id == "goPopup")
             return;
 
-          node = node.parentNode;
+          parentElt = parentElt.parentNode;
         }
 #endif
 
         if (window.XULBrowserWindow) {
-          var nodeItem = event.target.node;
+          let elt = event.target;
+          let placesNode = elt._placesNode;
 
           var linkURI;
-          if (nodeItem && PlacesUtils.nodeIsURI(nodeItem))
-            linkURI = nodeItem.uri;
-          else if (node.hasAttribute("targetURI"))
-            linkURI = node.getAttribute("targetURI");
+          if (placesNode && PlacesUtils.nodeIsURI(placesNode))
+            linkURI = placesNode.uri;
+          else if (elt.hasAttribute("targetURI"))
+            linkURI = elt.getAttribute("targetURI");
 
           if (linkURI)
             window.XULBrowserWindow.setOverLink(linkURI, null);
         }
       ]]></handler>
 
       <handler event="DOMMenuItemInactive"><![CDATA[
-        var node = event.target;
-        if (node.parentNode != this)
+        let elt = event.target;
+        if (elt.parentNode != this)
           return;
 
         if (window.XULBrowserWindow)
           window.XULBrowserWindow.setOverLink("", null);
       ]]></handler>
 
       <handler event="dragstart"><![CDATA[
-        if (!event.target.node)
+        if (!event.target._placesNode)
           return;
 
-        let draggedNode = event.target.node;
+        let draggedElt = event.target._placesNode;
 
         // Force a copy action if parent node is a query or we are dragging a
         // not-removable node.
-        if (!PlacesControllerDragHelper.canMoveNode(draggedNode))
+        if (!PlacesControllerDragHelper.canMoveNode(draggedElt))
           event.dataTransfer.effectAllowed = "copyLink";
 
-        // Activate the view and cache the dragged node.
-        this._rootView._draggedNode = draggedNode;
-        this._rootView.focus();
-
-        this._rootView._controller.setDataTransfer(event);
-
+        // Activate the view and cache the dragged element.
+        this._rootView._draggedElt = draggedElt;
+        this._rootView.controller.setDataTransfer(event);
         this.setAttribute("dragstart", "true");
         event.stopPropagation();
       ]]></handler>
 
       <handler event="drop"><![CDATA[
         PlacesControllerDragHelper.currentDropTarget = event.target;
 
         let dropPoint = this._getDropPoint(event);
@@ -413,65 +413,65 @@
           this._indicatorBar.hidden = true;
           event.stopPropagation();
           return;
         }
 
         // Mark this popup as being dragged over.
         this.setAttribute("dragover", "true");
 
-        if (dropPoint.folderNode) {
+        if (dropPoint.folderElt) {
           // We are dragging over a folder.
           // _overFolder should take the care of opening it on a timer.
-          if (this._overFolder.node &&
-              this._overFolder.node != dropPoint.folderNode) {
+          if (this._overFolder.elt &&
+              this._overFolder.elt != dropPoint.folderElt) {
             // We are dragging over a new folder, let's clear old values
             this._overFolder.clear();
           }
-          if (!this._overFolder.node) {
-            this._overFolder.node = dropPoint.folderNode;
+          if (!this._overFolder.elt) {
+            this._overFolder.elt = dropPoint.folderElt;
             // Create the timer to open this folder.
             this._overFolder.openTimer = this._overFolder
                                              .setTimer(this._overFolder.hoverTime);
           }
           // Since we are dropping into a folder set the corresponding style.
-          dropPoint.folderNode.setAttribute("_moz-menuactive", true);
+          dropPoint.folderElt.setAttribute("_moz-menuactive", true);
         }
         else {
           // We are not dragging over a folder.
           // Clear out old _overFolder information.
           this._overFolder.clear();
         }
 
         // Autoscroll the popup strip if we drag over the scroll buttons.
         let anonid = event.originalTarget.getAttribute('anonid');
         let scrollDir = anonid == "scrollbutton-up" ? -1 :
                         anonid == "scrollbutton-down" ? 1 : 0;
         if (scrollDir != 0) {
           this._scrollBox.scrollByIndex(scrollDir, false);
         }
 
         // Check if we should hide the drop indicator for this target.
-        if (dropPoint.folderNode || this._hideDropIndicator(event)) {
+        if (dropPoint.folderElt || this._hideDropIndicator(event)) {
           this._indicatorBar.hidden = true;
           event.preventDefault();
           event.stopPropagation();
           return;
         }
 
         // We should display the drop indicator relative to the arrowscrollbox.
         let sbo = this._scrollBox.scrollBoxObject;
         let newMarginTop = 0;
         if (scrollDir == 0) {
-          let node = this.firstChild;
-          while (node && event.screenY > node.boxObject.screenY +
-                                         node.boxObject.height / 2)
-            node = node.nextSibling;
-          newMarginTop = node ? node.boxObject.screenY - sbo.screenY :
-                                sbo.height;
+          let elt = this.firstChild;
+          while (elt && event.screenY > elt.boxObject.screenY +
+                                        elt.boxObject.height / 2)
+            elt = elt.nextSibling;
+          newMarginTop = elt ? elt.boxObject.screenY - sbo.screenY :
+                               sbo.height;
         }
         else if (scrollDir == 1)
           newMarginTop = sbo.height;
 
         // Set the new marginTop based on arrowscrollbox.
         newMarginTop += sbo.y - this._scrollBox.boxObject.y;
         this._indicatorBar.firstChild.style.marginTop = newMarginTop + "px";
         this._indicatorBar.hidden = false;
@@ -486,17 +486,17 @@
 
         // If we have not moved to a valid new target clear the drop indicator
         // this happens when moving out of the popup.
         let target = event.relatedTarget;
         if (!target)
           this._indicatorBar.hidden = true;
 
         // Close any folder being hovered over
-        if (this._overFolder.node) {
+        if (this._overFolder.elt) {
           this._overFolder.closeTimer = this._overFolder
                                             .setTimer(this._overFolder.hoverTime);
         }
 
         // The autoopened attribute is set when this folder was automatically
         // opened after the user dragged over it.  If this attribute is set,
         // auto-close the folder on drag exit.
         // We should also try to close this popup if the drag has started
@@ -511,578 +511,9 @@
       ]]></handler>
 
       <handler event="dragend"><![CDATA[
         this._cleanupDragDetails();
       ]]></handler>
 
     </handlers>
   </binding>
-
-
-  <binding id="places-menupopup"
-           extends="chrome://browser/content/places/menu.xml#places-popup-base">
-    <implementation>
-      <destructor><![CDATA[
-        if (this._result) {
-          this._result.removeObserver(this._resultObserver);
-          this._resultNode.containerOpen = false;
-          this._resultNode = null;
-          this._result = null;
-        }
-      ]]></destructor>
-
-      <field name="_initialized">false</field>
-      <method name="_ensureInitialized">
-        <body><![CDATA[
-          if (this._initialized)
-            return;
-
-          this._controller = new PlacesController(this);
-          this.controllers.appendController(this._controller);
-
-          // This function should only be called for top-level menus like the bookmarks menu.
-          // Submenus get their _result and _resultNode from their parents.
-          if (this.hasAttribute("place")) {
-            // Do the initial build.
-            this.place = this.place;
-          }
-          this._initialized = true;
-        ]]></body>
-      </method>
-
-      <property name="controller"
-                readonly="true"
-                onget="return this._controller;"/>
-
-      <method name="onPopupShowing">
-        <parameter name="aEvent"/>
-        <body><![CDATA[
-          var popup = aEvent.target;
-          var resultNode = popup._resultNode;
-          if (!resultNode.containerOpen)
-            resultNode.containerOpen = true;
-          if (!popup.parentNode._built)
-            this._rebuild(popup);
-        ]]></body>
-      </method>
-
-      <field name="_result">null</field>
-      <field name="_resultNode">null</field>
-
-      <!-- nsIPlacesView -->
-      <method name="getResult">
-        <body><![CDATA[
-          return this._result;
-        ]]></body>
-      </method>
-
-      <!-- nsIPlacesView -->
-      <method name="getResultNode">
-        <body><![CDATA[
-          this._ensureInitialized();
-          return this._resultNode;
-        ]]></body>
-      </method>
-
-      <method name="removeItem">
-        <parameter name="child"/>
-        <body><![CDATA[
-          // if document.popupNode pointed to this child, null it out,
-          // otherwise controller's command-updating may rely on the removed
-          // item still being "selected".
-          if (document.popupNode == child)
-            document.popupNode = null;
-
-          child.parentNode.removeChild(child);
-
-          if (this._endMarker != -1)
-            this._endMarker--;
-        ]]></body>
-      </method>
-
-      <method name="insertNewItem">
-        <parameter name="aChild"/>
-        <parameter name="aParentPopup"/>
-        <parameter name="aBefore"/>
-        <body><![CDATA[
-          let element = PlacesUIUtils.createMenuItemForNode(aChild,
-                                                            aParentPopup.ownerDocument);
-          if (aBefore)
-            aParentPopup.insertBefore(element, aBefore);
-          else {
-            // Add the new element to the menu.  If there is static content at
-            // the end of the menu, add the element before that.  Otherwise,
-            // just add to the end.
-            if (aParentPopup._endMarker != -1) {
-              aParentPopup.insertBefore(element,
-                                        aParentPopup.childNodes[aParentPopup._endMarker]);
-            }
-            else
-              aParentPopup.appendChild(element);
-          }
-
-          if (aParentPopup._endMarker != -1)
-            aParentPopup._endMarker++;
-
-#ifdef XP_MACOSX
-          // Bug 529062:
-          // We rely on the menu* bindings, but those aren't never applied
-          // in native mac menus, for elements which are added to the document
-          // through appendChild / insertBefore.
-          if (this.parentNode.parentNode.localName != "menubar")
-            return;
-
-          function applyBinding(elm) {
-            // getPropertyCSSValue is semi-deprecared, but there's no
-            // alternative for parsing css_uri values reliably.
-            let elmBindingURI = window.getComputedStyle(element, "")
-                                      .getPropertyCSSValue("-moz-binding");
-            if (elmBindingURI.primitiveType == CSSPrimitiveValue.CSS_URI)
-              document.addBinding(elm, elmBindingURI.getStringValue());
-          }
-
-          applyBinding(element);
-          if (element.localName == "menu")
-            applyBinding(element.firstChild);
-#endif
-        ]]></body>
-      </method>
-
-      <method name="_showEmptyMenuItem">
-        <parameter name="aPopup"/>
-        <body><![CDATA[
-          if (aPopup._emptyMenuItem) {
-            aPopup._emptyMenuItem.hidden = false;
-            return;
-          }
-
-          var label = PlacesUIUtils.getString("bookmarksMenuEmptyFolder");
-          aPopup._emptyMenuItem = document.createElement("menuitem");
-          aPopup._emptyMenuItem.setAttribute("label", label);
-          aPopup._emptyMenuItem.setAttribute("disabled", true);
-          aPopup.appendChild(aPopup._emptyMenuItem);
-        ]]></body>
-      </method>
-
-      <method name="_rebuild">
-        <parameter name="aPopup"/>
-        <body><![CDATA[
-          PlacesUIUtils.cleanPlacesPopup(aPopup);
-
-          // If this is a livemark container check if the status menuitem has
-          // to be added or removed.
-          if (PlacesUtils.nodeIsLivemarkContainer(aPopup._resultNode))
-            PlacesUIUtils.ensureLivemarkStatusMenuItem(aPopup);
-
-          var cc = aPopup._resultNode.childCount;
-          if (cc > 0) {
-            if (aPopup._emptyMenuItem)
-              aPopup._emptyMenuItem.hidden = true;
-
-            for (var i = 0; i < cc; ++i) {
-              var child = aPopup._resultNode.getChild(i);
-              this.insertNewItem(child, aPopup, null);
-            }
-          }
-          else {
-            // This menu is empty.  If there is no static content, add
-            // an element to show it is empty.
-            if (aPopup._startMarker == -1 && aPopup._endMarker == -1)
-              this._showEmptyMenuItem(aPopup);
-          }
-          aPopup.parentNode._built = true;
-        ]]></body>
-      </method>
-
-      <!-- nsINavHistoryResultObserver -->
-      <field name="_resultObserver"><![CDATA[({
-        _self: this,
-
-        get result() {
-          return this._self._result;
-        },
-
-        set result(val) {
-          if (this._self._result) {
-            this._self._result.removeObserver(this);
-            this._self._resultNode.containerOpen = false;
-          }
-
-          this._self.parentNode._built = false;
-          this._self._result = val;
-          if (val) {
-            this._self._resultNode = val.root;
-            this._self._resultNode._DOMElement = this._self.parentNode;
-          }
-          else {
-            this._self._resultNode = null;
-          }
-
-          return val;
-        },
-
-        nodeInserted: function PMV_nodeInserted(aParentNode, aNode, aIndex) {
-          let parentElt = aParentNode._DOMElement;
-          NS_ASSERT(parentElt, "parent node must have _DOMElement set");
-
-          if (!parentElt._built)
-            return;
-
-          // parentElt is the <menu> element for the container,
-          // we need the <menupopup>
-          let popup = parentElt.firstChild;
-
-          let index = popup._startMarker + 1 + aIndex;
-          this._self.insertNewItem(aNode, popup, popup.childNodes[index]);
-          if (popup._emptyMenuItem)
-            popup._emptyMenuItem.hidden = true;
-        },
-
-        nodeRemoved: function PMV_nodeRemoved(aParentNode, aNode, aIndex) {
-          let parentElt = aParentNode._DOMElement;
-          NS_ASSERT(parentElt, "parent node must have _DOMElement set");
-
-          if (!parentElt._built)
-            return;
-
-          // parentElt is the <menu> element for the container,
-          // we need the <menupopup>
-          let popup = parentElt.firstChild;
-
-          let nodeElt = aNode._DOMElement;
-          NS_ASSERT(nodeElt, "node must have _DOMElement set");
-          popup.removeChild(nodeElt);
-
-          // Figure out if we need to show the "<Empty>" menu-item.
-          // TODO Bug 517701: This doesn't seem to handle the case of an empty
-          // root (parentElt == this._self.parentNode).
-          if (!popup.hasChildNodes() ||
-              (popup.childNodes.length == 1 &&
-              popup.firstChild == popup._emptyMenuItem))
-            this._self._showEmptyMenuItem(popup);
-
-          if (popup._endMarker != -1)
-            popup._endMarker--;
-        },
-
-        nodeMoved:
-        function PMV_nodeMoved(aNode,
-                               aOldParent, aOldIndex,
-                               aNewParent, aNewIndex) {
-          // Note: the current implementation of moveItem does not actually
-          // use this notification when the item in question is moved from one
-          // folder to another.  Instead, it calls nodeRemoved and nodeInserted
-          // for the two folders.  Thus, we can assume aOldParent == aNewParent.
-
-          let nodeElt = aNode._DOMElement;
-          NS_ASSERT(nodeElt, "node must have _DOMElement set");
-
-          // If our root node is a folder, it might be moved. There's nothing
-          // we need to do in that case.
-          if (nodeElt == this._self.parentNode)
-            return;
-
-          // Move the node.
-          let popup = nodeElt.parentNode;
-          let index = popup._startMarker + 1 + aNewIndex;
-          popup.removeChild(nodeElt);
-          popup.insertBefore(nodeElt, popup.childNodes[index]);
-        },
-
-        nodeTitleChanged: function PMV__nodeTitleChanged(aNode, aNewTitle) {
-          let nodeElt = aNode._DOMElement;
-          NS_ASSERT(nodeElt, "node must have _DOMElement set");
-
-          // There's no UI representation for the root node, thus there's
-          // nothing to be done when the title changes.
-          if (nodeElt == this._self.parentNode)
-            return;
-
-          nodeElt.label = aNewTitle || PlacesUIUtils.getBestTitle(aNode);
-        },
-
-        nodeURIChanged: function PMV_nodeURIChanged(aNode, aURIString) {
-          let nodeElt = aNode._DOMElement;
-          NS_ASSERT(nodeElt, "node must have _DOMElement set");
-
-          nodeElt.setAttribute("scheme",
-                               PlacesUIUtils.guessUrlSchemeForUI(aURIString));
-        },
-
-        nodeIconChanged: function PMV_nodeIconChanged(aNode) {
-          let nodeElt = aNode._DOMElement;
-          NS_ASSERT(nodeElt, "node must have _DOMElement set");
-
-          // There's no UI representation for the root node, thus there's
-          // nothing to be done when the icon changes.
-          if (nodeElt == this._self.parentNode)
-            return;
-
-          var icon = aNode.icon;
-          if (icon) {
-            if (nodeElt.getAttribute("image") != icon)
-              nodeElt.setAttribute("image", icon);
-          }
-          else
-            nodeElt.removeAttribute("image");
-        },
-
-        nodeAnnotationChanged:
-        function PMV_nodeAnnotationChanged(aNode, aAnno) {
-          // Ensure the changed annotation is a livemark one.
-          if (/^livemark\//.test(aAnno) &&
-              PlacesUtils.nodeIsLivemarkContainer(aNode)) {
-            let nodeElt = aNode._DOMElement;
-            NS_ASSERT(nodeElt, "node must have _DOMElement set");
-
-            if (!nodeElt.hasAttribute("livemark"))
-              nodeElt.setAttribute("livemark", "true");
-
-            // Add or remove the livemark status menuitem.
-            PlacesUIUtils.ensureLivemarkStatusMenuItem(nodeElt.firstChild);
-          }
-        },
-
-        nodeHistoryDetailsChanged: function() { },
-        nodeTagsChanged: function() { },
-        nodeDateAddedChanged: function() { },
-        nodeLastModifiedChanged: function() { },
-        nodeKeywordChanged: function() { },
-
-        nodeReplaced:
-        function PMV_nodeReplaced(aParentNode, aOldNode, aNewNode, aIndex) {
-          let parentElt = aParentNode._DOMElement;
-          NS_ASSERT(parentElt, "parent node must have _DOMElement set");
-
-          if (!parentElt._built)
-            return;
-
-          // parentElt is the <menu> element for the container,
-          // we need the <menupopup>.
-          let popup = parentElt.firstChild;
-
-          let nodeElt = aOldNode._DOMElement;
-          NS_ASSERT(nodeElt, "node must have _DOMElement set");
-
-          // No worries: If nodeElt is the last item (i.e. no nextSibling),
-          // insertNewItem will insert the new element as the last item.
-          let next = nodeElt.nextSibling;
-          this._self.removeItem(nodeElt);
-          this._self.insertNewItem(aNewNode, popup, next);
-        },
-
-        containerOpened: function PMV_containerOpened(aNode) {
-          this.invalidateContainer(aNode);
-        },
-
-        containerClosed: function PMV_containerClosed(aNode) {
-          this.invalidateContainer(aNode);
-        },
-
-        containerStateChanged:
-        function PMV_containerStateChanged(aNode, aOldState, aNewState) {},
-
-        invalidateContainer: function PMV_invalidateContainer(aContainer) {
-          // Do nothing if the entire view is already marked un-built.
-          if (!this._self.parentNode._built)
-            return;
-
-          let containerNodeElt = aContainer._DOMElement;
-          NS_ASSERT(containerNodeElt, "node must have _DOMElement set");
-          containerNodeElt._built = false;
-
-          // If the menupopup is open we should live-update it.
-          if (containerNodeElt.open)
-            this._self._rebuild(containerNodeElt.firstChild);
-        },
-
-        sortingChanged: function PMV_sortingChanged(aSortingMode) {
-        },
-        
-        QueryInterface: function PTV_QueryInterface(aIID) {
-          if (aIID.equals(Ci.nsINavHistoryResultObserver) ||
-              aIID.equals(Ci.nsISupportsWeakReference) ||
-              aIID.equals(Ci.nsISupports))
-            return this;
-          throw Cr.NS_ERROR_NO_INTERFACE;
-        }
-      })]]></field>
-
-      <!-- nsIPlacesView -->
-      <property name="place">
-        <getter><![CDATA[
-          return this.getAttribute("place");
-        ]]></getter>
-        <setter><![CDATA[
-          this.setAttribute("place", val);
-          var queries = { }, options = { };
-          PlacesUtils.history.queryStringToQueries(val, queries, { }, options);
-          if (!queries.value.length)
-            queries.value = [PlacesUtils.history.getNewQuery()];
-          var result =
-            PlacesUtils.history.executeQueries(queries.value,
-                                               queries.value.length,
-                                               options.value);
-
-          result.addObserver(this._resultObserver, false);
-          return val;
-        ]]></setter>
-      </property>
-
-      <!-- nsIPlacesView -->
-      <property name="hasSelection">
-        <getter><![CDATA[
-          return this.selectedNode != null;
-        ]]></getter>
-      </property>
-
-      <!-- nsIPlacesView -->
-      <method name="getSelectionNodes">
-        <body><![CDATA[
-          var selectedNode = this.selectedNode;
-          return selectedNode ? [selectedNode] : [];
-        ]]></body>
-      </method>
-
-      <!-- nsIPlacesView -->
-      <method name="getRemovableSelectionRanges">
-        <body><![CDATA[
-          // On static content the current selectedNode would be the selection's
-          // parent node. We don't want to allow removing a node when the
-          // selection is not explicit.
-          if (document.popupNode &&
-              (document.popupNode == "menupopup" || !document.popupNode.node))
-            return [];
-
-          return [this.getSelectionNodes()];
-        ]]></body>
-      </method>
-
-      <!-- nsIPlacesView -->
-      <method name="getDraggableSelection">
-        <body><![CDATA[
-          return [this._draggedNode];
-        ]]></body>
-      </method>
-
-      <!-- nsIPlacesView -->
-      <property name="selectedNode">
-        <getter><![CDATA[
-          if (this._contextMenuShown) {
-            var popupNode = document.popupNode;
-            return popupNode.node || popupNode.parentNode._resultNode || null;
-          }
-          return null;
-        ]]></getter>
-      </property>
-
-      <!-- nsIPlacesView -->
-      <property name="insertionPoint">
-        <getter><![CDATA[
-          // there is no insertion point for history queries
-          // so bail out now and save a lot of work when updating commands
-          var resultNode = this._resultNode;
-          if (PlacesUtils.nodeIsQuery(resultNode) &&
-              PlacesUtils.asQuery(resultNode).queryOptions.queryType ==
-                Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY)
-              return null;
-
-          // By default, the insertion point is at the top level, at the end.
-          var index = PlacesUtils.bookmarks.DEFAULT_INDEX;
-          var container = null;
-          var orientation = Ci.nsITreeView.DROP_BEFORE;
-          var isTag = false;
-
-          if (PlacesUtils.nodeIsFolder(resultNode)) {
-            container = resultNode;
-            isTag = PlacesUtils.nodeIsTagQuery(resultNode);
-          }
-
-          var selectedNode = this.selectedNode;
-          if (selectedNode) {
-            var popupNode = document.popupNode;
-            if (!popupNode.node) {
-              // If a static menuitem is selected the insertion point
-              // is inside the folder, at the end.
-              container = selectedNode;
-              orientation = Ci.nsITreeView.DROP_ON;
-            }
-            else {
-              // In all other cases the insertion point is before that node.
-              container = selectedNode.parent;
-              index = container.getChildIndex(selectedNode);
-              isTag = PlacesUtils.nodeIsTagQuery(container);
-            }
-          }
-
-          if (PlacesControllerDragHelper.disallowInsertion(container))
-            return null;
-
-          return new InsertionPoint(PlacesUtils.getConcreteItemId(container),
-                                    index, orientation, isTag);
-        ]]></getter>
-      </property>
-
-      <!-- nsIPlacesView -->
-      <method name="selectAll">
-        <body/>
-      </method>
-
-      <method name="selectItems">
-        <body/>
-      </method>
-
-      <property name="selType" readonly="true" onget="return 'single';"/>
-
-      <method name="buildContextMenu">
-        <parameter name="aPopup"/>
-        <body><![CDATA[
-          this._ensureInitialized();
-          this._contextMenuShown = true;
-          window.updateCommands("places");
-          return this.controller.buildContextMenu(aPopup);
-        ]]></body>
-      </method>
-
-      <method name="destroyContextMenu">
-        <parameter name="aPopup"/>
-        <body>
-          <![CDATA[
-            this._contextMenuShown = false;
-            if (window.content)
-              window.content.focus();
-          ]]>
-        </body>
-      </method>
-    </implementation>
-    <handlers>
-      <handler event="popupshowing" phase="capturing"><![CDATA[
-        this._ensureInitialized();
-        var popup = event.target;
-        // Avoid handling popupshowing of inner views
-        if (!popup._resultNode || PlacesUIUtils.getViewForNode(popup) != this)
-          return;
-
-        this.onPopupShowing(event);
-      ]]></handler>
-
-      <handler event="popuphidden"><![CDATA[
-        var popup = event.target;
-        // We should avoid to handle events of inner views
-        if (!popup._resultNode || PlacesUIUtils.getViewForNode(popup) != this)
-          return;
-
-        // UI performance: folder queries are cheap, keep the resultnode open
-        // so we don't rebuild its contents whenever the popup is reopened.
-        if (!PlacesUtils.nodeIsFolder(popup._resultNode))
-          popup._resultNode.containerOpen = false;
-
-        // The autoopened attribute is set for folders which have been
-        // automatically opened when dragged over.  Turn off this attribute
-        // when the folder closes because it is no longer applicable.
-        popup.removeAttribute("autoopened");
-        popup.removeAttribute("dragstart");
-      ]]></handler>
-    </handlers>
-  </binding>
-
 </bindings>
--- a/browser/components/places/content/places.css
+++ b/browser/components/places/content/places.css
@@ -1,29 +1,21 @@
 tree[type="places"] {
   -moz-binding: url("chrome://browser/content/places/tree.xml#places-tree");
 }
 
-hbox[type="places"] {
-  -moz-binding: url("chrome://browser/content/places/toolbar.xml#places-bar");
-}
-
 .bookmarks-toolbar-customize,
-toolbarpaletteitem .bookmarks-toolbar-items {
+toolbarpaletteitem #PlacesToolbarItems {
   display: none;
 }
 
 toolbarpaletteitem .bookmarks-toolbar-customize {
   display: -moz-box;
 }
 
 .toolbar-drop-indicator {
   position: relative;
   z-index: 1;
 }
 
-menupopup[type="places"] {
-  -moz-binding: url("chrome://browser/content/places/menu.xml#places-menupopup");
-}
-
 menupopup[placespopup="true"] {
   -moz-binding: url("chrome://browser/content/places/menu.xml#places-popup-base");
 }
--- a/browser/components/places/content/places.js
+++ b/browser/components/places/content/places.js
@@ -326,17 +326,17 @@ var PlacesOrganizer = {
    * Handle focus changes on the trees.
    * When moving focus between panes we should update the details pane contents.
    * @param   aEvent
    *          The mouse event.
    */
   onTreeFocus: function PO_onTreeFocus(aEvent) {
     var currentView = aEvent.currentTarget;
     var selectedNodes = currentView.selectedNode ? [currentView.selectedNode] :
-                        this._content.getSelectionNodes();
+                        this._content.selectedNodes;
     this._fillDetailsPane(selectedNodes);
   },
 
   openFlatContainer: function PO_openFlatContainerFlatContainer(aContainer) {
     if (aContainer.itemId != -1)
       this._places.selectItems([aContainer.itemId]);
     else if (PlacesUtils.nodeIsQuery(aContainer))
       this._places.selectPlaceURI(aContainer.uri);
@@ -346,25 +346,25 @@ var PlacesOrganizer = {
     PlacesUIUtils.openNodeWithEvent(this._content.selectedNode, aEvent);
   },
 
   /**
    * Returns the options associated with the query currently loaded in the
    * main places pane.
    */
   getCurrentOptions: function PO_getCurrentOptions() {
-    return PlacesUtils.asQuery(this._content.getResult().root).queryOptions;
+    return PlacesUtils.asQuery(this._content.result.root).queryOptions;
   },
 
   /**
    * Returns the queries associated with the query currently loaded in the
    * main places pane.
    */
   getCurrentQueries: function PO_getCurrentQueries() {
-    return PlacesUtils.asQuery(this._content.getResult().root).getQueries();
+    return PlacesUtils.asQuery(this._content.result.root).getQueries();
   },
 
   /**
    * Show the migration wizard for importing from a file.
    */
   importBookmarks: function PO_import() {
     // XXX: ifdef it to be non-modal (non-"sheet") on mac (see bug 259039)
     var features = "modal,centerscreen,chrome,resizable=no";
@@ -604,17 +604,17 @@ var PlacesOrganizer = {
     var height = previewBox.boxObject.height;
     var width = height * (screen.width / screen.height);
     canvas.width = width;
     canvas.height = height;
   },
 
   onContentTreeSelect: function PO_onContentTreeSelect() {
     if (this._content.treeBoxObject.focused)
-      this._fillDetailsPane(this._content.getSelectionNodes());
+      this._fillDetailsPane(this._content.selectedNodes);
   },
 
   _fillDetailsPane: function PO__fillDetailsPane(aNodeList) {
     var infoBox = document.getElementById("infoBox");
     var detailsDeck = document.getElementById("detailsDeck");
 
     // Make sure the infoBox UI is visible if we need to use it, we hide it
     // below when we don't.
@@ -1281,17 +1281,17 @@ var ViewMenu = {
    *          current sort column or the title column will be used.
    * @param   aDirection
    *          The direction to sort - "ascending" or "descending".
    *          Can be null - the last direction or descending will be used.
    *
    * If both aColumnID and aDirection are null, the view will be unsorted.
    */
   setSortColumn: function VM_setSortColumn(aColumn, aDirection) {
-    var result = document.getElementById("placeContent").getResult();
+    var result = document.getElementById("placeContent").result;
     if (!aColumn && !aDirection) {
       result.sortingMode = Ci.nsINavHistoryQueryOptions.SORT_BY_NONE;
       return;
     }
 
     var columnId;
     if (aColumn) {
       columnId = aColumn.getAttribute("anonid");
deleted file mode 100644
--- a/browser/components/places/content/toolbar.xml
+++ /dev/null
@@ -1,1326 +0,0 @@
-<?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 Places Toolbar View.
-#
-# The Initial Developer of the Original Code is Google Inc.
-# Portions created by the Initial Developer are Copyright (C) 2005-2006
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#   Annie Sullivan <annie.sullivan@gmail.com>
-#   Ben Goodger <beng@google.com>
-#   Myk Melez <myk@mozilla.org>
-#   Marco Bonardo <mak77@bonardo.net>
-#   Asaf Romano <mano@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 *****
-
-
-<!DOCTYPE bindings [
-<!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd" >
-%browserDTD;
-]>
-
-<bindings id="placesToolbarBindings"
-          xmlns="http://www.mozilla.org/xbl"
-          xmlns:xbl="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">
-
-  <binding id="places-bar">
-    <resources>
-      <stylesheet src="chrome://browser/skin/places/places.css"/>
-    </resources>
-
-    <content>
-        <xul:toolbarbutton class="bookmark-item bookmarks-toolbar-customize"
-                           mousethrough="never"
-                           label="&bookmarksToolbarItem.label;"/>
-        <xul:hbox flex="1">
-          <xul:hbox align="center">
-            <xul:image class="toolbar-drop-indicator"
-                       mousethrough="always"
-                       collapsed="true"/>
-          </xul:hbox>
-          <xul:scrollbox orient="horizontal"
-                         class="bookmarks-toolbar-items"
-                         flex="1">
-            <children/>
-          </xul:scrollbox>
-          <xul:toolbarbutton type="menu"
-                             class="chevron"
-                             mousethrough="never"
-                             collapsed="true"
-                             tooltiptext="&bookmarksToolbarChevron.tooltip;"
-                             onpopupshowing="_onChevronPopupShowing(event);">
-            <xul:menupopup anonid="chevronPopup"
-                           popupsinherittooltip="true"
-                           xbl:inherits="tooltip"
-#ifndef XP_MACOSX
-                           context="placesContext"
-#endif
-            />
-          </xul:toolbarbutton>
-        </xul:hbox>
-    </content>
-
-    <implementation implements="nsIAccessibleProvider, nsITimerCallback, nsIDOMEventListener">
-      <constructor><![CDATA[
-        this._init();
-      ]]></constructor>
-
-      <destructor><![CDATA[
-        this._scrollbox.removeEventListener("overflow", this, false);
-        this._scrollbox.removeEventListener("underflow", this, false);
-        window.removeEventListener("resize", this, false);
-
-        if (this._result) {
-          this._result.removeObserver(this._resultObserver);
-          this._resultNode.containerOpen = false;
-          this._resultNode = null;
-          this._result = null;
-        }
-      ]]></destructor>
-
-      <property name="controller"
-                readonly="true"
-                onget="return this._controller;"/>
-
-      <method name="_init">
-        <body><![CDATA[
-          // XBL bug is in the middle...
-          // When toolbar customization is opened, this binding is attached
-          // again, as a result of adding the item under the wrapper.  However,
-          // the binding isn't detached from the "original" hbox element due
-          // to bug 83635.
-          //
-          // Then, when the customization dialog is closed, the binding is
-          // attached the third time, as a result of adding our element back to
-          // the toolbar.
-          //
-          // So, We'll just continue using the original binding, which was
-          // never removed, and avoid using the new bindings.  This means that
-          // this workaround will work just until bug 83635 is fixed.
-          //
-          // However, when the binding is "reconstructed", we do need to add
-          // back the event listeners and the places controller.
-          //
-          // Note: we could avoid part of this mess by moving the "Bookmark
-          // Toolbar Items" placeholder out of this binding.
-
-          // We also need to avoid initializing _result and _resultNode and
-          // _controller as XBL fields.  Otherwise, they'll be unset when the
-          // "extra" bindings are applied.
-
-          this._scrollbox.addEventListener("overflow", this, false);
-          this._scrollbox.addEventListener("underflow", this, false);
-          window.addEventListener("resize", this, false);
-
-          if (this._result === undefined) {
-            this._result = null;
-            this._resultNode = null;
-            if (this.hasAttribute("place")) {
-              // Do the initial build.
-              this.place = this.place;
-            }
-          }
-
-          // Attach the places controller.
-          if (!this._controller) 
-            this._controller = new PlacesController(this);
-
-          this.controllers.appendController(this._controller);
-        ]]></body>
-      </method>
-
-      <field name="_scrollbox">
-        document.getAnonymousElementByAttribute(this, "class",
-                                                "bookmarks-toolbar-items")
-      </field>
-      <field name="_dropIndicator">
-        document.getAnonymousElementByAttribute(this, "class",
-                                                "toolbar-drop-indicator")
-      </field>
-      <field name="_chevron">
-        document.getAnonymousElementByAttribute(this, "class", "chevron")
-      </field>
-      <field name="_chevronPopup">
-        document.getAnonymousElementByAttribute(this, "anonid", "chevronPopup")
-      </field>
-
-      <field name="_openedMenuButton">null</field>
-      <field name="_allowPopupShowing">true</field>
-
-      <field name="_isRTL">
-        document.defaultView.getComputedStyle(this.parentNode, "")
-                            .direction == "rtl"
-      </field>
-
-      <!-- nsIPlacesView -->
-      <method name="getResult">
-        <body><![CDATA[
-          return this._result;
-        ]]></body>
-      </method>
-
-      <!-- nsIPlacesView -->
-      <method name="getResultNode">
-        <body><![CDATA[
-          return this._resultNode;
-        ]]></body>
-      </method>
-
-      <method name="_rebuild">
-        <body><![CDATA[
-          // Clear out references to existing nodes, since they will be removed
-          // and re-added.
-          if (this._overFolder.node)
-            this._clearOverFolder();
-          this._openedMenuButton = null;
-
-          while (this.hasChildNodes())
-            this.removeChild(this.firstChild);
-
-          let cc = this._resultNode.childCount;
-          for (let i = 0; i < cc; ++i)
-            this.insertNewItem(this._resultNode.getChild(i), null);
-
-          if (this._chevronPopup.hasAttribute("type")) {
-            // Chevron has already been initialized, but since we are forcing
-            // a rebuild of the toolbar, it has to be rebuilt.
-            // Otherwise, it will be initialized when the toolbar overflows.
-            this._chevronPopup.place = this.place;
-          }
-        ]]></body>
-      </method>
-
-      <method name="insertNewItem">
-        <parameter name="aChild"/>
-        <parameter name="aBefore"/>
-        <body><![CDATA[
-          var type = aChild.type;
-          var button;
-          if (type == Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR)
-            button = document.createElement("toolbarseparator");
-          else {
-            button = document.createElement("toolbarbutton");
-            button.className = "bookmark-item";
-            button.setAttribute("label", aChild.title);
-            var icon = aChild.icon;
-            if (icon)
-              button.setAttribute("image", icon);
-
-            if (PlacesUtils.containerTypes.indexOf(type) != -1) {
-              button.setAttribute("type", "menu");
-              button.setAttribute("container", "true");
-
-              if (PlacesUtils.nodeIsQuery(aChild)) {
-                button.setAttribute("query", "true");
-                if (PlacesUtils.nodeIsTagQuery(aChild))
-                  button.setAttribute("tagContainer", "true");
-              }
-              else if (PlacesUtils.nodeIsLivemarkContainer(aChild))
-                button.setAttribute("livemark", "true");
-
-              var popup = document.createElement("menupopup");
-              popup.setAttribute("placespopup", "true");
-              button.appendChild(popup);
-              popup._resultNode = PlacesUtils.asContainer(aChild);
-#ifndef XP_MACOSX
-              popup.setAttribute("context", "placesContext");
-#endif
-            }
-            else if (PlacesUtils.nodeIsURI(aChild))
-              button.setAttribute("scheme", PlacesUIUtils.guessUrlSchemeForUI(aChild.uri));
-          }
-
-          button.node = aChild;
-          aChild._DOMElement = button;
-          if (aBefore)
-            this.insertBefore(button, aBefore);
-          else
-            this.appendChild(button);
-        ]]></body>
-      </method>
-
-      <method name="removeItem">
-        <parameter name="child"/>
-        <body><![CDATA[
-          // if document.popupNode pointed to this child, null it out,
-          // otherwise controller's command-updating may rely on the removed
-          // item still being "selected".
-          if (document.popupNode == child)
-            document.popupNode = null;
-
-          child.parentNode.removeChild(child);
-        ]]></body>
-      </method>
-
-      <method name="_updateChevronPopupNodesVisibility">
-        <body><![CDATA[
-          for (let i = 0; i < this._chevronPopup.childNodes.length; i++) {
-            this._chevronPopup.childNodes[i].hidden =
-              this.childNodes[i].style.visibility != "hidden";
-          }
-        ]]></body>
-      </method>
-
-      <method name="_onChevronPopupShowing">
-        <parameter name="aEvent"/>
-        <body><![CDATA[
-          // Handle popupshowing only for the chevron popup, not for
-          // nested ones.
-          if (aEvent.target != this._chevronPopup)
-            return;
-
-          this._updateChevronPopupNodesVisibility();
-        ]]></body>
-      </method>
-
-      <method name="handleEvent">
-        <parameter name="aEvent"/>
-        <body><![CDATA[
-          // Both overflow/underflow and resize events should not be handled
-          // for descendant nodes.
-          if (aEvent.target != aEvent.currentTarget)
-            return;
-
-          switch (aEvent.type) {
-            case "resize":
-              // This handler updates nodes visibility in both the toolbar
-              // and the chevron popup when a window resize does not change
-              // the overflow status of the toolbar.
-              break;
-
-            case "overflow":
-              // Ignore purely vertical overflows.
-              if (aEvent.detail == 0)
-                return;
-
-              // Attach the popup binding to the chevron popup if it has not yet
-              // been initialized.
-              if (!this._chevronPopup.hasAttribute("type")) {
-                this._chevronPopup.setAttribute("place", this.place);
-                this._chevronPopup.setAttribute("type", "places");
-              }
-              this._chevron.collapsed = false;
-              break;
-
-            case "underflow":
-              // Ignore purely vertical underflows.
-              if (aEvent.detail == 0)
-                return;
-
-              this._chevron.collapsed = true;
-              break;
-          }
-
-          this.updateChevron();
-        ]]></body>
-      </method>
-
-      <method name="updateChevron">
-        <body><![CDATA[
-          // If the chevron is collapsed there's nothing to update.
-          if (this._chevron.collapsed)
-            return;
-
-          // XXX (bug 508816) Scrollbox does not handle correctly RTL mode.
-          // This workarounds the issue scrolling the box to the right.
-          if (this._isRTL)
-            this._scrollbox.scrollLeft = this._scrollbox.scrollWidth;
-
-          // Update the chevron on a timer.  This will avoid repeated work when
-          // lot of changes happen in a small timeframe.
-          if (this._updateChevronTimer)
-            this._updateChevronTimer.cancel();
-          this._updateChevronTimer = this._setTimer(100);
-        ]]></body>
-      </method>
-
-      <method name="_updateChevronTimerCallback">
-        <body><![CDATA[
-          var scrollRect = this._scrollbox.getBoundingClientRect();
-          var childOverflowed = false;
-          for (let i = 0; i < this.childNodes.length; i++) {
-            let child = this.childNodes[i];
-            // Once a child overflows, all the next ones will.
-            if (!childOverflowed) {
-              let childRect = child.getBoundingClientRect();
-              childOverflowed = this._isRTL ? (childRect.left < scrollRect.left)
-                                            : (childRect.right > scrollRect.right);
-            }
-            child.style.visibility = childOverflowed ? "hidden" : "visible";
-          }
-
-          // We rebuild the chevron on popupShowing, so if it is open
-          // we must update it.
-          if (this._chevron.open)
-            this._updateChevronPopupNodesVisibility();
-        ]]></body>
-      </method>
-
-      <!-- nsIPlacesView -->
-      <property name="place">
-        <getter><![CDATA[
-          return this.getAttribute("place");
-        ]]></getter>
-        <setter><![CDATA[
-          this.setAttribute("place", val);
-
-          var history = PlacesUtils.history;
-          var queries = { }, options = { };
-          history.queryStringToQueries(val, queries, { }, options);
-          if (!queries.value.length)
-            queries.value = [history.getNewQuery()];
-          try {
-            var result =
-              history.executeQueries(queries.value, queries.value.length,
-                                     options.value);
-            result.addObserver(this._resultObserver, false);
-          }
-          catch(ex) {
-            // Invalid query, or had no results.
-            // This is valid, eg: user deletes his bookmarks toolbar folder.
-          }
-          return val;
-        ]]></setter>
-      </property>
-
-      <!-- nsIPlacesView -->
-      <property name="hasSelection">
-        <getter><![CDATA[
-          return this.selectedNode != null;
-        ]]></getter>
-      </property>
-
-      <!-- nsIPlacesView -->
-      <method name="getSelectionNodes">
-        <body><![CDATA[
-          var selectedNode = this.selectedNode;
-          return selectedNode ? [selectedNode] : [];
-        ]]></body>
-      </method>
-
-      <!-- nsIPlacesView -->
-      <method name="getRemovableSelectionRanges">
-        <body><![CDATA[
-          // On static content the current selectedNode would be the selection's
-          // parent node. We don't want to allow removing a node when the
-          // selection is not explicit.
-          if (document.popupNode &&
-              (document.popupNode == "menupopup" || !document.popupNode.node))
-            return [];
-
-          return [this.getSelectionNodes()];
-        ]]></body>
-      </method>
-
-      <!-- nsIPlacesView -->
-      <method name="getDraggableSelection">
-        <body><![CDATA[
-          return [this._draggedNode];
-        ]]></body>
-      </method>
-
-      <!-- nsIPlacesView -->
-      <property name="selectedNode">
-        <getter><![CDATA[
-          if (this._contextMenuShown) {
-            var popupNode = document.popupNode;
-            if (popupNode == this)
-              return this.getResultNode();
-
-            return popupNode.node || popupNode.parentNode._resultNode || null;
-          }
-          return null;
-        ]]></getter>
-      </property>
-
-      <!-- nsIPlacesView -->
-      <property name="insertionPoint">
-        <getter><![CDATA[
-          // By default, the insertion point is at the top level, at the end.
-          var index = PlacesUtils.bookmarks.DEFAULT_INDEX;
-          var container = this._resultNode;
-          var orientation = Ci.nsITreeView.DROP_BEFORE;
-          var isTag = false;
-
-          var selectedNode = this.selectedNode;
-          if (selectedNode) {
-            var popupNode = document.popupNode;
-            if (!popupNode.node) {
-              // If a static menuitem is selected the insertion point
-              // is inside the folder, at the end.
-              container = selectedNode;
-              orientation = Ci.nsITreeView.DROP_ON;
-            }
-            else {
-              // In all other cases the insertion point is before that node.
-              container = selectedNode.parent;
-              index = container.getChildIndex(selectedNode);
-              isTag = PlacesUtils.nodeIsTagQuery(container);
-            }
-          }
-
-          if (PlacesControllerDragHelper.disallowInsertion(container))
-            return null;
-
-          return new InsertionPoint(PlacesUtils.getConcreteItemId(container),
-                                    index, orientation, isTag);
-        ]]></getter>
-      </property>
-
-      <!-- nsIPlacesView -->
-      <method name="selectAll">
-        <body><![CDATA[
-          // Nothing
-        ]]></body>
-      </method>
-
-      <method name="selectItems">
-        <body><![CDATA[
-          // Nothing
-        ]]></body>
-      </method>
-
-      <!-- nsINavHistoryResultObserver -->
-      <field name="_resultObserver"><![CDATA[({
-        _self: this,
-
-        get result() {
-          return this._self._result;
-        },
-
-        set result(val) {
-          if (this._self._result) {
-            this._self._result.removeObserver(this);
-            this._self._resultNode.containerOpen = false;
-          }
-
-          this._self._result = val;
-          if (val) {
-            this._self._resultNode = val.root;
-            this._self._resultNode._DOMElement = this._self;
-            // This calls _rebuild through invalidateContainer.
-            this._self._resultNode.containerOpen = true;
-          }
-          else {
-            this._self._resultNode = null;
-          }
-
-          return val;
-        },
-
-        nodeInserted: function TV_V_nodeInserted(aParentNode, aNode, aIndex) {
-          let parentElt = aParentNode._DOMElement;
-          NS_ASSERT(parentElt, "parent node must have _DOMElement set");
-
-          if (parentElt == this._self) {
-            // Node is on the toolbar.
-            let children = this._self.childNodes;
-            this._self.insertNewItem(aNode,
-              aIndex < children.length ? children[aIndex] : null);
-            this._self.updateChevron();
-          }
-          else if (parentElt._built) {
-            // Node is within a built menu.
-            let popup = parentElt.firstChild;
-            let before = popup.childNodes[aIndex] || null;
-            this._self.insertNewItemToPopup(aNode, popup, before);
-            if (popup._emptyMenuItem)
-              popup._emptyMenuItem.hidden = true;
-          }
-        },
-
-        nodeRemoved: function TV_V_nodeRemoved(aParentNode, aNode, aIndex) {
-          let parentElt = aParentNode._DOMElement;
-          let nodeElt = aNode._DOMElement;
-
-          NS_ASSERT(parentElt, "parent node must have _DOMElement set");
-          NS_ASSERT(nodeElt, "node must have _DOMElement set");
-
-          if (parentElt == this._self) {
-            // Node is on the toolbar.
-            this._self.removeChild(nodeElt);
-            this._self.updateChevron();
-          }
-          else if (parentElt._built) {
-            // Node is within a built menu.
-            var popup = parentElt.firstChild;
-            popup.removeChild(nodeElt);
-            if (!popup.hasChildNodes() ||
-                (popup.childNodes.length == 1 &&
-                popup.firstChild == popup._emptyMenuItem))
-              this._self._showEmptyMenuItem(popup);
-
-            if (popup._endMarker != -1)
-              popup._endMarker--;
-          }
-        },
-
-        nodeMoved:
-        function TV_V_nodeMoved(aNode,
-                                aOldParent, aOldIndex,
-                                aNewParent, aNewIndex) {
-          // Note: the current implementation of moveItem does not actually
-          // use this notification when the item in question is moved from one
-          // folder to another.  Instead, it calls nodeRemoved and nodeInserted
-          // for the two folders.  Thus, we can assume aOldParent == aNewParent.
-
-          let nodeElt = aNode._DOMElement;
-          NS_ASSERT(nodeElt, "node must have _DOMElement set");
-
-          // If our root node is a folder, it might be moved. There's nothing
-          // we need to do in that case.
-          if (nodeElt == this._self)
-            return;
-
-          let parentElt = aNewParent._DOMElement;
-          NS_ASSERT(parentElt, "parent node must have _DOMElement set");
-
-          if (parentElt == this._self) {
-            // Container is on the toolbar.
-
-            // Move the node.
-            this._self.removeChild(nodeElt);
-            this._self.insertBefore(nodeElt, this._self.childNodes[aNewIndex]);
-
-            // If the chevron popup is open, keep it in sync.
-            if (this._self._chevron.open) {
-              let chevronPopup = this._self._chevronPopup;
-              let menuitem = chevronPopup.childNodes[aOldIndex];
-              chevronPopup.removeChild(menuitem);
-              chevronPopup.insertBefore(menuitem,
-                                        chevronPopup.childNodes[aNewIndex]);
-            }
-            this._self.updateChevron();
-          }
-          else if (parentElt._built) {
-            // Container is within a built menu.
-
-            // parentElt is the <menu> element for the container,
-            // we need the <menupopup>.
-            var popup = parentElt.firstChild;
-
-            // Move the node.
-            popup.removeChild(nodeElt);
-            popup.insertBefore(nodeElt, popup.childNodes[aNewIndex]);
-          }
-        },
-
-        nodeTitleChanged: function TV_V_nodeTitleChanged(aNode, aNewTitle) {
-          let nodeElt = aNode._DOMElement;
-          NS_ASSERT(nodeElt, "node must have _DOMElement set");
-
-          // There's no UI representation for the root node, thus there's
-          // nothing to be done when the title changes.
-          if (nodeElt == this._self)
-            return;
-
-          if (nodeElt.parentNode == this._self) {
-            // Node is on the toolbar
-            nodeElt.label = aNewTitle;
-            this._self.updateChevron();
-          }
-          else {
-            // Node is within a built menu.
-            nodeElt.label = aNewTitle || PlacesUIUtils.getBestTitle(aNode);
-          }
-        },
-
-        nodeURIChanged: function TV_V_nodeURIChanged(aNode, aURIString) {
-          let nodeElt = aNode._DOMElement;
-          NS_ASSERT(nodeElt, "node must have _DOMElement set");
-
-          nodeElt.setAttribute("scheme",
-                               PlacesUIUtils.guessUrlSchemeForUI(aURIString));
-        },
-
-        nodeIconChanged: function TV_V_nodeIconChanged(aNode) {
-          let nodeElt = aNode._DOMElement;
-          NS_ASSERT(nodeElt, "node must have _DOMElement set");
-
-          // There's no UI representation for the root node, thus there's
-          // nothing to be done when the icon changes.
-          if (nodeElt == this._self)
-            return;
-
-          let icon = aNode.icon;
-          if (icon) {
-            if (nodeElt.getAttribute("image") != icon)
-              nodeElt.setAttribute("image", icon);
-          }
-          else
-            nodeElt.removeAttribute("image");
-        },
-
-        nodeAnnotationChanged:
-        function TV_V_nodeAnnotationChanged(aNode, aAnno) {
-          // Ensure the changed annotation is a livemark one.
-          if (/^livemark\//.test(aAnno) &&
-              PlacesUtils.nodeIsLivemarkContainer(aNode)) {
-            let nodeElt = aNode._DOMElement;
-            NS_ASSERT(nodeElt, "node must have _DOMElement set");
-
-            if (!nodeElt.hasAttribute("livemark"))
-              nodeElt.setAttribute("livemark", "true");
-
-            // Add or remove the livemark status menuitem.
-            PlacesUIUtils.ensureLivemarkStatusMenuItem(nodeElt.firstChild);
-          }
-        },
-
-        nodeHistoryDetailsChanged: function() { },
-        nodeTagsChanged: function() { },
-        nodeDateAddedChanged: function() { },
-        nodeLastModifiedChanged: function() { },
-        nodeKeywordChanged: function() { },
-
-        nodeReplaced:
-        function TV_V_nodeReplaced(aParentNode, aOldNode, aNewNode, aIndex) {
-          let nodeElt = aOldNode._DOMElement;
-          NS_ASSERT(nodeElt, "node must have _DOMElement set");
-
-          // No worries: If nodeElt is the last item (i.e. no nextSibling),
-          // insertNewItem/insertNewItemToPopup will insert the new element as
-          // the last item.
-          let next = nodeElt.nextSibling;
-
-          let parentElt = aParentNode._DOMElement;
-          NS_ASSERT(parentElt, "parent node must have _DOMElement set");
-          if (parentElt == this._self) {
-            // Node is on the toolbar.
-            this._self.removeItem(nodeElt);
-            this._self.insertNewItem(aNewNode, next);
-            this._self.updateChevron();
-          }
-          else if (parentElt._built) {
-            // Node is within a built menu.
-            let popup = parentElt.firstChild;
-            popup.removeItem(nodeElt);
-            this._self.insertNewItemToPopup(aNewNode, popup, next);
-          }
-        },
-
-        containerOpened: function TV_V_containerOpened(aContainer) {
-          this.invalidateContainer(aContainer);
-        },
-
-        containerClosed: function TV_V_containerClosed(aContainer) {
-          this.invalidateContainer(aContainer);
-        },
-
-        containerStateChanged:
-        function TV_V_containerStateChanged(aNode, aOldState, aNewState) {},
-
-        invalidateContainer: function TV_V_invalidateContainer(aContainer) {
-          let containerNodeElt = aContainer._DOMElement;
-          NS_ASSERT(containerNodeElt, "node must have _DOMElement set");
-
-          if (containerNodeElt == this._self) {
-            // Container is the toolbar itself.
-            this._self._rebuild();
-          }
-          else if (containerNodeElt._built) {
-            // Container is a built menu.
-            containerNodeElt._built = false;
-            // If the menupopup is open we should live-update it.
-            if (containerNodeElt.open)
-              this._self._rebuildPopup(containerNodeElt.firstChild);
-          }
-        },
-
-        sortingChanged: function TV_V_sortingChanged(aSortingMode) {
-        },
-
-        QueryInterface: function PTV_QueryInterface(aIID) {
-          if (aIID.equals(Ci.nsINavHistoryResultObserver) ||
-              aIID.equals(Ci.nsISupportsWeakReference) ||
-              aIID.equals(Ci.nsISupports))
-            return this;
-          throw Cr.NS_ERROR_NO_INTERFACE;
-        }
-      })]]></field>
-
-      <property name="selType" onget="return 'single';"/>
-
-      <method name="buildContextMenu">
-        <parameter name="aPopup"/>
-        <body><![CDATA[
-          this._contextMenuShown = true;
-          window.updateCommands("places");
-          return this.controller.buildContextMenu(aPopup);
-        ]]></body>
-      </method>
-
-      <method name="destroyContextMenu">
-        <parameter name="aPopup"/>
-        <body><![CDATA[
-          this._contextMenuShown = false;
-          if (window.content)
-            window.content.focus();
-        ]]></body>
-      </method>
-
-      <method name="_showEmptyMenuItem">
-        <parameter name="aPopup"/>
-        <body><![CDATA[
-          if (aPopup._emptyMenuItem) {
-            aPopup._emptyMenuItem.hidden = false;
-            return;
-          }
-
-          var label = PlacesUIUtils.getString("bookmarksMenuEmptyFolder");
-          aPopup._emptyMenuItem = document.createElement("menuitem");
-          aPopup._emptyMenuItem.setAttribute("label", label);
-          aPopup._emptyMenuItem.setAttribute("disabled", true);
-          aPopup.appendChild(aPopup._emptyMenuItem);
-        ]]></body>
-      </method>
-
-      <method name="insertNewItemToPopup">
-        <parameter name="aChild"/>
-        <parameter name="aParentPopup"/>
-        <parameter name="aBefore"/>
-        <body><![CDATA[
-          var element = PlacesUIUtils.createMenuItemForNode(aChild,
-                                                            aParentPopup.ownerDocument);
-
-          if (aBefore)
-            aParentPopup.insertBefore(element, aBefore);
-          else {
-            // Add the new element to the menu.  If there is static content at
-            // the end of the menu, add the element before that.  Otherwise,
-            // just add to the end.
-            if (aParentPopup._endMarker != -1) {
-              let lastNode = aParentPopup.childNodes[aParentPopup._endMarker];
-              aParentPopup.insertBefore(element, lastNode);
-            }
-            else
-              aParentPopup.appendChild(element);
-          }
-
-          if (aParentPopup._endMarker != -1)
-            aParentPopup._endMarker++;
-        ]]></body>
-      </method>
-
-      <method name="_containerPopupShowing">
-        <parameter name="aPopup"/>
-        <body><![CDATA[
-          if (!aPopup.parentNode._built)
-            this._rebuildPopup(aPopup);
-        ]]></body>
-      </method>
-
-      <method name="_rebuildPopup">
-        <parameter name="aPopup"/>
-        <body><![CDATA[
-          PlacesUIUtils.cleanPlacesPopup(aPopup);
-
-          // If this is a livemark container check if the status menuitem has
-          // to be added or removed.
-          if (PlacesUtils.nodeIsLivemarkContainer(aPopup._resultNode))
-            PlacesUIUtils.ensureLivemarkStatusMenuItem(aPopup);
-
-          var resultNode = aPopup._resultNode;
-          if (!resultNode.containerOpen)
-            resultNode.containerOpen = true;
-
-          var cc = resultNode.childCount;
-          if (cc > 0) {
-            if (aPopup._emptyMenuItem)
-              aPopup._emptyMenuItem.hidden = true;
-
-            for (let i = 0; i < cc; ++i) {
-              var child = resultNode.getChild(i);
-              this.insertNewItemToPopup(child, aPopup, null);
-            }
-          }
-          else {
-            // This menu is empty.  If there is no static content, add
-            // an element to show it is empty.
-            if (aPopup._startMarker == -1 && aPopup._endMarker == -1)
-              this._showEmptyMenuItem(aPopup);
-          }
-          aPopup.parentNode._built = true;
-        ]]></body>
-      </method>
-
-      <field name="_overFolder"><![CDATA[
-       (
-         // Menu buttons should be opened when the mouse drags over them, and
-         // closed when the mouse drags off. This object manages opening and
-         // closing of folders when the mouse hovers.
-         { node: null, openTimer: null, hoverTime: 350, closeTimer: null }
-       );
-      ]]></field>
-
-      <method name="_clearOverFolder">
-        <body><![CDATA[
-          // The mouse is no longer dragging over the stored menubutton.
-          // Close the menubutton, clear out drag styles, and clear all
-          // timers for opening/closing it.
-          if (this._overFolder.node && this._overFolder.node.lastChild) {
-            if (!this._overFolder.node.lastChild.hasAttribute("dragover")) {
-              this._overFolder.node.lastChild.hidePopup();
-            }
-            this._overFolder.node.removeAttribute("dragover");
-            this._overFolder.node = null;
-          }
-          if (this._overFolder.openTimer) {
-            this._overFolder.openTimer.cancel();
-            this._overFolder.openTimer = null;
-          }
-          if (this._overFolder.closeTimer) {
-            this._overFolder.closeTimer.cancel();
-            this._overFolder.closeTimer = null;
-          }
-        ]]></body>
-      </method>
-
-      <method name="_getDropPoint">
-        <parameter name="aEvent"/>
-        <body><![CDATA[
-          // This function returns information about where to drop when
-          // dragging over the toolbar.
-          // The returned object has 3 properties:
-          // - ip: the insertion point for the bookmarks service.
-          // - beforeIndex: child index to drop before, for the drop indicator.
-          // - folderNode: the folder to drop into, if applicable.
-          var result = this.getResult();
-          if (!PlacesUtils.nodeIsFolder(this._resultNode))
-            return null;
-
-          var dropPoint = { ip: null, beforeIndex: null, folderNode: null };
-          var xulNode = aEvent.target;
-          if (xulNode.node) {
-            let nodeRect = xulNode.getBoundingClientRect();
-            let nodeIndex = Array.indexOf(this.childNodes, xulNode);
-            if (PlacesUtils.nodeIsFolder(xulNode.node) &&
-                !PlacesUtils.nodeIsReadOnly(xulNode.node)) {
-              // This is a folder.
-              // If we are in the middle of it, drop inside it.
-              // Otherwise, drop before it, with regards to RTL mode.
-              let threshold = nodeRect.width * 0.25;
-              if (this._isRTL ? (aEvent.clientX > nodeRect.right - threshold)
-                              : (aEvent.clientX < nodeRect.left + threshold)) {
-                // Drop before this folder.
-                dropPoint.ip =
-                  new InsertionPoint(PlacesUtils.getConcreteItemId(this._resultNode),
-                                     nodeIndex, Ci.nsITreeView.DROP_BEFORE);
-                dropPoint.beforeIndex = nodeIndex;
-              }
-              else if (this._isRTL ? (aEvent.clientX > nodeRect.left + threshold)
-                                   : (aEvent.clientX < nodeRect.right - threshold)) {
-                // Drop inside this folder.
-                dropPoint.ip =
-                  new InsertionPoint(PlacesUtils.getConcreteItemId(xulNode.node),
-                                     -1, Ci.nsITreeView.DROP_ON,
-                                     PlacesUtils.nodeIsTagQuery(xulNode.node));
-                dropPoint.beforeIndex = nodeIndex;
-                dropPoint.folderNode = xulNode;
-              }
-              else {
-                // Drop after this folder.
-                let beforeIndex =
-                  (nodeIndex == this.childNodes.length - 1) ? -1 : nodeIndex + 1;
-                dropPoint.ip =
-                  new InsertionPoint(PlacesUtils.getConcreteItemId(this._resultNode),
-                                     beforeIndex, Ci.nsITreeView.DROP_BEFORE);
-                dropPoint.beforeIndex = beforeIndex;
-              }
-            }
-            else {
-              // This is a non-folder node or a read-only folder.
-              // Drop before it with regards to RTL mode.
-              let threshold = nodeRect.width * 0.5;
-              if (this._isRTL ? (aEvent.clientX > nodeRect.left + threshold)
-                              : (aEvent.clientX < nodeRect.left + threshold)) {
-                // Drop before this bookmark.
-                dropPoint.ip =
-	                new InsertionPoint(PlacesUtils.getConcreteItemId(this._resultNode),
-	                                   nodeIndex, Ci.nsITreeView.DROP_BEFORE);
-                dropPoint.beforeIndex = nodeIndex;
-              }
-              else {
-                // Drop after this bookmark.
-                let beforeIndex =
-                  nodeIndex == this.childNodes.length - 1 ? -1 : nodeIndex + 1;
-                dropPoint.ip =
-                  new InsertionPoint(PlacesUtils.getConcreteItemId(this._resultNode),
-                                     beforeIndex, Ci.nsITreeView.DROP_BEFORE);
-                dropPoint.beforeIndex = beforeIndex;
-              }
-            }
-          }
-          else {
-            // We are most likely dragging on the empty area of the
-            // toolbar, we should drop after the last node.
-            dropPoint.ip =
-              new InsertionPoint(PlacesUtils.getConcreteItemId(this._resultNode),
-                                 -1, Ci.nsITreeView.DROP_BEFORE);
-            dropPoint.beforeIndex = -1;
-          }
-
-          return dropPoint;
-        ]]></body>
-      </method>
-
-      <method name="_setTimer">
-        <parameter name="aTime"/>
-        <body><![CDATA[
-          var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
-          timer.initWithCallback(this, aTime, timer.TYPE_ONE_SHOT);
-          return timer;
-        ]]></body>
-      </method>
-
-      <!-- nsITimerCallback -->
-      <method name="notify">
-        <parameter name="aTimer"/>
-        <body><![CDATA[
-          // Function to process all timer notifications.
-
-          if (aTimer == this._updateChevronTimer) {
-            this._updateChevronTimer = null;
-            this._updateChevronTimerCallback();
-          }
-
-          // * Timer to turn off indicator bar.
-          else if (aTimer == this._ibTimer) {
-            this._dropIndicator.collapsed = true;
-            this._ibTimer = null;
-          }
-
-          // * Timer to open a menubutton that's being dragged over.
-          else if (aTimer == this._overFolder.openTimer) {
-            // Set the autoopen attribute on the folder's menupopup so that
-            // the menu will automatically close when the mouse drags off of it.
-            this._overFolder.node.lastChild.setAttribute("autoopened", "true");
-            this._overFolder.node.open = true;
-            this._overFolder.openTimer = null;
-          }
-
-          // * Timer to close a menubutton that's been dragged off of.
-          else if (aTimer == this._overFolder.closeTimer) {
-            // Close the menubutton if we are not dragging over it or one of
-            // its children.  The autoopened attribute will let the menu know to
-            // close later if the menu is still being dragged over.
-            var currentNode = PlacesControllerDragHelper.currentDropTarget;
-            var inHierarchy = false;
-            while (currentNode) {
-              if (currentNode == this) {
-                inHierarchy = true;
-                break;
-              }
-              currentNode = currentNode.parentNode;
-            }
-            // The _clearOverFolder() function will close the menu for _overFolder.node.
-            // So null it out if we don't want to close it.
-            if (inHierarchy)
-              this._overFolder.node = null;
-
-            // Clear out the folder and all associated timers.
-            this._clearOverFolder();
-          }
-        ]]></body>
-      </method>
-
-      <method name="_cleanupDragDetails">
-        <body><![CDATA[
-          // Called on dragend and drop.
-          PlacesControllerDragHelper.currentDropTarget = null;
-          this._draggedNode = null;
-          if (this._ibTimer)
-            this._ibTimer.cancel();
-          this._dropIndicator.collapsed = true;
-        ]]></body>
-      </method>
-
-    </implementation>
-
-    <handlers>
-      <handler event="mouseover"><![CDATA[
-        var button = event.target;
-        if (button.parentNode == this && button.node &&
-            PlacesUtils.nodeIsURI(button.node))
-          window.XULBrowserWindow.setOverLink(event.target.node.uri, null);
-      ]]></handler>
-
-      <handler event="mouseout"><![CDATA[
-        window.XULBrowserWindow.setOverLink("", null);
-      ]]></handler>
-
-      <handler event="dragstart"><![CDATA[
-        // Sub menus have their own d&d handlers.
-        let draggedDOMNode = event.target;
-        if (draggedDOMNode.parentNode != this || !draggedDOMNode.node)
-          return;
-
-        if (draggedDOMNode.localName == "toolbarbutton" &&
-            draggedDOMNode.getAttribute("type") == "menu") {
-          // If the drag gesture on a container is toward down we open instead
-          // of dragging.
-          if (this._mouseDownTimer) {
-            this._mouseDownTimer.cancel();
-            this._mouseDownTimer = null;
-          }
-          let translateY = this._cachedMouseMoveEvent.clientY - event.clientY;
-          let translateX = this._cachedMouseMoveEvent.clientX - event.clientX;
-          if ((translateY) >= Math.abs(translateX/2)) {
-            // Don't start the drag.
-            event.preventDefault();
-            // Open the menu
-            draggedDOMNode.open = true;
-            return;
-          }
-          // If the menu is open, close it.
-          if (draggedDOMNode.open) {
-            draggedDOMNode.firstChild.hidePopup();
-            draggedDOMNode.open = false;
-          }
-        }
-
-        // Activate the view and cache the dragged node.
-        this._draggedNode = draggedDOMNode.node;
-        this.focus();
-
-        this._controller.setDataTransfer(event);
-        event.stopPropagation();
-      ]]></handler>
-
-      <handler event="dragover"><![CDATA[
-        PlacesControllerDragHelper.currentDropTarget = event.target;
-        let dt = event.dataTransfer;
-
-        let dropPoint = this._getDropPoint(event);
-        if (!dropPoint || !dropPoint.ip ||
-            !PlacesControllerDragHelper.canDrop(dropPoint.ip, dt)) {
-          this._dropIndicator.collapsed = true;
-          event.stopPropagation();
-          return;
-        }
-
-        if (this._ibTimer) {
-          this._ibTimer.cancel();
-          this._ibTimer = null;
-        }
-
-        if (dropPoint.folderNode || event.originalTarget == this._chevron) {
-          // Dropping over a menubutton or chevron button.
-          // Set styles and timer to open relative menupopup.
-          let overNode = dropPoint.folderNode || this._chevron;
-          if (this._overFolder.node != overNode) {
-            this._clearOverFolder();
-            this._overFolder.node = overNode;
-            this._overFolder.openTimer = this._setTimer(this._overFolder.hoverTime);
-          }
-          if (!this._overFolder.node.hasAttribute("dragover"))
-            this._overFolder.node.setAttribute("dragover", "true");
-
-          this._dropIndicator.collapsed = true;
-        }
-        else {
-          // Dragging over a normal toolbarbutton.
-          // Show indicator bar and move it to the appropriate drop point.
-          let ind = this._dropIndicator;
-          let halfInd = ind.clientWidth / 2;
-          let translateX;
-          if (this._isRTL) {
-            halfInd = Math.ceil(halfInd);
-            translateX = 0 - this._scrollbox.getBoundingClientRect().right -
-                             halfInd;
-            if (this.firstChild) {
-              if (dropPoint.beforeIndex == -1)
-                translateX += this.lastChild.getBoundingClientRect().left;
-              else {
-                translateX += this.childNodes[dropPoint.beforeIndex]
-                                .getBoundingClientRect().right;
-              }
-            }
-          }
-          else {
-            halfInd = Math.floor(halfInd);
-            translateX = 0 - this._scrollbox.getBoundingClientRect().left +
-                         halfInd;
-            if (this.firstChild) {
-              if (dropPoint.beforeIndex == -1)
-                translateX += this.lastChild.getBoundingClientRect().right;
-              else {
-                translateX += this.childNodes[dropPoint.beforeIndex]
-                                  .getBoundingClientRect().left;
-              }
-            }
-          }
-
-          ind.style.MozTransform = "translate(" + Math.round(translateX) + "px)";
-          ind.style.MozMarginStart = (-ind.clientWidth) + "px";
-          ind.collapsed = false;
-
-          // Clear out old folder information.
-          this._clearOverFolder();
-        }
-
-        event.preventDefault();
-        event.stopPropagation();
-      ]]></handler>
-
-      <handler event="drop"><![CDATA[
-        PlacesControllerDragHelper.currentDropTarget = event.target;
-
-        let dropPoint = this._getDropPoint(event);
-        if (dropPoint && dropPoint.ip) {
-          PlacesControllerDragHelper.onDrop(dropPoint.ip, event.dataTransfer);
-          event.preventDefault();
-        }
-
-        this._cleanupDragDetails();
-        event.stopPropagation();
-      ]]></handler>
-
-      <handler event="dragleave"><![CDATA[
-        PlacesControllerDragHelper.currentDropTarget = null;
-
-        // Set timer to turn off indicator bar (if we turn it off
-        // here, dragenter might be called immediately after, creating
-        // flicker).
-        if (this._ibTimer)
-          this._ibTimer.cancel();
-        this._ibTimer = this._setTimer(10);
-
-        // If we hovered over a folder, close it now.
-        if (this._overFolder.node)
-            this._overFolder.closeTimer = this._setTimer(this._overFolder.hoverTime);
-      ]]></handler>
-
-      <handler event="dragend"><![CDATA[
-        this._cleanupDragDetails();
-      ]]></handler>
-
-      <handler event="popupshowing" phase="capturing"><![CDATA[
-        if (!this._allowPopupShowing) {
-          this._allowPopupShowing = true;
-          event.preventDefault();
-          return;
-        }
-
-        var popup = event.originalTarget;
-
-        // Avoid handling popupshowing of inner views
-        if (popup._resultNode && PlacesUIUtils.getViewForNode(popup) == this)
-          this._containerPopupShowing(popup);
-
-        var parent = popup.parentNode;
-        if (parent.localName == "toolbarbutton")
-          this._openedMenuButton = parent;
-      ]]></handler>
-
-      <handler event="popuphidden"><![CDATA[
-        var popup = event.originalTarget;
-
-        // Avoid handling popuphidden of inner views
-        if (popup._resultNode && PlacesUIUtils.getViewForNode(popup) == this) {
-          // UI performance: folder queries are cheap, keep the resultnode open
-          // so we don't rebuild its contents whenever the popup is reopened.
-          if (!PlacesUtils.nodeIsFolder(popup._resultNode))
-            popup._resultNode.containerOpen = false;
-        }
-
-        var parent = popup.parentNode;
-        if (parent.localName == "toolbarbutton") {
-          this._openedMenuButton = null;
-          // Clear the dragover attribute if present, if we are dragging into a
-          // folder in the hierachy of current opened popup we don't clear
-          // this attribute on clearOverFolder.  See Notify for closeTimer.
-          if (parent.hasAttribute("dragover"))
-            parent.removeAttribute("dragover");
-        }
-      ]]></handler>
-
-#ifdef XP_UNIX
-#ifndef XP_MACOSX
-      <handler event="mousedown"><![CDATA[
-        var target = event.target;
-        if (event.button == 0 &&
-            target.localName == "toolbarbutton" &&
-            target.getAttribute("type") == "menu") {
-          this._allowPopupShowing = false;
-          // On Linux we can open the popup only after a delay.
-          // Indeed as soon as the menupopup opens we are unable to start a
-          // drag event.  See bug 500081 for details.
-          this._mouseDownTimer = Cc["@mozilla.org/timer;1"]
-                                   .createInstance(Ci.nsITimer);
-          var callback = {
-            _self: this,
-		        _target: target,
-		        notify: function(timer) {
-              this._target.open = true;
-              this._self._mouseDownTimer = null;
-            }
-          };
-
-          this._mouseDownTimer.initWithCallback(callback, 300,
-                                                Ci.nsITimer.TYPE_ONE_SHOT);
-        }
-      ]]></handler>
-#endif
-#endif
-      <handler event="mouseup"><![CDATA[
-        if (event.button != 0)
-          return;
-
-        if (this._mouseDownTimer) {
-          // On a click (down/up) we should open the menu popup
-          this._mouseDownTimer.cancel();
-          this._mouseDownTimer = null;
-          event.target.open = true;
-        }
-      ]]></handler>
-
-      <handler event="mousemove"><![CDATA[
-        // Used in dragStart to prevent dragging folders when dragging down
-        this._cachedMouseMoveEvent = event;
-
-        if (this._openedMenuButton == null ||
-            PlacesControllerDragHelper.getSession())
-          return;
-
-        var target = event.originalTarget;
-        if (this._openedMenuButton != target &&
-            target.localName == "toolbarbutton" &&
-            target.type == "menu") {
-          this._openedMenuButton.open = false;
-          target.open = true;
-        }
-      ]]></handler>
-    </handlers>
-  </binding>
-
-</bindings>
--- a/browser/components/places/content/tree.xml
+++ b/browser/components/places/content/tree.xml
@@ -31,79 +31,68 @@
 # 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 ***** 
+# ***** END LICENSE BLOCK *****
 
 <bindings id="placesTreeBindings"
           xmlns="http://www.mozilla.org/xbl"
           xmlns:xbl="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">
-  
+
   <binding id="places-tree" extends="chrome://global/content/bindings/tree.xml#tree">
     <implementation>
       <constructor><![CDATA[
         // Force an initial build.
         if (this.place)
           this.place = this.place;
       ]]></constructor>
 
       <destructor><![CDATA[
         // Break the treeviewer->result->treeviewer cycle.
         // Note: unsetting the result's viewer also unsets
         // the viewer's reference to our treeBoxObject.
-        var result = this.getResult();
+        var result = this.result;
         if (result) {
           result.root.containerOpen = false;
         }
         this.view = null;
       ]]></destructor>
 
       <property name="controller"
                 readonly="true"
-                onget="return this._controller;"/>
+                onget="return this._controller"/>
 
       <!-- overriding -->
       <property name="view">
         <getter><![CDATA[
           try {
             return this.treeBoxObject.view.QueryInterface(Ci.nsINavHistoryResultTreeViewer);
           }
           catch(e) {
             return null;
           }
         ]]></getter>
-        <setter><![CDATA[ 
+        <setter><![CDATA[
           return this.treeBoxObject.view = val;
         ]]></setter>
       </property>
 
-      <method name="getBestOptions">
-        <body><![CDATA[
-          // Get the best set of grouping options to use, either reuse the 
-          // existing ones or create new ones. 
-          var options = this.getResult().queryOptions;
-          if (!options)
-            options = PlacesUtils.history.getNewQueryOptions();
-          return options;
-        ]]></body>
-      </method>
-
       <method name="applyFilter">
         <parameter name="filterString"/>
         <parameter name="folderRestrict"/>
         <body><![CDATA[
           // preserve grouping
-          var queryNode = PlacesUtils.asQuery(this.getResultNode());
+          var queryNode = PlacesUtils.asQuery(this.result.root);
           var options = queryNode.queryOptions.clone();
 
           // Make sure we're getting uri results.
           // We do not yet support searching into grouped queries or into
           // tag containers, so we must fall to the default case.
           if (PlacesUtils.nodeIsHistoryContainer(queryNode) ||
               options.resultType == options.RESULTS_AS_TAG_QUERY ||
               options.resultType == options.RESULTS_AS_TAG_CONTENTS)
@@ -115,23 +104,23 @@
           if (folderRestrict) {
             query.setFolders(folderRestrict, folderRestrict.length);
             options.queryType = options.QUERY_TYPE_BOOKMARKS;
           }
 
           this.load([query], options);
         ]]></body>
       </method>
-      
+
       <method name="load">
         <parameter name="queries"/>
         <parameter name="options"/>
         <body><![CDATA[
           // Cleanup old result if exists.
-          let oldResult = this.getResult();
+          let oldResult = this.result;
           if (oldResult) {
             oldResult.removeObserver(this.view);
             oldResult.root.containerOpen = false;
           }
 
           let result = PlacesUtils.history
                                   .executeQueries(queries, queries.length,
                                                   options);
@@ -178,20 +167,20 @@
             // reload with the last place set
             if (this.place)
               this.place = this.place;
           }
           return val;
         ]]></setter>
       </property>
 
-      <!-- 
+      <!--
         Causes a particular node represented by the specified placeURI to be
         selected in the tree. All containers above the node in the hierarchy
-        will be opened, so that the node is visible. 
+        will be opened, so that the node is visible.
         -->
       <method name="selectPlaceURI">
         <parameter name="placeURI"/>
         <body><![CDATA[
           // Do nothing if a node matching the given uri is already selected
           if (this.hasSelection && this.selectedNode.uri == placeURI)
             return;
 
@@ -221,48 +210,48 @@
             }
 
             if (!wasOpen)
               container.containerOpen = false;
 
             return null;
           }
 
-          var container = this.getResultNode();
+          var container = this.result.root;
           NS_ASSERT(container, "No result, cannot select place URI!");
           if (!container)
             return;
 
           var child = findNode(container, placeURI, []);
           if (child)
             this.selectNode(child);
           else {
             // If the specified child could not be located, clear the selection
             var selection = this.view.selection;
             selection.clearSelection();
           }
         ]]></body>
       </method>
 
-      <!-- 
-        Causes a particular node to be selected in the tree, resulting in all 
+      <!--
+        Causes a particular node to be selected in the tree, resulting in all
         containers above the node in the hierarchy to be opened, so that the
-        node is visible. 
+        node is visible.
         -->
       <method name="selectNode">
         <parameter name="node"/>
-        <body><![CDATA[ 
+        <body><![CDATA[
           var view = this.view;
 
           var parent = node.parent;
           if (parent && !parent.containerOpen) {
-            // Build a list of all of the nodes that are the parent of this one 
-            // in the result. 
+            // Build a list of all of the nodes that are the parent of this one
+            // in the result.
             var parents = [];
-            var root = this.getResultNode();
+            var root = this.result.root;
             while (parent && parent != root) {
               parents.push(parent);
               parent = parent.parent;
             }
 
             // Walk the list backwards (opening from the root of the hierarchy)
             // opening each folder as we go.
             for (var i = parents.length - 1; i >= 0; --i) {
@@ -274,39 +263,32 @@
             // Select the specified node...
           }
 
           var index = view.treeIndexForNode(node);
           if (index == Ci.nsINavHistoryResultTreeViewer.INDEX_INVISIBLE)
             return;
 
           view.selection.select(index);
-          // ... and ensure it's visible, not scrolled off somewhere. 
+          // ... and ensure it's visible, not scrolled off somewhere.
           this.treeBoxObject.ensureRowIsVisible(index);
         ]]></body>
       </method>
 
       <!-- nsIPlacesView -->
-      <method name="getResult">
-        <body><![CDATA[
+      <property name="result">
+        <getter><![CDATA[
           try {
             return this.view.QueryInterface(Ci.nsINavHistoryResultObserver).result;
           }
           catch (e) {
             return null;
           }
-        ]]></body>
-      </method>
-
-      <!-- nsIPlacesView -->
-      <method name="getResultNode">
-        <body><![CDATA[
-          return this.getResult().root;
-        ]]></body>
-      </method>
+        ]]></getter>
+      </property>
 
       <!-- nsIPlacesView -->
       <property name="place">
         <getter><![CDATA[
           return this.getAttribute("place");
         ]]></getter>
         <setter><![CDATA[
           this.setAttribute("place", val);
@@ -327,63 +309,63 @@
       </property>
 
       <!-- nsIPlacesView -->
       <property name="hasSelection">
         <getter><![CDATA[
           return this.view && this.view.selection.count >= 1;
         ]]></getter>
       </property>
-      
+
       <!-- nsIPlacesView -->
-      <method name="getSelectionNodes">
-        <body><![CDATA[ 
+      <property name="selectedNodes">
+        <getter><![CDATA[
           let nodes = [];
           if (!this.hasSelection)
             return nodes;
 
           let selection = this.view.selection;
           let rc = selection.getRangeCount();
           let resultview = this.view;
           for (let i = 0; i < rc; ++i) {
             let min = { }, max = { };
             selection.getRangeAt(i, min, max);
 
             for (let j = min.value; j <= max.value; ++j)
               nodes.push(resultview.nodeForTreeIndex(j));
           }
           return nodes;
-        ]]></body>
-      </method>
+        ]]></getter>
+      </property>
 
       <!-- nsIPlacesView -->
-      <method name="getRemovableSelectionRanges">
-        <body><![CDATA[ 
-          // This function exists in addition to getSelectionNodes because it
+      <property name="removableSelectionRanges">
+        <getter><![CDATA[
+          // This property exists in addition to selectedNodes because it
           // encodes selection ranges (which only occur in list views) into
           // the return value. For each removed range, the index at which items
           // will be re-inserted upon the remove transaction being performed is
-          // the first index of the range, so that the view updates correctly. 
+          // the first index of the range, so that the view updates correctly.
           //
           // For example, if we remove rows 2,3,4 and 7,8 from a list, when we
           // undo that operation, if we insert what was at row 3 at row 3 again,
-          // it will show up _after_ the item that was at row 5. So we need to 
-          // insert all items at row 2, and the tree view will update correctly. 
+          // it will show up _after_ the item that was at row 5. So we need to
+          // insert all items at row 2, and the tree view will update correctly.
           //
           // Also, this function collapses the selection to remove redundant
           // data, e.g. when deleting this selection:
           //
           //      http://www.foo.com/
           //  (-) Some Folder
           //        http://www.bar.com/
           //
-          // ... returning http://www.bar.com/ as part of the selection is 
-          // redundant because it is implied by removing "Some Folder". We 
+          // ... returning http://www.bar.com/ as part of the selection is
+          // redundant because it is implied by removing "Some Folder". We
           // filter out all such redundancies since some partial amount of
-          // the folder's children may be selected.          
+          // the folder's children may be selected.
           //
           let nodes = [];
           if (!this.hasSelection)
             return nodes;
 
           var selection = this.view.selection;
           var rc = selection.getRangeCount();
           var resultview = this.view;
@@ -391,36 +373,33 @@
           // the for loop) since the row index of a container is unique for the
           // entire view, and we could have some really wacky selection and we
           // don't want to blow up.
           var containers = { };
           for (var i = 0; i < rc; ++i) {
             var range = [];
             var min = { }, max = { };
             selection.getRangeAt(i, min, max);
-            
+
             for (var j = min.value; j <= max.value; ++j) {
               if (this.view.isContainer(j))
                 containers[j] = true;
               if (!(this.view.getParentIndex(j) in containers))
                 range.push(resultview.nodeForTreeIndex(j));
             }
             nodes.push(range);
           }
           return nodes;
-        ]]></body>
-      </method>
-      
+        ]]></getter>
+      </property>
+
       <!-- nsIPlacesView -->
-      <method name="getDraggableSelection">
-        <body><![CDATA[
-          return this.getSelectionNodes();
-        ]]></body>
-      </method>
-      
+      <property name="draggableSelection"
+                onget="return this.selectedNodes"/>
+
       <!-- nsIPlacesView -->
       <property name="selectedNode">
         <getter><![CDATA[
           var view = this.view;
           if (!view || view.selection.count != 1)
             return null;
 
           var selection = view.selection;
@@ -435,50 +414,50 @@
       <property name="insertionPoint">
         <getter><![CDATA[
           // invalidated on selection and focus changes
           if (this._cachedInsertionPoint !== undefined)
             return this._cachedInsertionPoint;
 
           // there is no insertion point for history queries
           // so bail out now and save a lot of work when updating commands
-          var resultNode = this.getResultNode();
+          var resultNode = this.result.root;
           if (PlacesUtils.nodeIsQuery(resultNode) &&
               PlacesUtils.asQuery(resultNode).queryOptions.queryType ==
                 Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY)
               return this._cachedInsertionPoint = null;
 
           var orientation = Ci.nsITreeView.DROP_BEFORE;
-          // If there is no selection, insert at the end of the container. 
+          // If there is no selection, insert at the end of the container.
           if (!this.hasSelection) {
             var index = this.view.rowCount - 1;
             this._cachedInsertionPoint =
               this._getInsertionPoint(index, orientation);
             return this._cachedInsertionPoint;
           }
 
           // This is a two-part process. The first part is determining the drop
           // orientation.
           // * The default orientation is to drop _before_ the selected item.
           // * If the selected item is a container, the default orientation
           //   is to drop _into_ that container.
           //
           // Warning: It may be tempting to use tree indexes in this code, but
-          //          you must not, since the tree is nested and as your tree 
+          //          you must not, since the tree is nested and as your tree
           //          index may change when folders before you are opened and
           //          closed. You must convert your tree index to a node, and
           //          then use getChildIndex to find your absolute index in
-          //          the parent container instead. 
+          //          the parent container instead.
           //
           var resultView = this.view;
           var selection = resultView.selection;
           var rc = selection.getRangeCount();
           var min = { }, max = { };
           selection.getRangeAt(rc - 1, min, max);
-          
+
           // If the sole selection is a container, and we are not in
           // a flatlist, insert into it.
           // Note that this only applies to _single_ selections,
           // if the last element within a multi-selection is a
           // container, insert _adjacent_ to the selection.
           //
           // If the sole selection is the bookmarks toolbar folder, we insert
           // into it even if it is not opened
@@ -493,28 +472,28 @@
           return this._cachedInsertionPoint;
         ]]></getter>
       </property>
 
       <method name="_getInsertionPoint">
         <parameter name="index"/>
         <parameter name="orientation"/>
         <body><![CDATA[
-          var result = this.getResult();
+          var result = this.result;
           var resultview = this.view;
           var container = result.root;
           var dropNearItemId = -1;
           NS_ASSERT(container, "null container");
           // When there's no selection, assume the container is the container
           // the view is populated from (i.e. the result's itemId).
           if (index != -1) {
             var lastSelected = resultview.nodeForTreeIndex(index);
             if (resultview.isContainer(index) && orientation == Ci.nsITreeView.DROP_ON) {
               // If the last selected item is an open container, append _into_
-              // it, rather than insert adjacent to it. 
+              // it, rather than insert adjacent to it.
               container = lastSelected;
               index = -1;
             }
             else if (lastSelected.containerOpen &&
                      orientation == Ci.nsITreeView.DROP_AFTER &&
                      lastSelected.hasChildren) {
              // If the last selected item is an open container and the user is
              // trying to drag into it as a first item, really insert into it.
@@ -564,17 +543,17 @@
                                     index, orientation,
                                     PlacesUtils.nodeIsTagQuery(container),
                                     dropNearItemId);
         ]]></body>
       </method>
 
       <!-- nsIPlacesView -->
       <method name="selectAll">
-        <body><![CDATA[ 
+        <body><![CDATA[
           this.view.selection.selectAll();
         ]]></body>
       </method>
 
       <!-- This method will select the first node in the tree that matches
            each given item id. It will open any parent nodes that it needs
            to in order to show the selected items.
       -->
@@ -652,22 +631,22 @@
             // subtree, revert the node to its previous openness.
             if (foundOne)
               nodesToOpen.unshift(node);
             node.containerOpen = previousOpenness;
             return foundOne;
           }
 
           // Disable notifications while looking for nodes.
-          let result = this.getResult();
+          let result = this.result;
           let didSuppressNotifications = result.suppressNotifications;
           if (!didSuppressNotifications)
             result.suppressNotifications = true
           try {
-            findNodes(this.getResultNode());
+            findNodes(this.result.root);
           }
           finally {
             if (!didSuppressNotifications)
               result.suppressNotifications = false;
           }
 
           // For all the nodes we've found, highlight the corresponding
           // index in the tree.
@@ -722,17 +701,17 @@
           win = win.parent;
         }
       ]]></handler>
 
       <handler event="dragstart"><![CDATA[
         if (event.target.localName != "treechildren")
           return;
 
-        let nodes = this.getSelectionNodes();
+        let nodes = this.selectedNodes;
         for (let i = 0; i < nodes.length; i++) {
           let node = nodes[i];
 
           // Disallow dragging the root node of a tree.
           if (!node.parent) {
             event.preventDefault();
             event.stopPropagation();
             return;
@@ -754,17 +733,17 @@
         if (event.target.localName != "treechildren")
           return;
 
         let row = { }, col = { }, child = { };
         this.treeBoxObject.getCellAt(event.clientX, event.clientY,
                                      row, col, child);
         let node = row.value != -1 ?
                    this.view.nodeForTreeIndex(row.value) :
-                   this.getResultNode();
+                   this.result.root;
         // cache the dropTarget for the view
         PlacesControllerDragHelper.currentDropTarget = node;
 
         // We have to calculate the orientation since view.canDrop will use
         // it and we want to be consistent with the dropfeedback.
         let tbo = this.treeBoxObject;
         let rowHeight = tbo.rowHeight;
         let eventY = event.clientY - tbo.treeBody.boxObject.y -
--- a/browser/components/places/jar.mn
+++ b/browser/components/places/jar.mn
@@ -4,21 +4,21 @@ browser.jar:
 *   content/browser/places/bookmarkProperties2.xul       (content/bookmarkProperties.xul)
 *   content/browser/places/places.xul                    (content/places.xul) 
 *   content/browser/places/places.js                     (content/places.js)
     content/browser/places/places.css                    (content/places.css)
     content/browser/places/organizer.css                 (content/organizer.css)
 *   content/browser/places/bookmarkProperties.xul        (content/bookmarkProperties.xul)
 *   content/browser/places/bookmarkProperties.js         (content/bookmarkProperties.js)
 *   content/browser/places/placesOverlay.xul             (content/placesOverlay.xul)
-*   content/browser/places/toolbar.xml                   (content/toolbar.xml)
 *   content/browser/places/menu.xml                      (content/menu.xml)
 *   content/browser/places/tree.xml                      (content/tree.xml)
 *   content/browser/places/controller.js                 (content/controller.js)
 *   content/browser/places/treeView.js                   (content/treeView.js)
+*   content/browser/places/browserPlacesViews.js         (content/browserPlacesViews.js)
 # keep the Places version of the history sidebar at history/history-panel.xul 
 # to prevent having to worry about between versions of the browser
 *   content/browser/history/history-panel.xul            (content/history-panel.xul) 
 *   content/browser/places/history-panel.js              (content/history-panel.js)
 # ditto for the bookmarks sidebar
 *   content/browser/bookmarks/bookmarksPanel.xul         (content/bookmarksPanel.xul)
 *   content/browser/bookmarks/bookmarksPanel.js          (content/bookmarksPanel.js)
 *   content/browser/bookmarks/sidebarUtils.js            (content/sidebarUtils.js)
--- a/browser/components/places/src/PlacesUIUtils.jsm
+++ b/browser/components/places/src/PlacesUIUtils.jsm
@@ -669,27 +669,29 @@ var PlacesUIUtils = {
 
   /**
    * Returns the closet ancestor places view for the given DOM node
    * @param aNode
    *        a DOM node
    * @return the closet ancestor places view if exists, null otherwsie.
    */
   getViewForNode: function PUIU_getViewForNode(aNode) {
-    var node = aNode;
+    let node = aNode;
 
-    // the view for a <menu> of which its associated menupopup is a places view,
-    // is the menupopup
-    if (node.localName == "menu" && !node.node &&
-        node.firstChild.getAttribute("type") == "places")
-      return node.firstChild;
+    // The view for a <menu> of which its associated menupopup is a places
+    // view, is the menupopup.
+    if (node.localName == "menu" && !node._placesNode &&
+        node.firstChild._placesView)
+      return node.firstChild._placesView;
 
-    while (node) {
-      // XXXmano: Use QueryInterface(nsIPlacesView) once we implement it...
-      if (node.getAttribute("type") == "places")
+    // XXXmano: somehow we reach the xul document here!
+    while (node instanceof Ci.nsIDOMElement) {
+      if (node._placesView)
+        return node._placesView;
+      if (node.localName == "tree" && node.getAttribute("type") == "places")
         return node;
 
       node = node.parentNode;
     }
 
     return null;
   },
 
@@ -935,134 +937,16 @@ var PlacesUIUtils = {
    * @return guessed scheme for this url string.
    *
    * @note this is not supposed be perfect, so use it only for UI purposes.
    */
   guessUrlSchemeForUI: function PUU_guessUrlSchemeForUI(aUrlString) {
     return aUrlString.substr(0, aUrlString.indexOf(":"));
   },
 
-  /**
-   * Creates a menu item ready to be added to a popup.
-   * Helper for the toolbar and menu views.
-   * @param aNode
-   *        Places node used as source for DOM node.
-   * @param aDocument
-   *        The node will be created in this document.
-   * @return a DOM menuitem node.
-   */
-  createMenuItemForNode:
-  function PUU_createMenuItemForNode(aNode, aDocument) {
-    var element;
-    // For add-ons backwards compatibility, if the caller does not provide
-    // a document, we guess one.
-    var document = aDocument || this._getTopBrowserWin().document;
-    var type = aNode.type;
-    if (type == Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR) {
-      element = document.createElement("menuseparator");
-    }
-    else {
-      if (PlacesUtils.uriTypes.indexOf(type) != -1) {
-        element = document.createElement("menuitem");
-        element.className = "menuitem-iconic bookmark-item menuitem-with-favicon";
-        element.setAttribute("scheme", this.guessUrlSchemeForUI(aNode.uri));
-      }
-      else if (PlacesUtils.containerTypes.indexOf(type) != -1) {
-        element = document.createElement("menu");
-        element.setAttribute("container", "true");
-
-        if (aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY) {
-          element.setAttribute("query", "true");
-          if (PlacesUtils.nodeIsTagQuery(aNode))
-            element.setAttribute("tagContainer", "true");
-          else if (PlacesUtils.nodeIsDay(aNode))
-            element.setAttribute("dayContainer", "true");
-          else if (PlacesUtils.nodeIsHost(aNode))
-            element.setAttribute("hostContainer", "true");
-        }
-        else if (aNode.itemId != -1) {
-          if (PlacesUtils.nodeIsLivemarkContainer(aNode))
-            element.setAttribute("livemark", "true");
-        }
-
-        var popup = document.createElement("menupopup");
-        popup.setAttribute("placespopup", "true");
-        popup._resultNode = PlacesUtils.asContainer(aNode);
-#ifdef XP_MACOSX
-        // Binding on Mac native menus is lazy attached, so onPopupShowing,
-        // in the capturing phase, fields are not yet initialized.
-        // In that phase we have to ensure markers are not undefined to build
-        // the popup correctly.
-        popup._startMarker = -1;
-        popup._endMarker = -1;
-#else
-        // no context menu on mac
-        popup.setAttribute("context", "placesContext");
-#endif
-        element.appendChild(popup);
-        element.className = "menu-iconic bookmark-item";
-      }
-      else
-        throw "Unexpected node";
-
-      element.setAttribute("label", this.getBestTitle(aNode));
-
-      var icon = aNode.icon;
-      if (icon)
-        element.setAttribute("image", icon);
-    }
-    element.node = aNode;
-    element.node._DOMElement = element;
-
-    return element;
-  },
-
-  cleanPlacesPopup: function PUIU_cleanPlacesPopup(aPopup) {
-    // Remove places popup children and update markers to keep track of
-    // their indices.
-    var start = aPopup._startMarker != -1 ? aPopup._startMarker + 1 : 0;
-    var end = aPopup._endMarker != -1 ? aPopup._endMarker :
-                                        aPopup.childNodes.length;
-    var items = [];
-    var placesNodeFound = false;
-    for (var i = start; i < end; ++i) {
-      var item = aPopup.childNodes[i];
-      if (item.getAttribute("builder") == "end") {
-        // we need to do this for menus that have static content at the end but
-        // are initially empty, eg. the history menu, we need to know where to
-        // start inserting new items.
-        aPopup._endMarker = i;
-        break;
-      }
-      if (item.node) {
-        items.push(item);
-        placesNodeFound = true;
-      }
-      else {
-        // This is static content...
-        if (!placesNodeFound) {
-          // ...at the start of the popup
-          // Initialized in menu.xml, in the base binding
-          aPopup._startMarker++;
-        }
-        else {
-          // ...after places nodes
-          aPopup._endMarker = i;
-          break;
-        }
-      }
-    }
-
-    for (var i = 0; i < items.length; ++i) {
-      aPopup.removeChild(items[i]);
-      if (aPopup._endMarker != -1)
-        aPopup._endMarker--;
-    }
-  },
-
   getBestTitle: function PUIU_getBestTitle(aNode) {
     var title;
     if (!aNode.title && PlacesUtils.uriTypes.indexOf(aNode.type) != -1) {
       // if node title is empty, try to set the label using host and filename
       // PlacesUtils._uri() will throw if aNode.uri is not a valid URI
       try {
         var uri = PlacesUtils._uri(aNode.uri);
         var host = uri.host;
@@ -1359,57 +1243,16 @@ var PlacesUIUtils = {
       for (let [name, id] in Iterator(this.leftPaneQueries)) {
         if (aItemId == id)
           queryName = name;
       }
     }
     return queryName; 
   },
 
-  /**
-  * Add, update or remove the livemark status menuitem.
-  * @param aPopup
-  *        The livemark container popup
-  */
-  ensureLivemarkStatusMenuItem:
-  function PUIU_ensureLivemarkStatusMenuItem(aPopup) {
-    var itemId = aPopup._resultNode.itemId;
-
-    var lmStatus = null;
-    if (PlacesUtils.annotations
-                   .itemHasAnnotation(itemId, "livemark/loadfailed"))
-      lmStatus = "bookmarksLivemarkFailed";
-    else if (PlacesUtils.annotations
-                        .itemHasAnnotation(itemId, "livemark/loading"))
-      lmStatus = "bookmarksLivemarkLoading";
-
-    if (lmStatus && !aPopup._lmStatusMenuItem) {
-      // Create the status menuitem and cache it in the popup object.
-      let document = aPopup.ownerDocument;
-      aPopup._lmStatusMenuItem = document.createElement("men