Merge m-c to tracemonkey.
authorRobert Sayre <sayrer@gmail.com>
Fri, 19 Dec 2008 15:50:52 -0500
changeset 23101 229681f85e7aef406b41c6529a59addd969ff310
parent 23100 5af9839712f7f6d2be011763ce4a0370c1f7b5f5 (current diff)
parent 22952 7cd58efd035ab76e461e1d6e519376bbace7b15d (diff)
child 23102 a5bd620ceeea59969dc196f4d88310c42ac9eee9
push id4346
push userrsayre@mozilla.com
push dateFri, 26 Dec 2008 01:26:36 +0000
treeherdermozilla-central@8eb5a5b83a93 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone1.9.2a1pre
Merge m-c to tracemonkey.
js/src/js.cpp
js/src/jsemit.cpp
js/src/jsobj.cpp
js/src/jsopcode.tbl
js/src/jstracer.cpp
modules/plugin/test/mochitest/Makefile.in
modules/plugin/test/mochitest/test_npruntime.xul
modules/plugin/test/testplugin/nptest.def
modules/plugin/test/testplugin/nptest.h
modules/plugin/test/testplugin/nptest_gtk2.cpp
modules/plugin/test/testplugin/nptest_macosx.mm
modules/plugin/test/testplugin/nptest_platform.h
modules/plugin/test/testplugin/nptest_utils.cpp
modules/plugin/test/testplugin/nptest_utils.h
modules/plugin/test/testplugin/nptest_windows.cpp
--- a/Makefile.in
+++ b/Makefile.in
@@ -37,68 +37,70 @@
 
 DEPTH		= .
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-include $(topsrcdir)/config/config.mk
-
-default alldep all::
-	$(RM) -rf $(DIST)/sdk
-	$(RM) -rf $(DIST)/include
-	$(RM) -rf $(DIST)/private
-	$(RM) -rf $(DIST)/public
-	$(RM) -rf $(DIST)/bin/components
-	$(RM) -rf _tests
+default::
 
 TIERS += base
 
 #
 # tier "base" - basic setup
 #
 tier_base_dirs = \
 	config \
 	build \
 	probes \
 	$(NULL)
 
 ifdef MOZ_MEMORY
 tier_base_dirs += memory/jemalloc
 endif
 
-ifdef ENABLE_TESTS
-# Additional makefile targets to call automated test suites
-include $(topsrcdir)/testing/testsuite-targets.mk
-endif
-
 include $(topsrcdir)/$(MOZ_BUILD_APP)/build.mk
 
 TIERS += testharness
 
 # test harnesses
 ifdef ENABLE_TESTS
 tier_testharness_dirs += tools/test-harness
 endif
 
+include $(topsrcdir)/config/config.mk
+
 GARBAGE_DIRS += dist _javagen _profile _tests staticlib
 DIST_GARBAGE = config.cache config.log config.status config-defs.h \
    dependencies.beos config/autoconf.mk config/myrules.mk config/myconfig.mk \
    unallmakefiles mozilla-config.h \
    netwerk/necko-config.h xpcom/xpcom-config.h xpcom/xpcom-private.h \
    $(topsrcdir)/.mozconfig.mk $(topsrcdir)/.mozconfig.out
 
+default alldep all::
+	$(RM) -rf $(DIST)/sdk
+	$(RM) -rf $(DIST)/include
+	$(RM) -rf $(DIST)/private
+	$(RM) -rf $(DIST)/public
+	$(RM) -rf $(DIST)/bin/components
+	$(RM) -rf _tests
+
 # Build pseudo-external modules first when export is explicitly called
 export::
 	$(RM) -rf $(DIST)/sdk
 	$(MAKE) -C config export
 	$(MAKE) tier_nspr
 
+ifdef ENABLE_TESTS
+# Additional makefile targets to call automated test suites
+include $(topsrcdir)/testing/testsuite-targets.mk
+endif
+
 include $(topsrcdir)/config/rules.mk
 
 # After we build tier toolkit, go back and build the tools from previous dirs
 tier_toolkit::
 	$(MAKE) tools_tier_js
 	$(MAKE) tools_tier_xpcom
 	$(MAKE) tools_tier_necko
 	$(MAKE) tools_tier_gecko
--- a/browser/Makefile.in
+++ b/browser/Makefile.in
@@ -39,22 +39,26 @@ DEPTH		= ..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(topsrcdir)/config/config.mk
 
 DIRS = base components locales themes fuel app
 
+ifeq ($(OS_ARCH),WINNT)
+ifdef MOZ_INSTALLER
+DIRS += installer/windows
+endif
+endif
+
 include $(topsrcdir)/config/rules.mk
 
 ifeq ($(OS_ARCH),WINNT)
 ifdef MOZ_INSTALLER
-DIRS += installer/windows
-
 ifdef MOZ_BRANDING_DIRECTORY
 DEFINES += -DOFFICIAL_BRANDING=1
 endif
 
 # For Windows build the uninstaller during the application build since the
 # uninstaller is included with the application for mar file generation.
 libs::
 	$(MAKE) -C installer/windows uninstaller
--- a/browser/installer/Makefile.in
+++ b/browser/installer/Makefile.in
@@ -63,17 +63,23 @@ ifneq (,$(BUILD_STATIC_LIBS)$(MOZ_ENABLE
 ifeq (WINNT,$(OS_ARCH))
 MOZ_PKG_MANIFEST_P = $(srcdir)/windows/packages-static
 else
 ifneq (,$(filter-out OS2 Darwin,$(OS_ARCH)))
 MOZ_PKG_MANIFEST_P = $(srcdir)/unix/packages-static
 endif
 endif
 else
-$(error you need a "--enable-static or --enable-libxul" build to package a build)
+define message
+Please don't package debug builds.
+Your build was configured without --enable-static or --enable-libxul.
+This is probably because it's a debug build
+endef
+default libs installer::
+	$(error $(message))
 endif
 
 MOZ_NONLOCALIZED_PKG_LIST = \
 	xpcom \
 	browser \
 	$(NULL)
 
 MOZ_LOCALIZED_PKG_LIST = $(AB_CD)
@@ -101,12 +107,12 @@ MOZ_PKG_MAC_EXTRA=--symlink "/Applicatio
 endif
 
 ifndef LIBXUL_SDK
 INSTALL_SDK = 1
 endif
 
 include $(topsrcdir)/toolkit/mozapps/installer/packager.mk
 
-installer: removed-files
+installer:: removed-files
 ifdef INSTALLER_DIR
 	$(MAKE) -C $(INSTALLER_DIR)
 endif
--- a/config/config.mk
+++ b/config/config.mk
@@ -851,8 +851,13 @@ endif
 #
 
 # Make sure any compiled classes work with at least JVM 1.4
 JAVAC_FLAGS += -source 1.4
 
 ifdef MOZ_DEBUG
 JAVAC_FLAGS += -g
 endif
+
+ifdef TIERS
+DIRS += $(foreach tier,$(TIERS),$(tier_$(tier)_dirs))
+STATIC_DIRS += $(foreach tier,$(TIERS),$(tier_$(tier)_staticdirs))
+endif
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -460,32 +460,40 @@ ifdef MOZ_UPDATE_XTERM
 # makes the make -s output easier to read.  Echo -n does not work on all
 # platforms, but we can trick sed into doing it.
 UPDATE_TITLE = sed -e "s!Y!$@ in $(shell $(BUILD_TOOLS)/print-depth-path.sh)/$(dir)!" $(MOZILLA_DIR)/config/xterm.str;
 UPDATE_TITLE_export = sed -e "s!Y!export in $(shell $(BUILD_TOOLS)/print-depth-path.sh)/$*!" $(MOZILLA_DIR)/config/xterm.str;
 UPDATE_TITLE_libs = sed -e "s!Y!libs in $(shell $(BUILD_TOOLS)/print-depth-path.sh)/$*!" $(MOZILLA_DIR)/config/xterm.str;
 UPDATE_TITLE_tools = sed -e "s!Y!tools in $(shell $(BUILD_TOOLS)/print-depth-path.sh)/$*!" $(MOZILLA_DIR)/config/xterm.str;
 endif
 
+ifneq (,$(strip $(DIRS)))
 LOOP_OVER_DIRS = \
     @$(EXIT_ON_ERROR) \
-    $(foreach dir,$(DIRS),$(UPDATE_TITLE) $(MAKE) -C $(dir) $@; ) true
+    $(foreach dir,$(DIRS),$(UPDATE_TITLE) $(MAKE) -C $(dir) $@; )
+endif
 
 # we only use this for the makefiles target and other stuff that doesn't matter
+ifneq (,$(strip $(PARALLEL_DIRS)))
 LOOP_OVER_PARALLEL_DIRS = \
     @$(EXIT_ON_ERROR) \
-    $(foreach dir,$(PARALLEL_DIRS),$(UPDATE_TITLE) $(MAKE) -C $(dir) $@; ) true
+    $(foreach dir,$(PARALLEL_DIRS),$(UPDATE_TITLE) $(MAKE) -C $(dir) $@; )
+endif
 
+ifneq (,$(strip $(STATIC_DIRS)))
 LOOP_OVER_STATIC_DIRS = \
     @$(EXIT_ON_ERROR) \
-    $(foreach dir,$(STATIC_DIRS),$(UPDATE_TITLE) $(MAKE) -C $(dir) $@; ) true
+    $(foreach dir,$(STATIC_DIRS),$(UPDATE_TITLE) $(MAKE) -C $(dir) $@; )
+endif
 
+ifneq (,$(strip $(TOOL_DIRS)))
 LOOP_OVER_TOOL_DIRS = \
     @$(EXIT_ON_ERROR) \
-    $(foreach dir,$(TOOL_DIRS),$(UPDATE_TITLE) $(MAKE) -C $(dir) $@; ) true
+    $(foreach dir,$(TOOL_DIRS),$(UPDATE_TITLE) $(MAKE) -C $(dir) $@; )
+endif
 
 ifdef PARALLEL_DIRS
 # create a bunch of fake targets for order-only processing
 PARALLEL_DIRS_export = $(addsuffix _export,$(PARALLEL_DIRS))
 PARALLEL_DIRS_libs = $(addsuffix _libs,$(PARALLEL_DIRS))
 PARALLEL_DIRS_tools = $(addsuffix _tools,$(PARALLEL_DIRS))
 
 .PHONY: $(PARALLEL_DIRS_export) $(PARALLEL_DIRS_libs) $(PARALLEL_DIRS_tools)
@@ -704,29 +712,26 @@ endif
 SUBMAKEFILES += $(addsuffix /Makefile, $(DIRS) $(TOOL_DIRS) $(PARALLEL_DIRS))
 
 # The root makefile doesn't want to do a plain export/libs, because
 # of the tiers and because of libxul. Suppress the default rules in favor
 # of something else. Makefiles which use this var *must* provide a sensible
 # default rule before including rules.mk
 ifndef SUPPRESS_DEFAULT_RULES
 ifdef TIERS
-
-DIRS += $(foreach tier,$(TIERS),$(tier_$(tier)_dirs))
-STATIC_DIRS += $(foreach tier,$(TIERS),$(tier_$(tier)_staticdirs))
-
 default all alldep::
 	$(EXIT_ON_ERROR) \
 	$(foreach tier,$(TIERS),$(MAKE) tier_$(tier); ) true
 
 else
 
 default all::
-	@$(EXIT_ON_ERROR) \
-	$(foreach dir,$(STATIC_DIRS),$(MAKE) -C $(dir); ) true
+ifneq (,$(strip $(STATIC_DIRS)))
+	$(foreach dir,$(STATIC_DIRS),$(MAKE) -C $(dir); )
+endif
 	$(MAKE) export
 	$(MAKE) libs
 	$(MAKE) tools
 
 # Do depend as well
 alldep:: 
 	$(MAKE) export
 	$(MAKE) depend
@@ -818,19 +823,19 @@ ifdef PARALLEL_DIRS
 tools:: $(PARALLEL_DIRS_tools)
 
 $(PARALLEL_DIRS_tools): %_tools: %/Makefile
 	+@$(UPDATE_TITLE_tools) $(MAKE) -C $* tools
 endif
 
 tools:: $(SUBMAKEFILES) $(MAKE_DIRS)
 	+$(LOOP_OVER_DIRS)
-ifdef TOOL_DIRS
+ifneq (,$(strip $(TOOL_DIRS)))
 	@$(EXIT_ON_ERROR) \
-	$(foreach dir,$(TOOL_DIRS),$(UPDATE_TITLE) $(MAKE) -C $(dir) libs; ) true
+	$(foreach dir,$(TOOL_DIRS),$(UPDATE_TITLE) $(MAKE) -C $(dir) libs; )
 endif
 
 #
 # Rule to create list of libraries for final link
 #
 export::
 ifdef LIBRARY_NAME
 ifdef EXPORT_LIBRARY
@@ -2165,17 +2170,17 @@ FORCE:
 tags: TAGS
 
 TAGS: $(SUBMAKEFILES) $(CSRCS) $(CPPSRCS) $(wildcard *.h)
 	-etags $(CSRCS) $(CPPSRCS) $(wildcard *.h)
 	+$(LOOP_OVER_PARALLEL_DIRS)
 	+$(LOOP_OVER_DIRS)
 
 echo-variable-%:
-	@echo $($*)
+	@echo "$($*)"
 
 echo-tiers:
 	@echo $(TIERS)
 
 echo-tier-dirs:
 	@$(foreach tier,$(TIERS),echo '$(tier):'; echo '  dirs: $(tier_$(tier)_dirs)'; echo '  staticdirs: $(tier_$(tier)_staticdirs)'; )
 
 echo-dirs:
--- a/configure.in
+++ b/configure.in
@@ -5242,17 +5242,17 @@ fi
 dnl ========================================================
 dnl Disable printing
 dnl ========================================================
 MOZ_ARG_DISABLE_BOOL(printing,
 [  --disable-printing  Disable printing support],
     NS_PRINTING=,
     NS_PRINTING=1 )
 
-if test "$MOZ_WIDGET_TOOLKIT" == "qt"; then
+if test "$MOZ_WIDGET_TOOLKIT" = "qt"; then
     AC_MSG_WARN([Printing does not work with Qt at this time. Omitting printing support.])
     NS_PRINTING=
 fi
 
 if test "$NS_PRINTING"; then
     AC_DEFINE(NS_PRINTING)
     AC_DEFINE(NS_PRINT_PREVIEW)
 fi
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -227,16 +227,17 @@ include $(topsrcdir)/config/rules.mk
 		test_NodeIterator_mutations_2.html \
 		test_bug28293.html \
 		file_bug28293.sjs \
 		test_bug445225.html \
 		file_bug445225_multipart.txt \
 		file_bug445225_multipart.txt^headers^ \
 		test_title.html \
 		test_bug453521.html \
+		test_bug391728.html \
 		file_bug391728.html \
 		test_bug454325.html \
 		file_bug391728_2.html \
 		test_bug456262.html \
 		test_bug368972.html \
 		test_bug448993.html \
 		test_bug450160.html \
 		test_bug454326.html \
@@ -270,14 +271,10 @@ include $(topsrcdir)/config/rules.mk
 		bug444322.txt \
 		bug444322.js \
 		$(NULL)
 
 # Disabled for now. Mochitest isn't reliable enough for these.
 # test_bug444546.html \
 # bug444546.sjs \
 
-# Disabled because of a leak that occurs when the test plugin can actually load
-# instances.
-# test_bug391728.html \
-
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
--- a/content/canvas/src/nsCanvasRenderingContext2D.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp
@@ -3395,18 +3395,21 @@ nsCanvasRenderingContext2D::DrawWindow(n
 
     nsIPresShell* presShell = presContext->PresShell();
     NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
 
     nsRect r(nsPresContext::CSSPixelsToAppUnits(aX),
              nsPresContext::CSSPixelsToAppUnits(aY),
              nsPresContext::CSSPixelsToAppUnits(aW),
              nsPresContext::CSSPixelsToAppUnits(aH));
-    presShell->RenderDocument(r, PR_FALSE, PR_TRUE, bgColor,
-                              mThebes);
+    PRUint32 renderDocFlags = nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING;
+    if (flags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_DRAW_CARET) {
+        renderDocFlags |= nsIPresShell::RENDER_CARET;
+    }
+    presShell->RenderDocument(r, renderDocFlags, bgColor, mThebes);
 
     // get rid of the pattern surface ref, just in case
     mThebes->SetColor(gfxRGBA(1,1,1,1));
     DirtyAllStyles();
 
     Redraw();
 
     return rv;
--- a/content/events/src/nsDOMDragEvent.cpp
+++ b/content/events/src/nsDOMDragEvent.cpp
@@ -72,40 +72,49 @@ NS_IMPL_RELEASE_INHERITED(nsDOMDragEvent
 
 NS_INTERFACE_MAP_BEGIN(nsDOMDragEvent)
   NS_INTERFACE_MAP_ENTRY(nsIDOMDragEvent)
   NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(DragEvent)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMMouseEvent)
 
 NS_IMETHODIMP
 nsDOMDragEvent::InitDragEvent(const nsAString & aType,
-                              PRBool aCanBubble,
-                              PRBool aCancelable,
-                              nsIDOMAbstractView* aView,
-                              PRInt32 aDetail,
+                              PRBool aCanBubble, PRBool aCancelable,
+                              nsIDOMAbstractView* aView, PRInt32 aDetail,
+                              PRInt32 aScreenX, PRInt32 aScreenY,
+                              PRInt32 aClientX, PRInt32 aClientY, 
+                              PRBool aCtrlKey, PRBool aAltKey, PRBool aShiftKey,
+                              PRBool aMetaKey, PRUint16 aButton,
+                              nsIDOMEventTarget *aRelatedTarget,
                               nsIDOMDataTransfer* aDataTransfer)
 {
-  nsresult rv = nsDOMUIEvent::InitUIEvent(aType, aCanBubble, aCancelable, aView, aDetail);
+  nsresult rv = nsDOMMouseEvent::InitMouseEvent(aType, aCanBubble, aCancelable,
+                  aView, aDetail, aScreenX, aScreenY, aClientX, aClientY,
+                  aCtrlKey, aAltKey, aShiftKey, aMetaKey, aButton,
+                  aRelatedTarget);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (mEventIsInternal && mEvent) {
     nsDragEvent* dragEvent = static_cast<nsDragEvent*>(mEvent);
     dragEvent->dataTransfer = aDataTransfer;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMDragEvent::InitDragEventNS(const nsAString & aNamespaceURIArg,
                                 const nsAString & aType,
-                                PRBool aCanBubble,
-                                PRBool aCancelable,
-                                nsIDOMAbstractView* aView,
-                                PRInt32 aDetail,
+                                PRBool aCanBubble, PRBool aCancelable,
+                                nsIDOMAbstractView* aView, PRInt32 aDetail,
+                                PRInt32 aScreenX, PRInt32 aScreenY,
+                                PRInt32 aClientX, PRInt32 aClientY, 
+                                PRBool aCtrlKey, PRBool aAltKey, PRBool aShiftKey,
+                                PRBool aMetaKey, PRUint16 aButton,
+                                nsIDOMEventTarget *aRelatedTarget,
                                 nsIDOMDataTransfer* aDataTransfer)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 nsDOMDragEvent::GetDataTransfer(nsIDOMDataTransfer** aDataTransfer)
 {
--- a/content/events/src/nsDOMMouseEvent.cpp
+++ b/content/events/src/nsDOMMouseEvent.cpp
@@ -101,21 +101,22 @@ NS_IMETHODIMP
 nsDOMMouseEvent::InitMouseEvent(const nsAString & aType, PRBool aCanBubble, PRBool aCancelable,
                                 nsIDOMAbstractView *aView, PRInt32 aDetail, PRInt32 aScreenX, 
                                 PRInt32 aScreenY, PRInt32 aClientX, PRInt32 aClientY, 
                                 PRBool aCtrlKey, PRBool aAltKey, PRBool aShiftKey, 
                                 PRBool aMetaKey, PRUint16 aButton, nsIDOMEventTarget *aRelatedTarget)
 {
   nsresult rv = nsDOMUIEvent::InitUIEvent(aType, aCanBubble, aCancelable, aView, aDetail);
   NS_ENSURE_SUCCESS(rv, rv);
-  
+
   switch(mEvent->eventStructType)
   {
     case NS_MOUSE_EVENT:
     case NS_MOUSE_SCROLL_EVENT:
+    case NS_DRAG_EVENT:
     {
        static_cast<nsMouseEvent_base*>(mEvent)->relatedTarget = aRelatedTarget;
        static_cast<nsMouseEvent_base*>(mEvent)->button = aButton;
        nsInputEvent* inputEvent = static_cast<nsInputEvent*>(mEvent);
        inputEvent->isControl = aCtrlKey;
        inputEvent->isAlt = aAltKey;
        inputEvent->isShift = aShiftKey;
        inputEvent->isMeta = aMetaKey;
@@ -158,16 +159,17 @@ nsDOMMouseEvent::InitNSMouseEvent(const 
 NS_IMETHODIMP
 nsDOMMouseEvent::GetButton(PRUint16* aButton)
 {
   NS_ENSURE_ARG_POINTER(aButton);
   switch(mEvent->eventStructType)
   {
     case NS_MOUSE_EVENT:
     case NS_MOUSE_SCROLL_EVENT:
+    case NS_DRAG_EVENT:
       *aButton = static_cast<nsMouseEvent_base*>(mEvent)->button;
       break;
     default:
       NS_WARNING("Tried to get mouse button for non-mouse event!");
       *aButton = nsMouseEvent::eLeftButton;
       break;
   }
   return NS_OK;
@@ -178,16 +180,17 @@ nsDOMMouseEvent::GetRelatedTarget(nsIDOM
 {
   NS_ENSURE_ARG_POINTER(aRelatedTarget);
   *aRelatedTarget = nsnull;
   nsISupports* relatedTarget = nsnull;
   switch(mEvent->eventStructType)
   {
     case NS_MOUSE_EVENT:
     case NS_MOUSE_SCROLL_EVENT:
+    case NS_DRAG_EVENT:
       relatedTarget = static_cast<nsMouseEvent_base*>(mEvent)->relatedTarget;
       break;
     default:
       break;
   }
 
   if (relatedTarget) {
     CallQueryInterface(relatedTarget, aRelatedTarget);
--- a/content/events/test/test_dragstart.html
+++ b/content/events/test/test_dragstart.html
@@ -49,22 +49,24 @@ function afterDragTests()
   expectError(function() gDataTransfer.setDragImage(draggable, 10, 10),
               "NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR", "setDragImage when read only");
   expectError(function() gDataTransfer.addElement(draggable),
               "NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR", "addElement when read only");
 
   var evt = document.createEvent("dragevent");
   ok(evt instanceof DragEvent, "synthetic dragevent class")
   ok(evt instanceof MouseEvent, "synthetic event inherits from MouseEvent")
-  evt.initDragEvent("dragstart", true, true, window, 1, null);
+  evt.initDragEvent("dragstart", true, true, window, 1, 40, 35, 20, 15,
+                    false, true, false, false, 0, null, null);
   $("synthetic").dispatchEvent(evt);
 
   var evt = document.createEvent("dragevents");
   ok(evt instanceof DragEvent, "synthetic dragevents class")
-  evt.initDragEvent("dragover", true, true, window, 0, null);
+  evt.initDragEvent("dragover", true, true, window, 0, 40, 35, 20, 15,
+                    true, false, true, true, 2, document.documentElement, null);
   $("synthetic2").dispatchEvent(evt);
 
   // next, dragging links and images
   sendMouseEventsForDrag("link");
   sendMouseEventsForDrag("image");
 
 //  disable testing input dragging for now, as it doesn't seem to be testable 
 //  draggable = $("input");
@@ -429,37 +431,56 @@ function doDragStartInput(event)
 //  is(dt.getData("text/plain"), "Text", "input text/plain");
 
 //  event.preventDefault();
 }
 
 function doDragStartSynthetic(event)
 {
   is(event.type, "dragstart", "synthetic dragstart event type");
-return;
+
   var dt = event.dataTransfer;
-  ok(dt instanceof DataTransfer, "synthetic dragstart dataTransfer is DataTransfer");
-
-  checkTypes(dt, [], 0, "synthetic dragstart");
+//  ok(dt instanceof DataTransfer, "synthetic dragstart dataTransfer is DataTransfer");
+//  checkTypes(dt, [], 0, "synthetic dragstart");
 
   is(event.detail, 1, "synthetic dragstart detail");
+  is(event.screenX, 40, "synthetic dragstart screenX");
+  is(event.screenY, 35, "synthetic dragstart screenY");
+  is(event.clientX, 20, "synthetic dragstart clientX");
+  is(event.clientY, 15, "synthetic dragstart clientY");
+  is(event.ctrlKey, false, "synthetic dragstart ctrlKey");
+  is(event.altKey, true, "synthetic dragstart altKey");
+  is(event.shiftKey, false, "synthetic dragstart shiftKey");
+  is(event.metaKey, false, "synthetic dragstart metaKey");
+  is(event.button, 0, "synthetic dragstart button ");
+  is(event.relatedTarget, null, "synthetic dragstart relatedTarget");
 
   dt.setData("text/plain", "Text");
   is(dt.getData("text/plain"), "Text", "synthetic dragstart data is set after adding");
 }
 
 function doDragOverSynthetic(event)
 {
   is(event.type, "dragover", "synthetic dragover event type");
-return;
 
   var dt = event.dataTransfer;
-  ok(dt instanceof DataTransfer, "synthetic dragover dataTransfer is DataTransfer");
+//  ok(dt instanceof DataTransfer, "synthetic dragover dataTransfer is DataTransfer");
+// checkTypes(dt, [], 0, "synthetic dragover");
 
-  checkTypes(dt, [], 0, "synthetic dragover");
+  is(event.detail, 0, "synthetic dragover detail");
+  is(event.screenX, 40, "synthetic dragover screenX");
+  is(event.screenY, 35, "synthetic dragover screenY");
+  is(event.clientX, 20, "synthetic dragover clientX");
+  is(event.clientY, 15, "synthetic dragover clientY");
+  is(event.ctrlKey, true, "synthetic dragover ctrlKey");
+  is(event.altKey, false, "synthetic dragover altKey");
+  is(event.shiftKey, true, "synthetic dragover shiftKey");
+  is(event.metaKey, true, "synthetic dragover metaKey");
+  is(event.button, 2, "synthetic dragover button");
+  is(event.relatedTarget, document.documentElement, "synthetic dragover relatedTarget");
 
   dt.setData("text/plain", "Text");
   is(dt.getData("text/plain"), "Text", "synthetic dragover data is set after adding");
 }
 
 function onDragStartDraggable(event)
 {
   var dt = event.dataTransfer;
--- a/content/xul/document/src/nsXULDocument.cpp
+++ b/content/xul/document/src/nsXULDocument.cpp
@@ -1014,22 +1014,34 @@ nsXULDocument::AttributeChanged(nsIDocum
             for (i = entry->mListeners.Count() - 1; i >= 0; --i) {
                 BroadcastListener* bl =
                     static_cast<BroadcastListener*>(entry->mListeners[i]);
 
                 if ((bl->mAttribute == aAttribute) ||
                     (bl->mAttribute == nsGkAtoms::_asterix)) {
                     nsCOMPtr<nsIDOMElement> listenerEl
                         = do_QueryReferent(bl->mListener);
-                    if (listenerEl) {
+                    nsCOMPtr<nsIContent> l = do_QueryInterface(listenerEl);
+                    if (l) {
+                      nsAutoString currentValue;
+                      PRBool hasAttr = l->GetAttr(kNameSpaceID_None,
+                                                  aAttribute,
+                                                  currentValue);
+                      // We need to update listener only if we're
+                      // (1) removing an existing attribute,
+                      // (2) adding a new attribute or
+                      // (3) changing the value of an attribute.
+                      PRBool needsAttrChange =
+                          attrSet != hasAttr || !value.Equals(currentValue);
                       nsDelayedBroadcastUpdate delayedUpdate(domele,
                                                              listenerEl,
                                                              aAttribute,
                                                              value,
-                                                             attrSet);
+                                                             attrSet,
+                                                             needsAttrChange);
                       mDelayedAttrChangeBroadcasts.AppendElement(delayedUpdate);
                     }
                 }
             }
         }
     }
 
     // checks for modifications in broadcasters
@@ -3278,27 +3290,28 @@ nsXULDocument::EndUpdate(nsUpdateType aU
     nsXMLDocument::EndUpdate(aUpdateType);
     if (mUpdateNestLevel == 0) {
         PRUint32 length = mDelayedAttrChangeBroadcasts.Length();
         if (length) {
           nsTArray<nsDelayedBroadcastUpdate> delayedAttrChangeBroadcasts;
             mDelayedAttrChangeBroadcasts.SwapElements(
                                              delayedAttrChangeBroadcasts);
             for (PRUint32 i = 0; i < length; ++i) {
-                nsCOMPtr<nsIContent> listener =
-                    do_QueryInterface(delayedAttrChangeBroadcasts[i].mListener);
                 nsIAtom* attrName = delayedAttrChangeBroadcasts[i].mAttrName;
-                nsString value = delayedAttrChangeBroadcasts[i].mAttr;
-                if (delayedAttrChangeBroadcasts[i].mSetAttr) {
-                    listener->SetAttr(kNameSpaceID_None, attrName, value,
-                                      PR_TRUE);
-                }
-                else {
-                    listener->UnsetAttr(kNameSpaceID_None, attrName,
-                                        PR_TRUE);
+                if (delayedAttrChangeBroadcasts[i].mNeedsAttrChange) {
+                    nsCOMPtr<nsIContent> listener =
+                        do_QueryInterface(delayedAttrChangeBroadcasts[i].mListener);
+                    nsString value = delayedAttrChangeBroadcasts[i].mAttr;
+                    if (delayedAttrChangeBroadcasts[i].mSetAttr) {
+                        listener->SetAttr(kNameSpaceID_None, attrName, value,
+                                          PR_TRUE);
+                    } else {
+                        listener->UnsetAttr(kNameSpaceID_None, attrName,
+                                            PR_TRUE);
+                    }
                 }
                 nsCOMPtr<nsIContent> broadcaster =
                     do_QueryInterface(delayedAttrChangeBroadcasts[i].mBroadcaster);
                 ExecuteOnBroadcastHandlerFor(broadcaster,
                                              delayedAttrChangeBroadcasts[i].mListener,
                                              attrName);
             }
         }
--- a/content/xul/document/src/nsXULDocument.h
+++ b/content/xul/document/src/nsXULDocument.h
@@ -700,38 +700,41 @@ protected:
 
     class nsDelayedBroadcastUpdate
     {
     public:
       nsDelayedBroadcastUpdate(nsIDOMElement* aBroadcaster,
                                nsIDOMElement* aListener,
                                const nsAString &aAttr)
       : mBroadcaster(aBroadcaster), mListener(aListener), mAttr(aAttr),
-        mSetAttr(PR_FALSE) {}
+        mSetAttr(PR_FALSE), mNeedsAttrChange(PR_FALSE) {}
 
       nsDelayedBroadcastUpdate(nsIDOMElement* aBroadcaster,
                                nsIDOMElement* aListener,
                                nsIAtom* aAttrName,
                                const nsAString &aAttr,
-                               PRBool aSetAttr)
+                               PRBool aSetAttr,
+                               PRBool aNeedsAttrChange)
       : mBroadcaster(aBroadcaster), mListener(aListener), mAttr(aAttr),
-        mAttrName(aAttrName), mSetAttr(aSetAttr) {}
+        mAttrName(aAttrName), mSetAttr(aSetAttr),
+        mNeedsAttrChange(aNeedsAttrChange) {}
 
       nsDelayedBroadcastUpdate(const nsDelayedBroadcastUpdate& aOther)
       : mBroadcaster(aOther.mBroadcaster), mListener(aOther.mListener),
         mAttr(aOther.mAttr), mAttrName(aOther.mAttrName),
-        mSetAttr(aOther.mSetAttr) {}
+        mSetAttr(aOther.mSetAttr), mNeedsAttrChange(aOther.mNeedsAttrChange) {}
 
       nsCOMPtr<nsIDOMElement> mBroadcaster;
       nsCOMPtr<nsIDOMElement> mListener;
       // Note if mAttrName isn't used, this is the name of the attr, otherwise
       // this is the value of the attribute.
       nsString                mAttr;
       nsCOMPtr<nsIAtom>       mAttrName;
-      PRBool                  mSetAttr;
+      PRPackedBool            mSetAttr;
+      PRPackedBool            mNeedsAttrChange;
     };
 
     nsTArray<nsDelayedBroadcastUpdate> mDelayedBroadcasters;
     nsTArray<nsDelayedBroadcastUpdate> mDelayedAttrChangeBroadcasts;
 private:
     // helpers
 
 };
--- a/content/xul/document/test/Makefile.in
+++ b/content/xul/document/test/Makefile.in
@@ -48,12 +48,13 @@ include $(topsrcdir)/config/rules.mk
 		test_bug311681.xul \
 		test_bug199692.xul \
 		test_bug391002.xul \
 		test_bug403868.xul \
 		test_bug414907.xul \
 		test_bug418216.xul \
 		test_bug445177.xul \
 		test_bug449457.xul \
+		test_bug468176.xul \
 		$(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/content/xul/document/test/test_bug468176.xul
@@ -0,0 +1,85 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="/tests/SimpleTest/test.css" type="text/css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=468176
+-->
+<window title="Test for Bug 468176"
+  id="test_bug468176_xul"
+  xmlns:html="http://www.w3.org/1999/xhtml"
+  xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+  <script type="application/javascript" src="/MochiKit/packed.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+
+<body id="body" xmlns="http://www.w3.org/1999/xhtml">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=468176">Mozilla Bug 468176</a>
+
+<xul:hbox id="b1" value="foo"/>
+
+<xul:hbox id="o1">
+  <xul:observes id="inner" element="b1" attribute="*"/>
+</xul:hbox>
+
+<pre id="test">
+  <script class="testbody" type="text/javascript">
+<![CDATA[
+  SimpleTest.waitForExplicitFinish();
+
+  var broadcastCount = 0;
+  function b_listener(evt) {
+    ++broadcastCount;
+  }
+
+  function do_test() {
+    var b1 = document.getElementById("b1");
+    var o1 = document.getElementById("o1");
+    var inner = document.getElementById("inner");
+    is(o1.getAttribute("value"), b1.getAttribute("value"), "Wrong value (1)");
+
+    inner.addEventListener("broadcast", b_listener, true);
+    b1.setAttribute("value", "bar");
+    is(o1.getAttribute("value"), b1.getAttribute("value"), "Wrong value (2)");
+    is(broadcastCount, 1, "Wrong value (3)");
+
+    b1.removeAttribute("value");
+    is(o1.hasAttribute("value"), b1.hasAttribute("value"), "Wrong value (4)");
+    is(broadcastCount, 2, "Wrong value (5)");
+
+    o1.setAttribute("value", "foo");
+    isnot(o1.getAttribute("value"), b1.getAttribute("value"), "Wrong value (6)");
+    is(broadcastCount, 2, "Wrong value (7)");
+
+    b1.setAttribute("value", "foobar");
+    is(o1.getAttribute("value"), b1.getAttribute("value"), "Wrong value (8)");
+    is(broadcastCount, 3, "Wrong value (9)");
+
+    b1.removeAttribute("value");
+    is(o1.getAttribute("value"), b1.getAttribute("value"), "Wrong value (10)");
+    is(broadcastCount, 4, "Wrong value (11)");
+
+    b1.removeAttribute("value");
+    is(o1.getAttribute("value"), b1.getAttribute("value"), "Wrong value (12)");
+    is(broadcastCount, 4, "Wrong value (13)");
+
+    o1.setAttribute("value", "bar");
+    b1.setAttribute("value", "bar"); // This should still dispatch 'broadcast'
+    is(o1.getAttribute("value"), b1.getAttribute("value"), "Wrong value (14)");
+    is(broadcastCount, 5, "Wrong value (15)");
+
+    //After removing listener, changes to broadcaster shouldn't have any effect.
+    o1.parentNode.removeChild(o1);
+    b1.setAttribute("value", "foo");
+    isnot(o1.getAttribute("value"), b1.getAttribute("value"), "Wrong value (16)");
+    is(broadcastCount, 5, "Wrong value (17)");
+
+    SimpleTest.finish();
+  }
+
+  addLoadEvent(do_test);
+]]>
+  </script>
+</pre>
+</body>
+</window>
--- a/content/xul/templates/src/nsTemplateRule.cpp
+++ b/content/xul/templates/src/nsTemplateRule.cpp
@@ -310,24 +310,16 @@ nsTemplateRule::~nsTemplateRule()
     while (mConditions) {
         nsTemplateCondition* cdel = mConditions;
         mConditions = mConditions->GetNext();
         delete cdel;
     }
 }
 
 nsresult
-nsTemplateRule::GetAction(nsIContent** aAction) const
-{
-    *aAction = mAction;
-    NS_IF_ADDREF(*aAction);
-    return NS_OK;
-}
-
-nsresult
 nsTemplateRule::GetRuleNode(nsIDOMNode** aRuleNode) const
 {
     *aRuleNode = mRuleNode;
     NS_IF_ADDREF(*aRuleNode);
     return NS_OK;
 }
 
 void nsTemplateRule::SetCondition(nsTemplateCondition* aCondition)
--- a/content/xul/templates/src/nsTemplateRule.h
+++ b/content/xul/templates/src/nsTemplateRule.h
@@ -144,21 +144,18 @@ public:
                    nsTemplateQuerySet* aQuerySet);
 
     ~nsTemplateRule();
 
     /**
      * Return the <action> node that this rule was constructed from, or its
      * logical equivalent for shorthand syntaxes. That is, the parent node of
      * the content that should be generated for this rule.
-     * @param aAction an out parameter, which will contain the content node
-     *   that this rule uses to generated content
-     * @return NS_OK if no errors occur.
      */
-    nsresult GetAction(nsIContent** aAction) const;
+    nsIContent* GetAction() const { return mAction; }
 
     /**
      * Return the <rule> content node that this rule was constructed from.
      * @param aResult an out parameter, which will contain the rule node
      * @return NS_OK if no errors occur.
      */
     nsresult GetRuleNode(nsIDOMNode** aResult) const;
 
--- a/content/xul/templates/src/nsXULContentBuilder.cpp
+++ b/content/xul/templates/src/nsXULContentBuilder.cpp
@@ -1228,19 +1228,17 @@ nsXULContentBuilder::CreateContainerCont
                 rv = newmatch->RuleMatched(aQuerySet, matchedrule,
                                            ruleindex, nextresult);
                 if (NS_FAILED(rv)) {
                     nsTemplateMatch::Destroy(mPool, newmatch, PR_FALSE);
                     return rv;
                 }
 
                 // Grab the template node
-                nsCOMPtr<nsIContent> action;
-                matchedrule->GetAction(getter_AddRefs(action));
-
+                nsCOMPtr<nsIContent> action = matchedrule->GetAction();
                 BuildContentFromTemplate(action, aElement, aElement, PR_TRUE,
                                          mRefVariable == matchedrule->GetMemberVariable(),
                                          nextresult, aNotify, newmatch,
                                          aContainer, aNewIndexInContainer);
             }
         }
 
         if (prevmatch) {
@@ -1702,19 +1700,17 @@ nsXULContentBuilder::ReplaceMatch(nsIXUL
             if (mContentSupportMap.Get(child, &match)) {
                 if (content == match->GetContainer())
                     RemoveMember(child);
             }
         }
     }
 
     if (aNewMatch) {
-        nsCOMPtr<nsIContent> action;
-        aNewMatchRule->GetAction(getter_AddRefs(action));
-
+        nsCOMPtr<nsIContent> action = aNewMatchRule->GetAction();
         return BuildContentFromTemplate(action, content, content, PR_TRUE,
                                         mRefVariable == aNewMatchRule->GetMemberVariable(),
                                         aNewMatch->mResult, PR_TRUE, aNewMatch,
                                         nsnull, nsnull);
     }
 
     return NS_OK;
 }
--- a/content/xul/templates/src/nsXULSortService.cpp
+++ b/content/xul/templates/src/nsXULSortService.cpp
@@ -62,16 +62,17 @@
 #include "nsIDOMNode.h"
 #include "nsIDocument.h"
 #include "nsINameSpaceManager.h"
 #include "nsIServiceManager.h"
 #include "nsGkAtoms.h"
 #include "nsXULContentUtils.h"
 #include "nsString.h"
 #include "nsQuickSort.h"
+#include "nsWhitespaceTokenizer.h"
 #include "nsXULSortService.h"
 #include "nsIDOMXULElement.h"
 #include "nsIXULTemplateBuilder.h"
 #include "nsTemplateMatch.h"
 
 NS_IMPL_ISUPPORTS1(XULSortServiceImpl, nsIXULSortService)
 
 void
@@ -409,36 +410,24 @@ XULSortServiceImpl::InitializeSortState(
       sort.Append(sortResource);
 
       aRootElement->GetAttr(kNameSpaceID_None, nsGkAtoms::sortResource2, sortResource2);
       if (!sortResource2.IsEmpty()) {
         nsCOMPtr<nsIAtom> sortkeyatom2 = do_GetAtom(sortResource2);
         aSortState->sortKeys.AppendObject(sortkeyatom2);
         sort.AppendLiteral(" ");
         sort.Append(sortResource2);
+      }
     }
   }
-    }
-    else {
-    PRInt32 start = 0, end = 0;
-    while ((end = sort.FindChar(' ',start)) >= 0) {
-      if (end > start) {
-        nsCOMPtr<nsIAtom> keyatom = do_GetAtom(Substring(sort, start, end - start));
-        if (!keyatom)
-          return NS_ERROR_OUT_OF_MEMORY;
-
-        aSortState->sortKeys.AppendObject(keyatom);
-      }
-      start = end + 1;
-    }
-    if (start < (PRInt32)sort.Length()) {
-      nsCOMPtr<nsIAtom> keyatom = do_GetAtom(Substring(sort, start));
-      if (!keyatom)
-        return NS_ERROR_OUT_OF_MEMORY;
-
+  else {
+    nsWhitespaceTokenizer tokenizer(sort);
+    while (tokenizer.hasMoreTokens()) {
+      nsCOMPtr<nsIAtom> keyatom = do_GetAtom(tokenizer.nextToken());
+      NS_ENSURE_TRUE(keyatom, NS_ERROR_OUT_OF_MEMORY);
       aSortState->sortKeys.AppendObject(keyatom);
     }
   }
 
   aSortState->sort.Assign(sort);
 
   // set up sort order info
   if (aSortDirection.EqualsLiteral("descending"))
--- a/content/xul/templates/src/nsXULTemplateBuilder.cpp
+++ b/content/xul/templates/src/nsXULTemplateBuilder.cpp
@@ -86,16 +86,17 @@
 #include "nsIURL.h"
 #include "nsIXPConnect.h"
 #include "nsContentCID.h"
 #include "nsRDFCID.h"
 #include "nsXULContentUtils.h"
 #include "nsString.h"
 #include "nsVoidArray.h"
 #include "nsXPIDLString.h"
+#include "nsWhitespaceTokenizer.h"
 #include "nsGkAtoms.h"
 #include "nsXULElement.h"
 #include "jsapi.h"
 #include "prlog.h"
 #include "rdf.h"
 #include "pldhash.h"
 #include "plhash.h"
 #include "nsIDOMClassInfo.h"
@@ -1748,22 +1749,26 @@ nsXULTemplateBuilder::CompileQueries()
 
     // Determine if there are any special settings we need to observe
     mFlags = 0;
 
     nsAutoString flags;
     mRoot->GetAttr(kNameSpaceID_None, nsGkAtoms::flags, flags);
 
     // if the dont-test-empty flag is set, containers should not be checked to
-    // see if they are empty
-    if (flags.Find(NS_LITERAL_STRING("dont-test-empty")) >= 0)
+    // see if they are empty. If dont-recurse is set, then don't process the
+    // template recursively and only show one level of results.
+    nsWhitespaceTokenizer tokenizer(flags);
+    while (tokenizer.hasMoreTokens()) {
+      const nsDependentSubstring& token(tokenizer.nextToken());
+      if (token.EqualsLiteral("dont-test-empty"))
         mFlags |= eDontTestEmpty;
-
-    if (flags.Find(NS_LITERAL_STRING("dont-recurse")) >= 0)
+      else if (token.EqualsLiteral("dont-recurse"))
         mFlags |= eDontRecurse;
+    }
 
     nsCOMPtr<nsIDOMNode> rootnode = do_QueryInterface(mRoot);
     nsresult rv =
         mQueryProcessor->InitializeForBuilding(mDataSource, this, rootnode);
     if (NS_FAILED(rv))
         return rv;
 
     // Set the "container" and "member" variables, if the user has specified
--- a/content/xul/templates/src/nsXULTreeBuilder.cpp
+++ b/content/xul/templates/src/nsXULTreeBuilder.cpp
@@ -1395,30 +1395,26 @@ nsXULTreeBuilder::RebuildAll()
 
 nsresult
 nsXULTreeBuilder::GetTemplateActionRowFor(PRInt32 aRow, nsIContent** aResult)
 {
     // Get the template in the DOM from which we're supposed to
     // generate text
     nsTreeRows::Row& row = *(mRows[aRow]);
 
-    nsCOMPtr<nsIContent> action;
-
     // The match stores the indices of the rule and query to use. Use these
     // to look up the right nsTemplateRule and use that rule's action to get
     // the treerow in the template.
     PRInt16 ruleindex = row.mMatch->RuleIndex();
     if (ruleindex >= 0) {
         nsTemplateQuerySet* qs = mQuerySets[row.mMatch->QuerySetPriority()];
         nsTemplateRule* rule = qs->GetRuleAt(ruleindex);
         if (rule) {
-            rule->GetAction(getter_AddRefs(action));
-
             nsCOMPtr<nsIContent> children;
-            nsXULContentUtils::FindChildByTag(action, kNameSpaceID_XUL,
+            nsXULContentUtils::FindChildByTag(rule->GetAction(), kNameSpaceID_XUL,
                                               nsGkAtoms::treechildren,
                                               getter_AddRefs(children));
             if (children) {
                 nsCOMPtr<nsIContent> item;
                 nsXULContentUtils::FindChildByTag(children, kNameSpaceID_XUL,
                                                   nsGkAtoms::treeitem,
                                                   getter_AddRefs(item));
                 if (item)
--- a/dom/public/idl/events/nsIDOMDragEvent.idl
+++ b/dom/public/idl/events/nsIDOMDragEvent.idl
@@ -36,28 +36,48 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "domstubs.idl"
 #include "nsIDOMMouseEvent.idl"
 
 interface nsIDOMAbstractView;
 interface nsIDOMDataTransfer;
 
-[scriptable, uuid(18FEEFD7-A461-4865-BCF1-4DC8A2F30584)]
+[scriptable, uuid(D52CF140-FB90-44DF-8D69-4B2BAB4D461F)]
 interface nsIDOMDragEvent : nsIDOMMouseEvent
 {
   readonly attribute nsIDOMDataTransfer dataTransfer;
 
   void initDragEvent(in DOMString typeArg,
                      in boolean canBubbleArg,
                      in boolean cancelableArg,
                      in nsIDOMAbstractView aView,
-                     in PRInt32 aDetail,
+                     in long aDetail,
+                     in long aScreenX,
+                     in long aScreenY,
+                     in long aClientX,
+                     in long aClientY,
+                     in boolean aCtrlKey,
+                     in boolean aAltKey,
+                     in boolean aShiftKey,
+                     in boolean aMetaKey,
+                     in unsigned short aButton,
+                     in nsIDOMEventTarget aRelatedTarget,
                      in nsIDOMDataTransfer aDataTransfer);
 
   void initDragEventNS(in DOMString namespaceURIArg,
                        in DOMString typeArg,
                        in boolean canBubbleArg,
                        in boolean cancelableArg,
                        in nsIDOMAbstractView aView,
-                       in PRInt32 aDetail,
+                       in long aDetail,
+                       in long aScreenX,
+                       in long aScreenY,
+                       in long aClientX,
+                       in long aClientY,
+                       in boolean aCtrlKey,
+                       in boolean aAltKey,
+                       in boolean aShiftKey,
+                       in boolean aMetaKey,
+                       in unsigned short aButton,
+                       in nsIDOMEventTarget aRelatedTarget,
                        in nsIDOMDataTransfer aDataTransfer);
 };
--- a/intl/unicharutil/util/nsBidiUtils.cpp
+++ b/intl/unicharutil/util/nsBidiUtils.cpp
@@ -572,17 +572,16 @@ PRUnichar HandleNumberInChar(PRUnichar a
     default:
       return aChar;
   }
 }
 
 nsresult HandleNumbers(PRUnichar* aBuffer, PRUint32 aSize, PRUint32 aNumFlag)
 {
   PRUint32 i;
-  PRUnichar prev = 0;
 
   switch (aNumFlag) {
     case IBMBIDI_NUMERAL_HINDI:
     case IBMBIDI_NUMERAL_ARABIC:
     case IBMBIDI_NUMERAL_REGULAR:
     case IBMBIDI_NUMERAL_HINDICONTEXT:
       for (i=0;i<aSize;i++)
         aBuffer[i] = HandleNumberInChar(aBuffer[i], i>0 ? aBuffer[i-1] : 0, aNumFlag);
--- a/js/src/config/config.mk
+++ b/js/src/config/config.mk
@@ -851,8 +851,13 @@ endif
 #
 
 # Make sure any compiled classes work with at least JVM 1.4
 JAVAC_FLAGS += -source 1.4
 
 ifdef MOZ_DEBUG
 JAVAC_FLAGS += -g
 endif
+
+ifdef TIERS
+DIRS += $(foreach tier,$(TIERS),$(tier_$(tier)_dirs))
+STATIC_DIRS += $(foreach tier,$(TIERS),$(tier_$(tier)_staticdirs))
+endif
--- a/js/src/config/rules.mk
+++ b/js/src/config/rules.mk
@@ -460,32 +460,40 @@ ifdef MOZ_UPDATE_XTERM
 # makes the make -s output easier to read.  Echo -n does not work on all
 # platforms, but we can trick sed into doing it.
 UPDATE_TITLE = sed -e "s!Y!$@ in $(shell $(BUILD_TOOLS)/print-depth-path.sh)/$(dir)!" $(MOZILLA_DIR)/config/xterm.str;
 UPDATE_TITLE_export = sed -e "s!Y!export in $(shell $(BUILD_TOOLS)/print-depth-path.sh)/$*!" $(MOZILLA_DIR)/config/xterm.str;
 UPDATE_TITLE_libs = sed -e "s!Y!libs in $(shell $(BUILD_TOOLS)/print-depth-path.sh)/$*!" $(MOZILLA_DIR)/config/xterm.str;
 UPDATE_TITLE_tools = sed -e "s!Y!tools in $(shell $(BUILD_TOOLS)/print-depth-path.sh)/$*!" $(MOZILLA_DIR)/config/xterm.str;
 endif
 
+ifneq (,$(strip $(DIRS)))
 LOOP_OVER_DIRS = \
     @$(EXIT_ON_ERROR) \
-    $(foreach dir,$(DIRS),$(UPDATE_TITLE) $(MAKE) -C $(dir) $@; ) true
+    $(foreach dir,$(DIRS),$(UPDATE_TITLE) $(MAKE) -C $(dir) $@; )
+endif
 
 # we only use this for the makefiles target and other stuff that doesn't matter
+ifneq (,$(strip $(PARALLEL_DIRS)))
 LOOP_OVER_PARALLEL_DIRS = \
     @$(EXIT_ON_ERROR) \
-    $(foreach dir,$(PARALLEL_DIRS),$(UPDATE_TITLE) $(MAKE) -C $(dir) $@; ) true
+    $(foreach dir,$(PARALLEL_DIRS),$(UPDATE_TITLE) $(MAKE) -C $(dir) $@; )
+endif
 
+ifneq (,$(strip $(STATIC_DIRS)))
 LOOP_OVER_STATIC_DIRS = \
     @$(EXIT_ON_ERROR) \
-    $(foreach dir,$(STATIC_DIRS),$(UPDATE_TITLE) $(MAKE) -C $(dir) $@; ) true
+    $(foreach dir,$(STATIC_DIRS),$(UPDATE_TITLE) $(MAKE) -C $(dir) $@; )
+endif
 
+ifneq (,$(strip $(TOOL_DIRS)))
 LOOP_OVER_TOOL_DIRS = \
     @$(EXIT_ON_ERROR) \
-    $(foreach dir,$(TOOL_DIRS),$(UPDATE_TITLE) $(MAKE) -C $(dir) $@; ) true
+    $(foreach dir,$(TOOL_DIRS),$(UPDATE_TITLE) $(MAKE) -C $(dir) $@; )
+endif
 
 ifdef PARALLEL_DIRS
 # create a bunch of fake targets for order-only processing
 PARALLEL_DIRS_export = $(addsuffix _export,$(PARALLEL_DIRS))
 PARALLEL_DIRS_libs = $(addsuffix _libs,$(PARALLEL_DIRS))
 PARALLEL_DIRS_tools = $(addsuffix _tools,$(PARALLEL_DIRS))
 
 .PHONY: $(PARALLEL_DIRS_export) $(PARALLEL_DIRS_libs) $(PARALLEL_DIRS_tools)
@@ -704,29 +712,26 @@ endif
 SUBMAKEFILES += $(addsuffix /Makefile, $(DIRS) $(TOOL_DIRS) $(PARALLEL_DIRS))
 
 # The root makefile doesn't want to do a plain export/libs, because
 # of the tiers and because of libxul. Suppress the default rules in favor
 # of something else. Makefiles which use this var *must* provide a sensible
 # default rule before including rules.mk
 ifndef SUPPRESS_DEFAULT_RULES
 ifdef TIERS
-
-DIRS += $(foreach tier,$(TIERS),$(tier_$(tier)_dirs))
-STATIC_DIRS += $(foreach tier,$(TIERS),$(tier_$(tier)_staticdirs))
-
 default all alldep::
 	$(EXIT_ON_ERROR) \
 	$(foreach tier,$(TIERS),$(MAKE) tier_$(tier); ) true
 
 else
 
 default all::
-	@$(EXIT_ON_ERROR) \
-	$(foreach dir,$(STATIC_DIRS),$(MAKE) -C $(dir); ) true
+ifneq (,$(strip $(STATIC_DIRS)))
+	$(foreach dir,$(STATIC_DIRS),$(MAKE) -C $(dir); )
+endif
 	$(MAKE) export
 	$(MAKE) libs
 	$(MAKE) tools
 
 # Do depend as well
 alldep:: 
 	$(MAKE) export
 	$(MAKE) depend
@@ -818,19 +823,19 @@ ifdef PARALLEL_DIRS
 tools:: $(PARALLEL_DIRS_tools)
 
 $(PARALLEL_DIRS_tools): %_tools: %/Makefile
 	+@$(UPDATE_TITLE_tools) $(MAKE) -C $* tools
 endif
 
 tools:: $(SUBMAKEFILES) $(MAKE_DIRS)
 	+$(LOOP_OVER_DIRS)
-ifdef TOOL_DIRS
+ifneq (,$(strip $(TOOL_DIRS)))
 	@$(EXIT_ON_ERROR) \
-	$(foreach dir,$(TOOL_DIRS),$(UPDATE_TITLE) $(MAKE) -C $(dir) libs; ) true
+	$(foreach dir,$(TOOL_DIRS),$(UPDATE_TITLE) $(MAKE) -C $(dir) libs; )
 endif
 
 #
 # Rule to create list of libraries for final link
 #
 export::
 ifdef LIBRARY_NAME
 ifdef EXPORT_LIBRARY
@@ -2165,17 +2170,17 @@ FORCE:
 tags: TAGS
 
 TAGS: $(SUBMAKEFILES) $(CSRCS) $(CPPSRCS) $(wildcard *.h)
 	-etags $(CSRCS) $(CPPSRCS) $(wildcard *.h)
 	+$(LOOP_OVER_PARALLEL_DIRS)
 	+$(LOOP_OVER_DIRS)
 
 echo-variable-%:
-	@echo $($*)
+	@echo "$($*)"
 
 echo-tiers:
 	@echo $(TIERS)
 
 echo-tier-dirs:
 	@$(foreach tier,$(TIERS),echo '$(tier):'; echo '  dirs: $(tier_$(tier)_dirs)'; echo '  staticdirs: $(tier_$(tier)_staticdirs)'; )
 
 echo-dirs:
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -2867,16 +2867,24 @@ if test ! "$GNU_CXX"; then
 	;;
      *)
 	AC_CHECK_LIB(C, demangle)
 	;;
      esac
 fi
 AC_CHECK_LIB(socket, socket)
 
+dnl Enable VFP support on ARM
+MOZ_ARG_DISABLE_BOOL(arm-vfp,
+[  --disable-arm-vfp       Disable ARM VFP instructions in JavaScript JIT],
+   MOZ_ARM_VFP=, MOZ_ARM_VFP=1, MOZ_ARM_VFP=1)
+if test "$MOZ_ARM_VFP"; then
+   AC_DEFINE(NJ_ARM_VFP)
+fi
+
 dnl ========================================================
 dnl = pthread support
 dnl = Start by checking whether the system support pthreads
 dnl ========================================================
 case "$target_os" in
 darwin*)
     USE_PTHREADS=1
     ;;
@@ -5032,16 +5040,22 @@ for lib_arg in $NSPR_LIBS $TK_LIBS; do
   case $lib_arg in
     -L* ) LIBS_PATH="${LIBS_PATH:+$LIBS_PATH:}"`expr $lib_arg : "-L\(.*\)"` ;;
       * ) ;;
   esac
 done
 AC_SUBST(LIBS_PATH)
 
 dnl ========================================================
+dnl JavaScript shell
+dnl ========================================================
+
+AC_HAVE_FUNCS(setlocale)
+
+dnl ========================================================
 dnl Use cygwin wrapper for win32 builds, except MSYS/MinGW
 dnl ========================================================
 case "$host_os" in
 mingw*)
     WIN_TOP_SRC=`cd $srcdir; pwd -W`
     ;;
 cygwin*|msvc*|mks*)
     HOST_CC="\$(CYGWIN_WRAPPER) $HOST_CC"
--- a/js/src/js.cpp
+++ b/js/src/js.cpp
@@ -3985,17 +3985,17 @@ main(int argc, char **argv, char **envp)
     JSDJContext *jsdjc;
 #endif
 #ifdef JSDEBUGGER_C_UI
     JSBool jsdbc;
 #endif /* JSDEBUGGER_C_UI */
 #endif /* JSDEBUGGER */
 
     CheckHelpMessages();
-#ifndef WINCE
+#ifdef HAVE_SETLOCALE
     setlocale(LC_ALL, "");
 #endif
     gStackBase = (jsuword)&stackDummy;
 
 #ifdef XP_OS2
    /* these streams are normally line buffered on OS/2 and need a \n, *
     * so we need to unbuffer then to get a reasonable prompt          */
     setbuf(stdout,0);
--- a/js/src/nanojit/NativeARM.h
+++ b/js/src/nanojit/NativeARM.h
@@ -56,17 +56,19 @@
 namespace nanojit
 {
 
 const int NJ_LOG2_PAGE_SIZE = 12;       // 4K
 
 // If NJ_ARM_VFP is defined, then VFP is assumed to
 // be present.  If it's not defined, then softfloat
 // is used, and NJ_SOFTFLOAT is defined.
-#define NJ_ARM_VFP
+// When nanojit is used as part of Mozilla's JavaScript engine, this is
+// #defined or left #undefined by js/src/configure.in.
+//#define NJ_ARM_VFP
 
 #ifdef NJ_ARM_VFP
 
 // only d0-d7; we'll use d7 as s14-s15 for i2f/u2f/etc.
 #define NJ_VFP_MAX_REGISTERS            8
 
 #else
 
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -97,20 +97,20 @@ template<class E> class nsCOMArray;
 class nsWeakFrame;
 class nsIScrollableFrame;
 class gfxASurface;
 class gfxContext;
 
 typedef short SelectionType;
 typedef PRUint32 nsFrameState;
 
-// 5c103bc2-788e-4bbe-b82e-635bea34e78f
+// 23439d06-4642-4c4e-b60b-d84ad9bd8897
 #define NS_IPRESSHELL_IID \
-{ 0x5c103bc2, 0x788e, 0x4bbe, \
-  { 0xb8, 0x2e, 0x63, 0x5b, 0xea, 0x34, 0xe7, 0x8f } }
+  { 0x23439d06, 0x4642, 0x4c4e, \
+    { 0xb6, 0x0b, 0xd8, 0x4a, 0xd9, 0xbd, 0x88, 0x97 } }
 
 // Constants for ScrollContentIntoView() function
 #define NS_PRESSHELL_SCROLL_TOP      0
 #define NS_PRESSHELL_SCROLL_BOTTOM   100
 #define NS_PRESSHELL_SCROLL_LEFT     0
 #define NS_PRESSHELL_SCROLL_RIGHT    100
 #define NS_PRESSHELL_SCROLL_CENTER   50
 #define NS_PRESSHELL_SCROLL_ANYWHERE -1
@@ -711,29 +711,36 @@ public:
    * Render the document into an arbitrary gfxContext
    * Designed for getting a picture of a document or a piece of a document
    * Note that callers will generally want to call FlushPendingNotifications
    * to get an up-to-date view of the document
    * @param aRect is the region to capture into the offscreen buffer, in the
    * root frame's coordinate system (if aIgnoreViewportScrolling is false)
    * or in the root scrolled frame's coordinate system
    * (if aIgnoreViewportScrolling is true). The coordinates are in appunits.
-   * @param aUntrusted set to PR_TRUE if the contents may be passed to malicious
+   * @param aFlags see below;
+   *   set RENDER_IS_UNTRUSTED if the contents may be passed to malicious
    * agents. E.g. we might choose not to paint the contents of sensitive widgets
    * such as the file name in a file upload widget, and we might choose not
    * to paint themes.
-   * @param aIgnoreViewportScrolling ignore clipping/scrolling/scrollbar painting
-   * due to scrolling in the viewport
+   *   set RENDER_IGNORE_VIEWPORT_SCROLLING to ignore
+   * clipping/scrolling/scrollbar painting due to scrolling in the viewport
+   *   set RENDER_CARET to draw the caret if one would be visible
+   * (by default the caret is never drawn)
    * @param aBackgroundColor a background color to render onto
    * @param aRenderedContext the gfxContext to render to. We render so that
    * one CSS pixel in the source document is rendered to one unit in the current
    * transform.
    */
-  NS_IMETHOD RenderDocument(const nsRect& aRect, PRBool aUntrusted,
-                            PRBool aIgnoreViewportScrolling,
+  enum {
+    RENDER_IS_UNTRUSTED = 0x01,
+    RENDER_IGNORE_VIEWPORT_SCROLLING = 0x02,
+    RENDER_CARET = 0x04
+  };
+  NS_IMETHOD RenderDocument(const nsRect& aRect, PRUint32 aFlags,
                             nscolor aBackgroundColor,
                             gfxContext* aRenderedContext) = 0;
 
   /**
    * Renders a node aNode to a surface and returns it. The aRegion may be used
    * to clip the rendering. This region is measured in device pixels from the
    * edge of the presshell area. The aPoint, aScreenRect and aSurface
    * arguments function in a similar manner as RenderSelection.
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -874,18 +874,17 @@ public:
   NS_IMETHOD IsReflowLocked(PRBool* aIsLocked);  
 
   virtual nsresult ReconstructFrames(void);
   virtual void Freeze();
   virtual void Thaw();
 
   virtual nsIFrame* GetFrameForPoint(nsIFrame* aFrame, nsPoint aPt);
 
-  NS_IMETHOD RenderDocument(const nsRect& aRect, PRBool aUntrusted,
-                            PRBool aIgnoreViewportScrolling,
+  NS_IMETHOD RenderDocument(const nsRect& aRect, PRUint32 aFlags,
                             nscolor aBackgroundColor,
                             gfxContext* aThebesContext);
 
   virtual already_AddRefed<gfxASurface> RenderNode(nsIDOMNode* aNode,
                                                    nsIRegion* aRegion,
                                                    nsPoint& aPoint,
                                                    nsRect* aScreenRect);
 
@@ -4930,22 +4929,21 @@ PresShell::ComputeRepaintRegionForCopy(n
 {
   return nsLayoutUtils::ComputeRepaintRegionForCopy(
       static_cast<nsIFrame*>(aRootView->GetClientData()),
       static_cast<nsIFrame*>(aMovingView->GetClientData()),
       aDelta, aCopyRect, aRepaintRegion);
 }
 
 NS_IMETHODIMP
-PresShell::RenderDocument(const nsRect& aRect, PRBool aUntrusted,
-                          PRBool aIgnoreViewportScrolling,
+PresShell::RenderDocument(const nsRect& aRect, PRUint32 aFlags,
                           nscolor aBackgroundColor,
                           gfxContext* aThebesContext)
 {
-  NS_ENSURE_TRUE(!aUntrusted, NS_ERROR_NOT_IMPLEMENTED);
+  NS_ENSURE_TRUE(!(aFlags & RENDER_IS_UNTRUSTED), NS_ERROR_NOT_IMPLEMENTED);
 
   gfxRect r(0, 0,
             nsPresContext::AppUnitsToFloatCSSPixels(aRect.width),
             nsPresContext::AppUnitsToFloatCSSPixels(aRect.height));
   aThebesContext->Save();
 
   aThebesContext->NewPath();
 #ifdef MOZ_GFX_OPTIMIZE_MOBILE
@@ -4981,22 +4979,23 @@ PresShell::RenderDocument(const nsRect& 
   // we want the window to be composited as a single image using
   // whatever operator was set; set OPERATOR_OVER here, which is
   // either already the case, or overrides the operator in a group.
   // the original operator will be present when we PopGroup.
   aThebesContext->SetOperator(gfxContext::OPERATOR_OVER);
 
   nsIFrame* rootFrame = FrameManager()->GetRootFrame();
   if (rootFrame) {
-    nsDisplayListBuilder builder(rootFrame, PR_FALSE, PR_FALSE);
+    nsDisplayListBuilder builder(rootFrame, PR_FALSE,
+        (aFlags & RENDER_CARET) != 0);
     nsDisplayList list;
 
     nsRect rect(aRect);
     nsIFrame* rootScrollFrame = GetRootScrollFrame();
-    if (aIgnoreViewportScrolling && rootScrollFrame) {
+    if ((aFlags & RENDER_IGNORE_VIEWPORT_SCROLLING) && rootScrollFrame) {
       nsPoint pos = GetRootScrollFrameAsScrollable()->GetScrollPosition();
       rect.MoveBy(-pos);
       builder.SetIgnoreScrollFrame(rootScrollFrame);
     }
 
     builder.SetBackgroundOnly(PR_FALSE);
     builder.EnterPresShell(rootFrame, rect);
 
@@ -7113,18 +7112,17 @@ DumpToPNG(nsIPresShell* shell, nsAString
     gfxPlatform::GetPlatform()->
     CreateOffscreenSurface(gfxIntSize(width, height),
       gfxASurface::ImageFormatARGB32);
   NS_ENSURE_TRUE(surface, NS_ERROR_OUT_OF_MEMORY);
 
   nsRefPtr<gfxContext> context = new gfxContext(surface);
   NS_ENSURE_TRUE(context, NS_ERROR_OUT_OF_MEMORY);
 
-  nsresult rv = shell->RenderDocument(r, PR_FALSE, PR_FALSE,
-                                      NS_RGB(255, 255, 0), context);
+  nsresult rv = shell->RenderDocument(r, 0, NS_RGB(255, 255, 0), context);
   NS_ENSURE_SUCCESS(rv, rv);
 
   imgContext->DrawSurface(surface, gfxSize(width, height));
 
   nsCOMPtr<imgIEncoder> encoder = do_CreateInstance("@mozilla.org/image/encoder;2?type=image/png");
   NS_ENSURE_TRUE(encoder, NS_ERROR_FAILURE);
   encoder->InitFromData(imgSurface->Data(), imgSurface->Stride() * height,
                         width, height, imgSurface->Stride(),
--- a/layout/generic/nsTextFrameThebes.cpp
+++ b/layout/generic/nsTextFrameThebes.cpp
@@ -604,20 +604,20 @@ IsAllWhitespace(const nsTextFragment* aF
  */
 class BuildTextRunsScanner {
 public:
   BuildTextRunsScanner(nsPresContext* aPresContext, gfxContext* aContext,
       nsIFrame* aLineContainer) :
     mCurrentFramesAllSameTextRun(nsnull),
     mContext(aContext),
     mLineContainer(aLineContainer),
-    mBidiEnabled(aPresContext->BidiEnabled()),    
+    mBidiEnabled(aPresContext->BidiEnabled()),
+    mSkipIncompleteTextRuns(PR_FALSE),
     mNextRunContextInfo(nsTextFrameUtils::INCOMING_NONE),
-    mCurrentRunContextInfo(nsTextFrameUtils::INCOMING_NONE),
-    mSkipIncompleteTextRuns(PR_FALSE) {
+    mCurrentRunContextInfo(nsTextFrameUtils::INCOMING_NONE) {
     ResetRunInfo();
   }
 
   void SetAtStartOfLine() {
     mStartOfLine = PR_TRUE;
     mCanStopOnThisLine = PR_FALSE;
   }
   void SetSkipIncompleteTextRuns(PRBool aSkip) {
--- a/layout/xul/base/src/nsMenuPopupFrame.cpp
+++ b/layout/xul/base/src/nsMenuPopupFrame.cpp
@@ -80,18 +80,16 @@
 #include "nsIBoxLayout.h"
 #include "nsIPopupBoxObject.h"
 #include "nsIReflowCallback.h"
 #include "nsBindingManager.h"
 #include "nsIDocShellTreeOwner.h"
 #include "nsIBaseWindow.h"
 #include "nsISound.h"
 
-const PRInt32 kMaxZ = 0x7fffffff; //XXX: Shouldn't there be a define somewhere for MaxInt for PRInt32
-
 PRInt8 nsMenuPopupFrame::sDefaultLevelParent = -1;
 
 // NS_NewMenuPopupFrame
 //
 // Wrapper for creating a new menu popup container
 //
 nsIFrame*
 NS_NewMenuPopupFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
@@ -730,208 +728,156 @@ nsMenuPopupFrame::GetRootViewForPopup(ns
       return view;
     }
     view = temp;
   }
 
   return nsnull;
 }
 
-//
-// AdjustPositionForAnchorAlign
-// 
-// Uses the anchor and alignment to move the popup around and anchor it to its
-// parent. |outFlushWithTopBottom| will be TRUE if the popup is flush with
-// either the top or bottom edge of its parent, and FALSE if it is flush with
-// the left or right edge of the parent.
-// 
-void
-nsMenuPopupFrame::AdjustPositionForAnchorAlign(PRInt32* ioXPos, PRInt32* ioYPos, const nsSize & inParentSize,
-                                               PRBool* outFlushWithTopBottom)
+nsPoint
+nsMenuPopupFrame::AdjustPositionForAnchorAlign(const nsRect& anchorRect,
+                                               PRBool& aHFlip, PRBool& aVFlip)
 {
+  // flip the anchor and alignment for right-to-left
   PRInt8 popupAnchor(mPopupAnchor);
   PRInt8 popupAlign(mPopupAlignment);
-
   if (GetStyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL) {
     popupAnchor = -popupAnchor;
     popupAlign = -popupAlign;
   }
 
-  // Adjust position for margins at the aligned corner
+  // first, determine at which corner of the anchor the popup should appear
+  nsPoint pnt;
+  switch (popupAnchor) {
+    case POPUPALIGNMENT_TOPLEFT:
+      pnt = anchorRect.TopLeft();
+      break;
+    case POPUPALIGNMENT_TOPRIGHT:
+      pnt = anchorRect.TopRight();
+      break;
+    case POPUPALIGNMENT_BOTTOMLEFT:
+      pnt = anchorRect.BottomLeft();
+      break;
+    case POPUPALIGNMENT_BOTTOMRIGHT:
+      pnt = anchorRect.BottomRight();
+      break;
+  }
+
+  // If the alignment is on the right edge of the popup, move the popup left
+  // by the width. Similarly, if the alignment is on the bottom edge of the
+  // popup, move the popup up by the height. In addition, account for the
+  // margins of the popup on the edge on which it is aligned.
   nsMargin margin;
   GetStyleMargin()->GetMargin(margin);
-  if (popupAlign == POPUPALIGNMENT_TOPLEFT) {
-    *ioXPos += margin.left;
-    *ioYPos += margin.top;
-  } else if (popupAlign == POPUPALIGNMENT_TOPRIGHT) {
-    *ioXPos += margin.right;
-    *ioYPos += margin.top;
-  } else if (popupAlign == POPUPALIGNMENT_BOTTOMLEFT) {
-    *ioXPos += margin.left;
-    *ioYPos += margin.bottom;
-  } else if (popupAlign == POPUPALIGNMENT_BOTTOMRIGHT) {
-    *ioXPos += margin.right;
-    *ioYPos += margin.bottom;
-  }
-  
-  if (popupAnchor == POPUPALIGNMENT_TOPRIGHT && popupAlign == POPUPALIGNMENT_TOPLEFT) {
-    *ioXPos += inParentSize.width;
-  }
-  else if (popupAnchor == POPUPALIGNMENT_TOPLEFT && popupAlign == POPUPALIGNMENT_TOPLEFT) {
-    *outFlushWithTopBottom = PR_TRUE;
-  }
-  else if (popupAnchor == POPUPALIGNMENT_TOPRIGHT && popupAlign == POPUPALIGNMENT_BOTTOMRIGHT) {
-    *ioXPos -= (mRect.width - inParentSize.width);
-    *ioYPos -= mRect.height;
-    *outFlushWithTopBottom = PR_TRUE;
-  }
-  else if (popupAnchor == POPUPALIGNMENT_BOTTOMRIGHT && popupAlign == POPUPALIGNMENT_BOTTOMLEFT) {
-    *ioXPos += inParentSize.width;
-    *ioYPos -= (mRect.height - inParentSize.height);
-  }
-  else if (popupAnchor == POPUPALIGNMENT_BOTTOMRIGHT && popupAlign == POPUPALIGNMENT_TOPRIGHT) {
-    *ioXPos -= (mRect.width - inParentSize.width);
-    *ioYPos += inParentSize.height;
-    *outFlushWithTopBottom = PR_TRUE;
-  }
-  else if (popupAnchor == POPUPALIGNMENT_TOPLEFT && popupAlign == POPUPALIGNMENT_TOPRIGHT) {
-    *ioXPos -= mRect.width;
-  }
-  else if (popupAnchor == POPUPALIGNMENT_TOPLEFT && popupAlign == POPUPALIGNMENT_BOTTOMLEFT) {
-    *ioYPos -= mRect.height;
-    *outFlushWithTopBottom = PR_TRUE;
-  }
-  else if (popupAnchor == POPUPALIGNMENT_BOTTOMLEFT && popupAlign == POPUPALIGNMENT_BOTTOMRIGHT) {
-    *ioXPos -= mRect.width;
-    *ioYPos -= (mRect.height - inParentSize.height);
-  }
-  else if (popupAnchor == POPUPALIGNMENT_BOTTOMLEFT && popupAlign == POPUPALIGNMENT_TOPLEFT) {
-    *ioYPos += inParentSize.height;
-    *outFlushWithTopBottom = PR_TRUE;
-  }
-  else
-    NS_WARNING ( "Hmmm, looks like you've hit a anchor/align case we weren't setup for." );
-
-} // AdjustPositionForAnchorAlign
-
-
-//
-// IsMoreRoomOnOtherSideOfParent
-//
-// Determine if there is more room on the screen for the popup to live if it was positioned
-// on the flip side of the parent from the side it is flush against (ie, if it's top edge was
-// flush against the bottom, is there more room if its bottom edge were flush against the top)
-//
-PRBool
-nsMenuPopupFrame::IsMoreRoomOnOtherSideOfParent ( PRBool inFlushAboveBelow, PRInt32 inScreenViewLocX, PRInt32 inScreenViewLocY,
-                                                     const nsRect & inScreenParentFrameRect, PRInt32 inScreenTopTwips, PRInt32 inScreenLeftTwips,
-                                                     PRInt32 inScreenBottomTwips, PRInt32 inScreenRightTwips )
-{
-  PRBool switchSides = PR_FALSE;
-  if ( inFlushAboveBelow ) {
-    PRInt32 availAbove = inScreenParentFrameRect.y - inScreenTopTwips;
-    PRInt32 availBelow = inScreenBottomTwips - (inScreenParentFrameRect.y + inScreenParentFrameRect.height) ;
-    if ( inScreenViewLocY > inScreenParentFrameRect.y )       // view is now below parent
-      switchSides = availAbove > availBelow;
-    else
-      switchSides = availBelow > availAbove;
-  }
-  else {
-    PRInt32 availLeft = inScreenParentFrameRect.x - inScreenLeftTwips;
-    PRInt32 availRight = inScreenRightTwips - (inScreenParentFrameRect.x + inScreenParentFrameRect.width) ;
-    if ( inScreenViewLocX > inScreenParentFrameRect.x )       // view is now to the right of parent
-      switchSides = availLeft > availRight;
-    else
-      switchSides = availRight > availLeft;           
+  switch (popupAlign) {
+    case POPUPALIGNMENT_TOPLEFT:
+      pnt.MoveBy(margin.left, margin.top);
+      break;
+    case POPUPALIGNMENT_TOPRIGHT:
+      pnt.MoveBy(-mRect.width - margin.right, margin.top);
+      break;
+    case POPUPALIGNMENT_BOTTOMLEFT:
+      pnt.MoveBy(margin.left, -mRect.height - margin.bottom);
+      break;
+    case POPUPALIGNMENT_BOTTOMRIGHT:
+      pnt.MoveBy(-mRect.width - margin.right, -mRect.height - margin.bottom);
+      break;
   }
 
-  return switchSides;
-  
-} // IsMoreRoomOnOtherSideOfParent
+  // Flipping horizontally is allowed as long as the popup is above or below
+  // the anchor. This will happen if both the anchor and alignment are top or
+  // both are bottom, but different values. Similarly, flipping vertically is
+  // allowed if the popup is to the left or right of the anchor. In this case,
+  // the values of the constants are such that both must be positive or both
+  // must be negative. A special case, used for overlap, allows flipping
+  // vertically as well.
+  aHFlip = (popupAnchor == -popupAlign);
+  aVFlip = ((popupAnchor > 0) == (popupAlign > 0)) ||
+            (popupAnchor == POPUPALIGNMENT_TOPLEFT && popupAlign == POPUPALIGNMENT_TOPLEFT);
 
+  return pnt;
+}
 
-//
-// MovePopupToOtherSideOfParent
-//
-// Move the popup to the other side of the parent (ie, if it the popup's top edge is flush against the
-// bottom of its parent, move the popup so that its bottom edge is now flush against the top of its
-// parent...same idea for left/right).
-//
-// NOTE: In moving the popup, it may need to change size in order to stay on the screen. This will
-//       have the side effect of touching |mRect|.
-//
-void
-nsMenuPopupFrame::MovePopupToOtherSideOfParent ( PRBool inFlushAboveBelow, PRInt32* ioXPos, PRInt32* ioYPos, 
-                                                 PRInt32* ioScreenViewLocX, PRInt32* ioScreenViewLocY,
-                                                 const nsRect & inScreenParentFrameRect, PRInt32 inScreenTopTwips, PRInt32 inScreenLeftTwips,
-                                                 PRInt32 inScreenBottomTwips, PRInt32 inScreenRightTwips )
+nscoord
+nsMenuPopupFrame::FlipOrResize(nscoord& aScreenPoint, nscoord aSize, 
+                               nscoord aScreenBegin, nscoord aScreenEnd,
+                               nscoord aAnchorBegin, nscoord aAnchorEnd,
+                               nscoord aMarginBegin, nscoord aMarginEnd,
+                               nscoord aOffsetForContextMenu, PRBool aFlip)
 {
-  if ( inFlushAboveBelow ) {
-    if ( *ioScreenViewLocY > inScreenParentFrameRect.y ) {     // view is currently below parent
-      // move it above.
-      PRInt32 shiftDistY = inScreenParentFrameRect.height + mRect.height;
-      *ioYPos -= shiftDistY;
-      *ioScreenViewLocY -= shiftDistY;
-      // trim it to fit.
-      if ( *ioScreenViewLocY < inScreenTopTwips ) {
-        PRInt32 trimY = inScreenTopTwips - *ioScreenViewLocY;
-        *ioYPos += trimY;
-        *ioScreenViewLocY += trimY;
-        mRect.height -= trimY;
+  // all of the coordinates used here are in app units relative to the screen
+
+  nscoord popupSize = aSize;
+  if (aScreenPoint < aScreenBegin) {
+    // at its current position, the popup would extend past the left or top
+    // edge of the screen, so it will have to be moved or resized.
+    if (aFlip) {
+      // check whether there is more room to the left and right (or top and
+      // bottom) of the anchor and put the popup on the side with more room.
+      if (aAnchorBegin - aScreenBegin >= aScreenEnd - aAnchorEnd) {
+        aScreenPoint = aScreenBegin;
+        popupSize = aAnchorBegin - aScreenPoint - aMarginEnd;
+      }
+      else {
+        // flip such that the popup is to the right or bottom of the anchor
+        // point instead. However, when flipping use the same margin size.
+        aScreenPoint = aAnchorEnd + aMarginEnd;
+        // check if the new position is still off the right or bottom edge of
+        // the screen. If so, resize the popup.
+        if (aScreenPoint + aSize > aScreenEnd)
+          popupSize = aScreenEnd - aScreenPoint;
       }
     }
-    else {                                               // view is currently above parent
-      // move it below
-      PRInt32 shiftDistY = inScreenParentFrameRect.height + mRect.height;
-      *ioYPos += shiftDistY;
-      *ioScreenViewLocY += shiftDistY;
+    else {
+      aScreenPoint = aScreenBegin;
     }
   }
-  else {
-    if ( *ioScreenViewLocX > inScreenParentFrameRect.x ) {     // view is currently to the right of the parent
-      // move it to the left.
-      PRInt32 shiftDistX = inScreenParentFrameRect.width + mRect.width;
-      *ioXPos -= shiftDistX;
-      *ioScreenViewLocX -= shiftDistX;
-      // trim it to fit.
-      if ( *ioScreenViewLocX < inScreenLeftTwips ) {
-        PRInt32 trimX = inScreenLeftTwips - *ioScreenViewLocX;
-        *ioXPos += trimX;
-        *ioScreenViewLocX += trimX;
-        mRect.width -= trimX;
+  else if (aScreenPoint + aSize > aScreenEnd) {
+    // at its current position, the popup would extend past the right or
+    // bottom edge of the screen, so it will have to be moved or resized.
+    if (aFlip) {
+      // check whether there is more room to the left and right (or top and
+      // bottom) of the anchor and put the popup on the side with more room.
+      if (aScreenEnd - aAnchorEnd >= aAnchorBegin - aScreenBegin) {
+        popupSize = aScreenEnd - aScreenPoint;
+      }
+      else {
+        // flip such that the popup is to the left or top of the anchor point
+        // instead.
+        aScreenPoint = aAnchorBegin - aSize - aMarginBegin - aOffsetForContextMenu;
+        // check if the new position is still off the left or top edge of the
+        // screen. If so, resize the popup.
+        if (aScreenPoint < aScreenBegin) {
+          aScreenPoint = aScreenBegin;
+          popupSize = aAnchorBegin - aScreenPoint - aMarginBegin - aOffsetForContextMenu;
+        }
       }
     }
-    else {                                               // view is currently to the right of the parent
-      // move it to the right
-      PRInt32 shiftDistX = inScreenParentFrameRect.width + mRect.width;
-      *ioXPos += shiftDistX;
-      *ioScreenViewLocX += shiftDistX;
-    }               
+    else {
+      aScreenPoint = aScreenEnd - aSize;
+    }
   }
 
-} // MovePopupToOtherSideOfParent
+  return popupSize;
+}
 
-// XXXndeakin this function will be reworked in bug 384062 such that positioning
-// of the popup is done only when the popup is first opened, so that the popup doesn't
-// move around when it is changed in some way.
 nsresult
 nsMenuPopupFrame::SetPopupPosition(nsIFrame* aAnchorFrame)
 {
   if (!mShouldAutoPosition && !mInContentShell) 
     return NS_OK;
 
-  PRBool sizedToPopup = PR_FALSE;
-
   nsPresContext* presContext = PresContext();
   nsIFrame* rootFrame = presContext->PresShell()->FrameManager()->GetRootFrame();
   NS_ASSERTION(rootFrame->GetView() && GetView() &&
                rootFrame->GetView() == GetView()->GetParent(),
                "rootFrame's view is not our view's parent???");
 
-  // if the frame is not specified, use the anchor node passed to ShowPopup. If
+  // if the frame is not specified, use the anchor node passed to OpenPopup. If
   // that wasn't specified either, use the root frame. Note that mAnchorContent
   // might be a different document so its presshell must be used.
   if (!aAnchorFrame) {
     if (mAnchorContent) {
       nsCOMPtr<nsIDocument> document = mAnchorContent->GetDocument();
       if (document) {
         nsIPresShell *shell = document->GetPrimaryShell();
         if (!shell)
@@ -943,23 +889,23 @@ nsMenuPopupFrame::SetPopupPosition(nsIFr
 
     if (!aAnchorFrame) {
       aAnchorFrame = rootFrame;
       if (!aAnchorFrame)
         return NS_OK;
     }
   }
 
+  PRBool sizedToPopup = PR_FALSE;
   if (aAnchorFrame->GetContent()) {
     // the popup should be the same size as the anchor menu, for example, a menulist.
     sizedToPopup = nsMenuFrame::IsSizedToPopup(aAnchorFrame->GetContent(), PR_FALSE);
   }
 
-  // |ParentSize|
-  //   The dimensions of the anchor in its app units
+  // the dimensions of the anchor in its app units
   nsSize parentSize = aAnchorFrame->GetSize();
 
   // the anchor may be in a different document with a different scale,
   // so adjust the size so that it is in the app units of the popup instead
   // of the anchor. This is done by converting to device pixels by dividing
   // by the anchor's app units per device pixel and then converting back to
   // app units by multiplying by the popup's app units per device pixel.
   float adj = float(presContext->AppUnitsPerDevPixel()) /
@@ -968,326 +914,165 @@ nsMenuPopupFrame::SetPopupPosition(nsIFr
   parentSize.height = NSToCoordCeil(parentSize.height * adj);
 
   // Set the popup's size to the preferred size. Below, this size will be
   // adjusted to fit on the screen or within the content area. If the anchor
   // is sized to the popup, use the anchor's width instead of the preferred
   // width. The preferred size should already be set by the parent frame.
   NS_ASSERTION(mPrefSize.width >= 0 || mPrefSize.height >= 0,
                "preferred size of popup not set");
-  if (sizedToPopup) {
-    mRect.width = parentSize.width;
-  }
-  else {
-    mRect.width = mPrefSize.width;
-  }
+  mRect.width = sizedToPopup ? parentSize.width : mPrefSize.width;
   mRect.height = mPrefSize.height;
 
-  // |xpos| and |ypos| hold the x and y positions of where the popup will be moved to,
-  // in app units, in the coordinate system of the _parent view_.
-  PRBool readjustAboveBelow = PR_FALSE;
-  PRInt32 xpos = 0, ypos = 0;
-  nsMargin margin;
+  // the screen position in app units where the popup should appear
+  nsPoint screenPoint;
+
+  // For anchored popups, the anchor rectangle. For non-anchored popups, the
+  // size will be 0.
+  nsRect anchorRect;
 
-  // the positon in app units where the popup should appear.
-  PRInt32 screenViewLocX, screenViewLocY;
+  // indicators of whether the popup should be flipped or resized.
+  PRBool hFlip = PR_FALSE, vFlip = PR_FALSE;
+  
+  nsMargin margin;
+  GetStyleMargin()->GetMargin(margin);
 
-  // the screen rectangle of the anchor, or if null, the root frame, in dev pixels.
-  nsRect anchorScreenRect;
+  // the screen rectangle of the root frame, in dev pixels.
   nsRect rootScreenRect = rootFrame->GetScreenRectInAppUnits();
 
-  nsIDeviceContext* devContext = PresContext()->DeviceContext();
+  nsIDeviceContext* devContext = presContext->DeviceContext();
   nscoord offsetForContextMenu = 0;
+  // if mScreenXPos and mScreenYPos are -1, then we are anchored. If they
+  // have other values, then the popup appears unanchored at that screen
+  // coordinate.
   if (mScreenXPos == -1 && mScreenYPos == -1) {
-    // if we are anchored to our parent, there are certain things we don't want to do
-    // when repositioning the view to fit on the screen, such as end up positioned over
-    // the parent. When doing this reposition, we want to move the popup to the side with
-    // the most room. The combination of anchor and alignment dictate if we readjust 
-    // above/below or to the left/right.
+    // if we are anchored, there are certain things we don't want to do when
+    // repositioning the popup to fit on the screen, such as end up positioned
+    // over the anchor, for instance a popup appearing over the menu label.
+    // When doing this reposition, we want to move the popup to the side with
+    // the most room. The combination of anchor and alignment dictate if we 
+    // readjust above/below or to the left/right.
     if (mAnchorContent) {
-      anchorScreenRect = aAnchorFrame->GetScreenRectInAppUnits();
-      // adjust for differences in the anchor frame's scaling
-      anchorScreenRect.ScaleRoundOut(adj);
-      xpos = anchorScreenRect.x - rootScreenRect.x;
-      ypos = anchorScreenRect.y - rootScreenRect.y;
+      anchorRect = aAnchorFrame->GetScreenRectInAppUnits();
+      anchorRect.ScaleRoundOut(adj);
 
-      // move the popup according to the anchor and alignment. This will also tell us
-      // which axis the popup is flush against in case we have to move it around later.
-      AdjustPositionForAnchorAlign(&xpos, &ypos, parentSize, &readjustAboveBelow);
+      // move the popup according to the anchor and alignment. This will also
+      // tell us which axis the popup is flush against in case we have to move
+      // it around later. The AdjustPositionForAnchorAlign method accounts for
+      // the popup's margin.
+      screenPoint = AdjustPositionForAnchorAlign(anchorRect, hFlip, vFlip);
     }
     else {
       // with no anchor, the popup is positioned relative to the root frame
-      anchorScreenRect = rootScreenRect;
-      GetStyleMargin()->GetMargin(margin);
-      xpos = margin.left;
-      ypos = margin.top;
+      anchorRect = rootScreenRect;
+      screenPoint = anchorRect.TopLeft() + nsPoint(margin.left, margin.top);
     }
 
-    // add on the offset
-    xpos += presContext->CSSPixelsToAppUnits(mXPos);
-    ypos += presContext->CSSPixelsToAppUnits(mYPos);
-
-    screenViewLocX = rootScreenRect.x + xpos;
-    screenViewLocY = rootScreenRect.y + ypos;
+    // mXPos and mYPos specify an additonal offset passed to OpenPopup that
+    // should be added to the position
+    screenPoint.x += presContext->CSSPixelsToAppUnits(mXPos);
+    screenPoint.y += presContext->CSSPixelsToAppUnits(mYPos);
   }
   else {
     // the popup is positioned at a screen coordinate.
     // first convert the screen position in mScreenXPos and mScreenYPos from
     // CSS pixels into device pixels, ignoring any scaling as mScreenXPos and
     // mScreenYPos are unscaled screen coordinates.
     PRInt32 factor = devContext->UnscaledAppUnitsPerDevPixel();
-    screenViewLocX = nsPresContext::CSSPixelsToAppUnits(mScreenXPos) / factor;
-    screenViewLocY = nsPresContext::CSSPixelsToAppUnits(mScreenYPos) / factor;
 
+    // context menus should be offset by two pixels so that they don't appear
+    // directly where the cursor is. Otherwise, it is too easy to have the
+    // context menu close up again.
     if (mAdjustOffsetForContextMenu) {
       PRInt32 offsetForContextMenuDev =
         nsPresContext::CSSPixelsToAppUnits(2) / factor;
       offsetForContextMenu = presContext->DevPixelsToAppUnits(offsetForContextMenuDev);
     }
 
-    // next, convert back into app units accounting for the scaling,
-    // and add the margins on the popup
-    GetStyleMargin()->GetMargin(margin);
-    screenViewLocX = presContext->DevPixelsToAppUnits(screenViewLocX) +
-        margin.left + offsetForContextMenu;
-    screenViewLocY = presContext->DevPixelsToAppUnits(screenViewLocY) +
-        margin.top + offsetForContextMenu;
-
-    // determine the x and y position by subtracting the desired screen
-    // position from the screen position of the root frame.
-    xpos = screenViewLocX - rootScreenRect.x;
-    ypos = screenViewLocY - rootScreenRect.y;
-  }
+    // next, convert into app units accounting for the scaling
+    screenPoint.x = presContext->DevPixelsToAppUnits(
+                      nsPresContext::CSSPixelsToAppUnits(mScreenXPos) / factor);
+    screenPoint.y = presContext->DevPixelsToAppUnits(
+                      nsPresContext::CSSPixelsToAppUnits(mScreenYPos) / factor);
+    anchorRect = nsRect(screenPoint, nsSize());
 
-  // Compute info about the screen dimensions. Because of multiple monitor systems,
-  // the left or top sides of the screen may be in negative space (main monitor is on the
-  // right, etc). We need to be sure to do the right thing.
-  nsRect rect;
-  if ( mMenuCanOverlapOSBar ) {
-    devContext->GetRect(rect);
-  }
-  else {
-    devContext->GetClientRect(rect);
-  }
+    // add the margins on the popup
+    screenPoint.MoveBy(margin.left + offsetForContextMenu,
+                       margin.top + offsetForContextMenu);
 
-  // keep 3px margin to the right and bottom of the screen for WinXP dropshadow
-  rect.width  -= nsPresContext::CSSPixelsToAppUnits(3);
-  rect.height -= nsPresContext::CSSPixelsToAppUnits(3);
-
-  // for content shells, clip to the client area rather than the screen area
-  if (mInContentShell) {
-    rect.IntersectRect(rect, rootScreenRect);
+    // screen positioned popups can be flipped vertically but never horizontally
+    vFlip = PR_TRUE;
   }
 
-  PRInt32 screenLeftTwips   = rect.x;
-  PRInt32 screenTopTwips    = rect.y;
-  PRInt32 screenWidthTwips  = rect.width;
-  PRInt32 screenHeightTwips = rect.height;
-  PRInt32 screenRightTwips  = rect.XMost();
-  PRInt32 screenBottomTwips = rect.YMost();
-
-  if (mPopupAnchor != POPUPALIGNMENT_NONE && mScreenXPos == -1 && mScreenYPos == -1) {
-    //
-    // Popup is anchored to the parent, guarantee that it does not cover the parent. We
-    // shouldn't do anything funky if it will already fit on the screen as is.
-    //
-
-    ///////////////////////////////////////////////////////////////////////////////
-    //
-    //                +------------------------+          
-    //                |           /\           |
-    // parentPos -> - +------------------------+
-    //              | |                        |
-    //       offset | |                        |
-    //              | |                        |
-    //              | |                        | (screenViewLocX,screenViewLocY)
-    //              - |========================|+--------------
-    //                | parentSize           > ||
-    //                |========================||
-    //                |                        || Submenu 
-    //                +------------------------+|  ( = mRect )
-    //                |           \/           ||
-    //                +------------------------+
-
-    // Don't let it spill off the screen to the top
-    if (screenViewLocY < screenTopTwips) {
-      PRInt32 moveDist = screenTopTwips - screenViewLocY;
-      screenViewLocY = screenTopTwips;
-      ypos += moveDist;
-    }
-    
-    // if it doesn't fit on the screen, do our magic.
-    if ( (screenViewLocX + mRect.width) > screenRightTwips ||
-           screenViewLocX < screenLeftTwips ||
-          (screenViewLocY + mRect.height) > screenBottomTwips ) {
-      nsRect screenParentFrameRect(anchorScreenRect);
+  // screenRect will hold the rectangle of the available screen space. It
+  // will be reduced by the OS chrome such as menubars. It addition, for
+  // content shells, it will be the area of the content rather than the
+  // screen.
+  nsRect screenRect;
+  if (mMenuCanOverlapOSBar)
+    devContext->GetRect(screenRect);
+  else
+    devContext->GetClientRect(screenRect);
 
-      // figure out which side of the parent has the most free space so we can move/resize
-      // the popup there. This should still work if the parent frame is partially screen.
-      PRBool switchSides = IsMoreRoomOnOtherSideOfParent ( readjustAboveBelow, screenViewLocX, screenViewLocY,
-                                                            screenParentFrameRect, screenTopTwips, screenLeftTwips,
-                                                            screenBottomTwips, screenRightTwips );
-      
-      // move the popup to the correct side, if necessary. Note that MovePopupToOtherSideOfParent() 
-      // can change width/height of |mRect|.
-      if ( switchSides )
-        MovePopupToOtherSideOfParent ( readjustAboveBelow, &xpos, &ypos, &screenViewLocX, &screenViewLocY, 
-                                        screenParentFrameRect, screenTopTwips, screenLeftTwips,
-                                        screenBottomTwips, screenRightTwips );
-                                        
-      // We are allowed to move the popup along the axis to which we're not anchored to the parent
-      // in order to get it to not spill off the screen.
-      if ( readjustAboveBelow ) {
-        // move left to be on screen, but don't let it go off the screen at the left
-        if ( (screenViewLocX + mRect.width) > screenRightTwips ) {
-          PRInt32 moveDistX = (screenViewLocX + mRect.width) - screenRightTwips;
-          if ( screenViewLocX - moveDistX < screenLeftTwips )
-            moveDistX = screenViewLocX - screenLeftTwips;          
-          screenViewLocX -= moveDistX;
-          xpos -= moveDistX;
-        } else if (screenViewLocX < screenLeftTwips) {
-          // move right to be on screen, but don't let it go off the screen at the right
-          PRInt32 moveDistX = screenLeftTwips - screenViewLocX;
-          if ( (screenViewLocX + mRect.width + moveDistX) > screenRightTwips )
-            moveDistX = screenRightTwips - screenViewLocX - mRect.width;
-          screenViewLocX += moveDistX;
-          xpos += moveDistX;
-        }
-      }
-      else {
-        // move it up to be on screen, but don't let it go off the screen at the top
-        /*
-         *  |
-         *  |
-         *  |+----  screenViewLocY
-         *  ||
-         *  ||  Submenu ( = mRect )
-         * -+|
-         *   |
-         *   |
-         * - - - - - - - - - - screenBottomTwips (bottom of the screen)
-         *   |    \ 
-         *   |     }  moveDistY
-         *   |    / 
-         *   +----  screenViewLocY + mRect.height
-         */
+  // keep a 3 pixel margin to the right and bottom of the screen for the WinXP dropshadow
+  screenRect.SizeBy(-nsPresContext::CSSPixelsToAppUnits(3),
+                    -nsPresContext::CSSPixelsToAppUnits(3));
 
-        if ( (screenViewLocY + mRect.height) > screenBottomTwips ) {
-          PRInt32 moveDistY = (screenViewLocY + mRect.height) - screenBottomTwips;
-          if ( screenViewLocY - moveDistY < screenTopTwips )
-            moveDistY = screenViewLocY - screenTopTwips;          
-          screenViewLocY -= moveDistY;
-          ypos -= moveDistY; 
-        } 
-      }
-      
-      // Resize it to fit on the screen. By this point, we've given the popup as much
-      // room as we can w/out covering the parent. If it still can't be as big
-      // as it wants to be, well, it just has to suck up and deal. 
-      //
-      // ySpillage is calculated the same way as moveDistY above. see picture there.
-
-      PRInt32 xSpillage = (screenViewLocX + mRect.width) - screenRightTwips;
-      if ( xSpillage > 0 )
-        mRect.width -= xSpillage;
-      PRInt32 ySpillage = (screenViewLocY + mRect.height) - screenBottomTwips;
-      if ( ySpillage > 0 )
-        mRect.height -= ySpillage;
-
-      // shrink to fit onto the screen, vertically and horizontally
-      if(mRect.width > screenWidthTwips) 
-          mRect.width = screenWidthTwips;    
-      if(mRect.height > screenHeightTwips)
-          mRect.height = screenHeightTwips;   
-
-    } // if it doesn't fit on screen
-  } // if anchored to parent
-  else {
-  
-    //
-    // Popup not anchored to anything, just make sure it's on the screen by any
-    // means necessary
-    //
-
-    // If you decide to mess with this code in some way other than just
-    // converting it to be just like the anchored codepath, please make sure to
-    // not regress bug 120226, bug 172530, bug 245163.
-
-    // XXXbz this is really silly.  We should be able to anchor popups to a
-    // point or rect, not a frame, and we should be doing so with context
-    // menus.  Furthermore, we should not be adding in pixels manually to
-    // adjust position (in XULPopupListenerImpl::LaunchPopup comes to mind,
-    // though ConvertPosition in the same file has some 21-px bogosity in the
-    // y-direction too).
+  // for content shells, clip to the client area rather than the screen area
+  if (mInContentShell)
+    screenRect.IntersectRect(screenRect, rootScreenRect);
 
-    // shrink to fit onto the screen, vertically and horizontally
-    if(mRect.width > screenWidthTwips)
-       mRect.width = screenWidthTwips;
-    if(mRect.height > screenHeightTwips)
-       mRect.height = screenHeightTwips;
-
-    // First, adjust the X position.  For the X position, we slide the popup
-    // left or right as needed to get it on screen.
-    if ( screenViewLocX < screenLeftTwips ) {
-      PRInt32 moveDistX = screenLeftTwips - screenViewLocX;
-      xpos += moveDistX;
-      screenViewLocX += moveDistX;
-    }
-    if ( (screenViewLocX + mRect.width) > screenRightTwips )
-      xpos -= (screenViewLocX + mRect.width) - screenRightTwips;
-
-    // Now the Y position.  If the popup is up too high, slide it down so it's
-    // on screen. This can't make the popup overlap screenViewLocX/Y since
-    // we're moving it down away from screenViewLocY.
-    if ( screenViewLocY < screenTopTwips ) {
-      PRInt32 moveDistY = screenTopTwips - screenViewLocY;
-      ypos += moveDistY;
-      screenViewLocY += moveDistY;
-    }
-
-    // Now if the popup extends down too far, either resize it or flip it to be
-    // above the anchor point and resize it to fit above, depending on where we
-    // have more room. But ensure it doesn't overlap screenViewLocX/Y.
-    if ( (screenViewLocY + mRect.height) > screenBottomTwips ) {
-      // XXXbz it'd be good to make use of IsMoreRoomOnOtherSideOfParent and
-      // such here, but that's really focused on having a nonempty parent
-      // rect...
-      if (screenBottomTwips - screenViewLocY > screenViewLocY - screenTopTwips) {
-        // More space below our desired point.  Resize to fit in this space.
-        // Note that this is making mRect smaller; othewise we would not have
-        // reached this code.
-        mRect.height = screenBottomTwips - screenViewLocY;
-      } else {
-        // More space above our desired point.  Flip and resize to fit in this
-        // space.
-        // First figure out where the bottom of the popup is going to be.
-        nscoord newBottomY =
-          screenViewLocY - 2*offsetForContextMenu - margin.TopBottom();
-        // Make sure the bottom is on the screen
-        newBottomY = PR_MIN(newBottomY, screenBottomTwips);
-        newBottomY = PR_MAX(newBottomY, screenTopTwips);
-        if (mRect.height > newBottomY - screenTopTwips) {
-          // We wouldn't fit.  Shorten before flipping.
-          mRect.height = newBottomY - screenTopTwips;
-        }
-        // Adjust ypos to match
-        ypos += newBottomY - screenViewLocY - mRect.height;
-      }
-    }
+  // ensure that anchorRect is on screen
+  if (!anchorRect.IntersectRect(anchorRect, screenRect)) {
+    // if the anchor isn't within the screen, move it to the edge of the screen.
+    // IntersectRect will have set both the width and height of anchorRect to 0.
+    if (anchorRect.x < screenRect.x)
+      anchorRect.x = screenRect.x;
+    if (anchorRect.XMost() > screenRect.XMost())
+      anchorRect.x = screenRect.XMost();
+    if (anchorRect.y < screenRect.y)
+      anchorRect.y = screenRect.y;
+    if (anchorRect.YMost() > screenRect.YMost())
+      anchorRect.y = screenRect.YMost();
   }
 
-  presContext->GetViewManager()->MoveViewTo(GetView(), xpos, ypos); 
+  // shrink the the popup down if it is larger than the screen size
+  if (mRect.width > screenRect.width)
+    mRect.width = screenRect.width;
+  if (mRect.height > screenRect.height)
+    mRect.height = screenRect.height;
+
+  // at this point the anchor (anchorRect) is within the available screen
+  // area (screenRect) and the popup is known to be no larger than the screen.
+  // Next, check if there is enough space to show the popup at full size when
+  // positioned at screenPoint. If not, flip the popups to the opposite side
+  // of their anchor point, or resize them as necessary.
+  mRect.width = FlipOrResize(screenPoint.x, mRect.width, screenRect.x,
+                             screenRect.XMost(), anchorRect.x, anchorRect.XMost(),
+                             margin.left, margin.right, offsetForContextMenu, hFlip);
+  mRect.height = FlipOrResize(screenPoint.y, mRect.height, screenRect.y,
+                              screenRect.YMost(), anchorRect.y, anchorRect.YMost(),
+                              margin.top, margin.bottom, offsetForContextMenu, vFlip);
+
+  NS_ASSERTION(screenPoint.x >= screenRect.x && screenPoint.y >= screenRect.y &&
+               screenPoint.x + mRect.width <= screenRect.XMost() &&
+               screenPoint.y + mRect.height <= screenRect.YMost(),
+               "Popup is offscreen");
+
+  // determine the x and y position of the view by subtracting the desired
+  // screen position from the screen position of the root frame.
+  nsPoint viewPoint = screenPoint - rootScreenRect.TopLeft();
+  presContext->GetViewManager()->MoveViewTo(GetView(), viewPoint.x, viewPoint.y); 
 
   // Now that we've positioned the view, sync up the frame's origin.
-  // Note that (xpos,ypos) is the position relative to rootFrame.
-  nsBoxFrame::SetPosition(nsPoint(xpos, ypos) -
-                          GetParent()->GetOffsetTo(rootFrame));
+  nsBoxFrame::SetPosition(viewPoint - GetParent()->GetOffsetTo(rootFrame));
 
   if (sizedToPopup) {
     nsBoxLayoutState state(PresContext());
+    // XXXndeakin can parentSize.width still extend outside?
     SetBounds(state, nsRect(mRect.x, mRect.y, parentSize.width, mRect.height));
   }
 
   return NS_OK;
 }
 
 /* virtual */ nsMenuFrame*
 nsMenuPopupFrame::GetCurrentMenuItem()
@@ -1664,16 +1449,17 @@ nsMenuPopupFrame::AttributeChanged(PRInt
   
   if (aAttribute == nsGkAtoms::left || aAttribute == nsGkAtoms::top)
     MoveToAttributePosition();
 
   // accessibility needs this to ensure the frames get constructed when the
   // menugenerated attribute is set, see bug 279703 comment 42 for discussion
   if (aAttribute == nsGkAtoms::menugenerated &&
       mFrames.IsEmpty() && !mGeneratedChildren) {
+    EnsureWidget();
     PresContext()->PresShell()->FrameConstructor()->
       AddLazyChildren(mContent, LazyGeneratePopupDone, nsnull, PR_TRUE);
   }
   
   return rv;
 }
 
 void
--- a/layout/xul/base/src/nsMenuPopupFrame.h
+++ b/layout/xul/base/src/nsMenuPopupFrame.h
@@ -294,27 +294,41 @@ protected:
   void MoveToInternal(PRInt32 aLeft, PRInt32 aTop);                             
 
   // redefine to tell the box system not to move the views.
   virtual void GetLayoutFlags(PRUint32& aFlags);
 
   void InitPositionFromAnchorAlign(const nsAString& aAnchor,
                                    const nsAString& aAlign);
 
-  void AdjustPositionForAnchorAlign ( PRInt32* ioXPos, PRInt32* ioYPos, const nsSize & inParentRect,
-                                      PRBool* outFlushWithTopBottom ) ;
+  // return the position where the popup should be, when it should be
+  // anchored at anchorRect. aHFlip and aVFlip will be set if the popup may be
+  // flipped in that direction if there is not enough space available.
+  nsPoint AdjustPositionForAnchorAlign(const nsRect& anchorRect, PRBool& aHFlip, PRBool& aVFlip);
+
 
-  PRBool IsMoreRoomOnOtherSideOfParent ( PRBool inFlushAboveBelow, PRInt32 inScreenViewLocX, PRInt32 inScreenViewLocY,
-                                           const nsRect & inScreenParentFrameRect, PRInt32 inScreenTopTwips, PRInt32 inScreenLeftTwips,
-                                           PRInt32 inScreenBottomTwips, PRInt32 inScreenRightTwips ) ;
-
-  void MovePopupToOtherSideOfParent ( PRBool inFlushAboveBelow, PRInt32* ioXPos, PRInt32* ioYPos, 
-                                           PRInt32* ioScreenViewLocX, PRInt32* ioScreenViewLocY,
-                                           const nsRect & inScreenParentFrameRect, PRInt32 inScreenTopTwips, PRInt32 inScreenLeftTwips,
-                                           PRInt32 inScreenBottomTwips, PRInt32 inScreenRightTwips ) ;
+  // check if the popup will fit into the available space and resize it. This
+  // method handles only one axis at a time so is called twice, once for
+  // horizontal and once for vertical. All arguments are specified for this
+  // one axis. All coordinates are in app units relative to the screen.
+  //   aScreenPoint - the point where the popup should appear
+  //   aSize - the size of the popup
+  //   aScreenBegin - the left or top edge of the screen
+  //   aScreenEnd - the right or bottom edge of the screen
+  //   aAnchorBegin - the left or top edge of the anchor rectangle
+  //   aAnchorEnd - the right or bottom edge of the anchor rectangle
+  //   aMarginBegin - the left or top margin of the popup
+  //   aMarginEnd - the right or bottom margin of the popup
+  //   aOffsetForContextMenu - the additional offset to add for context menus
+  //   aFlip - whether to flip or resize the popup when there isn't space
+  nscoord FlipOrResize(nscoord& aScreenPoint, nscoord aSize, 
+                       nscoord aScreenBegin, nscoord aScreenEnd,
+                       nscoord aAnchorBegin, nscoord aAnchorEnd,
+                       nscoord aMarginBegin, nscoord aMarginEnd,
+                       nscoord aOffsetForContextMenu, PRBool aFlip);
 
   // Move the popup to the position specified in its |left| and |top| attributes.
   void MoveToAttributePosition();
 
   // the content that the popup is anchored to, if any, which may be in a
   // different document than the popup.
   nsCOMPtr<nsIContent> mAnchorContent;
 
--- a/modules/plugin/test/Makefile.in
+++ b/modules/plugin/test/Makefile.in
@@ -15,17 +15,16 @@
 # The Original Code is mozilla.org code.
 #
 # The Initial Developer of the Original Code is mozilla.org
 # Portions created by the Initial Developer are Copyright (C) 2008
 # the Initial Developer. All Rights Reserved.
 #
 # Contributor(s):
 #   Dave Townsend <dtownsend@oxymoronical.com>
-#   Josh Aas <josh@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
@@ -46,16 +45,9 @@ include $(DEPTH)/config/autoconf.mk
 MODULE = test_plugin
 
 DIRS = testplugin
 
 XPCSHELL_TESTS = \
   unit \
   $(NULL)
 
-# plugin mochitests only work on UNIX variants, including Mac OS X, at this time
-ifneq (,$(filter gtk2 cocoa windows,$(MOZ_WIDGET_TOOLKIT)))
-ifdef ENABLE_TESTS
-DIRS  += mochitest
-endif
-endif
-
 include $(topsrcdir)/config/rules.mk
deleted file mode 100644
--- a/modules/plugin/test/mochitest/Makefile.in
+++ /dev/null
@@ -1,50 +0,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 mozilla.org code.
-#
-# The Initial Developer of the Original Code is
-# Mozilla Foundation.
-# Portions created by the Initial Developer are Copyright (C) 2007
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#
-# Alternatively, the contents of this file may be used under the terms of
-# either of 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 *****
-
-DEPTH		= ../../../..
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-relativesrcdir  = modules/plugin/test
-
-include $(DEPTH)/config/autoconf.mk
-include $(topsrcdir)/config/rules.mk
-
-_TEST_FILES =	test_npruntime.xul
-
-libs:: $(_TEST_FILES)
-	$(INSTALL) $^ $(DEPTH)/_tests/testing/mochitest/chrome/$(relativesrcdir)
deleted file mode 100644
--- a/modules/plugin/test/mochitest/test_npruntime.xul
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
-                 type="text/css"?>
-<window title="Basic Plugin Tests"
-  xmlns:html="http://www.w3.org/1999/xhtml"
-  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-  <title>Basic Plugin Tests</title>
-  <script type="application/javascript" 
-   src="chrome://mochikit/content/MochiKit/packed.js"></script>
-  <script type="application/javascript"
-          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
-<body xmlns="http://www.w3.org/1999/xhtml" onload="runTests()">
-<embed id="plugin1" type="application/x-test" width="400" height="400"></embed>
-</body>
-<script class="testbody" type="application/javascript">
-<![CDATA[
-SimpleTest.waitForExplicitFinish();
-
-function runTests() {
-  var pluginElement = document.getElementById("plugin1");
-
-  ok(pluginElement.identifierToStringTest('foo') == "foo", "identifierToStringTest failed");
-
-  SimpleTest.finish();
-}
-]]>
-</script>
-</window>
--- a/modules/plugin/test/testplugin/Makefile.in
+++ b/modules/plugin/test/testplugin/Makefile.in
@@ -49,35 +49,22 @@ MODULE_NAME  = TestPlugin
 REQUIRES = \
   plugin \
   $(NULL)
 
 # Need to custom install plugins
 NO_DIST_INSTALL	= 1
 NO_INSTALL = 1
 
-CPPSRCS   =  \
-  nptest.cpp \
-  nptest_utils.cpp \
-  $(NULL)
-
-ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
-CMMSRCS = nptest_macosx.mm
+ifeq ($(OS_ARCH),WINNT)
+RCFILE    = nptest.rc
+RESFILE   = nptest.res
 endif
 
-ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
-CPPSRCS += nptest_gtk2.cpp
-endif
-
-ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
-CPPSRCS  += nptest_windows.cpp
-RCFILE    = nptest.rc
-RESFILE   = nptest.res
-DEFFILE   = $(win_srcdir)/nptest.def
-endif
+CPPSRCS   = nptest.cpp
 
 include $(topsrcdir)/config/rules.mk
 
 install-plugin: $(SHARED_LIBRARY)
 ifdef SHARED_LIBRARY
 ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
 	$(INSTALL) $(srcdir)/Info.plist $(DIST)/bin/plugins/Test.plugin/Contents
 	$(INSTALL) $(SHARED_LIBRARY) $(DIST)/bin/plugins/Test.plugin/Contents/MacOS
--- a/modules/plugin/test/testplugin/nptest.cpp
+++ b/modules/plugin/test/testplugin/nptest.cpp
@@ -1,524 +1,83 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* ***** BEGIN LICENSE BLOCK *****
- * 
- * Copyright (c) 2008, Mozilla Corporation
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * 
- * * Redistributions of source code must retain the above copyright notice, this
- *   list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- *   this list of conditions and the following disclaimer in the documentation
- *   and/or other materials provided with the distribution.
- * * Neither the name of the Mozilla Corporation nor the names of its
- *   contributors may be used to endorse or promote products derived from this
- *   software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- * 
+ * 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 mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is mozilla.org
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
  * Contributor(s):
  *   Dave Townsend <dtownsend@oxymoronical.com>
- *   Josh Aas <josh@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 ***** */
 
-#include "nptest.h"
-#include "nptest_utils.h"
-#include "nptest_platform.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-#define PLUGIN_NAME        "Test Plug-in"
-#define PLUGIN_DESCRIPTION "Plug-in for testing purposes."
-#define PLUGIN_VERSION     "1.0.0.0"
-
-//
-// static data
-//
-
-static NPNetscapeFuncs* sBrowserFuncs = NULL;
-static NPClass sNPClass;
-
-//
-// identifiers
-//
-
-#define IDENTIFIER_TO_STRING_TEST_METHOD 0
-#define NUM_METHOD_IDENTIFIERS           1
-
-static NPIdentifier sPluginMethodIdentifiers[NUM_METHOD_IDENTIFIERS];
-static const NPUTF8 *sPluginMethodIdentifierNames[NUM_METHOD_IDENTIFIERS] = {
-  "identifierToStringTest",
-};
-
-static bool sIdentifiersInitialized = false;
-
-static void initializeIdentifiers()
-{
-  if (!sIdentifiersInitialized) {
-    NPN_GetStringIdentifiers(sPluginMethodIdentifierNames, NUM_METHOD_IDENTIFIERS, sPluginMethodIdentifiers);
-    sIdentifiersInitialized = true;    
-  }
-}
-
-static void clearIdentifiers()
-{
-  memset(sPluginMethodIdentifierNames, 0, NUM_METHOD_IDENTIFIERS * sizeof(NPIdentifier));
-  sIdentifiersInitialized = false;
-}
-
-//
-// function signatures
-//
-
-bool identifierToStringTest(const NPVariant* args, uint32_t argCount, NPVariant* result);
-
-NPObject* scriptableAllocate(NPP npp, NPClass* aClass);
-void scriptableDeallocate(NPObject* npobj);
-void scriptableInvalidate(NPObject* npobj);
-bool scriptableHasMethod(NPObject* npobj, NPIdentifier name);
-bool scriptableInvoke(NPObject* npobj, NPIdentifier name, const NPVariant* args, uint32_t argCount, NPVariant* result);
-bool scriptableInvokeDefault(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
-bool scriptableHasProperty(NPObject* npobj, NPIdentifier name);
-bool scriptableGetProperty(NPObject* npobj, NPIdentifier name, NPVariant* result);
-bool scriptableSetProperty(NPObject* npobj, NPIdentifier name, const NPVariant* value);
-bool scriptableRemoveProperty(NPObject* npobj, NPIdentifier name);
-bool scriptableEnumerate(NPObject* npobj, NPIdentifier** identifier, uint32_t* count);
-bool scriptableConstruct(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
-
-//
-// npapi plugin functions
-//
-
-#ifdef XP_UNIX
-NP_EXPORT(char*)
-NP_GetPluginVersion()
-{
-  return PLUGIN_VERSION;
-}
-#endif
+#include "npapi.h"
+#include "npfunctions.h"
 
 #if defined(XP_UNIX)
-NP_EXPORT(char*) NP_GetMIMEDescription()
-#elif defined(XP_WIN)
-char* NP_GetMIMEDescription()
-#endif
-{
-  return "application/x-test:tst:Test mimetype";
-}
-
-#ifdef XP_UNIX
-NP_EXPORT(NPError)
-NP_GetValue(void* future, NPPVariable aVariable, void* aValue) {
-  switch (aVariable) {
-    case NPPVpluginNameString:
-      *((char**)aValue) = PLUGIN_NAME;
-      break;
-    case NPPVpluginDescriptionString:
-      *((char**)aValue) = PLUGIN_DESCRIPTION;
-      break;
-    default:
-      return NPERR_INVALID_PARAM;
-      break;
-  }
-  return NPERR_NO_ERROR;
-}
-#endif
-
-static void fillPluginFunctionTable(NPPluginFuncs* pFuncs)
-{
-  pFuncs->version = 11;
-  pFuncs->size = sizeof(*pFuncs);
-  pFuncs->newp = NPP_New;
-  pFuncs->destroy = NPP_Destroy;
-  pFuncs->setwindow = NPP_SetWindow;
-  pFuncs->newstream = NPP_NewStream;
-  pFuncs->destroystream = NPP_DestroyStream;
-  pFuncs->asfile = NPP_StreamAsFile;
-  pFuncs->writeready = NPP_WriteReady;
-  pFuncs->write = NPP_Write;
-  pFuncs->print = NPP_Print;
-  pFuncs->event = NPP_HandleEvent;
-  pFuncs->urlnotify = NPP_URLNotify;
-  pFuncs->getvalue = NPP_GetValue;
-  pFuncs->setvalue = NPP_SetValue;
-}
-
-#if defined(XP_MACOSX)
-NP_EXPORT(NPError) NP_Initialize(NPNetscapeFuncs* bFuncs)
-#elif defined(XP_WIN)
-NPError OSCALL NP_Initialize(NPNetscapeFuncs* bFuncs)
-#elif defined(XP_UNIX)
-NP_EXPORT(NPError) NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs)
-#endif
-{
-  sBrowserFuncs = bFuncs;
-
-  initializeIdentifiers();
-
-  memset(&sNPClass, 0, sizeof(NPClass));
-  sNPClass.structVersion =  NP_CLASS_STRUCT_VERSION;
-  sNPClass.allocate =       (NPAllocateFunctionPtr)scriptableAllocate;
-  sNPClass.deallocate =     (NPDeallocateFunctionPtr)scriptableDeallocate;
-  sNPClass.invalidate =     (NPInvalidateFunctionPtr)scriptableInvalidate;
-  sNPClass.hasMethod =      (NPHasMethodFunctionPtr)scriptableHasMethod;
-  sNPClass.invoke =         (NPInvokeFunctionPtr)scriptableInvoke;
-  sNPClass.invokeDefault =  (NPInvokeDefaultFunctionPtr)scriptableInvokeDefault;
-  sNPClass.hasProperty =    (NPHasPropertyFunctionPtr)scriptableHasProperty;
-  sNPClass.getProperty =    (NPGetPropertyFunctionPtr)scriptableGetProperty;
-  sNPClass.setProperty =    (NPSetPropertyFunctionPtr)scriptableSetProperty;
-  sNPClass.removeProperty = (NPRemovePropertyFunctionPtr)scriptableRemoveProperty;
-  sNPClass.enumerate =      (NPEnumerationFunctionPtr)scriptableEnumerate;
-  sNPClass.construct =      (NPConstructFunctionPtr)scriptableConstruct;
 
-#if defined(XP_UNIX) && !defined(XP_MACOSX)
-  fillPluginFunctionTable(pFuncs);
-#endif
-
-  return NPERR_NO_ERROR;
-}
-
-#if defined(XP_MACOSX)
-NP_EXPORT(NPError) NP_GetEntryPoints(NPPluginFuncs* pFuncs)
-#elif defined(XP_WIN)
-NPError OSCALL NP_GetEntryPoints(NPPluginFuncs* pFuncs)
-#endif
-#if defined(XP_MACOSX) || defined(XP_WIN)
-{
-  fillPluginFunctionTable(pFuncs);
-  return NPERR_NO_ERROR;
-}
-#endif
-
-#if defined(XP_UNIX)
-NP_EXPORT(NPError) NP_Shutdown()
-#elif defined(XP_WIN)
-NPError OSCALL NP_Shutdown()
-#endif
-{
-  clearIdentifiers();
-
-  return NPERR_NO_ERROR;
-}
-
-NPError
-NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* saved)
-{
-  NPN_SetValue(instance, NPPVpluginWindowBool, NULL);
+#define PLUGIN_NAME         "Test Plug-in"
+#define PLUGIN_DESCRIPTION  "Plug-in for testing purposes."
+#define PLUGIN_VERSION      "1.0.0.0"
 
-  // set up our our instance data
-  InstanceData* instanceData = (InstanceData*)malloc(sizeof(InstanceData));
-  if (!instanceData)
-    return NPERR_OUT_OF_MEMORY_ERROR;
-  memset(instanceData, 0, sizeof(InstanceData));
-  instanceData->npp = instance;
-  instance->pdata = instanceData;
-
-  TestNPObject* scriptableObject = (TestNPObject*)NPN_CreateObject(instance, &sNPClass);
-  if (!scriptableObject) {
-    printf("NPN_CreateObject failed to create an object, can't create a plugin instance\n");
-    return NPERR_GENERIC_ERROR;
-  }
-  NPN_RetainObject(scriptableObject);
-  scriptableObject->npp = instance;
-  instanceData->scriptableObject = scriptableObject;
-
-  // do platform-specific initialization
-  NPError err = pluginInstanceInit(instanceData);
-  if (err != NPERR_NO_ERROR)
-    return err;
-
-  return NPERR_NO_ERROR;
-}
-
-NPError
-NPP_Destroy(NPP instance, NPSavedData** save)
-{
-  InstanceData* instanceData = (InstanceData*)(instance->pdata);
-  NPN_ReleaseObject(instanceData->scriptableObject);
-  free(instanceData);
-  return NPERR_NO_ERROR;
-}
-
-NPError
-NPP_SetWindow(NPP instance, NPWindow* window)
-{
-  InstanceData* instanceData = (InstanceData*)(instance->pdata);
-  instanceData->window = *window;
-  return NPERR_NO_ERROR;
+NP_EXPORT(char*)
+NP_GetPluginVersion(void) {
+    return PLUGIN_VERSION;
 }
 
-NPError
-NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16_t* stype)
-{
-  *stype = NP_ASFILEONLY;
-  return NPERR_NO_ERROR;
-}
-
-NPError
-NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason)
-{
-  return NPERR_NO_ERROR;
-}
-
-int32_t
-NPP_WriteReady(NPP instance, NPStream* stream)
-{
-  return 0;
-}
-
-int32_t
-NPP_Write(NPP instance, NPStream* stream, int32_t offset, int32_t len, void* buffer)
-{
-  return 0;
-}
-
-void
-NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname)
-{
-}
-
-void
-NPP_Print(NPP instance, NPPrint* platformPrint)
-{
-}
-
-int16_t
-NPP_HandleEvent(NPP instance, void* event)
-{
-  InstanceData* instanceData = (InstanceData*)(instance->pdata);
-  return pluginHandleEvent(instanceData, event);
-}
-
-void
-NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData)
-{
-}
-
-NPError
-NPP_GetValue(NPP instance, NPPVariable variable, void* value)
-{
-  if (variable == NPPVpluginScriptableNPObject) {
-    NPObject* object = ((InstanceData*)instance->pdata)->scriptableObject;
-    NPN_RetainObject(object);
-    *((NPObject**)value) = object;
-    return NPERR_NO_ERROR;
-  }
-
-  return NPERR_GENERIC_ERROR;
+NP_EXPORT(char*)
+NP_GetMIMEDescription(void) {
+    return "application/x-test:tst:Test mimetype";
 }
 
-NPError
-NPP_SetValue(NPP instance, NPNVariable variable, void* value)
-{
-  return NPERR_GENERIC_ERROR;
-}
-
-//
-// npapi browser functions
-//
-
-bool
-NPN_SetProperty(NPP instance, NPObject* obj, NPIdentifier propertyName, const NPVariant* value)
-{
-  return sBrowserFuncs->setproperty(instance, obj, propertyName, value);
-}
-
-NPIdentifier
-NPN_GetIntIdentifier(int32_t intid)
-{
-  return sBrowserFuncs->getintidentifier(intid);
-}
-
-NPIdentifier
-NPN_GetStringIdentifier(const NPUTF8* name)
-{
-  return sBrowserFuncs->getstringidentifier(name);
-}
-
-void
-NPN_GetStringIdentifiers(const NPUTF8 **names, int32_t nameCount, NPIdentifier *identifiers)
-{
-  return sBrowserFuncs->getstringidentifiers(names, nameCount, identifiers);
+NP_EXPORT(NPError)
+NP_Initialize(NPNetscapeFuncs*, NPPluginFuncs*) {
+    return NPERR_NO_ERROR;
 }
 
-NPUTF8*
-NPN_UTF8FromIdentifier(NPIdentifier identifier)
-{
-  return sBrowserFuncs->utf8fromidentifier(identifier);
-}
-
-int32_t
-NPN_IntFromIdentifier(NPIdentifier identifier)
-{
-  return sBrowserFuncs->intfromidentifier(identifier);
-}
-
-NPError
-NPN_GetValue(NPP instance, NPNVariable variable, void* value)
-{
-  return sBrowserFuncs->getvalue(instance, variable, value);
-}
-
-NPError
-NPN_SetValue(NPP instance, NPPVariable variable, void* value)
-{
-  return sBrowserFuncs->setvalue(instance, variable, value);
-}
-
-bool
-NPN_HasProperty(NPP instance, NPObject* obj, NPIdentifier propertyName)
-{
-  return sBrowserFuncs->hasproperty(instance, obj, propertyName);
-}
-
-NPObject*
-NPN_CreateObject(NPP instance, NPClass* aClass)
-{
-  return sBrowserFuncs->createobject(instance, aClass);
+NP_EXPORT(NPError)
+NP_Shutdown(void) {
+    return NPERR_NO_ERROR;
 }
 
-const char*
-NPN_UserAgent(NPP instance)
-{
-  return sBrowserFuncs->uagent(instance);
-}
-
-NPObject*
-NPN_RetainObject(NPObject* obj)
-{
-  return sBrowserFuncs->retainobject(obj);
-}
-
-void
-NPN_ReleaseObject(NPObject* obj)
-{
-  return sBrowserFuncs->releaseobject(obj);
-}
-
-void*
-NPN_MemAlloc(uint32_t size)
-{
-  return sBrowserFuncs->memalloc(size);
-}
-
-void
-NPN_MemFree(void* ptr)
-{
-  return sBrowserFuncs->memfree(ptr);
-}
-
-//
-// npruntime object functions
-//
-
-NPObject*
-scriptableAllocate(NPP npp, NPClass* aClass)
-{
-  TestNPObject* object = (TestNPObject*)NPN_MemAlloc(sizeof(TestNPObject));
-  if (!object)
-    return NULL;
-  memset(object, 0, sizeof(TestNPObject));
-  return object;
-}
-
-void
-scriptableDeallocate(NPObject* npobj)
-{
-  NPN_MemFree(npobj);
-}
-
-void
-scriptableInvalidate(NPObject* npobj)
-{
-}
-
-bool
-scriptableHasMethod(NPObject* npobj, NPIdentifier name)
-{
-  for (int i = 0; i < NUM_METHOD_IDENTIFIERS; i++) {
-    if (name == sPluginMethodIdentifiers[i])
-      return true;
-  }
-  return false;
+NP_EXPORT(NPError) 
+NP_GetValue(void *future, NPPVariable aVariable, void *aValue) {
+   switch (aVariable) {
+     case NPPVpluginNameString:
+       *((char **)aValue) = PLUGIN_NAME;
+       break;
+     case NPPVpluginDescriptionString:
+       *((char **)aValue) = PLUGIN_DESCRIPTION;
+       break;
+     default:
+       return NPERR_INVALID_PARAM;
+       break;
+   }
+   return NPERR_NO_ERROR;
 }
 
-bool
-scriptableInvoke(NPObject* npobj, NPIdentifier name, const NPVariant* args, uint32_t argCount, NPVariant* result)
-{
-  if (name == sPluginMethodIdentifiers[IDENTIFIER_TO_STRING_TEST_METHOD])
-    return identifierToStringTest(args, argCount, result);
-  return false;
-}
-
-bool
-scriptableInvokeDefault(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
-{
-  return false;
-}
-
-bool
-scriptableHasProperty(NPObject* npobj, NPIdentifier name)
-{
-  return false;
-}
-
-bool
-scriptableGetProperty(NPObject* npobj, NPIdentifier name, NPVariant* result)
-{
-  return false;
-}
-
-bool
-scriptableSetProperty(NPObject* npobj, NPIdentifier name, const NPVariant* value)
-{
-  return false;
-}
-
-bool
-scriptableRemoveProperty(NPObject* npobj, NPIdentifier name)
-{
-  return false;
-}
-
-bool
-scriptableEnumerate(NPObject* npobj, NPIdentifier** identifier, uint32_t* count)
-{
-  return false;
-}
-
-bool
-scriptableConstruct(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
-{
-  return false;
-}
-
-//
-// test functions
-//
-
-bool
-identifierToStringTest(const NPVariant* args, uint32_t argCount, NPVariant* result)
-{
-  if (argCount != 1)
-    return false;
-  NPIdentifier identifier = variantToIdentifier(args[0]);
-  if (!identifier)
-    return false;
-  NPUTF8* utf8String = NPN_UTF8FromIdentifier(identifier);
-  if (!utf8String)
-    return false;
-  STRINGZ_TO_NPVARIANT(utf8String, *result);
-  return true;
-}
+#endif
deleted file mode 100644
--- a/modules/plugin/test/testplugin/nptest.def
+++ /dev/null
@@ -1,7 +0,0 @@
-LIBRARY   NPTEST
-
-EXPORTS
-  NP_GetEntryPoints     @1
-  NP_Initialize         @2
-  NP_Shutdown           @3
-  NP_GetMIMEDescription @4
deleted file mode 100644
--- a/modules/plugin/test/testplugin/nptest.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * 
- * Copyright (c) 2008, Mozilla Corporation
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * 
- * * Redistributions of source code must retain the above copyright notice, this
- *   list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- *   this list of conditions and the following disclaimer in the documentation
- *   and/or other materials provided with the distribution.
- * * Neither the name of the Mozilla Corporation nor the names of its
- *   contributors may be used to endorse or promote products derived from this
- *   software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- * 
- * Contributor(s):
- *   Josh Aas <josh@mozilla.com>
- * 
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef nptest_h_
-#define nptest_h_
-
-#include "mozilla-config.h"
-
-#include "npapi.h"
-#include "npfunctions.h"
-#include "npruntime.h"
-
-typedef struct TestNPObject : NPObject {
-  NPP npp;
-} TestNPObject;
-
-typedef struct InstanceData {
-  NPP npp;
-  NPWindow window;
-  TestNPObject* scriptableObject;
-} InstanceData;
-
-#endif // nptest_h_
deleted file mode 100644
--- a/modules/plugin/test/testplugin/nptest_gtk2.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * 
- * Copyright (c) 2008, Mozilla Corporation
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * 
- * * Redistributions of source code must retain the above copyright notice, this
- *   list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- *   this list of conditions and the following disclaimer in the documentation
- *   and/or other materials provided with the distribution.
- * * Neither the name of the Mozilla Corporation nor the names of its
- *   contributors may be used to endorse or promote products derived from this
- *   software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- * 
- * Contributor(s):
- *   Josh Aas <josh@mozilla.com>
- * 
- * ***** END LICENSE BLOCK ***** */
-
-#include "nptest_platform.h"
-
-NPError
-pluginInstanceInit(InstanceData* instanceData)
-{
-  return NPERR_NO_ERROR;
-}
-
-int16_t
-pluginHandleEvent(InstanceData* instanceData, void* event)
-{
-  return 0;
-}
-
-void
-pluginDraw(InstanceData* instanceData)
-{
-}
deleted file mode 100644
--- a/modules/plugin/test/testplugin/nptest_macosx.mm
+++ /dev/null
@@ -1,167 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * 
- * Copyright (c) 2008, Mozilla Corporation
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * 
- * * Redistributions of source code must retain the above copyright notice, this
- *   list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- *   this list of conditions and the following disclaimer in the documentation
- *   and/or other materials provided with the distribution.
- * * Neither the name of the Mozilla Corporation nor the names of its
- *   contributors may be used to endorse or promote products derived from this
- *   software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- * 
- * Contributor(s):
- *   Josh Aas <josh@mozilla.com>
- * 
- * ***** END LICENSE BLOCK ***** */
-
-#include "nptest_platform.h"
-#include <CoreServices/CoreServices.h>
-
-NPError
-pluginInstanceInit(InstanceData* instanceData)
-{
-  NPP npp = instanceData->npp;
-  // select the right drawing model if necessary
-  NPBool supportsCoreGraphics = false;
-  if (NPN_GetValue(npp, NPNVsupportsCoreGraphicsBool, &supportsCoreGraphics) == NPERR_NO_ERROR && supportsCoreGraphics) {
-    NPN_SetValue(npp, NPPVpluginDrawingModel, (void*)NPDrawingModelCoreGraphics);
-  } else {
-    printf("CoreGraphics drawing model not supported, can't create a plugin instance.\n");
-    return NPERR_INCOMPATIBLE_VERSION_ERROR;
-  }
-  return NPERR_NO_ERROR;
-}
-
-int16_t
-pluginHandleEvent(InstanceData* instanceData, void* event)
-{
-  EventRecord* carbonEvent = (EventRecord*)event;
-  if (carbonEvent && (carbonEvent->what == updateEvt)) {
-    pluginDraw(instanceData);
-    return 1;
-  }
-  return 0;
-}
-
-void
-pluginDraw(InstanceData* instanceData)
-{
-  if (!instanceData)
-    return;
-
-  NPP npp = instanceData->npp;
-  if (!npp)
-    return;
-
-  const char* uaString = NPN_UserAgent(npp);
-  if (!uaString)
-    return;
-
-  NPWindow window = instanceData->window;
-
-  CGContextRef cgContext = ((NP_CGContext*)(window.window))->context;
-
-  CFStringRef uaCFString = CFStringCreateWithCString(kCFAllocatorDefault, uaString, kCFStringEncodingASCII);
-
-  float windowWidth = window.width;
-  float windowHeight = window.height;
-
-  // save the cgcontext gstate
-  CGContextSaveGState(cgContext);
-
-  // we get a flipped context
-  CGContextTranslateCTM(cgContext, 0.0, windowHeight);
-  CGContextScaleCTM(cgContext, 1.0, -1.0);
-
-  // draw a gray background for the plugin
-  CGContextAddRect(cgContext, CGRectMake(0, 0, windowWidth, windowHeight));
-  CGContextSetGrayFillColor(cgContext, 0.5, 1.0);
-  CGContextDrawPath(cgContext, kCGPathFill);
-
-  // draw a black frame around the plugin
-  CGContextAddRect(cgContext, CGRectMake(0, 0, windowWidth, windowHeight));
-  CGContextSetGrayStrokeColor(cgContext, 0.0, 1.0);
-  CGContextSetLineWidth(cgContext, 6.0);
-  CGContextStrokePath(cgContext);
-
-  // draw the UA string using ATSUI
-  CGContextSetGrayFillColor(cgContext, 0.0, 1.0);
-  ATSUStyle atsuStyle;
-  ATSUCreateStyle(&atsuStyle);
-  CFIndex stringLength = CFStringGetLength(uaCFString);
-  UniChar* unicharBuffer = (UniChar*)malloc((stringLength + 1) * sizeof(UniChar));
-  CFStringGetCharacters(uaCFString, CFRangeMake(0, stringLength), unicharBuffer);
-  UniCharCount runLengths = kATSUToTextEnd;
-  ATSUTextLayout atsuLayout;
-  ATSUCreateTextLayoutWithTextPtr(unicharBuffer,
-                                  kATSUFromTextBeginning,
-                                  kATSUToTextEnd,
-                                  stringLength,
-                                  1,
-                                  &runLengths,
-                                  &atsuStyle,
-                                  &atsuLayout);
-  ATSUAttributeTag contextTag = kATSUCGContextTag;
-  ByteCount byteSize = sizeof(CGContextRef);
-  ATSUAttributeValuePtr contextATSUPtr = &cgContext;
-  ATSUSetLayoutControls(atsuLayout, 1, &contextTag, &byteSize, &contextATSUPtr);
-  ATSUTextMeasurement lineAscent, lineDescent;
-  ATSUGetLineControl(atsuLayout,
-                     kATSUFromTextBeginning,
-                     kATSULineAscentTag,
-                     sizeof(ATSUTextMeasurement),
-                     &lineAscent,
-                     &byteSize);
-  ATSUGetLineControl(atsuLayout,
-                     kATSUFromTextBeginning,
-                     kATSULineDescentTag,
-                     sizeof(ATSUTextMeasurement),
-                     &lineDescent,
-                     &byteSize);
-  float lineHeight = FixedToFloat(lineAscent) + FixedToFloat(lineDescent);
-  ItemCount softBreakCount;
-  ATSUBatchBreakLines(atsuLayout,
-                      kATSUFromTextBeginning,
-                      stringLength,
-                      FloatToFixed(windowWidth - 10.0),
-                      &softBreakCount);
-  ATSUGetSoftLineBreaks(atsuLayout,
-                        kATSUFromTextBeginning,
-                        kATSUToTextEnd,
-                        0, NULL, &softBreakCount);
-  UniCharArrayOffset* softBreaks = (UniCharArrayOffset*)malloc(softBreakCount * sizeof(UniCharArrayOffset));
-  ATSUGetSoftLineBreaks(atsuLayout,
-                        kATSUFromTextBeginning,
-                        kATSUToTextEnd,
-                        softBreakCount, softBreaks, &softBreakCount);
-  UniCharArrayOffset currentDrawOffset = kATSUFromTextBeginning;
-  unsigned int i = 0;
-  while (i < softBreakCount) {
-    ATSUDrawText(atsuLayout, currentDrawOffset, softBreaks[i], FloatToFixed(5.0), FloatToFixed(windowHeight - 5.0 - (lineHeight * (i + 1.0))));
-    currentDrawOffset = softBreaks[i];
-    i++;
-  }
-  ATSUDrawText(atsuLayout, currentDrawOffset, kATSUToTextEnd, FloatToFixed(5.0), FloatToFixed(windowHeight - 5.0 - (lineHeight * (i + 1.0))));
-  free(unicharBuffer);
-  free(softBreaks);
-
-  // restore the cgcontext gstate
-  CGContextRestoreGState(cgContext);
-}
deleted file mode 100644
--- a/modules/plugin/test/testplugin/nptest_platform.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * 
- * Copyright (c) 2008, Mozilla Corporation
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * 
- * * Redistributions of source code must retain the above copyright notice, this
- *   list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- *   this list of conditions and the following disclaimer in the documentation
- *   and/or other materials provided with the distribution.
- * * Neither the name of the Mozilla Corporation nor the names of its
- *   contributors may be used to endorse or promote products derived from this
- *   software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- * 
- * Contributor(s):
- *   Josh Aas <josh@mozilla.com>
- * 
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef nptest_platform_h_
-#define nptest_platform_h_
-
-#include "nptest.h"
-
-NPError pluginInstanceInit(InstanceData* instanceData);
-int16_t pluginHandleEvent(InstanceData* instanceData, void* event);
-// draws a gray box with a black border containing the browser UA string
-void    pluginDraw(InstanceData* instanceData);
-
-#endif // nptest_platform_h_
deleted file mode 100644
--- a/modules/plugin/test/testplugin/nptest_utils.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * 
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- * 
- * Contributor(s):
- *   Josh Aas <josh@mozilla.com>
- * 
- * ***** END LICENSE BLOCK ***** */
-
-#include "nptest_utils.h"
-
-#include <string.h>
-
-NPUTF8*
-createCStringFromNPVariant(const NPVariant* variant)
-{
-  size_t length = NPVARIANT_TO_STRING(*variant).UTF8Length;
-  NPUTF8* result = (NPUTF8*)malloc(length + 1);
-  memcpy(result, NPVARIANT_TO_STRING(*variant).UTF8Characters, length);
-  result[length] = '\0';
-  return result;
-}
-
-NPIdentifier
-variantToIdentifier(NPVariant variant)
-{
-  if (NPVARIANT_IS_STRING(variant))
-    return stringVariantToIdentifier(variant);
-  else if (NPVARIANT_IS_INT32(variant))
-    return int32VariantToIdentifier(variant);
-  else if (NPVARIANT_IS_DOUBLE(variant))
-    return doubleVariantToIdentifier(variant);
-  return 0;
-}
-
-NPIdentifier
-stringVariantToIdentifier(NPVariant variant)
-{
-  assert(NPVARIANT_IS_STRING(variant));
-  NPUTF8* utf8String = createCStringFromNPVariant(&variant);
-  NPIdentifier identifier = NPN_GetStringIdentifier(utf8String);
-  free(utf8String);
-  return identifier;
-}
-
-NPIdentifier
-int32VariantToIdentifier(NPVariant variant)
-{
-  assert(NPVARIANT_IS_INT32(variant));
-  int32 integer = NPVARIANT_TO_INT32(variant);
-  return NPN_GetIntIdentifier(integer);
-}
-
-NPIdentifier
-doubleVariantToIdentifier(NPVariant variant)
-{
-  assert(NPVARIANT_IS_DOUBLE(variant));
-  double value = NPVARIANT_TO_DOUBLE(variant);
-  // sadly there is no "getdoubleidentifier"
-  int32 integer = static_cast<int32>(value);
-  return NPN_GetIntIdentifier(integer);
-}
deleted file mode 100644
--- a/modules/plugin/test/testplugin/nptest_utils.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * 
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- * 
- * Contributor(s):
- *   Josh Aas <josh@mozilla.com>
- * 
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef nptest_utils_h_
-#define nptest_utils_h_
-
-#include "nptest.h"
-
-NPUTF8* createCStringFromNPVariant(const NPVariant* variant);
-
-NPIdentifier variantToIdentifier(NPVariant variant);
-NPIdentifier stringVariantToIdentifier(NPVariant variant);
-NPIdentifier int32VariantToIdentifier(NPVariant variant);
-NPIdentifier doubleVariantToIdentifier(NPVariant variant);
-
-#endif // nptest_utils_h_
deleted file mode 100644
--- a/modules/plugin/test/testplugin/nptest_windows.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * 
- * Copyright (c) 2008, Mozilla Corporation
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * 
- * * Redistributions of source code must retain the above copyright notice, this
- *   list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- *   this list of conditions and the following disclaimer in the documentation
- *   and/or other materials provided with the distribution.
- * * Neither the name of the Mozilla Corporation nor the names of its
- *   contributors may be used to endorse or promote products derived from this
- *   software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- * 
- * Contributor(s):
- *   Josh Aas <josh@mozilla.com>
- * 
- * ***** END LICENSE BLOCK ***** */
-
-#include "nptest_platform.h"
-
-NPError
-pluginInstanceInit(InstanceData* instanceData)
-{
-  return NPERR_NO_ERROR;
-}
-
-int16_t
-pluginHandleEvent(InstanceData* instanceData, void* event)
-{
-  return 0;
-}
-
-void
-pluginDraw(InstanceData* instanceData)
-{
-}
--- a/testing/mochitest/runtests.py.in
+++ b/testing/mochitest/runtests.py.in
@@ -328,17 +328,18 @@ Are you executing $objdir/_tests/testing
     testURL = A11YTESTS_URL
     if options.testPath:
       urlOpts.append("testPath=" + encodeURIComponent(options.testPath))
   elif options.browserChrome:
     testURL = "about:blank"
 
   # allow relative paths for logFile
   if options.logFile:
-    options.logFile = os.path.normpath(os.path.join(oldcwd, options.logFile))
+    logpath = os.path.join(oldcwd, os.path.expanduser(options.logFile))
+    options.logFile = os.path.normpath(logpath)
   if options.browserChrome:
     makeTestConfig(options)
   else:
     if options.autorun:
       urlOpts.append("autorun=1")
     if options.closeWhenDone:
       urlOpts.append("closeWhenDone=1")
     if options.logFile:
--- a/toolkit/components/places/src/nsNavHistory.cpp
+++ b/toolkit/components/places/src/nsNavHistory.cpp
@@ -5260,16 +5260,20 @@ nsNavHistory::IdleTimerCallback(nsITimer
 // nsIDownloadHistory **********************************************************
 
 NS_IMETHODIMP
 nsNavHistory::AddDownload(nsIURI* aSource, nsIURI* aReferrer,
                           PRTime aStartTime)
 {
   NS_ASSERTION(NS_IsMainThread(), "This can only be called on the main thread");
 
+  // don't add when history is disabled and silently fail
+  if (IsHistoryDisabled())
+    return NS_OK;
+
   PRInt64 visitID;
   return AddVisit(aSource, aStartTime, aReferrer, TRANSITION_DOWNLOAD, PR_FALSE,
                   0, &visitID);
 }
 
 // nsPIPlacesDatabase **********************************************************
 
 NS_IMETHODIMP
--- a/toolkit/components/places/tests/unit/test_download_history.js
+++ b/toolkit/components/places/tests/unit/test_download_history.js
@@ -17,91 +17,140 @@
  *
  * The Initial Developer of the Original Code is
  * Mozilla Corporation.
  * Portions created by the Initial Developer are Copyright (C) 2007
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   Shawn Wilsher <me@shawnwilsher.com> (Original Author)
+ *   Marco Bonardo <mak77@bonardo.net>
  *
  * 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 ***** */
 
-// Get history service
-try {
-  var histsvc = Cc["@mozilla.org/browser/nav-history-service;1"].
-                getService(Ci.nsINavHistoryService);
-} catch(ex) {
-  do_throw("Could not get history service\n");
-} 
+// Get services
+var histsvc = Cc["@mozilla.org/browser/nav-history-service;1"].
+              getService(Ci.nsINavHistoryService);
+let bh = histsvc.QueryInterface(Ci.nsIBrowserHistory);
+var os = Cc["@mozilla.org/observer-service;1"].
+         getService(Ci.nsIObserverService);
+var prefs = Cc["@mozilla.org/preferences-service;1"].
+            getService(Ci.nsIPrefBranch);
+var dh = Cc["@mozilla.org/browser/download-history;1"].
+         getService(Ci.nsIDownloadHistory);
+// Test that this nsIDownloadHistory is the one places implements.
+do_check_true(dh instanceof Ci.nsINavHistoryService);
+var pb = Cc["@mozilla.org/privatebrowsing;1"].
+         getService(Ci.nsIPrivateBrowsingService);
+
+
+const NS_LINK_VISITED_EVENT_TOPIC = "link-visited";
+const DISABLE_HISTORY_PREF = "browser.history_expire_days";
+const PB_KEEP_SESSION_PREF = "browser.privatebrowsing.keep_current_session";
+
+var testURI = uri("http://google.com/");
+var referrerURI = uri("http://yahoo.com");
 
 /**
  * Checks to see that a URI is in the database.
  *
  * @param aURI
  *        The URI to check.
- * @returns true if the URI is in the DB, false otherwise.
+ * @param aExpected
+ *        Boolean result expected from the db lookup.
  */
-function uri_in_db(aURI) {
+function uri_in_db(aURI, aExpected) {
   var options = histsvc.getNewQueryOptions();
   options.maxResults = 1;
   options.resultType = options.RESULTS_AS_URI;
   options.includeHidden = true;
   var query = histsvc.getNewQuery();
   query.uri = aURI;
   var result = histsvc.executeQuery(query, options);
   var root = result.root;
   root.containerOpen = true;
-  return (root.childCount == 1);
+  var cc = root.childCount;
+  root.containerOpen = false;
+  var checker = aExpected ? do_check_true : do_check_false;
+  checker(cc == 1);
+}
+
+function test_dh() {
+  dh.addDownload(testURI, referrerURI, Date.now() * 1000);
+
+  do_check_true(observer.topicReceived);
+  uri_in_db(testURI, true);
+  uri_in_db(referrerURI, true);
+}
+
+function test_dh_privateBrowsing() {
+  prefs.setBoolPref(PB_KEEP_SESSION_PREF, true);
+  pb.privateBrowsingEnabled = true;
+
+  dh.addDownload(testURI, referrerURI, Date.now() * 1000);
+
+  do_check_false(observer.topicReceived);
+  uri_in_db(testURI, false);
+  uri_in_db(referrerURI, false);
+
+  // Cleanup
+  pb.privateBrowsingEnabled = false;
 }
 
+function test_dh_disabledHistory() {
+  // Disable history
+  prefs.setIntPref(DISABLE_HISTORY_PREF, 0);
+
+  dh.addDownload(testURI, referrerURI, Date.now() * 1000);
+
+  do_check_false(observer.topicReceived);
+  uri_in_db(testURI, false);
+  uri_in_db(referrerURI, false);
+
+  // Cleanup
+  prefs.setIntPref(DISABLE_HISTORY_PREF, 180);
+}
+
+var tests = [
+  test_dh,
+  test_dh_privateBrowsing,
+  test_dh_disabledHistory,
+];
+
+var observer = {
+  topicReceived: false,
+  observe: function tlvo_observe(aSubject, aTopic, aData)
+  {
+    if (NS_LINK_VISITED_EVENT_TOPIC == aTopic) {
+      this.topicReceived = true;
+    }
+  }
+};
+os.addObserver(observer, NS_LINK_VISITED_EVENT_TOPIC, false);
+
 // main
 function run_test() {
-  // Test that when we get nsIDownloadHistory that it's the one places
-  // implements.
-  var dh = Cc["@mozilla.org/browser/download-history;1"].
-           getService(Ci.nsIDownloadHistory);
-  do_check_true(dh instanceof Ci.nsINavHistoryService);
+  while (tests.length) {
+    // Sanity checks
+    uri_in_db(testURI, false);
+    uri_in_db(referrerURI, false);
 
-  // now to make sure all the functionality works!
-  const NS_LINK_VISITED_EVENT_TOPIC = "link-visited";
-  var ios = Cc["@mozilla.org/network/io-service;1"].
-            getService(Ci.nsIIOService);
-  var testURI = ios.newURI("http://google.com/", null, null);
-
-  do_check_false(uri_in_db(testURI));
+    (tests.shift())();
 
-  var topicReceived = false;
-  var obs = {
-    observe: function tlvo_observe(aSubject, aTopic, aData)
-    {
-      if (NS_LINK_VISITED_EVENT_TOPIC == aTopic) {
-        do_check_true(uri_in_db(testURI));
-        do_check_eq(testURI, aSubject);
-        topicReceived = true;
-      }
-    }
-  };
+    // Cleanup
+    bh.removeAllPages();
+    observer.topicReceived = false;
+  }
 
-  var os = Cc["@mozilla.org/observer-service;1"].
-           getService(Ci.nsIObserverService);
-  os.addObserver(obs, NS_LINK_VISITED_EVENT_TOPIC, false);
-
-  var referrerURI = ios.newURI("http://yahoo.com", null, null);
-  do_check_false(uri_in_db(referrerURI));
-  do_check_false(uri_in_db(testURI));
-  dh.addDownload(testURI, referrerURI, Date.now() * 1000);
-  do_check_true(topicReceived);
-  do_check_true(uri_in_db(testURI));
-  do_check_true(uri_in_db(referrerURI));
+  os.removeObserver(observer, NS_LINK_VISITED_EVENT_TOPIC);
 }
--- a/toolkit/content/tests/widgets/popup_trigger.js
+++ b/toolkit/content/tests/widgets/popup_trigger.js
@@ -145,16 +145,56 @@ var popupTests = [
   events: [ "popupshowing thepopup", "popupshown thepopup" ],
   autohide: "thepopup",
   steps: ["before_start", "before_end", "after_start", "after_end",
           "start_before", "start_after", "end_before", "end_after", "overlap"],
   test: function(testname, step) { gMenuPopup.openPopup(gTrigger, step, 0, 0, false, false); },
   result: function(testname, step) { compareEdge(gTrigger, gMenuPopup, step, 0, 0, testname); }
 },
 {
+  // these tests check the same but with a 10 pixel margin on the popup
+  testname: "open popup anchored with margin",
+  events: [ "popupshowing thepopup", "popupshown thepopup" ],
+  autohide: "thepopup",
+  steps: ["before_start", "before_end", "after_start", "after_end",
+          "start_before", "start_after", "end_before", "end_after", "overlap"],
+  test: function(testname, step) {
+    gMenuPopup.setAttribute("style", "margin: 10px;");
+    gMenuPopup.openPopup(gTrigger, step, 0, 0, false, false);
+  },
+  result: function(testname, step) {
+    var rightmod = step == "before_end" || step == "after_end" ||
+                   step == "start_before" || step == "start_after";
+    var bottommod = step == "before_start" || step == "before_end" ||
+                    step == "start_after" || step == "end_after";
+    compareEdge(gTrigger, gMenuPopup, step, rightmod ? -10 : 10, bottommod ? -10 : 10, testname);
+    gMenuPopup.removeAttribute("style");
+  }
+},
+{
+  // these tests check the same but with a -8 pixel margin on the popup
+  testname: "open popup anchored with negative margin",
+  events: [ "popupshowing thepopup", "popupshown thepopup" ],
+  autohide: "thepopup",
+  steps: ["before_start", "before_end", "after_start", "after_end",
+          "start_before", "start_after", "end_before", "end_after", "overlap"],
+  test: function(testname, step) {
+    gMenuPopup.setAttribute("style", "margin: -8px;");
+    gMenuPopup.openPopup(gTrigger, step, 0, 0, false, false);
+  },
+  result: function(testname, step) {
+    var rightmod = step == "before_end" || step == "after_end" ||
+                   step == "start_before" || step == "start_after";
+    var bottommod = step == "before_start" || step == "before_end" ||
+                    step == "start_after" || step == "end_after";
+    compareEdge(gTrigger, gMenuPopup, step, rightmod ? 8 : -8, bottommod ? 8 : -8, testname);
+    gMenuPopup.removeAttribute("style");
+  }
+},
+{
   // these tests check to ensure that the position attribute can be used
   // to set the position of a popup instead of passing it as an argument
   testname: "open popup anchored with attribute",
   events: [ "popupshowing thepopup", "popupshown thepopup" ],
   autohide: "thepopup",
   steps: ["before_start", "before_end", "after_start", "after_end",
           "start_before", "start_after", "end_before", "end_after", "overlap"],
   test: function(testname, step) {
--- a/toolkit/crashreporter/tools/symbolstore.py
+++ b/toolkit/crashreporter/tools/symbolstore.py
@@ -346,50 +346,49 @@ def GetVCSFilename(file, srcdir):
     fileInfo = None
     root = ''
     if file in vcsFileInfoCache:
         # Already cached this info, use it.
         fileInfo = vcsFileInfoCache[file]
     else:
         if os.path.isdir(os.path.join(path, "CVS")):
             fileInfo = CVSFileInfo(file, srcdir)
-            if fileInfo:
-               root = fileInfo.root
         elif os.path.isdir(os.path.join(path, ".svn")) or \
              os.path.isdir(os.path.join(path, "_svn")):
             fileInfo = SVNFileInfo(file);
         elif os.path.isdir(os.path.join(srcdir, '.hg')) and \
              IsInDir(file, srcdir):
             fileInfo = HGFileInfo(file, srcdir)
         vcsFileInfoCache[file] = fileInfo
 
     if fileInfo:
         file = fileInfo.filename
+        root = fileInfo.root
 
     # we want forward slashes on win32 paths
     return (file.replace("\\", "/"), root)
 
 def GetPlatformSpecificDumper(**kwargs):
     """This function simply returns a instance of a subclass of Dumper
     that is appropriate for the current platform."""
     return {'win32': Dumper_Win32,
             'cygwin': Dumper_Win32,
             'linux2': Dumper_Linux,
             'sunos5': Dumper_Solaris,
             'darwin': Dumper_Mac}[sys.platform](**kwargs)
 
-def SourceIndex(fileStream, outputPath, cvs_root):
+def SourceIndex(fileStream, outputPath, vcs_root):
     """Takes a list of files, writes info to a data block in a .stream file"""
     # Creates a .pdb.stream file in the mozilla\objdir to be used for source indexing
     # Create the srcsrv data block that indexes the pdb file
     result = True
     pdbStreamFile = open(outputPath, "w")
-    pdbStreamFile.write('''SRCSRV: ini ------------------------------------------------\r\nVERSION=1\r\nSRCSRV: variables ------------------------------------------\r\nCVS_EXTRACT_CMD=%fnchdir%(%targ%)cvs.exe -d %fnvar%(%var2%) checkout -r %var4% -d %var4% -N %var3%\r\nMYSERVER=''')
-    pdbStreamFile.write(cvs_root)
-    pdbStreamFile.write('''\r\nSRCSRVTRG=%targ%\%var4%\%fnbksl%(%var3%)\r\nSRCSRVCMD=%CVS_EXTRACT_CMD%\r\nSRCSRV: source files ---------------------------------------\r\n''')
+    pdbStreamFile.write('''SRCSRV: ini ------------------------------------------------\r\nVERSION=2\r\nINDEXVERSION=2\r\nVERCTRL=http\r\nSRCSRV: variables ------------------------------------------\r\nHGSERVER=''')
+    pdbStreamFile.write(vcs_root)
+    pdbStreamFile.write('''\r\nSRCSRVVERCTRL=http\r\nHTTP_EXTRACT_TARGET=%hgserver%/raw-file/%var3%/%var2%\r\nSRCSRVTRG=%http_extract_target%\r\nSRCSRV: source files ---------------------------------------\r\n''')
     pdbStreamFile.write(fileStream) # can't do string interpolation because the source server also uses this and so there are % in the above
     pdbStreamFile.write("SRCSRV: end ------------------------------------------------\r\n\n")
     pdbStreamFile.close()
     return result
 
 class Dumper:
     """This class can dump symbols from a file with debug info, and
     store the output in a directory structure that is valid for use as
@@ -440,17 +439,17 @@ class Dumper:
         except:
             return ""
 
     # This is a no-op except on Win32
     def FixFilenameCase(self, file):
         return file
 
     # This is a no-op except on Win32
-    def SourceServerIndexing(self, debug_file, guid, sourceFileStream, cvs_root):
+    def SourceServerIndexing(self, debug_file, guid, sourceFileStream, vcs_root):
         return ""
 
     # subclasses override this if they want to support this
     def CopyDebug(self, file, debug_file, guid):
         pass
 
     def Process(self, file_or_dir):
         "Process a file or all the (valid) files in a directory."
@@ -476,19 +475,19 @@ class Dumper:
                         result = False
         return result
 
     def ProcessFile(self, file):
         """Dump symbols from this file into a symbol file, stored
         in the proper directory structure in  |symbol_path|."""
         result = False
         sourceFileStream = ''
-        # tries to get cvsroot from the .mozconfig first - if it's not set
-        # the tinderbox cvs_path will be assigned further down
-        cvs_root = os.environ.get("SRCSRV_ROOT")
+        # tries to get the vcs root from the .mozconfig first - if it's not set
+        # the tinderbox vcs path will be assigned further down
+        vcs_root = os.environ.get("SRCSRV_ROOT")
         for arch in self.archs:
             try:
                 cmd = os.popen("%s %s %s" % (self.dump_syms, arch, file), "r")
                 module_line = cmd.next()
                 if module_line.startswith("MODULE"):
                     # MODULE os cpu guid debug_file
                     (guid, debug_file) = (module_line.split())[3:5]
                     # strip off .pdb extensions, and append .sym
@@ -514,38 +513,38 @@ class Dumper:
                                 start = filename.find(self.srcdir)
                                 if start == -1:
                                     start = 0
                                 filename = filename[start:]
                             filename = self.FixFilenameCase(filename.rstrip())
                             sourcepath = filename
                             if self.vcsinfo:
                                 (filename, rootname) = GetVCSFilename(filename, self.srcdir)
-                                # sets cvs_root in case the loop through files were to end on an empty rootname
-                                if cvs_root is None:
+                                # sets vcs_root in case the loop through files were to end on an empty rootname
+                                if vcs_root is None:
                                   if rootname:
-                                     cvs_root = rootname
-                            # gather up files with cvs for indexing   
-                            if filename.startswith("cvs"):
+                                     vcs_root = rootname
+                            # gather up files with hg for indexing   
+                            if filename.startswith("hg"):
                                 (ver, checkout, source_file, revision) = filename.split(":", 3)
-                                sourceFileStream += sourcepath + "*MYSERVER*" + source_file + '*' + revision + "\r\n"
+                                sourceFileStream += sourcepath + "*" + source_file + '*' + revision + "\r\n"
                             f.write("FILE %s %s\n" % (index, filename))
                         else:
                             # pass through all other lines unchanged
                             f.write(line)
                     f.close()
                     cmd.close()
                     # we output relative paths so callers can get a list of what
                     # was generated
                     print rel_path
                     if self.copy_debug:
                         self.CopyDebug(file, debug_file, guid)
-                    if self.srcsrv:
+                    if self.srcsrv and vcs_root:
                         # Call on SourceServerIndexing
-                        result = self.SourceServerIndexing(debug_file, guid, sourceFileStream, cvs_root)
+                        result = self.SourceServerIndexing(debug_file, guid, sourceFileStream, vcs_root)
                     result = True
             except StopIteration:
                 pass
             except:
                 print >> sys.stderr, "Unexpected error: ", sys.exc_info()[0]
                 raise
         return result
 
@@ -592,23 +591,23 @@ class Dumper_Win32(Dumper):
                                 guid,
                                 debug_file).replace("\\", "/")
         print rel_path
         full_path = os.path.normpath(os.path.join(self.symbol_path,
                                                   rel_path))
         shutil.copyfile(file, full_path)
         pass
         
-    def SourceServerIndexing(self, debug_file, guid, sourceFileStream, cvs_root):
+    def SourceServerIndexing(self, debug_file, guid, sourceFileStream, vcs_root):
         # Creates a .pdb.stream file in the mozilla\objdir to be used for source indexing
         cwd = os.getcwd()
         streamFilename = debug_file + ".stream"
         stream_output_path = os.path.join(cwd, streamFilename)
         # Call SourceIndex to create the .stream file
-        result = SourceIndex(sourceFileStream, stream_output_path, cvs_root)
+        result = SourceIndex(sourceFileStream, stream_output_path, vcs_root)
         
         if self.copy_debug:
             pdbstr_path = os.environ.get("PDBSTR_PATH")
             pdbstr = os.path.normpath(pdbstr_path)
             pdb_rel_path = os.path.join(debug_file, guid, debug_file)
             pdb_filename = os.path.normpath(os.path.join(self.symbol_path, pdb_rel_path))
             # move to the dir with the stream files to call pdbstr
             os.chdir(os.path.dirname(stream_output_path))
--- a/toolkit/mozapps/extensions/content/extensions.xml
+++ b/toolkit/mozapps/extensions/content/extensions.xml
@@ -919,17 +919,17 @@
 
   <binding id="install-downloading" extends="chrome://mozapps/content/extensions/extensions.xml#addon-base">
     <content>
       <xul:hbox flex="1">
         <xul:vbox pack="start">
           <xul:image class="addonIcon" xbl:inherits="src=iconURL"/>
         </xul:vbox>
         <xul:vbox flex="1" class="addonTextBox">
-          <xul:hbox class="addon-name-version" xbl:inherits="name, version"/>
+          <xul:hbox class="addon-name-version" xbl:inherits="name, version=newVersion"/>
           <xul:progressmeter class="extension-item-progress" xbl:inherits="value=progress"/>
           <xul:label class="extension-item-status" xbl:inherits="value=status" value="&installWaiting.label;"/>
         </xul:vbox>
       </xul:hbox>
     </content>  
   </binding>
 
 <!-- based on preferences.xml paneButton -->
--- a/toolkit/mozapps/extensions/src/nsExtensionManager.js.in
+++ b/toolkit/mozapps/extensions/src/nsExtensionManager.js.in
@@ -5777,22 +5777,27 @@ ExtensionManager.prototype = {
 
       txn.addDownload(currItem);
       urls.push(currItem.xpiURL);
       hashes.push(currItem.xpiHash ? currItem.xpiHash : null);
       // if this is an update remove the update metadata to prevent it from
       // being updated during an install.
       if (!manager) {
         var id = currItem.id
-        ds.setItemProperties(id, {
+        var props = {
           availableUpdateURL: null,
           availableUpdateHash: null,
           availableUpdateVersion: null,
           availableUpdateInfo: null
-        });
+        };
+        var updateVersion = ds.getItemProperty(id, "availableUpdateVersion");
+        var updateURL = ds.getItemProperty(id, "availableUpdateURL");
+        if (updateVersion && (updateURL == currItem.xpiURL))
+          props.newVersion = EM_L(updateVersion);
+        ds.setItemProperties(id, props);
         ds.updateProperty(id, "availableUpdateURL");
         ds.updateProperty(id, "updateable");
       }
       var id = !manager ? PREFIX_ITEM_URI + currItem.id : currItem.xpiURL;
       ds.updateDownloadState(id, "waiting");
     }
     this._transactions.push(txn);