mozilla-central merge
authorOleg Romashin <romaxa@gmail.com>
Fri, 08 Aug 2008 13:05:00 +0300
changeset 16958 a112dbac26939193539d4108cba6b9421a2bc667
parent 16957 34a26361557b0c9651b76650c557771123aeb8b0 (current diff)
parent 16532 e57198815263dd93557bf6a7efff878b293f8958 (diff)
child 16959 a476a6e8a70abaac22a0c96e0a25e3733b53a82b
push idunknown
push userunknown
push dateunknown
milestone1.9.1a2pre
mozilla-central merge
config/autoconf.mk.in
configure.in
dom/tests/mochitest/ajax/jquery/src/Makefile.in
dom/tests/mochitest/ajax/jquery/src/ajax/Makefile.in
dom/tests/mochitest/ajax/jquery/src/ajax/ajax.js
dom/tests/mochitest/ajax/jquery/src/ajax/ajaxTest.js
dom/tests/mochitest/ajax/jquery/src/event/Makefile.in
dom/tests/mochitest/ajax/jquery/src/event/event.js
dom/tests/mochitest/ajax/jquery/src/event/eventTest.js
dom/tests/mochitest/ajax/jquery/src/fx/Makefile.in
dom/tests/mochitest/ajax/jquery/src/fx/fx.js
dom/tests/mochitest/ajax/jquery/src/fx/fxTest.js
dom/tests/mochitest/ajax/jquery/src/intro.js
dom/tests/mochitest/ajax/jquery/src/jquery/Makefile.in
dom/tests/mochitest/ajax/jquery/src/jquery/coreTest.js
dom/tests/mochitest/ajax/jquery/src/jquery/jquery.js
dom/tests/mochitest/ajax/jquery/src/outro.js
dom/tests/mochitest/ajax/jquery/src/selector/Makefile.in
dom/tests/mochitest/ajax/jquery/src/selector/selector.js
dom/tests/mochitest/ajax/jquery/src/selector/selectorTest.js
gfx/src/thebes/nsThebesDeviceContext.cpp
gfx/thebes/public/Makefile.in
gfx/thebes/public/gfxXlibNativeRenderer.h
gfx/thebes/src/Makefile.in
gfx/thebes/src/cairo-xlib-utils.h
gfx/thebes/src/gfxASurface.cpp
gfx/thebes/src/gfxFont.cpp
gfx/thebes/src/gfxXlibNativeRenderer.cpp
js/src/js.cpp
js/src/jsapi.cpp
js/src/jsarray.cpp
js/src/jsbool.cpp
js/src/jscntxt.cpp
js/src/jsdate.cpp
js/src/jsdtoa.cpp
js/src/jsemit.cpp
js/src/jsexn.cpp
js/src/jsfun.cpp
js/src/jsinterp.cpp
js/src/jsiter.cpp
js/src/jslock.cpp
js/src/jsmath.cpp
js/src/jsnum.cpp
js/src/jsobj.cpp
js/src/jsopcode.cpp
js/src/jsparse.cpp
js/src/jsregexp.cpp
js/src/jsstr.cpp
js/src/jsxml.cpp
modules/libfishsound/AUTHORS
modules/libfishsound/COPYING
modules/libfishsound/ChangeLog
modules/libfishsound/Makefile.in
modules/libfishsound/README
modules/libfishsound/README_MOZILLA
modules/libfishsound/include/Makefile.in
modules/libfishsound/include/fishsound/Makefile.in
modules/libfishsound/include/fishsound/comments.h
modules/libfishsound/include/fishsound/config.h
modules/libfishsound/include/fishsound/constants.h
modules/libfishsound/include/fishsound/decode.h
modules/libfishsound/include/fishsound/deprecated.h
modules/libfishsound/include/fishsound/encode.h
modules/libfishsound/include/fishsound/fishsound.h
modules/libfishsound/src/Makefile.in
modules/libfishsound/src/libfishsound/Makefile.in
modules/libfishsound/src/libfishsound/config.h
modules/libfishsound/src/libfishsound/convert.h
modules/libfishsound/src/libfishsound/convert_c.h
modules/libfishsound/src/libfishsound/convert_oil.h
modules/libfishsound/src/libfishsound/fishsound.c
modules/libfishsound/src/libfishsound/fishsound_comments.c
modules/libfishsound/src/libfishsound/fishsound_decode.c
modules/libfishsound/src/libfishsound/fishsound_encode.c
modules/libfishsound/src/libfishsound/fishsound_flac.c
modules/libfishsound/src/libfishsound/fishsound_speex.c
modules/libfishsound/src/libfishsound/fishsound_vorbis.c
modules/libfishsound/src/libfishsound/fs_compat.h
modules/libfishsound/src/libfishsound/fs_vector.c
modules/libfishsound/src/libfishsound/fs_vector.h
modules/libfishsound/src/libfishsound/private.h
modules/libfishsound/update.sh
modules/libogg/AUTHORS
modules/libogg/CHANGES
modules/libogg/COPYING
modules/libogg/Makefile.in
modules/libogg/README
modules/libogg/README_MOZILLA
modules/libogg/include/Makefile.in
modules/libogg/include/ogg/Makefile.in
modules/libogg/include/ogg/config_types.h
modules/libogg/include/ogg/ogg.h
modules/libogg/include/ogg/os_types.h
modules/libogg/src/Makefile.in
modules/libogg/src/bitwise.c
modules/libogg/src/framing.c
modules/libogg/src/ogg_bitwise.c
modules/libogg/src/ogg_framing.c
modules/libogg/update.sh
modules/liboggplay/Makefile.in
modules/liboggplay/README
modules/liboggplay/README_MOZILLA
modules/liboggplay/include/Makefile.in
modules/liboggplay/include/oggplay/Makefile.in
modules/liboggplay/include/oggplay/config_win32.h
modules/liboggplay/include/oggplay/oggplay.h
modules/liboggplay/include/oggplay/oggplay_callback_info.h
modules/liboggplay/include/oggplay/oggplay_enums.h
modules/liboggplay/include/oggplay/oggplay_query.h
modules/liboggplay/include/oggplay/oggplay_reader.h
modules/liboggplay/include/oggplay/oggplay_seek.h
modules/liboggplay/include/oggplay/oggplay_tools.h
modules/liboggplay/src/Makefile.in
modules/liboggplay/src/liboggplay/Makefile.in
modules/liboggplay/src/liboggplay/config.h
modules/liboggplay/src/liboggplay/oggplay.c
modules/liboggplay/src/liboggplay/oggplay_buffer.c
modules/liboggplay/src/liboggplay/oggplay_buffer.h
modules/liboggplay/src/liboggplay/oggplay_callback.c
modules/liboggplay/src/liboggplay/oggplay_callback.h
modules/liboggplay/src/liboggplay/oggplay_callback_info.c
modules/liboggplay/src/liboggplay/oggplay_data.c
modules/liboggplay/src/liboggplay/oggplay_data.h
modules/liboggplay/src/liboggplay/oggplay_file_reader.c
modules/liboggplay/src/liboggplay/oggplay_file_reader.h
modules/liboggplay/src/liboggplay/oggplay_private.h
modules/liboggplay/src/liboggplay/oggplay_query.c
modules/liboggplay/src/liboggplay/oggplay_seek.c
modules/liboggplay/src/liboggplay/oggplay_tcp_reader.c
modules/liboggplay/src/liboggplay/oggplay_tcp_reader.h
modules/liboggplay/src/liboggplay/oggplay_tools.c
modules/liboggplay/src/liboggplay/oggplay_yuv2rgb.c
modules/liboggplay/src/liboggplay/std_semaphore.h
modules/liboggplay/update.sh
modules/liboggplay_audio/Makefile.in
modules/liboggplay_audio/README_MOZILLA
modules/liboggplay_audio/sydney_audio.h
modules/liboggplay_audio/sydney_audio_alsa.c
modules/liboggplay_audio/sydney_audio_mac.c
modules/liboggplay_audio/sydney_audio_oss.c
modules/liboggplay_audio/sydney_audio_waveapi.c
modules/liboggplay_audio/update.sh
modules/liboggz/AUTHORS
modules/liboggz/COPYING
modules/liboggz/ChangeLog
modules/liboggz/Makefile.in
modules/liboggz/README
modules/liboggz/README_MOZILLA
modules/liboggz/include/Makefile.in
modules/liboggz/include/oggz/Makefile.in
modules/liboggz/include/oggz/config.h
modules/liboggz/include/oggz/config_win32.h
modules/liboggz/include/oggz/oggz.h
modules/liboggz/include/oggz/oggz_comments.h
modules/liboggz/include/oggz/oggz_constants.h
modules/liboggz/include/oggz/oggz_deprecated.h
modules/liboggz/include/oggz/oggz_io.h
modules/liboggz/include/oggz/oggz_off_t.h
modules/liboggz/include/oggz/oggz_off_t_generated.h
modules/liboggz/include/oggz/oggz_read.h
modules/liboggz/include/oggz/oggz_seek.h
modules/liboggz/include/oggz/oggz_stream.h
modules/liboggz/include/oggz/oggz_table.h
modules/liboggz/include/oggz/oggz_write.h
modules/liboggz/src/Makefile.in
modules/liboggz/src/liboggz/Makefile.in
modules/liboggz/src/liboggz/metric_internal.c
modules/liboggz/src/liboggz/oggz.c
modules/liboggz/src/liboggz/oggz_auto.c
modules/liboggz/src/liboggz/oggz_auto.h
modules/liboggz/src/liboggz/oggz_byteorder.h
modules/liboggz/src/liboggz/oggz_comments.c
modules/liboggz/src/liboggz/oggz_compat.h
modules/liboggz/src/liboggz/oggz_dlist.c
modules/liboggz/src/liboggz/oggz_dlist.h
modules/liboggz/src/liboggz/oggz_io.c
modules/liboggz/src/liboggz/oggz_macros.h
modules/liboggz/src/liboggz/oggz_private.h
modules/liboggz/src/liboggz/oggz_read.c
modules/liboggz/src/liboggz/oggz_seek.c
modules/liboggz/src/liboggz/oggz_stream.c
modules/liboggz/src/liboggz/oggz_stream.h
modules/liboggz/src/liboggz/oggz_stream_private.h
modules/liboggz/src/liboggz/oggz_table.c
modules/liboggz/src/liboggz/oggz_vector.c
modules/liboggz/src/liboggz/oggz_vector.h
modules/liboggz/src/liboggz/oggz_write.c
modules/liboggz/update.sh
modules/libtheora/AUTHORS
modules/libtheora/CHANGES
modules/libtheora/COPYING
modules/libtheora/LICENSE
modules/libtheora/Makefile.in
modules/libtheora/README
modules/libtheora/README_MOZILLA
modules/libtheora/include/Makefile.in
modules/libtheora/include/theora/Makefile.in
modules/libtheora/include/theora/codec.h
modules/libtheora/include/theora/config.h
modules/libtheora/include/theora/theora.h
modules/libtheora/include/theora/theoradec.h
modules/libtheora/lib/Makefile.in
modules/libtheora/lib/config.h
modules/libtheora/lib/cpu.c
modules/libtheora/lib/cpu.h
modules/libtheora/lib/dec/apiwrapper.c
modules/libtheora/lib/dec/apiwrapper.h
modules/libtheora/lib/dec/bitwise.c
modules/libtheora/lib/dec/bitwise.h
modules/libtheora/lib/dec/dct.h
modules/libtheora/lib/dec/decapiwrapper.c
modules/libtheora/lib/dec/decinfo.c
modules/libtheora/lib/dec/decint.h
modules/libtheora/lib/dec/decode.c
modules/libtheora/lib/dec/dequant.c
modules/libtheora/lib/dec/dequant.h
modules/libtheora/lib/dec/enquant.h
modules/libtheora/lib/dec/fragment.c
modules/libtheora/lib/dec/huffdec.c
modules/libtheora/lib/dec/huffdec.h
modules/libtheora/lib/dec/huffman.h
modules/libtheora/lib/dec/idct.c
modules/libtheora/lib/dec/idct.h
modules/libtheora/lib/dec/info.c
modules/libtheora/lib/dec/internal.c
modules/libtheora/lib/dec/ocintrin.h
modules/libtheora/lib/dec/quant.c
modules/libtheora/lib/dec/quant.h
modules/libtheora/lib/dec/state.c
modules/libtheora/lib/dec/x86/mmxfrag.c
modules/libtheora/lib/dec/x86/mmxidct.c
modules/libtheora/lib/dec/x86/mmxstate.c
modules/libtheora/lib/dec/x86/x86int.h
modules/libtheora/lib/dec/x86/x86state.c
modules/libtheora/lib/internal.h
modules/libtheora/update.sh
modules/libvorbis/AUTHORS
modules/libvorbis/COPYING
modules/libvorbis/Makefile.in
modules/libvorbis/README
modules/libvorbis/README_MOZILLA
modules/libvorbis/include/Makefile.in
modules/libvorbis/include/vorbis/Makefile.in
modules/libvorbis/include/vorbis/codec.h
modules/libvorbis/lib/Makefile.in
modules/libvorbis/lib/backends.h
modules/libvorbis/lib/bitrate.h
modules/libvorbis/lib/codebook.h
modules/libvorbis/lib/codec_internal.h
modules/libvorbis/lib/envelope.h
modules/libvorbis/lib/highlevel.h
modules/libvorbis/lib/lookup.h
modules/libvorbis/lib/lookup_data.h
modules/libvorbis/lib/lpc.h
modules/libvorbis/lib/lsp.h
modules/libvorbis/lib/masking.h
modules/libvorbis/lib/mdct.h
modules/libvorbis/lib/misc.h
modules/libvorbis/lib/os.h
modules/libvorbis/lib/psy.h
modules/libvorbis/lib/registry.h
modules/libvorbis/lib/scales.h
modules/libvorbis/lib/smallft.h
modules/libvorbis/lib/vorbis_analysis.c
modules/libvorbis/lib/vorbis_bitrate.c
modules/libvorbis/lib/vorbis_block.c
modules/libvorbis/lib/vorbis_codebook.c
modules/libvorbis/lib/vorbis_envelope.c
modules/libvorbis/lib/vorbis_floor0.c
modules/libvorbis/lib/vorbis_floor1.c
modules/libvorbis/lib/vorbis_info.c
modules/libvorbis/lib/vorbis_lookup.c
modules/libvorbis/lib/vorbis_lpc.c
modules/libvorbis/lib/vorbis_lsp.c
modules/libvorbis/lib/vorbis_mapping0.c
modules/libvorbis/lib/vorbis_mdct.c
modules/libvorbis/lib/vorbis_psy.c
modules/libvorbis/lib/vorbis_registry.c
modules/libvorbis/lib/vorbis_res0.c
modules/libvorbis/lib/vorbis_sharedbook.c
modules/libvorbis/lib/vorbis_smallft.c
modules/libvorbis/lib/vorbis_synthesis.c
modules/libvorbis/lib/vorbis_window.c
modules/libvorbis/lib/window.h
modules/libvorbis/todo.txt
modules/libvorbis/update.sh
toolkit/library/libxul-config.mk
toolkit/themes/gnomestripe/mozapps/extensions/searchIcons.png
toolkit/themes/pinstripe/mozapps/extensions/searchIcons.png
toolkit/toolkit-tiers.mk
toolkit/xre/nsAppRunner.cpp
widget/src/Makefile.in
--- a/accessible/build/Makefile.in
+++ b/accessible/build/Makefile.in
@@ -89,13 +89,16 @@ EXTRA_DSO_LDOPTS =           \
 	$(MOZ_COMPONENT_LIBS)    \
 	$(NULL)
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
 EXTRA_DSO_LDOPTS += $(MOZ_GTK2_LIBS)
 endif
 
 ifeq ($(OS_ARCH),WINNT)
-OS_LIBS += oleaut32.lib
+OS_LIBS += \
+	oleaut32.lib \
+	version.lib \
+	$(NULL)
 endif
 
 include $(topsrcdir)/config/rules.mk
 
--- a/accessible/src/base/nsAccessNode.cpp
+++ b/accessible/src/base/nsAccessNode.cpp
@@ -107,22 +107,33 @@ nsIAccessibilityService *nsAccessNode::G
 
   return sAccService;
 }
 
 /*
  * Class nsAccessNode
  */
  
-//-----------------------------------------------------
-// construction 
-//-----------------------------------------------------
-NS_IMPL_QUERY_INTERFACE2(nsAccessNode, nsIAccessNode, nsPIAccessNode)
-NS_IMPL_ADDREF(nsAccessNode)
-NS_IMPL_RELEASE_WITH_DESTROY(nsAccessNode, LastRelease())
+////////////////////////////////////////////////////////////////////////////////
+// nsAccessible. nsISupports
+
+NS_IMPL_CYCLE_COLLECTION_0(nsAccessNode)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsAccessNode)
+  NS_INTERFACE_MAP_ENTRY(nsIAccessNode)
+  NS_INTERFACE_MAP_ENTRY(nsPIAccessNode)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIAccessNode)
+NS_INTERFACE_MAP_END
+ 
+NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(nsAccessNode, nsIAccessNode)
+NS_IMPL_CYCLE_COLLECTING_RELEASE_FULL(nsAccessNode, nsIAccessNode,
+                                      LastRelease())
+
+////////////////////////////////////////////////////////////////////////////////
+// nsAccessible. Constructor
 
 nsAccessNode::nsAccessNode(nsIDOMNode *aNode, nsIWeakReference* aShell): 
   mDOMNode(aNode), mWeakShell(aShell)
 {
 #ifdef DEBUG_A11Y
   mIsInitialized = PR_FALSE;
 #endif
 }
--- a/accessible/src/base/nsAccessNode.h
+++ b/accessible/src/base/nsAccessNode.h
@@ -69,23 +69,26 @@ class nsApplicationAccessibleWrap;
 class nsIDocShellTreeItem;
 
 #define ACCESSIBLE_BUNDLE_URL "chrome://global-platform/locale/accessible.properties"
 #define PLATFORM_KEYS_BUNDLE_URL "chrome://global-platform/locale/platformKeys.properties"
 
 typedef nsInterfaceHashtable<nsVoidPtrHashKey, nsIAccessNode>
         nsAccessNodeHashtable;
 
-class nsAccessNode: public nsIAccessNode, public nsPIAccessNode
+class nsAccessNode: public nsIAccessNode,
+                    public nsPIAccessNode
 {
   public: // construction, destruction
     nsAccessNode(nsIDOMNode *, nsIWeakReference* aShell);
     virtual ~nsAccessNode();
 
-    NS_DECL_ISUPPORTS
+    NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+    NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsAccessNode, nsIAccessNode)
+
     NS_DECL_NSIACCESSNODE
     NS_DECL_NSPIACCESSNODE
 
     static void InitXPAccessibility();
     static void ShutdownXPAccessibility();
 
     /**
      * Return an application accessible.
--- a/accessible/src/base/nsAccessibilityUtils.cpp
+++ b/accessible/src/base/nsAccessibilityUtils.cpp
@@ -60,16 +60,17 @@
 #include "nsIDOMWindowInternal.h"
 #include "nsIEventListenerManager.h"
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsIScrollableFrame.h"
 #include "nsIEventStateManager.h"
 #include "nsISelection2.h"
 #include "nsISelectionController.h"
+#include "nsGUIEvent.h"
 
 #include "nsContentCID.h"
 #include "nsComponentManagerUtils.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsWhitespaceTokenizer.h"
 
 static NS_DEFINE_IID(kRangeCID, NS_RANGE_CID);
 
@@ -286,16 +287,58 @@ nsAccUtils::HasListener(nsIContent *aCon
 {
   NS_ENSURE_TRUE(aContent, PR_FALSE);
   nsCOMPtr<nsIEventListenerManager> listenerManager;
   aContent->GetListenerManager(PR_FALSE, getter_AddRefs(listenerManager));
 
   return listenerManager && listenerManager->HasListenersFor(aEventType);  
 }
 
+PRBool
+nsAccUtils::DispatchMouseEvent(PRUint32 aEventType,
+                               nsIPresShell *aPresShell,
+                               nsIContent *aContent)
+{
+  nsIFrame *frame = aPresShell->GetPrimaryFrameFor(aContent);
+  if (!frame)
+    return PR_FALSE;
+
+  nsIFrame* rootFrame = aPresShell->GetRootFrame();
+  if (!rootFrame)
+    return PR_FALSE;
+
+  nsCOMPtr<nsIWidget> rootWidget = rootFrame->GetWindow();
+  if (!rootWidget)
+    return PR_FALSE;
+
+  // Compute x and y coordinates.
+  nsPoint point = frame->GetOffsetToExternal(rootFrame);
+  nsSize size = frame->GetSize();
+
+  nsPresContext* presContext = aPresShell->GetPresContext();
+
+  PRInt32 x = presContext->AppUnitsToDevPixels(point.x + size.width / 2);
+  PRInt32 y = presContext->AppUnitsToDevPixels(point.y + size.height / 2);
+  
+  // Fire mouse event.
+  nsMouseEvent event(PR_TRUE, aEventType, rootWidget,
+                     nsMouseEvent::eReal, nsMouseEvent::eNormal);
+
+  event.refPoint = nsIntPoint(x, y);
+  
+  event.clickCount = 1;
+  event.button = nsMouseEvent::eLeftButton;
+  event.time = PR_IntervalNow();
+  
+  nsEventStatus status = nsEventStatus_eIgnore;
+  aPresShell->HandleEventWithTarget(&event, frame, aContent, &status);
+
+  return PR_TRUE;
+}
+
 PRUint32
 nsAccUtils::GetAccessKeyFor(nsIContent *aContent)
 {
   if (!aContent)
     return 0;
 
   // Accesskeys are registered by @accesskey attribute only. At first check
   // whether it is presented on the given element to avoid the slow
--- a/accessible/src/base/nsAccessibilityUtils.h
+++ b/accessible/src/base/nsAccessibilityUtils.h
@@ -120,16 +120,27 @@ public:
 
   /**
    * Return true if the given node has registered event listener of the given
    * type.
    */
   static PRBool HasListener(nsIContent *aContent, const nsAString& aEventType);
 
   /**
+   * Send mouse events to the given element.
+   *
+   * @param aEventType  an event type (see nsGUIEvent.h for constants)
+   * @param aPresShell  the presshell for the given element
+   * @param aContent    the element element
+   */
+  static PRBool DispatchMouseEvent(PRUint32 aEventType,
+                                   nsIPresShell *aPresShell,
+                                   nsIContent *aContent);
+
+  /**
    * Return an accesskey registered on the given element by
    * nsIEventStateManager or 0 if there is no registered accesskey.
    *
    * @param aContent - the given element.
    */
   static PRUint32 GetAccessKeyFor(nsIContent *aContent);
 
   /**
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -135,19 +135,33 @@ nsAccessibleDOMStringList::Contains(cons
 
   return NS_OK;
 }
 
 /*
  * Class nsAccessible
  */
 
-//-----------------------------------------------------
-// construction 
-//-----------------------------------------------------
+////////////////////////////////////////////////////////////////////////////////
+// nsAccessible. nsISupports
+
+NS_IMPL_CYCLE_COLLECTION_CLASS(nsAccessible)
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsAccessible, nsAccessNode)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mParent)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFirstChild)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mNextSibling)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsAccessible, nsAccessNode)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mParent)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFirstChild)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mNextSibling)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
 NS_IMPL_ADDREF_INHERITED(nsAccessible, nsAccessNode)
 NS_IMPL_RELEASE_INHERITED(nsAccessible, nsAccessNode)
 
 #ifdef DEBUG_A11Y
 /*
  * static
  * help method. to detect whether this accessible object implements
  * nsIAccessibleText, when it is text or has text child node.
@@ -183,17 +197,22 @@ PRBool nsAccessible::IsTextInterfaceSupp
 }
 #endif
 
 nsresult nsAccessible::QueryInterface(REFNSIID aIID, void** aInstancePtr)
 {
   // Custom-built QueryInterface() knows when we support nsIAccessibleSelectable
   // based on role attribute and aria-multiselectable
   *aInstancePtr = nsnull;
-  
+
+  if (aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant))) {
+    *aInstancePtr = &NS_CYCLE_COLLECTION_NAME(nsAccessible);
+    return NS_OK;
+  }
+
   if (aIID.Equals(NS_GET_IID(nsIAccessible))) {
     *aInstancePtr = static_cast<nsIAccessible*>(this);
     NS_ADDREF_THIS();
     return NS_OK;
   }
 
   if(aIID.Equals(NS_GET_IID(nsPIAccessible))) {
     *aInstancePtr = static_cast<nsPIAccessible*>(this);
@@ -478,17 +497,17 @@ NS_IMETHODIMP nsAccessible::SetFirstChil
 {
   mFirstChild = aFirstChild;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP nsAccessible::SetNextSibling(nsIAccessible *aNextSibling)
 {
-  mNextSibling = aNextSibling? aNextSibling: DEAD_END_ACCESSIBLE;
+  mNextSibling = aNextSibling;
   return NS_OK;
 }
 
 nsIContent *nsAccessible::GetRoleContent(nsIDOMNode *aDOMNode)
 {
   // Given the DOM node for an acessible, return content node that
   // we should look for ARIA properties on.
   // For non-document accessibles, this is the associated content node.
@@ -533,25 +552,23 @@ NS_IMETHODIMP nsAccessible::Shutdown()
 NS_IMETHODIMP nsAccessible::InvalidateChildren()
 {
   // Document has transformed, reset our invalid children and child count
 
   // Reset the sibling pointers, they will be set up again the next time
   // CacheChildren() is called.
   // Note: we don't want to start creating accessibles at this point,
   // so don't use GetNextSibling() here. (bug 387252)
-  nsAccessible* child = static_cast<nsAccessible*>(mFirstChild);
+  nsAccessible* child = static_cast<nsAccessible*>(mFirstChild.get());
   while (child) {
     child->mParent = nsnull;
-    if (child->mNextSibling == DEAD_END_ACCESSIBLE) {
-      break;
-    }
-    nsIAccessible *next = child->mNextSibling;
+
+    nsCOMPtr<nsIAccessible> next = child->mNextSibling;
     child->mNextSibling = nsnull;
-    child = static_cast<nsAccessible*>(next);
+    child = static_cast<nsAccessible*>(next.get());
   }
 
   mAccChildCount = eChildCountUninitialized;
   mFirstChild = nsnull;
   return NS_OK;
 }
 
 NS_IMETHODIMP nsAccessible::GetParent(nsIAccessible **  aParent)
@@ -603,19 +620,18 @@ NS_IMETHODIMP nsAccessible::GetNextSibli
       PRInt32 numChildren;
       parent->GetChildCount(&numChildren);  // Make sure we cache all of the children
     }
   }
 
   if (mNextSibling || !mParent) {
     // If no parent, don't try to calculate a new sibling
     // It either means we're at the root or shutting down the parent
-    if (mNextSibling != DEAD_END_ACCESSIBLE) {
-      NS_IF_ADDREF(*aNextSibling = mNextSibling);
-    }
+    NS_IF_ADDREF(*aNextSibling = mNextSibling);
+
     return NS_OK;
   }
 
   return NS_ERROR_FAILURE;
 }
 
   /* readonly attribute nsIAccessible previousSibling; */
 NS_IMETHODIMP nsAccessible::GetPreviousSibling(nsIAccessible * *aPreviousSibling) 
@@ -3132,50 +3148,40 @@ NS_IMETHODIMP nsAccessible::ExtendSelect
 /* [noscript] void getNativeInterface(out voidPtr aOutAccessible); */
 NS_IMETHODIMP nsAccessible::GetNativeInterface(void **aOutAccessible)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 void nsAccessible::DoCommandCallback(nsITimer *aTimer, void *aClosure)
 {
-  NS_ASSERTION(gDoCommandTimer, "How did we get here if there was no gDoCommandTimer?");
+  NS_ASSERTION(gDoCommandTimer,
+               "How did we get here if there was no gDoCommandTimer?");
   NS_RELEASE(gDoCommandTimer);
 
-  nsIContent *content = reinterpret_cast<nsIContent*>(aClosure);
-  nsCOMPtr<nsIDOMXULElement> xulElement(do_QueryInterface(content));
-  if (xulElement) {
-    xulElement->Click();
-  }
-  else {
-    nsIDocument *doc = content->GetDocument();
-    if (!doc) {
-      return;
-    }
-    nsCOMPtr<nsIPresShell> presShell = doc->GetPrimaryShell();
-    nsPIDOMWindow *outerWindow = doc->GetWindow();
-    if (presShell && outerWindow) {
-      nsAutoPopupStatePusher popupStatePusher(outerWindow, openAllowed);
-
-      nsMouseEvent downEvent(PR_TRUE, NS_MOUSE_BUTTON_DOWN, nsnull,
-                             nsMouseEvent::eSynthesized);
-      nsMouseEvent upEvent(PR_TRUE, NS_MOUSE_BUTTON_UP, nsnull,
-                           nsMouseEvent::eSynthesized);
-      nsMouseEvent clickEvent(PR_TRUE, NS_MOUSE_CLICK, nsnull,
-                              nsMouseEvent::eSynthesized);
-
-      nsEventStatus eventStatus = nsEventStatus_eIgnore;
-      content->DispatchDOMEvent(&downEvent, nsnull,
-                                 presShell->GetPresContext(), &eventStatus);
-      content->DispatchDOMEvent(&upEvent, nsnull,
-                                 presShell->GetPresContext(), &eventStatus);
-      content->DispatchDOMEvent(&clickEvent, nsnull,
-                                 presShell->GetPresContext(), &eventStatus);
-    }
-  }
+  nsCOMPtr<nsIContent> content =
+    reinterpret_cast<nsIContent*>(aClosure);
+
+  nsIDocument *doc = content->GetDocument();
+  if (!doc)
+    return;
+
+  nsCOMPtr<nsIPresShell> presShell = doc->GetPrimaryShell();
+
+  // Scroll into view.
+  presShell->ScrollContentIntoView(content, NS_PRESSHELL_SCROLL_ANYWHERE,
+                                   NS_PRESSHELL_SCROLL_ANYWHERE);
+
+  // Fire mouse down and mouse up events.
+  PRBool res = nsAccUtils::DispatchMouseEvent(NS_MOUSE_BUTTON_DOWN, presShell,
+                                              content);
+  if (!res)
+    return;
+
+  nsAccUtils::DispatchMouseEvent(NS_MOUSE_BUTTON_UP, presShell, content);
 }
 
 /*
  * Use Timer to execute "Click" command of XUL/HTML element (e.g. menuitem, button...).
  *
  * When "Click" is to open a "modal" dialog/window, it won't return untill the
  * dialog/window is closed. If executing "Click" command directly in
  * nsXXXAccessible::DoAction, it will block AT-Tools(e.g. GOK) that invoke
--- a/accessible/src/base/nsAccessible.h
+++ b/accessible/src/base/nsAccessible.h
@@ -64,19 +64,16 @@ class nsIFrame;
 class nsIPresShell;
 class nsIDOMNode;
 class nsIAtom;
 class nsIView;
 
 #define NS_OK_NO_ARIA_VALUE \
 NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_GENERAL, 0x21)
 
-// When mNextSibling is set to this, it indicates there ar eno more siblings
-#define DEAD_END_ACCESSIBLE static_cast<nsIAccessible*>((void*)1)
-
 // Saves a data member -- if child count equals this value we haven't
 // cached children or child count yet
 enum { eChildCountUninitialized = -1 };
 
 class nsAccessibleDOMStringList : public nsIDOMDOMStringList
 {
 public:
   nsAccessibleDOMStringList();
@@ -101,16 +98,18 @@ class nsAccessible : public nsAccessNode
                      public nsIAccessibleSelectable,
                      public nsIAccessibleValue
 {
 public:
   nsAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
   virtual ~nsAccessible();
 
   NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsAccessible, nsAccessNode)
+
   NS_DECL_NSIACCESSIBLE
   NS_DECL_NSPIACCESSIBLE
   NS_DECL_NSIACCESSIBLEHYPERLINK
   NS_DECL_NSIACCESSIBLESELECTABLE
   NS_DECL_NSIACCESSIBLEVALUE
 
   // nsIAccessNode
   NS_IMETHOD Shutdown();
@@ -267,16 +266,18 @@ protected:
    * in xul:tree accessible to lie to AT. Must be overridden in wrap classes.
    *
    * @param aEvent  the accessible event to fire.
    */
   virtual nsresult FirePlatformEvent(nsIAccessibleEvent *aEvent) = 0;
 
   // Data Members
   nsCOMPtr<nsIAccessible> mParent;
-  nsIAccessible *mFirstChild, *mNextSibling;
+  nsCOMPtr<nsIAccessible> mFirstChild;
+  nsCOMPtr<nsIAccessible> mNextSibling;
+
   nsRoleMapEntry *mRoleMapEntry; // Non-null indicates author-supplied role; possibly state & value as well
   PRInt32 mAccChildCount;
 };
 
 
 #endif  
 
--- a/accessible/src/base/nsAccessibleEventData.cpp
+++ b/accessible/src/base/nsAccessibleEventData.cpp
@@ -52,17 +52,32 @@
 #include "nsIAccessibleText.h"
 #include "nsIContent.h"
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
 
 PRBool nsAccEvent::gLastEventFromUserInput = PR_FALSE;
 nsIDOMNode* nsAccEvent::gLastEventNodeWeak = 0;
 
-NS_IMPL_ISUPPORTS2(nsAccEvent, nsAccEvent, nsIAccessibleEvent)
+////////////////////////////////////////////////////////////////////////////////
+// nsAccEvent. nsISupports
+
+NS_IMPL_CYCLE_COLLECTION_2(nsAccEvent, mAccessible, mDocAccessible)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsAccEvent)
+  NS_INTERFACE_MAP_ENTRY(nsIAccessibleEvent)
+  NS_INTERFACE_MAP_ENTRY(nsAccEvent)
+  NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(nsAccEvent)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(nsAccEvent)
+
+////////////////////////////////////////////////////////////////////////////////
+// nsAccEvent. Constructors
 
 nsAccEvent::nsAccEvent(PRUint32 aEventType, nsIAccessible *aAccessible,
                        PRBool aIsAsynch, EEventRule aEventRule):
   mEventType(aEventType), mAccessible(aAccessible), mEventRule(aEventRule)
 {
   CaptureIsFromUserInput(aIsAsynch);
 }
 
--- a/accessible/src/base/nsAccessibleEventData.h
+++ b/accessible/src/base/nsAccessibleEventData.h
@@ -44,16 +44,17 @@
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsCOMArray.h"
 #include "nsIAccessibleEvent.h"
 #include "nsIAccessible.h"
 #include "nsIAccessibleDocument.h"
 #include "nsIDOMNode.h"
 #include "nsString.h"
+#include "nsCycleCollectionParticipant.h"
 
 class nsIPresShell;
 
 #define NS_ACCEVENT_IMPL_CID                            \
 {  /* 55b89892-a83d-4252-ba78-cbdf53a86936 */           \
   0x55b89892,                                           \
   0xa83d,                                               \
   0x4252,                                               \
@@ -88,35 +89,37 @@ public:
              PRBool aIsAsynch = PR_FALSE,
              EEventRule aEventRule = eRemoveDupes);
   // Initialize with an nsIDOMNode
   nsAccEvent(PRUint32 aEventType, nsIDOMNode *aDOMNode,
              PRBool aIsAsynch = PR_FALSE,
              EEventRule aEventRule = eRemoveDupes);
   virtual ~nsAccEvent() {}
 
-  NS_DECL_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_CLASS(nsAccEvent)
+
   NS_DECL_NSIACCESSIBLEEVENT
 
   static void GetLastEventAttributes(nsIDOMNode *aNode,
                                      nsIPersistentProperties *aAttributes);
 
 protected:
   already_AddRefed<nsIAccessible> GetAccessibleByNode();
 
   void CaptureIsFromUserInput(PRBool aIsAsynch);
   PRBool mIsFromUserInput;
 
-private:
   PRUint32 mEventType;
   EEventRule mEventRule;
   nsCOMPtr<nsIAccessible> mAccessible;
   nsCOMPtr<nsIDOMNode> mDOMNode;
   nsCOMPtr<nsIAccessibleDocument> mDocAccessible;
 
+private:
   static PRBool gLastEventFromUserInput;
   static nsIDOMNode* gLastEventNodeWeak;
 
 public:
   static PRUint32 EventType(nsIAccessibleEvent *aAccEvent) {
     PRUint32 eventType;
     aAccEvent->GetEventType(&eventType);
     return eventType;
--- a/accessible/src/base/nsApplicationAccessible.cpp
+++ b/accessible/src/base/nsApplicationAccessible.cpp
@@ -45,21 +45,58 @@
 #include "nsIComponentManager.h"
 #include "nsServiceManagerUtils.h"
 
 nsApplicationAccessible::nsApplicationAccessible():
     nsAccessibleWrap(nsnull, nsnull), mChildren(nsnull)
 {
 }
 
+////////////////////////////////////////////////////////////////////////////////
 // nsISupports
-NS_IMPL_ISUPPORTS_INHERITED0(nsApplicationAccessible,
-                             nsAccessible)
+
+NS_IMPL_CYCLE_COLLECTION_CLASS(nsApplicationAccessible)
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsApplicationAccessible,
+                                                  nsAccessible)
+
+  nsCOMPtr<nsISimpleEnumerator> enumerator;
+  tmp->mChildren->Enumerate(getter_AddRefs(enumerator));
+
+  nsCOMPtr<nsIWeakReference> childWeakRef;
+  nsCOMPtr<nsIAccessible> accessible;
+
+  PRBool hasMoreElements;
+  while(NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreElements))
+        && hasMoreElements) {
 
+    enumerator->GetNext(getter_AddRefs(childWeakRef));
+    accessible = do_QueryReferent(childWeakRef);
+    if (accessible) {
+      NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, accessible);
+      cb.NoteXPCOMChild(accessible);
+    }
+  }
+  
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsApplicationAccessible,
+                                                nsAccessible)
+  tmp->mChildren->Clear();
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsApplicationAccessible)
+NS_INTERFACE_MAP_END_INHERITING(nsAccessible)
+
+NS_IMPL_ADDREF_INHERITED(nsApplicationAccessible, nsAccessible)
+NS_IMPL_RELEASE_INHERITED(nsApplicationAccessible, nsAccessible)
+
+////////////////////////////////////////////////////////////////////////////////
 // nsIAccessNode
+
 NS_IMETHODIMP
 nsApplicationAccessible::Init()
 {
   nsresult rv;
   mChildren = do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
   return rv;
 }
 
--- a/accessible/src/base/nsApplicationAccessible.h
+++ b/accessible/src/base/nsApplicationAccessible.h
@@ -58,16 +58,18 @@
 
 class nsApplicationAccessible: public nsAccessibleWrap
 {
 public:
   nsApplicationAccessible();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsApplicationAccessible,
+                                           nsAccessible)
 
   // nsPIAccessNode
   NS_IMETHOD Init();
 
   // nsIAccessible
   NS_IMETHOD GetName(nsAString & aName);
   NS_IMETHOD GetRole(PRUint32 *aRole);
   NS_IMETHOD GetFinalRole(PRUint32 *aFinalRole);
--- a/accessible/src/base/nsBaseWidgetAccessible.cpp
+++ b/accessible/src/base/nsBaseWidgetAccessible.cpp
@@ -183,21 +183,24 @@ nsLinkableAccessible::GetActionName(PRUi
     return NS_ERROR_NOT_IMPLEMENTED;
   }
   return NS_ERROR_INVALID_ARG;
 }
 
 NS_IMETHODIMP
 nsLinkableAccessible::DoAction(PRUint8 aIndex)
 {
+  if (aIndex != eAction_Jump)
+    return NS_ERROR_INVALID_ARG;
+  
   nsCOMPtr<nsIAccessible> actionAcc = GetActionAccessible();
   if (actionAcc)
     return actionAcc->DoAction(aIndex);
-
-  return NS_ERROR_INVALID_ARG;
+  
+  return nsHyperTextAccessibleWrap::DoAction(aIndex);
 }
 
 NS_IMETHODIMP
 nsLinkableAccessible::GetKeyboardShortcut(nsAString& aKeyboardShortcut)
 {
   aKeyboardShortcut.Truncate();
 
   nsCOMPtr<nsIAccessible> actionAcc = GetActionAccessible();
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -130,17 +130,44 @@ nsDocAccessible::nsDocAccessible(nsIDOMN
 
 //-----------------------------------------------------
 // destruction
 //-----------------------------------------------------
 nsDocAccessible::~nsDocAccessible()
 {
 }
 
-NS_INTERFACE_MAP_BEGIN(nsDocAccessible)
+////////////////////////////////////////////////////////////////////////////////
+// nsDocAccessible. nsISupports
+
+PR_STATIC_CALLBACK(PLDHashOperator)
+ElementTraverser(const void *aKey, nsIAccessNode *aAccessNode,
+                 void *aUserArg)
+{
+  nsCycleCollectionTraversalCallback *cb = 
+    static_cast<nsCycleCollectionTraversalCallback*>(aUserArg);
+
+  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb, aAccessNode);
+  cb->NoteXPCOMChild(aAccessNode);
+  return PL_DHASH_NEXT;
+}
+
+NS_IMPL_CYCLE_COLLECTION_CLASS(nsDocAccessible)
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDocAccessible, nsAccessible)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mEventsToFire)
+  tmp->mAccessNodeCache.EnumerateRead(ElementTraverser, &cb); 
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDocAccessible, nsAccessible)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mEventsToFire)
+  tmp->ClearCache(tmp->mAccessNodeCache);
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDocAccessible)
   NS_INTERFACE_MAP_ENTRY(nsIAccessibleDocument)
   NS_INTERFACE_MAP_ENTRY(nsPIAccessibleDocument)
   NS_INTERFACE_MAP_ENTRY(nsIDocumentObserver)
   NS_INTERFACE_MAP_ENTRY(nsIMutationObserver)
   NS_INTERFACE_MAP_ENTRY(nsIScrollPositionListener)
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIAccessibleDocument)
   NS_INTERFACE_MAP_ENTRY(nsIObserver)
--- a/accessible/src/base/nsDocAccessible.h
+++ b/accessible/src/base/nsDocAccessible.h
@@ -60,16 +60,18 @@ class nsDocAccessible : public nsHyperTe
                         public nsIAccessibleDocument,
                         public nsPIAccessibleDocument,
                         public nsIDocumentObserver,
                         public nsIObserver,
                         public nsIScrollPositionListener,
                         public nsSupportsWeakReference
 {  
   NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDocAccessible, nsAccessible)
+
   NS_DECL_NSIACCESSIBLEDOCUMENT
   NS_DECL_NSPIACCESSIBLEDOCUMENT
   NS_DECL_NSIOBSERVER
 
   public:
     nsDocAccessible(nsIDOMNode *aNode, nsIWeakReference* aShell);
     virtual ~nsDocAccessible();
 
--- a/accessible/src/msaa/nsAccessNodeWrap.cpp
+++ b/accessible/src/msaa/nsAccessNodeWrap.cpp
@@ -32,16 +32,17 @@
  * 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 "nsAccessNodeWrap.h"
+#include <tchar.h> 
 #include "ISimpleDOMNode_i.c"
 #include "nsAccessibilityAtoms.h"
 #include "nsIAccessibilityService.h"
 #include "nsIAccessible.h"
 #include "nsAttrName.h"
 #include "nsIDocument.h"
 #include "nsIDOMCSSStyleDeclaration.h"
 #include "nsIDOMNodeList.h"
@@ -61,16 +62,18 @@
 /// the accessible library and cached methods
 HINSTANCE nsAccessNodeWrap::gmAccLib = nsnull;
 HINSTANCE nsAccessNodeWrap::gmUserLib = nsnull;
 LPFNACCESSIBLEOBJECTFROMWINDOW nsAccessNodeWrap::gmAccessibleObjectFromWindow = nsnull;
 LPFNNOTIFYWINEVENT nsAccessNodeWrap::gmNotifyWinEvent = nsnull;
 LPFNGETGUITHREADINFO nsAccessNodeWrap::gmGetGUIThreadInfo = nsnull;
 
 PRBool nsAccessNodeWrap::gIsEnumVariantSupportDisabled = 0;
+// Used to determine whether an IAccessible2 compatible screen reader is loaded.
+PRBool nsAccessNodeWrap::gIsIA2Disabled = PR_FALSE;
 
 nsIAccessibleTextChangeEvent *nsAccessNodeWrap::gTextEvent = nsnull;
 
 
 /* For documentation of the accessibility architecture, 
  * see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
  */
 
@@ -594,16 +597,18 @@ void nsAccessNodeWrap::InitAccessibility
 
   if (gmUserLib) {
     if (!gmNotifyWinEvent)
       gmNotifyWinEvent = (LPFNNOTIFYWINEVENT)GetProcAddress(gmUserLib,"NotifyWinEvent");
     if (!gmGetGUIThreadInfo)
       gmGetGUIThreadInfo = (LPFNGETGUITHREADINFO)GetProcAddress(gmUserLib,"GetGUIThreadInfo");
   }
 
+  DoATSpecificProcessing();
+  
   nsAccessNode::InitXPAccessibility();
 }
 
 void nsAccessNodeWrap::ShutdownAccessibility()
 {
   NS_IF_RELEASE(gTextEvent);
   ::DestroyCaret();
 
@@ -650,8 +655,45 @@ GetHRESULT(nsresult aResult)
     case NS_ERROR_NOT_IMPLEMENTED:
       return E_NOTIMPL;
 
     default:
       return E_FAIL;
   }
 }
 
+PRBool nsAccessNodeWrap::IsOnlyMsaaCompatibleJawsPresent()
+{
+  HMODULE jhookhandle = ::GetModuleHandleW(NS_LITERAL_STRING("jhook").get());
+  if (!jhookhandle)
+    return PR_FALSE;  // No JAWS, or some other screen reader, use IA2
+
+  PRUnichar fileName[MAX_PATH];
+  ::GetModuleFileNameW(jhookhandle, fileName, MAX_PATH);
+
+  DWORD dummy;
+  DWORD length = ::GetFileVersionInfoSizeW(fileName, &dummy);
+
+  LPBYTE versionInfo = new BYTE[length];
+  ::GetFileVersionInfoW(fileName, 0, length, versionInfo);
+
+  UINT uLen;
+  VS_FIXEDFILEINFO *fixedFileInfo;
+  ::VerQueryValueW(versionInfo, L"\\", (LPVOID*)&fixedFileInfo, &uLen);
+  DWORD dwFileVersionMS = fixedFileInfo->dwFileVersionMS;
+  DWORD dwFileVersionLS = fixedFileInfo->dwFileVersionLS;
+  delete [] versionInfo;
+
+  DWORD dwLeftMost = HIWORD(dwFileVersionMS);
+//  DWORD dwSecondLeft = LOWORD(dwFileVersionMS);
+  DWORD dwSecondRight = HIWORD(dwFileVersionLS);
+//  DWORD dwRightMost = LOWORD(dwFileVersionLS);
+
+  return (dwLeftMost < 8
+          || (dwLeftMost == 8 && dwSecondRight < 2173));
+}
+
+void nsAccessNodeWrap::DoATSpecificProcessing()
+{
+  if (IsOnlyMsaaCompatibleJawsPresent())
+    // All versions below 8.0.2173 are not compatible
+    gIsIA2Disabled  = PR_TRUE;
+}
--- a/accessible/src/msaa/nsAccessNodeWrap.h
+++ b/accessible/src/msaa/nsAccessNodeWrap.h
@@ -153,23 +153,31 @@ class nsAccessNodeWrap :  public nsAcces
     static HINSTANCE gmAccLib;
     static HINSTANCE gmUserLib;
     static LPFNACCESSIBLEOBJECTFROMWINDOW gmAccessibleObjectFromWindow;
     static LPFNNOTIFYWINEVENT gmNotifyWinEvent;
     static LPFNGETGUITHREADINFO gmGetGUIThreadInfo;
 
     static int FilterA11yExceptions(unsigned int aCode, EXCEPTION_POINTERS *aExceptionInfo);
 
+    static PRBool IsOnlyMsaaCompatibleJawsPresent();
+    static void DoATSpecificProcessing();
   protected:
     void GetAccessibleFor(nsIDOMNode *node, nsIAccessible **newAcc);
     ISimpleDOMNode* MakeAccessNode(nsIDOMNode *node);
 
     static PRBool gIsEnumVariantSupportDisabled;
 
     /**
+     * Used to determine whether an IAccessible2 compatible screen reader is
+     * loaded. Currently used for JAWS versions older than 8.0.2173.
+     */
+     static PRBool gIsIA2Disabled;
+
+    /**
      * It is used in nsHyperTextAccessibleWrap for IA2::newText/oldText
      * implementation.
      */
     static nsIAccessibleTextChangeEvent *gTextEvent;
 };
 
 /**
  * Converts nsresult to HRESULT.
--- a/accessible/src/msaa/nsAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsAccessibleWrap.cpp
@@ -112,17 +112,17 @@ STDMETHODIMP nsAccessibleWrap::QueryInte
     *ppv = static_cast<IAccessible*>(this);
   else if (IID_IEnumVARIANT == iid && !gIsEnumVariantSupportDisabled) {
     long numChildren;
     get_accChildCount(&numChildren);
     if (numChildren > 0)  // Don't support this interface for leaf elements
       *ppv = static_cast<IEnumVARIANT*>(this);
   } else if (IID_IServiceProvider == iid)
     *ppv = static_cast<IServiceProvider*>(this);
-  else if (IID_IAccessible2 == iid)
+  else if (IID_IAccessible2 == iid && !gIsIA2Disabled)
     *ppv = static_cast<IAccessible2*>(this);
 
   if (NULL == *ppv) {
     HRESULT hr = CAccessibleComponent::QueryInterface(iid, ppv);
     if (SUCCEEDED(hr))
       return hr;
   }
 
--- a/accessible/tests/mochitest/Makefile.in
+++ b/accessible/tests/mochitest/Makefile.in
@@ -42,25 +42,28 @@ srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = accessible
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _TEST_FILES =\
 		moz.png \
+		nsIAccessible_actions.js \
 		nsIAccessible_name.css \
 		nsIAccessible_name.xbl \
 		test_aria_activedescendant.html \
 		test_aria_role_article.html \
 		test_bug368835.xul \
 		test_bug420863.html \
 		test_cssattrs.html \
 		test_groupattrs.xul \
 	$(warning test_table_indexes.html temporarily disabled) \
+		test_nsIAccessible_actions.html \
+		test_nsIAccessible_actions.xul \
 		test_nsIAccessible_name.html \
 		test_nsIAccessible_name.xul \
 		test_nsIAccessibleTable_1.html \
 		test_nsIAccessibleTable_2.html \
 		test_nsIAccessibleTable_3.html \
 		test_nsIAccessibleTable_4.html \
 		test_nsIAccessibleTable_listboxes.xul \
 		test_nsIAccessibleDocument.html \
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/nsIAccessible_actions.js
@@ -0,0 +1,150 @@
+////////////////////////////////////////////////////////////////////////////////
+// General
+
+const nsIAccessibleRetrieval = Components.interfaces.nsIAccessibleRetrieval;
+const nsIAccessibleRole = Components.interfaces.nsIAccessibleRole;
+
+var gAccRetrieval = null;
+
+function initialize()
+{
+  gAccRetrieval = Components.classes["@mozilla.org/accessibleRetrieval;1"].
+  getService(nsIAccessibleRetrieval);
+}
+
+addLoadEvent(initialize);
+
+////////////////////////////////////////////////////////////////////////////////
+// Event constants
+
+const MOUSEDOWN_EVENT = 1;
+const MOUSEUP_EVENT = 2;
+const CLICK_EVENT = 4;
+const COMMAND_EVENT = 8;
+
+const CLICK_EVENTS = MOUSEDOWN_EVENT | MOUSEUP_EVENT | CLICK_EVENT;
+const ALL_EVENTS = CLICK_EVENTS | COMMAND_EVENT;
+
+////////////////////////////////////////////////////////////////////////////////
+// Public functions
+
+function testActions(aArray, aIndex)
+{
+  if (!aIndex)
+    aIndex = 0;
+
+  if (aIndex == aArray.length) {
+    SimpleTest.finish();
+    return;
+  }
+
+  var ID = aArray[aIndex].ID;
+  var actionName = aArray[aIndex].actionName;
+  var events = aArray[aIndex].events;
+
+  var elm = document.getElementById(ID);
+  if (!elm) {
+    ok(false, "There is no element with ID " + ID);
+    SimpleTest.finish();
+    return null;
+  }
+
+  var acc = null;
+  try {
+    acc = gAccRetrieval.getAccessibleFor(elm);
+  } catch(e) {
+  }
+
+  if (!acc) {
+    ok(false, "There is no accessible for " + ID);
+    SimpleTest.finish();
+    return null;
+  }
+
+  is(acc.getActionName(0), actionName,
+     "Wrong action name of the accessible for " + ID);
+
+  gEventHandler.initialize(ID, elm, events);
+
+  acc.doAction(0);
+
+  window.setTimeout(
+    function()
+    {
+      gEventHandler.checkEvents();
+      testActions(aArray, aIndex + 1);
+    },
+    200
+  );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Private
+
+var gEventHandler =
+{
+  initialize: function(aID, aElm, aExpectedEvents)
+  {
+    this.ID = aID,
+    this.element = aElm;
+    this.mExpectedEvents = aExpectedEvents;
+    this.mFiredEvents = 0;
+
+    if (this.mExpectedEvents & MOUSEDOWN_EVENT)
+      aElm.addEventListener("mousedown", this, false);
+
+    if (this.mExpectedEvents & MOUSEUP_EVENT)
+      aElm.addEventListener("mouseup", this, false);
+
+    if (this.mExpectedEvents & CLICK_EVENT)
+      aElm.addEventListener("click", this, false);
+
+    if (this.mExpectedEvents & COMMAND_EVENT)
+      aElm.addEventListener("command", this, false);
+  },
+
+  checkEvents: function()
+  {
+    if (this.mExpectedEvents & MOUSEDOWN_EVENT) {
+      ok(this.mFiredEvents & MOUSEDOWN_EVENT,
+         "mousedown hasn't been fired for " + this.ID);
+      this.element.removeEventListener("mousedown", this, false);
+    }
+
+    if (this.mExpectedEvents & MOUSEUP_EVENT) {
+      ok(this.mFiredEvents & MOUSEUP_EVENT,
+         "mouseup hasn't been fired for " + this.ID);
+      this.element.removeEventListener("mouseup", this, false);
+    }
+
+    if (this.mExpectedEvents & CLICK_EVENT) {
+      ok(this.mFiredEvents & CLICK_EVENT,
+         "click hasn't been fired for " + this.ID);
+      this.element.removeEventListener("click", this, false);
+    }
+
+    if (this.mExpectedEvents & COMMAND_EVENT) {
+      ok(this.mFiredEvents & COMMAND_EVENT,
+         "command hasn't been fired for " + this.ID);
+      this.element.removeEventListener("command", this, false);
+    }
+  },
+
+  ID: "",
+  element: null,
+
+  handleEvent : function(aEvent)
+  {
+    if (aEvent.type == "mousedown")
+      this.mFiredEvents |= MOUSEDOWN_EVENT;
+    else if(aEvent.type == "mouseup")
+      this.mFiredEvents |= MOUSEUP_EVENT;
+    else if(aEvent.type == "click")
+      this.mFiredEvents |= CLICK_EVENT;
+    else if(aEvent.type == "command")
+      this.mFiredEvents |= COMMAND_EVENT;
+  },
+
+  mExpectedEvents: 0,
+  mFiredEvents: 0
+};
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/test_nsIAccessible_actions.html
@@ -0,0 +1,49 @@
+<html>
+
+<head>
+  <title>nsIAccessible actions testing</title>
+
+  <link rel="stylesheet" type="text/css"
+        href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/MochiKit/packed.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/a11y/accessible/nsIAccessible_actions.js"></script>
+
+  <script type="application/javascript">
+    function doTest()
+    {
+      var actionsArray = [
+        {
+          ID: "clickable",
+          actionName: "click",
+          events: CLICK_EVENTS
+        }
+      ];
+      testActions(actionsArray);
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addLoadEvent(doTest);
+  </script>
+</head>
+
+<body>
+
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=410765"
+     title="nsIAccessible actions testing">
+    Mozilla Bug 410765
+  </a>
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test">
+  </pre>
+
+  <div id="clickable" onclick="">Clickable text</div>
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/test_nsIAccessible_actions.xul
@@ -0,0 +1,98 @@
+<?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"?>
+<?xml-stylesheet href="chrome://mochikit/content/a11y/accessible/nsIAccessible_name.css"
+                 type="text/css"?>
+
+
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        title="nsIAccessible actions testing">
+
+  <script type="application/javascript" 
+          src="chrome://mochikit/content/MochiKit/packed.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
+  <script type="application/javascript"
+          src="chrome://mochikit/content/a11y/accessible/nsIAccessible_actions.js" />
+
+  <script type="application/javascript">
+  <![CDATA[
+    function doTest()
+    {
+      var actionsArray = [
+        {
+          ID: "menu",
+          actionName: "click",
+          events: CLICK_EVENTS
+        },
+        {
+          ID: "submenu",
+          actionName: "click",
+          events: CLICK_EVENTS
+        },
+        {
+          ID: "menuitem",
+          actionName: "click",
+          events: ALL_EVENTS
+        },
+        {
+          ID: "button",
+          actionName: "press",
+          events: ALL_EVENTS
+        },
+        {
+          ID: "buttonmenu",
+          actionName: "press",
+          events: CLICK_EVENTS
+        },
+        {
+          ID: "buttonmenu_item",
+          actionName: "click",
+          events: CLICK_EVENTS
+        }
+      ];
+      testActions(actionsArray);
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addLoadEvent(doTest);
+  ]]>
+  </script>
+
+  <body xmlns="http://www.w3.org/1999/xhtml">
+    <a target="_blank"
+       href="https://bugzilla.mozilla.org/show_bug.cgi?id=410765"
+       title="nsIAccessible actions testing">
+      Mozilla Bug 410765
+    </a>
+    <p id="display"></p>
+    <div id="content" style="display: none">
+    </div>
+    <pre id="test">
+    </pre>
+  </body>
+
+  <menubar>
+    <menu label="menu" id="menu">
+      <menupopup>
+        <menuitem label="menu item" id="menuitem"/>
+        <menu label="submenu" id="submenu">
+          <menupopup>
+            <menuitem label="menu item"/>
+          </menupopup>
+        </menu>
+      </menupopup>
+    </menu>
+  </menubar>
+
+  <button label="button" id="button"/>
+
+  <button type="menu" id="buttonmenu" label="button">
+    <menupopup>
+      <menuitem label="item1" id="buttonmenu_item"/>
+      <menuitem label="item1"/>
+    </menupopup>
+  </button>
+</window>
+
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0cf87d712919a07e9be01bf4024c1a598cbd7e6f
GIT binary patch
literal 7897
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
DJYPrh
--- a/browser/base/content/aboutRobots.xhtml
+++ b/browser/base/content/aboutRobots.xhtml
@@ -24,16 +24,17 @@
 #
 # Contributor(s):
 #   Adam Lock <adamlock@netscape.com>
 #   William R. Price <wrprice@alumni.rice.edu>
 #   Henrik Skupin <mozilla@hskupin.info>
 #   Jeff Walden <jwalden+code@mit.edu>
 #   Johnathan Nightingale <johnath@mozilla.com>
 #   Justin Dolske <dolske@mozilla.com>
+#   Ehsan Akhgari <ehsan.akhgari@gmail.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
@@ -75,23 +76,42 @@
           button.style.visibility = "hidden";
         } else {
           var newLabel = button.getAttribute("label2");
           button.setAttribute("label", newLabel);
           buttonClicked = true;
         }
       }
     ]]></script>
+
+    <style type="text/css"><![CDATA[
+      #errorPageContainer {
+        background: url('chrome://browser/content/aboutRobots-icon.png') left 0 no-repeat -moz-Field;
+        -moz-background-origin: content;
+      }
+
+      #errorTrailerDescText {
+        float: right;
+      }
+
+      body[dir=rtl] #errorPageContainer {
+        background-image: url('chrome://browser/content/aboutRobots-icon-rtl.png');
+        background-position: right 0;
+      }
+
+      body[dir=rtl] #errorTrailerDescText {
+        float: left;
+      }
+    ]]></style>
   </head>
 
   <body dir="&locale.dir;">
 
     <!-- PAGE CONTAINER (for styling purposes only) -->
-    <div id="errorPageContainer"
-         style="background: url('chrome://browser/content/aboutRobots-icon.png') left 0 no-repeat -moz-Field; -moz-background-origin: content;">
+    <div id="errorPageContainer">
     
       <!-- Error Title -->
       <div id="errorTitle">
         <h1 id="errorTitleText">&robots.errorTitleText;</h1>
       </div>
       
       <!-- LONG CONTENT (the section most likely to require scrolling) -->
       <div id="errorLongContent">
@@ -108,17 +128,17 @@
             <li>&robots.errorLongDesc2;</li>
             <li>&robots.errorLongDesc3;</li>
             <li>&robots.errorLongDesc4;</li>
           </ul>
         </div>
 
         <!-- Short Description -->
         <div id="errorTrailerDesc">
-          <p id="errorTrailerDescText" style="float: right;">&robots.errorTrailerDescText;</p>
+          <p id="errorTrailerDescText">&robots.errorTrailerDescText;</p>
         </div>
 
       </div>
 
       <!-- Button -->
       <xul:button xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
                   id="errorTryAgain"
                   label="&retry.label;"
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -99,20 +99,24 @@
     <tooltip id="aHTMLTooltip" onpopupshowing="return FillInHTMLTooltip(document.tooltipNode);"/>
 
     <!-- for search and content formfill/pw manager -->
     <panel type="autocomplete" chromedir="&locale.dir;" id="PopupAutoComplete" noautofocus="true" hidden="true"/>
 
     <!-- for url bar autocomplete -->
     <panel type="autocomplete-richlistbox" chromedir="&locale.dir;" id="PopupAutoCompleteRichResult" noautofocus="true" hidden="true"/>
 
+    <!-- XXX panel element that has one or more text fields should not be
+             top-most panel, for IME users. See bug 433340 comment 100. -->
     <panel id="editBookmarkPanel"
            orient="vertical"
            ignorekeys="true"
            hidden="true"
+           noautohide="true"
+           onpopupshowing="this.removeAttribute('noautohide');"
            onpopupshown="StarUI.panelShown(event);"
            aria-labelledby="editBookmarkPanelTitle">
       <hbox flex="1" align="top">
         <image id="editBookmarkPanelStarIcon"/>
         <vbox flex="1">
           <label id="editBookmarkPanelTitle" flex="1"/>
           <description id="editBookmarkPanelDescription" flex="1"/>
           <hbox>
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -273,17 +273,16 @@
         <parameter name="aStartsBlank"/>
         <body>
         <![CDATA[
           return ({
             mTabBrowser: this,
             mTab: aTab,
             mBrowser: aBrowser,
             mBlank: aStartsBlank,
-            mLastURI: null,
 
             // cache flags for correct status bar update after tab switching
             mStateFlags: 0,
             mStatus: 0,
             mMessage: "",
             mTotalProgress: 0,
 
             // count of open requests (should always be 0 or 1)
@@ -1386,31 +1385,45 @@
           ]]>
         </body>
       </method>
 
       <method name="removeTab">
         <parameter name="aTab"/>
         <body>
           <![CDATA[
+            this._endRemoveTab(this._beginRemoveTab(aTab, true));
+          ]]>
+        </body>
+      </method>
+
+      <!-- Returns the tab being removed.  This might not be the same as aTab,
+           in cases when aTab is not actually a tab -->
+      <method name="_beginRemoveTab">
+        <parameter name="aTab"/>
+        <parameter name="aFireBeforeUnload"/>
+        <body>
+          <![CDATA[
             this._browsers = null; // invalidate cache
             if (aTab.localName != "tab")
               aTab = this.mCurrentTab;
 
             var l = this.mTabContainer.childNodes.length;
             if (l == 1 && this.mPrefs.getBoolPref("browser.tabs.autoHide")) {
               // hide the tab bar
               this.mPrefs.setBoolPref("browser.tabs.forceHide", true);
               this.setStripVisibilityTo(false);
               return;
             }
 
-            var ds = this.getBrowserForTab(aTab).docShell;
-            if (ds.contentViewer && !ds.contentViewer.permitUnload())
-              return;
+            if (aFireBeforeUnload) {
+              var ds = this.getBrowserForTab(aTab).docShell;
+              if (ds.contentViewer && !ds.contentViewer.permitUnload())
+                return;
+            }
 
             // see notes in addTab
             var _delayedUpdate = function(aTabContainer) {
               aTabContainer.adjustTabstrip();
               aTabContainer.mTabstrip._updateScrollButtonsDisabledState();
             }
             setTimeout(_delayedUpdate, 0, this.mTabContainer);
 
@@ -1430,76 +1443,82 @@
             // We're committed to closing the tab now.  
             // Dispatch a notification.
             // We dispatch it before any teardown so that event listeners can
             // inspect the tab that's about to close.
             var evt = document.createEvent("Events");
             evt.initEvent("TabClose", true, false);
             aTab.dispatchEvent(evt);
 
-            var index = -1;
-            if (this.mCurrentTab == aTab)
-              index = this.mTabContainer.selectedIndex;
-            else {
-              // Find and locate the tab in our list.
-              for (var i = 0; i < l; i++)
-                if (this.mTabContainer.childNodes[i] == aTab)
-                  index = i;
-            }
+            var index = aTab._tPos;
 
             // Remove the tab's filter and progress listener.
             const filter = this.mTabFilters[index];
             var oldBrowser = this.getBrowserAtIndex(index);
             oldBrowser.webProgress.removeProgressListener(filter);
             filter.removeProgressListener(this.mTabListeners[index]);
             this.mTabFilters.splice(index, 1);
             this.mTabListeners.splice(index, 1);
 
             // Remove our title change and blocking listeners
             oldBrowser.removeEventListener("DOMTitleChanged", this.onTitleChanged, true);
 
             // We are no longer the primary content area.
             oldBrowser.setAttribute("type", "content-targetable");
 
-            // Get the index of the tab we're removing before unselecting it
-            var currentIndex = this.mTabContainer.selectedIndex;
-
-            var oldTab = aTab;
-
-            // clean up the before/afterselected attributes before removing the tab
-            oldTab._selected = false;
-
             // Remove this tab as the owner of any other tabs, since it's going away.
-            for (i = 0; i < this.mTabContainer.childNodes.length; ++i) {
+            for (var i = 0; i < this.mTabs.length; ++i) {
               var tab = this.mTabContainer.childNodes[i];
-              if ("owner" in tab && tab.owner == oldTab)
+              if ("owner" in tab && tab.owner == aTab)
                 // |tab| is a child of the tab we're removing, make it an orphan
                 tab.owner = null;
             }
 
+            return aTab;
+          ]]>
+        </body>
+      </method>
+
+      <method name="_endRemoveTab">
+        <parameter name="aTab"/>
+        <body>
+          <![CDATA[
+            var browser = this.getBrowserForTab(aTab);
+            var length = this.mTabs.length;
+
+            // Get the index of the tab we're removing before unselecting it
+            var currentIndex = this.mTabContainer.selectedIndex;
+            var index = aTab._tPos;
+
+            // clean up the before/afterselected attributes before removing the
+            // tab.  But make sure this happens after we grab currentIndex.
+            aTab._selected = false;
+
             // Because of the way XBL works (fields just set JS
             // properties on the element) and the code we have in place
             // to preserve the JS objects for any elements that have
             // JS properties set on them, the browser element won't be
             // destroyed until the document goes away.  So we force a
             // cleanup ourselves.
             // This has to happen before we remove the child so that the
             // XBL implementation of nsIObserver still works.  But
             // clearing focusedWindow happens below because it gets
             // reset by updateCurrentBrowser.
-            oldBrowser.destroy();
-
-            if (oldBrowser == this.mCurrentBrowser)
+            browser.destroy();
+
+            if (browser == this.mCurrentBrowser)
               this.mCurrentBrowser = null;
 
             // Remove the tab
-            this.mTabContainer.removeChild(oldTab);
+            this.mTabContainer.removeChild(aTab);
+            // Update our length
+            --length;
             // invalidate cache, because mTabContainer is about to change
             this._browsers = null; 
-            this.mPanelContainer.removeChild(oldBrowser.parentNode);
+            this.mPanelContainer.removeChild(browser.parentNode);
 
             try {
               // if we're at the right side (and not the logical end,
               // which is why this works for both LTR and RTL)
               // of the tabstrip, we need to ensure that we stay 
               // completely scrolled to the right side
               var tabStrip = this.mTabContainer.mTabstrip;
               var scrollPos = {};
@@ -1518,44 +1537,89 @@
 
             // Find the tab to select
             var newIndex = -1;
             if (currentIndex > index)
               newIndex = currentIndex-1;
             else if (currentIndex < index)
               newIndex = currentIndex;
             else {
-              if ("owner" in oldTab && oldTab.owner &&
+              if ("owner" in aTab && aTab.owner &&
                   this.mPrefs.getBoolPref("browser.tabs.selectOwnerOnClose")) {
-                for (i = 0; i < this.mTabContainer.childNodes.length; ++i) {
+                for (var i = 0; i < length; ++i) {
                   tab = this.mTabContainer.childNodes[i];
-                  if (tab == oldTab.owner) {
+                  if (tab == aTab.owner) {
                     newIndex = i;
                     break;
                   }
                 }
               }
               if (newIndex == -1)
-                newIndex = (index == l - 1) ? index - 1 : index;
+                newIndex = (index == length) ? index - 1 : index;
             }
 
             // Select the new tab
-            this.selectedTab = this.mTabContainer.childNodes[newIndex];
-
-            for (i = oldTab._tPos; i < this.mTabContainer.childNodes.length; i++) {
+            this.selectedTab = this.mTabs[newIndex];
+
+            for (i = aTab._tPos; i < length; i++) {
               this.mTabContainer.childNodes[i]._tPos = i;
             }
             this.mTabBox.selectedPanel = this.getBrowserForTab(this.mCurrentTab).parentNode;
             this.mCurrentTab._selected = true;
 
             this.updateCurrentBrowser();
 
             // see comment above destroy above
-            oldBrowser.focusedWindow = null;
-            oldBrowser.focusedElement = null;
+            browser.focusedWindow = null;
+            browser.focusedElement = null;
+          ]]>
+        </body>
+      </method>
+
+      <method name="swapBrowsersAndCloseOther">
+        <parameter name="aOurTab"/>
+        <parameter name="aOtherTab"/>
+        <body>
+          <![CDATA[
+            var remoteBrowser =
+              aOtherTab.ownerDocument.defaultView.getBrowser();
+            var tabCount = remoteBrowser.mTabs.length;
+
+            // First, start teardown of the other browser.  Make sure to not
+            // fire the beforeunload event in the process.
+            var tabToRemove = remoteBrowser._beginRemoveTab(aOtherTab, false);
+
+            // Unhook our progress listener
+            var ourIndex = aOurTab._tPos;
+            const filter = this.mTabFilters[ourIndex];
+            var tabListener = this.mTabListeners[ourIndex];
+            var ourBrowser = this.getBrowserForTab(aOurTab);
+            ourBrowser.webProgress.removeProgressListener(filter);
+            filter.removeProgressListener(tabListener);
+            var tabListenerBlank = tabListener.mBlank;
+
+            // Swap the docshells
+            ourBrowser.swapDocShells(remoteBrowser.getBrowserForTab(aOtherTab));
+
+            // Finish tearing down the tab that's going away.
+            remoteBrowser._endRemoveTab(tabToRemove);
+
+            // Restore the progress listener
+            tabListener = this.mTabProgressListener(aOurTab, ourBrowser,
+                                                    tabListenerBlank);
+            this.mTabListeners[ourIndex] = tabListener;
+            filter.addProgressListener(tabListener,
+              Components.interfaces.nsIWebProgress.NOTIFY_ALL);
+              
+            ourBrowser.webProgress.addProgressListener(filter,
+              Components.interfaces.nsIWebProgress.NOTIFY_ALL);
+
+            // close the other window if this was its last tab
+            if (tabCount == 1)
+              aOtherTab.ownerDocument.defaultView.close();
           ]]>
         </body>
       </method>
 
       <method name="reloadAllTabs">
         <body>
           <![CDATA[
             var l = this.mPanelContainer.childNodes.length;
@@ -1874,29 +1938,36 @@
                 // move the dropped tab
                 if (newIndex > draggedTab._tPos)
                   newIndex--;
                 if (newIndex != draggedTab._tPos)
                   this.moveTabTo(draggedTab, newIndex);
               }
             }
             else if (draggedTab) {
-              // copy the dropped tab and remove it from the other window
-              // (making it seem to have moved between windows)
+              // swap the dropped tab with a new one we create and then close
+              // it in the other window (making it seem to have moved between
+              // windows)
               newIndex = this.getNewIndex(aEvent);
-              newTab = this.duplicateTab(draggedTab);
-              this.moveTabTo(newTab, newIndex);
-              this.selectedTab = newTab;
+              newTab = this.addTab("about:blank");
+              var newBrowser = this.getBrowserForTab(newTab);
+              // Stop the about:blank load
+              newBrowser.stop();
+              // make sure it has a docshell
+              newBrowser.docShell;
               
-              var remoteBrowser = draggedTab.ownerDocument.defaultView.getBrowser();
-              var tabCount = remoteBrowser.tabContainer.childNodes.length;
-              remoteBrowser.removeTab(draggedTab);
-              // close the other window if this was its last tab
-              if (tabCount == 1)
-                draggedTab.ownerDocument.defaultView.close();
+              this.moveTabTo(newTab, newIndex);
+              
+              this.swapBrowsersAndCloseOther(newTab, draggedTab);
+
+              // We need to set selectedTab after we've done
+              // swapBrowsersAndCloseOther, so that the updateCurrentBrowser
+              // it triggers will correctly update our URL bar.
+              this.selectedTab = newTab;
+              this.setTabTitle(newTab);
             }
             else {
               var url = transferUtils.retrieveURLFromData(aXferData.data, aXferData.flavour.contentType);
 
               // valid urls don't contain spaces ' '; if we have a space it isn't a valid url.
               // Also disallow dropping javascript: or data: urls--bail out
               if (!url || !url.length || url.indexOf(" ", 0) != -1 ||
                   /^\s*(javascript|data):/.test(url))
--- a/browser/base/content/test/Makefile.in
+++ b/browser/base/content/test/Makefile.in
@@ -54,16 +54,18 @@ include $(topsrcdir)/config/rules.mk
 _BROWSER_FILES = browser_bug321000.js \
                  browser_bug405137.js \
                  browser_bug409481.js \
                  browser_autodiscovery.js \
                  browser_bug420160.js \
                  autodiscovery.html \
                  moz.png \
                  browser_getshortcutoruri.js \
+                 browser_page_style_menu.js \
+                 page_style_sample.html \
     $(NULL)
 
 ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
 _BROWSER_FILES += browser_customize.js \
     $(NULL)
 endif
 
 # disable tests on linux for now..
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_page_style_menu.js
@@ -0,0 +1,66 @@
+function test() {
+  waitForExplicitFinish();
+  finish();
+  return;
+
+  var tab = gBrowser.addTab();
+  gBrowser.selectedTab = tab;
+  tab.linkedBrowser.addEventListener("load", checkPageStyleMenu, true);
+  content.location =
+    "chrome://mochikit/content/browser/browser/base/content/test/page_style_sample.html";
+}
+
+function checkPageStyleMenu() {
+  var menupopup = document.getElementById("pageStyleMenu")
+                          .getElementsByTagName("menupopup")[0];
+  stylesheetFillPopup(menupopup);
+
+  var items = [];
+  var current = menupopup.getElementsByTagName("menuseparator")[0];
+  while (current.nextSibling) {
+    current = current.nextSibling;
+    items.push(current);
+  }
+
+  var validLinks = 0;
+  Array.forEach(content.document.getElementsByTagName("link"), function (link) {
+    var title = link.getAttribute("title");
+    var rel = link.getAttribute("rel");
+    var media = link.getAttribute("media");
+    var idstring = "link " + (title ? title : "without title and") +
+                   " with rel=\"" + rel + "\"" +
+                   (media ? " and media=\"" + media + "\"" : "");
+
+    var item = items.filter(function (item) item.label == title);
+    var found = item.length == 1;
+    var checked = found && (item[0].getAttribute("checked") == "true");
+
+    switch (link.getAttribute("data-state")) {
+      case "0":
+        ok(!found, idstring + " does not show up in page style menu");
+        break;
+      case "0-todo":
+        validLinks++;
+        todo(!found, idstring + " should not show up in page style menu");
+        ok(!checked, idstring + " is not selected");
+        break;
+      case "1":
+        validLinks++;
+        ok(found, idstring + " shows up in page style menu");
+        ok(!checked, idstring + " is not selected");
+        break;
+      case "2":
+        validLinks++;
+        ok(found, idstring + " shows up in page style menu");
+        ok(checked, idstring + " is selected");
+        break;
+      default:
+        throw "data-state attribute is missing or has invalid value";
+    }
+  });
+
+  is(validLinks, items.length, "all valid links found");
+
+  gBrowser.removeCurrentTab();
+  finish();
+}
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/page_style_sample.html
@@ -0,0 +1,31 @@
+<html>
+  <head>
+    <title>Test for page style menu</title>
+    <!-- data-state values:
+      0:      should not appear in the page style menu
+      0-todo: should not appear in the page style menu, but does
+      1:      should appear in the page style menu
+      2:      should appear in the page style menu as the selected stylesheet -->
+    <link data-state="1" href="404.css" title="1" rel="alternate stylesheet">
+    <link data-state="0"                title="2" rel="alternate stylesheet">
+    <link data-state="0" href="404.css"           rel="alternate stylesheet">
+    <link data-state="0" href="404.css" title=""  rel="alternate stylesheet">
+    <link data-state="1" href="404.css" title="3" rel="stylesheet alternate">
+    <link data-state="1" href="404.css" title="4" rel=" alternate stylesheet ">
+    <link data-state="1" href="404.css" title="5" rel="alternate stylesheet">
+    <link data-state="2" href="404.css" title="6" rel="stylesheet">
+    <link data-state="1" href="404.css" title="7" rel="foo stylesheet">
+    <link data-state="0" href="404.css" title="8" rel="alternate">
+    <link data-state="1" href="404.css" title="9" rel="alternate STYLEsheet">
+    <link data-state="1" href="404.css" title="10" rel="alternate stylesheet" media="">
+    <link data-state="1" href="404.css" title="11" rel="alternate stylesheet" media="all">
+    <link data-state="1" href="404.css" title="12" rel="alternate stylesheet" media="ALL ">
+    <link data-state="1" href="404.css" title="13" rel="alternate stylesheet" media="screen">
+    <link data-state="1" href="404.css" title="14" rel="alternate stylesheet" media=" Screen">
+    <link data-state="1" href="404.css" title="15" rel="alternate stylesheet" media="screen foo">
+    <link data-state="1" href="404.css" title="16" rel="alternate stylesheet" media="all  screen">
+    <link data-state="0-todo" href="404.css" title="17" rel="alternate stylesheet" media="allscreen">
+    <link data-state="0-todo" href="404.css" title="18" rel="alternate stylesheet" media="_all">
+  </head>
+  <body></body>
+</html>
--- a/browser/base/jar.mn
+++ b/browser/base/jar.mn
@@ -10,16 +10,17 @@ browser.jar:
 %  overlay chrome://global/content/viewPartialSource.xul chrome://browser/content/viewSourceOverlay.xul
 %  style chrome://global/content/customizeToolbar.xul chrome://browser/content/browser.css
 %  style chrome://global/content/customizeToolbar.xul chrome://browser/skin/
 *       content/browser/aboutDialog.xul               (content/aboutDialog.xul)
 *       content/browser/aboutDialog.js                (content/aboutDialog.js)
         content/browser/aboutDialog.css               (content/aboutDialog.css)
 *       content/browser/aboutRobots.xhtml             (content/aboutRobots.xhtml)
         content/browser/aboutRobots-icon.png          (content/aboutRobots-icon.png)
+        content/browser/aboutRobots-icon-rtl.png      (content/aboutRobots-icon-rtl.png)
         content/browser/aboutRobots-widget-left.png   (content/aboutRobots-widget-left.png)
         content/browser/aboutRobots-widget-right.png  (content/aboutRobots-widget-right.png)
 *       content/browser/browser.css                   (content/browser.css)
 *       content/browser/browser.js                    (content/browser.js)
 *       content/browser/browser.xul                   (content/browser.xul)
 *       content/browser/credits.xhtml                 (content/credits.xhtml)
 *       content/browser/EULA.js                       (content/EULA.js)
 *       content/browser/EULA.xhtml                    (content/EULA.xhtml)
--- a/browser/components/places/content/bookmarksPanel.xul
+++ b/browser/components/places/content/bookmarksPanel.xul
@@ -58,18 +58,17 @@
           src="chrome://browser/content/bookmarks/bookmarksPanel.js"/>
 
   <commandset id="placesCommands"/>
   <commandset id="editMenuCommands"/>
   <popup id="placesContext"/>
 
   <hbox align="center">
     <label value="&search.label;" accesskey="&search.accesskey;" control="search-box"/>
-    <textbox id="search-box" flex="1"
-             type="timed" timeout="500"
+    <textbox id="search-box" flex="1" type="search"
              oncommand="searchBookmarks(this.value);"/>
   </hbox>
 
   <tree id="bookmarks-view" class="sidebar-placesTree" type="places"
         flex="1"
         hidecolumnpicker="true"
         context="placesContext"
         onkeypress="SidebarUtils.handleTreeKeyPress(event);"
--- a/browser/components/places/content/history-panel.xul
+++ b/browser/components/places/content/history-panel.xul
@@ -81,17 +81,17 @@
               selection="link"
               selectiontype="single"
               oncommand="historyAddBookmarks();"/>
   </popup>
 
   <hbox align="center">
     <label value="&find.label;" accesskey="&find.accesskey;" 
            control="search-box"/>
-    <textbox id="search-box" flex="1" type="timed" timeout="500"
+    <textbox id="search-box" flex="1" type="search"
              oncommand="searchHistory(this.value);"/>
     <button id="viewButton" style="min-width:0px !important;" type="menu"
             label="&view.label;" accesskey="&view.accesskey;" selectedsort="day"
             persist="selectedsort">
       <menupopup>
         <menuitem id="bydayandsite" label="&byDayAndSite.label;" 
                   accesskey="&byDayAndSite.accesskey;" type="radio"
                   oncommand="this.parentNode.parentNode.setAttribute('selectedsort', 'dayandsite'); GroupBy('dayandsite');"/>
--- a/browser/components/places/content/menu.xml
+++ b/browser/components/places/content/menu.xml
@@ -897,45 +897,62 @@
         ]]></getter>
       </property>
 
       <!-- nsIPlacesView -->
       <property name="insertionPoint">
         <getter><![CDATA[
           // By default, the insertion point is at the top level, at the end.
           var index = PlacesUtils.bookmarks.DEFAULT_INDEX;
-          var folderId = 0;
+          var container = null;
           var orientation = Ci.nsITreeView.DROP_BEFORE;
           var isTag = false;
 
           if (PlacesUtils.nodeIsFolder(this._resultNode)) {
-            folderId = PlacesUtils.getConcreteItemId(this._resultNode);
+            container = this._resultNode;
             isTag = PlacesUtils.nodeIsTagQuery(this._resultNode);
           }
 
           var selectedNode = this.selectedNode;
           if (selectedNode) {
             var popupNode = document.popupNode;
             if (!popupNode.node) {
               // If a static menuitem is selected the insertion point
               // is inside the folder, at the end.
-              folderId = PlacesUtils.getConcreteItemId(selectedNode);
+              container = selectedNode;
               orientation = Ci.nsITreeView.DROP_ON;
             }
             else {
               // In all other cases the insertion point is before that node.
-              folderId = PlacesUtils.getConcreteItemId(selectedNode.parent);
+              container = selectedNode.parent;
               index = PlacesUtils.getIndexOfNode(selectedNode);
               isTag = PlacesUtils.nodeIsTagQuery(selectedNode.parent);
             }
           }
-          return new InsertionPoint(folderId, index, orientation, isTag);
+
+          if (this._disallowInsertion(container))
+            return null;
+
+          return new InsertionPoint(PlacesUtils.getConcreteItemId(container),
+                                    index, orientation, isTag);
         ]]></getter>
       </property>
 
+      <method name="_disallowInsertion">
+        <parameter name="aContainer"/>
+        <body><![CDATA[
+          // allow dropping into Tag containers
+          if (PlacesUtils.nodeIsTagQuery(aContainer))
+            return false;
+          // Disallow insertion of items under readonly folders
+          return (!PlacesUtils.nodeIsFolder(aContainer) ||
+                   PlacesUtils.nodeIsReadOnly(aContainer));
+        ]]></body>
+      </method>
+
       <!-- nsIPlacesView -->
       <method name="selectAll">
         <body/>
       </method>
 
       <method name="selectItems">
         <body/>
       </method>
--- a/browser/components/places/content/toolbar.xml
+++ b/browser/components/places/content/toolbar.xml
@@ -380,40 +380,57 @@
         ]]></getter>
       </property>
 
       <!-- nsIPlacesView -->
       <property name="insertionPoint">
         <getter><![CDATA[
           // By default, the insertion point is at the top level, at the end. 
           var index = PlacesUtils.bookmarks.DEFAULT_INDEX;
-          var folderId = PlacesUtils.getConcreteItemId(this._result.root);
+          var container = this._result.root;
           var orientation = Ci.nsITreeView.DROP_BEFORE;
           var isTag = false;
 
           var selectedNode = this.selectedNode;
           if (selectedNode) {
             var popupNode = document.popupNode;
             if (!popupNode.node) {
               // If a static menuitem is selected the insertion point
               // is inside the folder, at the end.
-              folderId = PlacesUtils.getConcreteItemId(selectedNode);
+              container = selectedNode;
               orientation = Ci.nsITreeView.DROP_ON;
             }
             else {
               // In all other cases the insertion point is before that node.
-              folderId = PlacesUtils.getConcreteItemId(selectedNode.parent);
+              container = selectedNode.parent;
               index = PlacesUtils.getIndexOfNode(selectedNode);
               isTag = PlacesUtils.nodeIsTagQuery(selectedNode.parent);
             }
           }
-          return new InsertionPoint(folderId, index, orientation, isTag);
+
+          if (this._disallowInsertion(container))
+            return null;
+
+          return new InsertionPoint(PlacesUtils.getConcreteItemId(container),
+                                    index, orientation, isTag);
         ]]></getter>
       </property>
 
+      <method name="_disallowInsertion">
+        <parameter name="aContainer"/>
+        <body><![CDATA[
+          // allow dropping into Tag containers
+          if (PlacesUtils.nodeIsTagQuery(aContainer))
+            return false;
+          // Disallow insertion of items under readonly folders
+          return (!PlacesUtils.nodeIsFolder(aContainer) ||
+                   PlacesUtils.nodeIsReadOnly(aContainer));
+        ]]></body>
+      </method>
+
       <!-- nsIPlacesView -->
       <method name="selectAll">
         <body><![CDATA[ 
           // Nothing
         ]]></body>
       </method>
 
       <method name="selectItems">
--- a/browser/components/places/content/tree.xml
+++ b/browser/components/places/content/tree.xml
@@ -482,17 +482,17 @@
               !this.flatList)
             orientation = Ci.nsITreeView.DROP_ON;
 
           this._cachedInsertionPoint =
             this._getInsertionPoint(max.value, orientation);
           return this._cachedInsertionPoint;
         ]]></getter>
       </property>
-      
+
       <method name="_disallowInsertion">
         <parameter name="aContainer"/>
         <body><![CDATA[
           // allow dropping into Tag containers
           if (PlacesUtils.nodeIsTagQuery(aContainer))
             return false;
           // Disallow insertion of items under readonly folders
           return (!PlacesUtils.nodeIsFolder(aContainer) ||
--- a/browser/components/preferences/applications.js
+++ b/browser/components/preferences/applications.js
@@ -1597,46 +1597,17 @@ var gApplicationsPane = {
     if (this._sortColumn.getAttribute("sortDirection") == "descending")
       this._visibleTypes.reverse();
   },
 
   /**
    * Filter the list when the user enters a filter term into the filter field.
    */
   filter: function() {
-    if (this._filter.value == "") {
-      this.clearFilter();
-      return;
-    }
-
     this._rebuildView();
-
-    document.getElementById("clearFilter").disabled = false;
-  },
-
-  _filterTimeout: null,
-
-  onFilterInput: function() {
-    if (this._filterTimeout)
-      clearTimeout(this._filterTimeout);
-   
-    this._filterTimeout = setTimeout("gApplicationsPane.filter()", 500);
-  },
-
-  onFilterKeyPress: function(aEvent) {
-    if (aEvent.keyCode == KeyEvent.DOM_VK_ESCAPE)
-      this.clearFilter();
-  },
-  
-  clearFilter: function() {
-    this._filter.value = "";
-    this._rebuildView();
-
-    this._filter.focus();
-    document.getElementById("clearFilter").disabled = true;
   },
 
   focusFilterBox: function() {
     this._filter.focus();
     this._filter.select();
   },
 
 
--- a/browser/components/preferences/applications.xul
+++ b/browser/components/preferences/applications.xul
@@ -105,22 +105,21 @@
 
     <script type="application/x-javascript" src="chrome://browser/content/preferences/applications.js"/>
 
     <keyset>
       <key key="&focusSearch1.key;" modifiers="accel" oncommand="gApplicationsPane.focusFilterBox();"/>
       <key key="&focusSearch2.key;" modifiers="accel" oncommand="gApplicationsPane.focusFilterBox();"/>
     </keyset>
 
-    <hbox align="center">
-      <label accesskey="&filter.accesskey;" control="filter">&filter.label;</label>
-      <textbox id="filter" flex="1" oninput="gApplicationsPane.onFilterInput();" 
-              onkeypress="gApplicationsPane.onFilterKeyPress(event);"/>
-      <button id="clearFilter" icon="clear" label="&clear.label;" accesskey="&clear.accesskey;" 
-              oncommand="gApplicationsPane.clearFilter();" disabled="true"/>
+    <hbox>
+      <textbox id="filter" flex="1"
+               type="search"
+               emptytext="&filter.emptytext;"
+               oncommand="gApplicationsPane.filter();"/>
     </hbox>
 
     <separator class="thin"/>
 
     <richlistbox id="handlersView" orient="vertical" persist="lastSelectedType"
                  preference="pref.downloads.disable_button.edit_actions"
                  onselect="gApplicationsPane.onSelectionChanged();">
       <listheader equalsize="always" style="border: 0; padding: 0; -moz-appearance: none;">
--- a/browser/components/sessionstore/src/nsSessionStore.js
+++ b/browser/components/sessionstore/src/nsSessionStore.js
@@ -223,20 +223,17 @@ SessionStoreService.prototype = {
       try {
         // parse the session state into JS objects
         this._initialState = this._safeEval(iniString);
         // set bool detecting crash
         this._lastSessionCrashed =
           this._initialState.session && this._initialState.session.state &&
           this._initialState.session.state == STATE_RUNNING_STR;
         
-        // restore the features of the first window from localstore.rdf
-        WINDOW_ATTRIBUTES.forEach(function(aAttr) {
-          delete this._initialState.windows[0][aAttr];
-        }, this);
+        // make sure that at least the first window doesn't have anything hidden
         delete this._initialState.windows[0].hidden;
       }
       catch (ex) { debug("The session file is invalid: " + ex); }
     }
     
     // if last session crashed, backup the session
     if (this._lastSessionCrashed) {
       try {
--- a/browser/components/shell/src/nsWindowsShellService.cpp
+++ b/browser/components/shell/src/nsWindowsShellService.cpp
@@ -217,38 +217,32 @@ static SETTING gSettings[] = {
   // Protocol Handlers
   { MAKE_KEY_NAME1("HTTP", DI),    "", VAL_FILE_ICON, APP_PATH_SUBSTITUTION },
   { MAKE_KEY_NAME1("HTTP", SOP),   "", VAL_OPEN, APP_PATH_SUBSTITUTION },
   { MAKE_KEY_NAME1("HTTPS", DI),   "", VAL_FILE_ICON, APP_PATH_SUBSTITUTION },
   { MAKE_KEY_NAME1("HTTPS", SOP),  "", VAL_OPEN, APP_PATH_SUBSTITUTION }
 };
 
 PRBool
-nsWindowsShellService::IsDefaultBrowserVista(PRBool aStartupCheck, PRBool* aIsDefaultBrowser)
+nsWindowsShellService::IsDefaultBrowserVista(PRBool* aIsDefaultBrowser)
 {
 #if !defined(MOZ_DISABLE_VISTA_SDK_REQUIREMENTS)
   IApplicationAssociationRegistration* pAAR;
   
   HRESULT hr = CoCreateInstance(CLSID_ApplicationAssociationRegistration,
                                 NULL,
                                 CLSCTX_INPROC,
                                 IID_IApplicationAssociationRegistration,
                                 (void**)&pAAR);
-  
+
   if (SUCCEEDED(hr)) {
     hr = pAAR->QueryAppIsDefaultAll(AL_EFFECTIVE,
                                     APP_REG_NAME,
                                     aIsDefaultBrowser);
-    
-    // If this is the first browser window, maintain internal state that we've
-    // checked this session (so that subsequent window opens don't show the 
-    // default browser dialog).
-    if (aStartupCheck)
-      mCheckedThisSession = PR_TRUE;
-    
+
     pAAR->Release();
     return PR_TRUE;
   }
 #endif  
   return PR_FALSE;
 }
 
 NS_IMETHODIMP
@@ -311,36 +305,39 @@ nsWindowsShellService::IsDefaultBrowser(
     if (settings->flags & EXE_NAME_SUBSTITUTION) {
       PRInt32 offset = key.Find("%APPEXE%");
       key.Replace(offset, 8, exeName);
     }
 
     ::ZeroMemory(currValue, sizeof(currValue));
     HKEY theKey;
     rv = OpenKeyForReading(HKEY_CLASSES_ROOT, key, &theKey);
-    if (NS_SUCCEEDED(rv)) {
-      DWORD len = sizeof currValue;
-      DWORD res = ::RegQueryValueExW(theKey, PromiseFlatString(value).get(),
-                                     NULL, NULL, (LPBYTE)currValue, &len);
-      // Close the key we opened.
-      ::RegCloseKey(theKey);
-      if (REG_FAILED(res) ||
-          !dataLongPath.Equals(currValue, CaseInsensitiveCompare) &&
-          !dataShortPath.Equals(currValue, CaseInsensitiveCompare)) {
-        // Key wasn't set, or was set to something else (something else became the default browser)
-        *aIsDefaultBrowser = PR_FALSE;
-        return NS_OK;
-      }
+    if (NS_FAILED(rv)) {
+      *aIsDefaultBrowser = PR_FALSE;
+      return NS_OK;
+    }
+
+    DWORD len = sizeof currValue;
+    DWORD res = ::RegQueryValueExW(theKey, PromiseFlatString(value).get(),
+                                   NULL, NULL, (LPBYTE)currValue, &len);
+    // Close the key we opened.
+    ::RegCloseKey(theKey);
+    if (REG_FAILED(res) ||
+        !dataLongPath.Equals(currValue, CaseInsensitiveCompare) &&
+        !dataShortPath.Equals(currValue, CaseInsensitiveCompare)) {
+      // Key wasn't set, or was set to something other than our registry entry
+      *aIsDefaultBrowser = PR_FALSE;
+      return NS_OK;
     }
   }
 
   // Only check if Firefox is the default browser on Vista if the previous
   // checks show that Firefox is the default browser.
-  if (aIsDefaultBrowser)
-    IsDefaultBrowserVista(aStartupCheck, aIsDefaultBrowser);
+  if (*aIsDefaultBrowser)
+    IsDefaultBrowserVista(aIsDefaultBrowser);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsWindowsShellService::SetDefaultBrowser(PRBool aClaimAllTypes, PRBool aForAllUsers)
 {
   nsresult rv;
@@ -353,31 +350,31 @@ nsWindowsShellService::SetDefaultBrowser
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = appHelper->AppendNative(NS_LITERAL_CSTRING("uninstall"));
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = appHelper->AppendNative(NS_LITERAL_CSTRING("helper.exe"));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCAutoString appHelperPath;
-  rv = appHelper->GetNativePath(appHelperPath);
+  nsAutoString appHelperPath;
+  rv = appHelper->GetPath(appHelperPath);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (aForAllUsers) {
     appHelperPath.AppendLiteral(" /SetAsDefaultAppGlobal");
   } else {
     appHelperPath.AppendLiteral(" /SetAsDefaultAppUser");
   }
 
-  STARTUPINFO si = {sizeof(si), 0};
+  STARTUPINFOW si = {sizeof(si), 0};
   PROCESS_INFORMATION pi = {0};
 
-  BOOL ok = CreateProcess(NULL, (LPSTR)appHelperPath.get(), NULL, NULL,
-                          FALSE, 0, NULL, NULL, &si, &pi);
+  BOOL ok = CreateProcessW(NULL, (LPWSTR)appHelperPath.get(), NULL, NULL,
+                           FALSE, 0, NULL, NULL, &si, &pi);
 
   if (!ok)
     return NS_ERROR_FAILURE;
 
   CloseHandle(pi.hProcess);
   CloseHandle(pi.hThread);
 
   return NS_OK;
@@ -761,18 +758,18 @@ nsWindowsShellService::GetUnreadMailCoun
   if (GetMailAccountKey(&accountKey)) {
     DWORD type, unreadCount;
     DWORD len = sizeof unreadCount;
     DWORD res = ::RegQueryValueExW(accountKey, L"MessageCount", 0,
                                    &type, (LPBYTE)&unreadCount, &len);
     if (REG_SUCCEEDED(res))
       *aCount = unreadCount;
 
-  // Close the key we opened.
-  ::RegCloseKey(accountKey);
+    // Close the key we opened.
+    ::RegCloseKey(accountKey);
   }
 
   return NS_OK;
 }
 
 PRBool
 nsWindowsShellService::GetMailAccountKey(HKEY* aResult)
 {
--- a/browser/components/shell/src/nsWindowsShellService.h
+++ b/browser/components/shell/src/nsWindowsShellService.h
@@ -52,24 +52,17 @@ public:
   nsWindowsShellService() : mCheckedThisSession(PR_FALSE) {}; 
   virtual ~nsWindowsShellService() {};
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSISHELLSERVICE
   NS_DECL_NSIWINDOWSSHELLSERVICE
 
 protected:
-  PRBool    IsDefaultBrowserVista(PRBool aStartupCheck, PRBool* aIsDefaultBrowser);
+  PRBool    IsDefaultBrowserVista(PRBool* aIsDefaultBrowser);
 
   PRBool    GetMailAccountKey(HKEY* aResult);
-  void      SetRegKey(const nsString& aKeyName,
-                      const nsString& aValueName,
-                      const nsString& aValue, PRBool aHKLMOnly);
-
-  DWORD     DeleteRegKey(HKEY baseKey, const nsString& keyName);
-  DWORD     DeleteRegKeyDefaultValue(HKEY baseKey,
-                                     const nsString& keyName);
 
 private:
   PRBool    mCheckedThisSession;
 };
 
 #endif // nswindowsshellservice_h____
--- a/browser/locales/all-locales
+++ b/browser/locales/all-locales
@@ -1,29 +1,27 @@
 af
 ar
 be
-bg
 ca
 cs
 da
 de
 el
 en-GB
 es-AR
 es-ES
 eu
 fi
 fr
 fy-NL
 ga-IE
 gu-IN
 he
 hu
-hy-AM
 id
 it
 ja
 ja-JP-mac
 ka
 ko
 ku
 lt
@@ -33,18 +31,16 @@ nb-NO
 nl
 nn-NO
 pa-IN
 pl
 pt-BR
 pt-PT
 ro
 ru
-si
 sk
-sl
 sq
 sr
 sv-SE
 tr
 uk
 zh-CN
 zh-TW
--- a/browser/locales/en-US/chrome/browser/preferences/applications.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/applications.dtd
@@ -2,13 +2,9 @@
 <!ENTITY  typeColumn.accesskey    "T">
 
 <!ENTITY  actionColumn2.label     "Action">
 <!ENTITY  actionColumn2.accesskey "A">
 
 <!ENTITY  focusSearch1.key        "f">
 <!ENTITY  focusSearch2.key        "k">
 
-<!ENTITY  filter.label            "Search:">
-<!ENTITY  filter.accesskey        "S">
-
-<!ENTITY  clear.label             "Clear">
-<!ENTITY  clear.accesskey         "l">
+<!ENTITY  filter.emptytext        "Search">
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -79,18 +79,21 @@ LIBXUL_DIST = $(DIST)
 endif
 
 XULRUNNER_STUB_NAME = @XULRUNNER_STUB_NAME@
 
 MOZ_CHROME_FILE_FORMAT	= @MOZ_CHROME_FILE_FORMAT@
 
 MOZ_WIDGET_TOOLKIT	= @MOZ_WIDGET_TOOLKIT@
 MOZ_GFX_TOOLKIT		= @MOZ_GFX_TOOLKIT@
+MOZ_DFB			= @MOZ_DFB@
 MOZ_X11			= @MOZ_X11@
 
+MOZ_PANGO = @MOZ_PANGO@
+
 MOZ_JS_LIBS		   = @MOZ_JS_LIBS@
 
 MOZ_DEBUG	= @MOZ_DEBUG@
 MOZ_DEBUG_MODULES = @MOZ_DEBUG_MODULES@
 MOZ_PROFILE_MODULES = @MOZ_PROFILE_MODULES@
 MOZ_DEBUG_ENABLE_DEFS		= @MOZ_DEBUG_ENABLE_DEFS@
 MOZ_DEBUG_DISABLE_DEFS	= @MOZ_DEBUG_DISABLE_DEFS@
 MOZ_DEBUG_FLAGS	= @MOZ_DEBUG_FLAGS@
--- a/config/system-headers
+++ b/config/system-headers
@@ -75,24 +75,25 @@ byteswap.h
 #define WRAP_CAIRO_HEADERS
 #endif
 #ifdef WRAP_CAIRO_HEADERS
 cairo.h
 cairo-atsui.h
 cairo-beos.h
 cairo-ft.h
 cairo-glitz.h
-cairo-nquartz.h
 cairo-os2.h
 cairo-pdf.h
 cairo-ps.h
 cairo-quartz.h
 cairo-win32.h
 cairo-xlib.h
 cairo-xlib-xrender.h
+cairo-directfb.h
+cairo-qpainter.h
 #endif
 callconv.h
 Carbon/Carbon.h
 CarbonEvents.h
 Carbon.h
 cassert
 c_asm.h
 cctype
--- a/config/version_win.pl
+++ b/config/version_win.pl
@@ -45,17 +45,17 @@ use Getopt::Long;
 use Getopt::Std;
 use POSIX;
 
 # Calculate the number of days since Jan. 1, 2000 from a buildid string
 sub daysFromBuildID
 {
     my ($buildid,) = @_;
 
-    my ($y, $m, $d, $h) = ($buildid =~ /^(\d{4})(\d{2})(\d{2})(\d{2})$/);
+    my ($y, $m, $d, $h) = ($buildid =~ /^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$/);
     $d || die("Unrecognized buildid string.");
 
     my $secondstodays = 60 * 60 * 24;
     return (POSIX::mktime(00, 00, 00, $d, $m, $y - 1900) -
             POSIX::mktime(00, 00, 00, 01, 01, 100)) / $secondstodays;
 }
 
 #Creates version resource file
--- a/configure.in
+++ b/configure.in
@@ -960,17 +960,17 @@ MOZ_ZLIB_CFLAGS=
 MOZ_ZLIB_LIBS='$(call EXPAND_LIBNAME_PATH,mozz,$(DEPTH)/modules/zlib/src)'
 MOZ_BZ2_CFLAGS=
 MOZ_BZ2_LIBS='$(call EXPAND_LIBNAME_PATH,bz2,$(DEPTH)/modules/libbz2/src)'
 MOZ_PNG_CFLAGS=
 MOZ_PNG_LIBS='$(call EXPAND_LIBNAME_PATH,mozpng,$(DEPTH)/modules/libimg/png)'
 
 MOZ_JS_LIBS='-L$(LIBXUL_DIST)/bin -lmozjs'
 DYNAMIC_XPCOM_LIBS='-L$(LIBXUL_DIST)/bin -lxpcom -lxpcom_core'
-MOZ_FIX_LINK_PATHS='-Wl,-rpath-link,$(LIBXUL_DIST)/bin'
+MOZ_FIX_LINK_PATHS='-Wl,-rpath-link,$(LIBXUL_DIST)/bin -Wl,-rpath-link,$(PREFIX)/lib'
 XPCOM_FROZEN_LDOPTS='-L$(LIBXUL_DIST)/bin -lxpcom'
 LIBXUL_LIBS='$(XPCOM_FROZEN_LDOPTS) -lxul'
 XPCOM_GLUE_LDOPTS='$(LIBXUL_DIST)/lib/$(LIB_PREFIX)xpcomglue_s.$(LIB_SUFFIX) $(XPCOM_FROZEN_LDOPTS)'
 XPCOM_STANDALONE_GLUE_LDOPTS='$(LIBXUL_DIST)/lib/$(LIB_PREFIX)xpcomglue.$(LIB_SUFFIX)'
 
 MOZ_COMPONENT_NSPR_LIBS='-L$(LIBXUL_DIST)/bin $(NSPR_LIBS)'
 MOZ_XPCOM_OBSOLETE_LIBS='-L$(LIBXUL_DIST)/lib -lxpcom_compat'
 
@@ -4703,39 +4703,38 @@ MOZ_ARG_HEADER(Toolkit Options)
                           Select default toolkit
                           Platform specific defaults:
                             BeOS - cairo-beos
                             Mac OS X - cairo-cocoa
                             Neutrino/QNX - photon
                             OS/2 - cairo-os2
                             Win32 - cairo-windows
                             WinCE - windows
+                            Gtk2 with DirectFB - cairo-gtk2-dfb
                             * - cairo-gtk2
                             * - cairo-qt],
     [ _DEFAULT_TOOLKIT=$enableval ],
     [ _DEFAULT_TOOLKIT=$_PLATFORM_DEFAULT_TOOLKIT])
 
     if test "$_DEFAULT_TOOLKIT" = "photon" \
         -o "$_DEFAULT_TOOLKIT" = "cairo-windows" \
         -o "$_DEFAULT_TOOLKIT" = "cairo-gtk2" \
+        -o "$_DEFAULT_TOOLKIT" = "cairo-gtk2-dfb" \
+        -o "$_DEFAULT_TOOLKIT" = "cairo-gtk2-x11" \
         -o "$_DEFAULT_TOOLKIT" = "cairo-qt" \
         -o "$_DEFAULT_TOOLKIT" = "cairo-beos" \
         -o "$_DEFAULT_TOOLKIT" = "cairo-os2" \
         -o "$_DEFAULT_TOOLKIT" = "cairo-mac" \
         -o "$_DEFAULT_TOOLKIT" = "cairo-cocoa"
     then
         dnl nglayout only supports building with one toolkit,
         dnl so ignore everything after the first comma (",").
         MOZ_WIDGET_TOOLKIT=`echo "$_DEFAULT_TOOLKIT" | sed -e "s/,.*$//"`
     else
-        if test "$no_x" != "yes"; then
-            AC_MSG_ERROR([Toolkit must be cairo-gtk2 or cairo-qt.])
-        else
-            AC_MSG_ERROR([Toolkit must be $_PLATFORM_DEFAULT_TOOLKIT (if supported).])
-        fi
+        AC_MSG_ERROR([You must specify a default toolkit (perhaps $_PLATFORM_DEFAULT_TOOLKIT).])
     fi
 
 AC_DEFINE_UNQUOTED(MOZ_DEFAULT_TOOLKIT,"$MOZ_WIDGET_TOOLKIT")
 
 dnl ========================================================
 dnl = Enable the toolkit as needed                         =
 dnl ========================================================
 
@@ -4745,34 +4744,61 @@ photon)
 	AC_DEFINE(MOZ_WIDGET_PHOTON)
     ;;
 
 cairo-windows)
     MOZ_WIDGET_TOOLKIT=windows
     MOZ_GFX_TOOLKIT=cairo
     ;;
 
-cairo-gtk2)
+cairo-gtk2|cairo-gtk2-x11)
     MOZ_WIDGET_TOOLKIT=gtk2
     MOZ_GFX_TOOLKIT=cairo
     MOZ_ENABLE_GTK2=1
     MOZ_ENABLE_XREMOTE=1
+
+    AC_DEFINE(MOZ_X11)
+    MOZ_X11=1
+
     TK_CFLAGS='$(MOZ_GTK2_CFLAGS)'
     TK_LIBS='$(MOZ_GTK2_LIBS)'
     AC_DEFINE(MOZ_WIDGET_GTK2)
     ;;
+
+cairo-gtk2-dfb)
+    MOZ_WIDGET_TOOLKIT=gtk2
+    MOZ_GFX_TOOLKIT=cairo
+    MOZ_ENABLE_GTK2=1
+
+    AC_DEFINE(MOZ_DFB)
+    MOZ_DFB=1
+
+    TK_CFLAGS='$(MOZ_GTK2_CFLAGS)'
+    TK_LIBS='$(MOZ_GTK2_LIBS)'
+    AC_DEFINE(MOZ_WIDGET_GTK2)
+    if test "$no_x" != "yes"; then
+        AC_MSG_WARN([Disabling X when DirectFB is specified.])
+        no_x=yes
+    fi
+    ;;
+
 cairo-qt)
     MOZ_WIDGET_TOOLKIT=qt
     MOZ_GFX_TOOLKIT=cairo
     MOZ_ENABLE_QT=1
     MOZ_ENABLE_XREMOTE=1
+
+    AC_DEFINE(MOZ_X11)
+    MOZ_X11=1
+
     TK_CFLAGS='$(MOZ_QT_CFLAGS)'
     TK_LIBS='$(MOZ_QT_LIBS)'
     AC_DEFINE(MOZ_WIDGET_QT)
     ;;
+
 cairo-beos)
     MOZ_WIDGET_TOOLKIT=beos
     MOZ_GFX_TOOLKIT=cairo
     TK_CFLAGS='$(MOZ_CAIRO_CFLAGS)'
     TK_LIBS='$(MOZ_CAIRO_LIBS)'
     ;;
 
 cairo-os2)
@@ -4802,20 +4828,27 @@ cairo-mac|cairo-cocoa)
     ;;
 esac
 
 if test "$MOZ_ENABLE_XREMOTE"; then
     AC_DEFINE(MOZ_ENABLE_XREMOTE)
 fi
 
 if test "$COMPILE_ENVIRONMENT"; then
-if test "$MOZ_ENABLE_GTK2"
-then
-    PKG_CHECK_MODULES(MOZ_GTK2, gtk+-2.0 >= $GTK2_VERSION gtk+-unix-print-2.0 gdk-x11-2.0 glib-2.0 gobject-2.0)
-fi
+  if test "$MOZ_ENABLE_GTK2"; then
+    if test "$MOZ_X11"; then
+      GDK_PACKAGES=gdk-x11-2.0
+    elif test "$MOZ_DFB"; then
+      PKG_CHECK_MODULES(MOZ_DFB, directfb >= 1.1.0)
+      GDK_PACKAGES=directfb
+    fi
+
+    PKG_CHECK_MODULES(MOZ_GTK2, gtk+-2.0 >= $GTK2_VERSION gtk+-unix-print-2.0 glib-2.0 gobject-2.0 $GDK_PACKAGES)
+  fi
+
 fi # COMPILE_ENVIRONMENT
 
 AC_SUBST(MOZ_DEFAULT_TOOLKIT)
 
 dnl ========================================================
 dnl = startup-notification support module
 dnl ========================================================
 
@@ -4901,22 +4934,17 @@ AC_SUBST(MOZ_ENABLE_QT)
 AC_SUBST(MOZ_ENABLE_XREMOTE)
 AC_SUBST(MOZ_GTK2_CFLAGS)
 AC_SUBST(MOZ_GTK2_LIBS)
 AC_SUBST(MOZ_QT_CFLAGS)
 AC_SUBST(MOZ_QT_LIBS)
 
 AC_SUBST(MOC)
 
-if test "$MOZ_ENABLE_GTK2" \
-|| test "$MOZ_ENABLE_QT"
-then
-    AC_DEFINE(MOZ_X11)
-    MOZ_X11=1
-fi
+AC_SUBST(MOZ_DFB)
 AC_SUBST(MOZ_X11)
 
 dnl ========================================================
 dnl =
 dnl = Components & Features
 dnl = 
 dnl ========================================================
 MOZ_ARG_HEADER(Components and Features)
@@ -5021,29 +5049,57 @@ MOZ_ARG_WITH_STRING(distribution-id,
 
 if test -z "$MOZ_DISTRIBUTION_ID"; then
    MOZ_DISTRIBUTION_ID="org.mozilla"
 fi
 
 AC_DEFINE_UNQUOTED(MOZ_DISTRIBUTION_ID,"$MOZ_DISTRIBUTION_ID")
 AC_SUBST(MOZ_DISTRIBUTION_ID)
 
+
+dnl ========================================================
+dnl complex text support off by default
+dnl ========================================================
+MOZ_PANGO=1
+MOZ_ARG_DISABLE_BOOL(pango,
+[  --disable-pango Disable usage of Pango ],
+    MOZ_PANGO=,
+    MOZ_PANGO=1)
+
+
 dnl ========================================================
 dnl = Xft and Pango
 dnl ========================================================
 if test "$MOZ_ENABLE_GTK2"
 then
-    PKG_CHECK_MODULES(MOZ_XFT, xft)
-    AC_SUBST(MOZ_XFT_CFLAGS)
-    AC_SUBST(MOZ_XFT_LIBS)
+    if test "$MOZ_X11"; then
+        PKG_CHECK_MODULES(MOZ_XFT, xft)
+        AC_SUBST(MOZ_XFT_CFLAGS)
+        AC_SUBST(MOZ_XFT_LIBS)
+    fi
+
+    AC_SUBST(MOZ_PANGO)
 
     PKG_CHECK_MODULES(_PANGOCHK, pango >= $PANGO_VERSION)
-    PKG_CHECK_MODULES(MOZ_PANGO, pango >= $PANGO_VERSION pangocairo >= $PANGO_VERSION pangoft2 >= $PANGO_VERSION)
-    AC_SUBST(MOZ_PANGO_CFLAGS)
-    AC_SUBST(MOZ_PANGO_LIBS)
+
+    if test "$MOZ_PANGO"
+    then
+        PKG_CHECK_MODULES(MOZ_PANGO, pango >= $PANGO_VERSION pangocairo >= $PANGO_VERSION pangoft2 >= $PANGO_VERSION)
+        AC_SUBST(MOZ_PANGO_CFLAGS)
+        AC_SUBST(MOZ_PANGO_LIBS)
+        AC_DEFINE(MOZ_PANGO)
+    else
+        PKG_CHECK_MODULES(MOZ_PANGO, pango >= $PANGO_VERSION pangoft2 >= $PANGO_VERSION)
+        AC_SUBST(MOZ_PANGO_CFLAGS)
+        AC_SUBST(MOZ_PANGO_LIBS)
+
+        PKG_CHECK_MODULES(FT2, freetype2 > 6.1.0 fontconfig)
+        AC_SUBST(FT2_CFLAGS)
+        AC_SUBST(FT2_LIBS)
+    fi
 fi
 
 dnl ========================================================
 dnl = PostScript print module
 dnl ========================================================
 MOZ_ARG_DISABLE_BOOL(postscript,
 [  --disable-postscript    Disable PostScript printing support ],
     MOZ_ENABLE_POSTSCRIPT=,
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -218,19 +218,17 @@ public:
 
   /**
    * Get/Set the base target of a link in a document.
    */
   virtual void GetBaseTarget(nsAString &aBaseTarget) const = 0;
   virtual void SetBaseTarget(const nsAString &aBaseTarget) = 0;
 
   /**
-   * Return a standard name for the document's character set. This
-   * will trigger a startDocumentLoad if necessary to answer the
-   * question.
+   * Return a standard name for the document's character set.
    */
   const nsCString& GetDocumentCharacterSet() const
   {
     return mCharacterSet;
   }
 
   /**
    * Set the document's character encoding. |aCharSetID| should be canonical. 
--- a/content/base/public/nsIFrameLoader.idl
+++ b/content/base/public/nsIFrameLoader.idl
@@ -71,13 +71,28 @@ interface nsIFrameLoader : nsISupports
   /**
    * Find out whether the loader's frame is at too great a depth in
    * the frame tree.  This can be used to decide what operations may
    * or may not be allowed on the loader's docshell.
    */
   readonly attribute boolean depthTooGreat;
 };
 
-[scriptable, uuid(feaf9285-05ac-4898-a69f-c3bd350767e4)]
+[scriptable, uuid(641c2d90-4ada-4367-bdb1-80831614161d)]
 interface nsIFrameLoaderOwner : nsISupports
 {
+  /**
+   * The frame loader owned by this nsIFrameLoaderOwner
+   */
   readonly attribute nsIFrameLoader frameLoader;
+
+  /**
+   * Swap frame loaders with the given nsIFrameLoaderOwner.  This may
+   * only be posible in a very limited range of circumstances, or
+   * never, depending on the object implementing this interface.
+   *
+   * @throws NS_ERROR_NOT_IMPLEMENTED if the swapping logic is not
+   *   implemented for the two given frame loader owners.
+   * @throws NS_ERROR_DOM_SECURITY_ERR if the swap is not allowed on
+   *   security grounds.
+   */
+  void swapFrameLoaders(in nsIFrameLoaderOwner aOtherOwner);
 };
--- a/content/base/public/nsIScriptElement.h
+++ b/content/base/public/nsIScriptElement.h
@@ -76,17 +76,22 @@ public:
   virtual already_AddRefed<nsIURI> GetScriptURI() = 0;
   
   /**
    * Script source text for inline script elements.
    */
   virtual void GetScriptText(nsAString& text) = 0;
 
   virtual void GetScriptCharset(nsAString& charset) = 0;
-  
+
+  /**
+   * Is the script deferred. Currently only supported by HTML scripts.
+   */
+  virtual PRBool GetScriptDeferred() = 0;
+
   void SetScriptLineNumber(PRUint32 aLineNumber)
   {
     mLineNumber = aLineNumber;
   }
   PRUint32 GetScriptLineNumber()
   {
     return mLineNumber;
   }
--- a/content/base/public/nsPresShellIterator.h
+++ b/content/base/public/nsPresShellIterator.h
@@ -53,16 +53,21 @@ public:
   {
     nsIPresShell* shell = nsnull;
     if (!mDoc->ShellsAreHidden() && HasMore()) {
       shell = GetNext();
       NS_IF_ADDREF(shell);
     }
     return shell;
   }
+
+  PRBool HasMoreThanOneShell() {
+    return mDoc->mPresShells.Length() > 1;
+  }
+  
 private:
   static void* operator new(size_t) CPP_THROW_NEW { return 0; }
   static void operator delete(void*, size_t) {}
 
   nsCOMPtr<nsIDocument> mDoc;
 };
 
 #endif
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -1706,16 +1706,18 @@ nsDocument::StartDocumentLoad(const char
     ScriptLoader()->SetEnabled(PR_FALSE);
 
     // styles
     CSSLoader()->SetEnabled(PR_FALSE); // Do not load/process styles when loading as data
   }
 
   mMayStartLayout = PR_FALSE;
 
+  mHaveInputEncoding = PR_TRUE;
+
   if (aReset) {
     Reset(aChannel, aLoadGroup);
   }
 
   nsCAutoString contentType;
   if (NS_SUCCEEDED(aChannel->GetContentType(contentType))) {
     // XXX this is only necessary for viewsource:
     nsACString::const_iterator start, end, semicolon;
@@ -3169,16 +3171,20 @@ nsDocument::EndUpdate(nsUpdateType aUpda
 
 void
 nsDocument::BeginLoad()
 {
   // Block onload here to prevent having to deal with blocking and
   // unblocking it while we know the document is loading.
   BlockOnload();
 
+  if (mScriptLoader) {
+    mScriptLoader->BeginDeferringScripts();
+  }
+
   NS_DOCUMENT_NOTIFY_OBSERVERS(BeginLoad, (this));
 }
 
 PRBool
 nsDocument::CheckGetElementByIdArg(const nsIAtom* aId)
 {
   if (aId == nsGkAtoms::_empty) {
     nsContentUtils::ReportToConsole(
@@ -3412,16 +3418,20 @@ nsDocument::DispatchContentLoadedEvents(
           }
         }
       }
       
       parent = parent->GetParentDocument();
     } while (parent);
   }
 
+  if (mScriptLoader) {
+    mScriptLoader->EndDeferringScripts();
+  }
+
   UnblockOnload(PR_TRUE);
 }
 
 void
 nsDocument::EndLoad()
 {
   // Drop the ref to our parser, if any, but keep hold of the sink so that we
   // can flush it from FlushPendingNotifications as needed.  We might have to
@@ -4954,17 +4964,22 @@ nsDocument::LookupNamespaceURI(const nsA
     SetDOMStringToNull(aNamespaceURI);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocument::GetInputEncoding(nsAString& aInputEncoding)
 {
-  return GetCharacterSet(aInputEncoding);
+  if (mHaveInputEncoding) {
+    return GetCharacterSet(aInputEncoding);
+  }
+
+  SetDOMStringToNull(aInputEncoding);
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocument::GetXmlEncoding(nsAString& aXmlEncoding)
 {
   if (mXMLDeclarationBits & XML_DECLARATION_BITS_DECLARATION_EXISTS &&
       mXMLDeclarationBits & XML_DECLARATION_BITS_ENCODING_EXISTS) {
     // XXX We don't store the encoding given in the xml declaration.
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -942,16 +942,20 @@ protected:
   PRPackedBool mIsRegularHTML:1;
 
   PRPackedBool mHasWarnedAboutBoxObjects:1;
 
   PRPackedBool mDelayFrameLoaderInitialization:1;
 
   PRPackedBool mSynchronousDOMContentLoaded:1;
 
+  // If true, we have an input encoding.  If this is false, then the
+  // document was created entirely in memory
+  PRPackedBool mHaveInputEncoding:1;
+
   PRUint8 mXMLDeclarationBits;
 
   PRUint8 mDefaultElementType;
 
   PRBool IdTableIsLive() const {
     // live if we've had over 63 misses
     return (mIdMissCount & 0x40) != 0;
   }
--- a/content/base/src/nsDocumentEncoder.cpp
+++ b/content/base/src/nsDocumentEncoder.cpp
@@ -349,17 +349,17 @@ nsDocumentEncoder::SerializeNodeEnd(nsID
 }
 
 nsresult
 nsDocumentEncoder::SerializeToStringRecursive(nsIDOMNode* aNode,
                                               nsAString& aStr,
                                               PRBool aDontSerializeRoot)
 {
   nsresult rv = NS_OK;
-  PRBool serializeClonedChildren;
+  PRBool serializeClonedChildren = PR_FALSE;
   nsCOMPtr<nsIDOMNode> maybeFixedNode;
   
   if (mNodeFixup)
     mNodeFixup->FixupNode(aNode, &serializeClonedChildren, getter_AddRefs(maybeFixedNode));
 
   if (!maybeFixedNode)
     maybeFixedNode = aNode;
 
--- a/content/base/src/nsFrameLoader.cpp
+++ b/content/base/src/nsFrameLoader.cpp
@@ -17,16 +17,17 @@
  *
  * The Initial Developer of the Original Code is
  * Netscape Communications Corporation.
  * Portions created by the Initial Developer are Copyright (C) 1998
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   Johnny Stenback <jst@netscape.com> (original author)
+ *   Boris Zbarsky <bzbarsky@mit.edu>
  *
  * 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
@@ -60,16 +61,22 @@
 #include "nsIDocShellLoadInfo.h"
 #include "nsIBaseWindow.h"
 #include "nsContentUtils.h"
 #include "nsUnicharUtils.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsFrameLoader.h"
 #include "nsIDOMEventTarget.h"
+#include "nsIFrame.h"
+#include "nsIFrameFrame.h"
+#include "nsDOMError.h"
+#include "nsPresShellIterator.h"
+#include "nsGUIEvent.h"
+#include "nsEventDispatcher.h"
 
 #include "nsIURI.h"
 #include "nsIURL.h"
 #include "nsNetUtil.h"
 
 #include "nsGkAtoms.h"
 #include "nsINameSpaceManager.h"
 
@@ -276,16 +283,377 @@ nsFrameLoader::Finalize()
 {
   nsCOMPtr<nsIBaseWindow> base_win(do_QueryInterface(mDocShell));
   if (base_win) {
     base_win->Destroy();
   }
   mDocShell = nsnull;
 }
 
+static void
+FirePageHideEvent(nsIDocShellTreeItem* aItem,
+                  nsIDOMEventTarget* aChromeEventHandler)
+{
+  nsPageTransitionEvent event(PR_TRUE, NS_PAGE_HIDE, PR_TRUE);
+  nsCOMPtr<nsIDOMDocument> doc = do_GetInterface(aItem);
+  event.target = do_QueryInterface(doc);
+  nsEventDispatcher::Dispatch(aChromeEventHandler, nsnull, &event);
+  
+  PRInt32 childCount = 0;
+  aItem->GetChildCount(&childCount);
+  nsAutoTArray<nsCOMPtr<nsIDocShellTreeItem>, 8> kids;
+  kids.AppendElements(childCount);
+  for (PRInt32 i = 0; i < childCount; ++i) {
+    aItem->GetChildAt(i, getter_AddRefs(kids[i]));
+  }
+
+  for (PRUint32 i = 0; i < kids.Length(); ++i) {
+    if (kids[i]) {
+      FirePageHideEvent(kids[i], aChromeEventHandler);
+    }
+  }
+}
+
+static void
+FirePageShowEvent(nsIDocShellTreeItem* aItem,
+                  nsIDOMEventTarget* aChromeEventHandler)
+{
+  PRInt32 childCount = 0;
+  aItem->GetChildCount(&childCount);
+  nsAutoTArray<nsCOMPtr<nsIDocShellTreeItem>, 8> kids;
+  kids.AppendElements(childCount);
+  for (PRInt32 i = 0; i < childCount; ++i) {
+    aItem->GetChildAt(i, getter_AddRefs(kids[i]));
+  }
+
+  for (PRUint32 i = 0; i < kids.Length(); ++i) {
+    if (kids[i]) {
+      FirePageShowEvent(kids[i], aChromeEventHandler);
+    }
+  }
+
+  nsPageTransitionEvent event(PR_TRUE, NS_PAGE_SHOW, PR_TRUE);
+  nsCOMPtr<nsIDOMDocument> doc = do_GetInterface(aItem);
+  event.target = do_QueryInterface(doc);
+  nsEventDispatcher::Dispatch(aChromeEventHandler, nsnull, &event);
+}
+
+static void
+SetTreeOwnerAndChromeEventHandlerOnDocshellTree(nsIDocShellTreeItem* aItem,
+                                                nsIDocShellTreeOwner* aOwner,
+                                                nsIDOMEventTarget* aHandler)
+{
+  NS_PRECONDITION(aItem, "Must have item");
+#ifdef DEBUG
+  PRInt32 itemType;
+  aItem->GetItemType(&itemType);
+  NS_ASSERTION(itemType == nsIDocShellTreeItem::typeContent,
+               "How did something else get in here?");
+#endif
+
+  aItem->SetTreeOwner(aOwner);
+  nsCOMPtr<nsIDocShell> shell(do_QueryInterface(aItem));
+  shell->SetChromeEventHandler(aHandler);
+
+  PRInt32 childCount = 0;
+  aItem->GetChildCount(&childCount);
+  for (PRInt32 i = 0; i < childCount; ++i) {
+    nsCOMPtr<nsIDocShellTreeItem> item;
+    aItem->GetChildAt(i, getter_AddRefs(item));
+    SetTreeOwnerAndChromeEventHandlerOnDocshellTree(item, aOwner, aHandler);
+  }
+}
+
+/**
+ * Set the type of the treeitem and hook it up to the treeowner.
+ * @param aItem the treeitem we're wrking working with
+ * @param aOwningContent the content node that owns aItem
+ * @param aTreeOwner the relevant treeowner; might be null
+ * @param aParentType the nsIDocShellTreeItem::GetType of our parent docshell
+ * @param aParentNode if non-null, the docshell we should be added as a child to
+ *
+ * @return whether aItem is top-level content
+ */
+static PRBool
+AddTreeItemToTreeOwner(nsIDocShellTreeItem* aItem, nsIContent* aOwningContent,
+                       nsIDocShellTreeOwner* aOwner, PRInt32 aParentType,
+                       nsIDocShellTreeNode* aParentNode)
+{
+  NS_PRECONDITION(aItem, "Must have docshell treeitem");
+  NS_PRECONDITION(aOwningContent, "Must have owning content");
+  
+  nsAutoString value;
+  PRBool isContent = PR_FALSE;
+
+  if (aOwningContent->IsNodeOfType(nsINode::eXUL)) {
+      aOwningContent->GetAttr(kNameSpaceID_None, nsGkAtoms::type, value);
+  }
+
+  // we accept "content" and "content-xxx" values.
+  // at time of writing, we expect "xxx" to be "primary" or "targetable", but
+  // someday it might be an integer expressing priority or something else.
+
+  isContent = value.LowerCaseEqualsLiteral("content") ||
+    StringBeginsWith(value, NS_LITERAL_STRING("content-"),
+                     nsCaseInsensitiveStringComparator());
+
+  if (isContent) {
+    // The web shell's type is content.
+
+    aItem->SetItemType(nsIDocShellTreeItem::typeContent);
+  } else {
+    // Inherit our type from our parent webshell.  If it is
+    // chrome, we'll be chrome.  If it is content, we'll be
+    // content.
+
+    aItem->SetItemType(aParentType);
+  }
+
+  // Now that we have our type set, add ourselves to the parent, as needed.
+  if (aParentNode) {
+    aParentNode->AddChild(aItem);
+  }
+
+  PRBool retval = PR_FALSE;
+  if (aParentType == nsIDocShellTreeItem::typeChrome && isContent) {
+    retval = PR_TRUE;
+
+    PRBool is_primary = value.LowerCaseEqualsLiteral("content-primary");
+
+    if (aOwner) {
+      PRBool is_targetable = is_primary ||
+        value.LowerCaseEqualsLiteral("content-targetable");
+      aOwner->ContentShellAdded(aItem, is_primary, is_targetable, value);
+    }
+  }
+
+  return retval;
+}
+
+nsresult
+nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
+                                   nsRefPtr<nsFrameLoader>& aFirstToSwap,
+                                   nsRefPtr<nsFrameLoader>& aSecondToSwap)
+{
+  NS_PRECONDITION((aFirstToSwap == this && aSecondToSwap == aOther) ||
+                  (aFirstToSwap == aOther && aSecondToSwap == this),
+                  "Swapping some sort of random loaders?");
+
+  nsIContent* ourContent = mOwnerContent;
+  nsIContent* otherContent = aOther->mOwnerContent;
+
+  if (!ourContent || !otherContent) {
+    // Can't handle this
+    return NS_ERROR_NOT_IMPLEMENTED;
+  }
+
+  // Make sure there are no same-origin issues
+  PRBool equal;
+  nsresult rv =
+    ourContent->NodePrincipal()->Equals(otherContent->NodePrincipal(), &equal);
+  if (NS_FAILED(rv) || !equal) {
+    // Security problems loom.  Just bail on it all
+    return NS_ERROR_DOM_SECURITY_ERR;
+  }
+
+  nsCOMPtr<nsIDocShell> ourDochell = GetExistingDocShell();
+  nsCOMPtr<nsIDocShell> otherDocshell = aOther->GetExistingDocShell();
+  if (!ourDochell || !otherDocshell) {
+    // How odd
+    return NS_ERROR_NOT_IMPLEMENTED;
+  }
+
+  // To avoid having to mess with session history, avoid swapping
+  // frameloaders that don't correspond to root same-type docshells.
+  nsCOMPtr<nsIDocShellTreeItem> ourTreeItem = do_QueryInterface(ourDochell);
+  nsCOMPtr<nsIDocShellTreeItem> otherTreeItem =
+    do_QueryInterface(otherDocshell);
+  nsCOMPtr<nsIDocShellTreeItem> ourRootTreeItem, otherRootTreeItem;
+  ourTreeItem->GetSameTypeRootTreeItem(getter_AddRefs(ourRootTreeItem));
+  otherTreeItem->GetSameTypeRootTreeItem(getter_AddRefs(otherRootTreeItem));
+  if (ourRootTreeItem != ourTreeItem || otherRootTreeItem != otherTreeItem) {
+    return NS_ERROR_NOT_IMPLEMENTED;
+  }
+
+  // Also make sure that the two docshells are the same type. Otherwise
+  // swapping is certainly not safe.  As far as that goes, make sure we only
+  // swap typeContent docshells, since otherwise it's hard to get treeowners
+  // right.
+  PRInt32 ourType = nsIDocShellTreeItem::typeChrome;
+  PRInt32 otherType = nsIDocShellTreeItem::typeChrome;
+  ourTreeItem->GetItemType(&ourType);
+  otherTreeItem->GetItemType(&otherType);
+  if (ourType != nsIDocShellTreeItem::typeContent ||
+      otherType != nsIDocShellTreeItem::typeContent) {
+    return NS_ERROR_NOT_IMPLEMENTED;
+  }
+  
+  // Save off the tree owners, frame elements, chrome event handlers, and
+  // docshell and document parents before doing anything else.
+  nsCOMPtr<nsIDocShellTreeOwner> ourOwner, otherOwner;
+  ourTreeItem->GetTreeOwner(getter_AddRefs(ourOwner));
+  otherTreeItem->GetTreeOwner(getter_AddRefs(otherOwner));
+  // Note: it's OK to have null treeowners.
+
+  nsCOMPtr<nsIDocShellTreeItem> ourParentItem, otherParentItem;
+  ourTreeItem->GetParent(getter_AddRefs(ourParentItem));
+  otherTreeItem->GetParent(getter_AddRefs(otherParentItem));
+  if (!ourParentItem || !otherParentItem) {
+    return NS_ERROR_NOT_IMPLEMENTED;
+  }
+
+  nsCOMPtr<nsPIDOMWindow> ourWindow = do_GetInterface(ourDochell);
+  nsCOMPtr<nsPIDOMWindow> otherWindow = do_GetInterface(otherDocshell);
+
+  nsCOMPtr<nsIDOMElement> ourFrameElement =
+    ourWindow->GetFrameElementInternal();
+  nsCOMPtr<nsIDOMElement> otherFrameElement =
+    otherWindow->GetFrameElementInternal();
+
+  nsCOMPtr<nsIDOMEventTarget> ourChromeEventHandler =
+    do_QueryInterface(ourWindow->GetChromeEventHandler());
+  nsCOMPtr<nsIDOMEventTarget> otherChromeEventHandler =
+    do_QueryInterface(otherWindow->GetChromeEventHandler());
+
+  NS_ASSERTION(SameCOMIdentity(ourFrameElement, ourContent) &&
+               SameCOMIdentity(otherFrameElement, otherContent) &&
+               SameCOMIdentity(ourChromeEventHandler, ourContent) &&
+               SameCOMIdentity(otherChromeEventHandler, otherContent),
+               "How did that happen, exactly?");
+
+  nsCOMPtr<nsIDocument> ourChildDocument =
+    do_QueryInterface(ourWindow->GetExtantDocument());
+  nsCOMPtr<nsIDocument> otherChildDocument =
+    do_QueryInterface(otherWindow->GetExtantDocument());
+  if (!ourChildDocument || !otherChildDocument) {
+    // This shouldn't be happening
+    return NS_ERROR_NOT_IMPLEMENTED;
+  }
+
+  nsCOMPtr<nsIDocument> ourParentDocument =
+    ourChildDocument->GetParentDocument();
+  nsCOMPtr<nsIDocument> otherParentDocument =
+    otherChildDocument->GetParentDocument();
+
+  // Make sure to swap docshells between the two frames.
+  nsIDocument* ourDoc = ourContent->GetCurrentDoc();
+  nsIDocument* otherDoc = otherContent->GetCurrentDoc();
+  if (!ourDoc || !otherDoc) {
+    // Again, how odd, given that we had docshells
+    return NS_ERROR_NOT_IMPLEMENTED;
+  }
+
+  NS_ASSERTION(ourDoc == ourParentDocument, "Unexpected parent document");
+  NS_ASSERTION(otherDoc == otherParentDocument, "Unexpected parent document");
+
+  nsPresShellIterator iter1(ourDoc);
+  nsPresShellIterator iter2(otherDoc);
+  if (iter1.HasMoreThanOneShell() || iter2.HasMoreThanOneShell()) {
+    return NS_ERROR_NOT_IMPLEMENTED;
+  }
+
+  nsIPresShell* ourShell = ourDoc->GetPrimaryShell();
+  nsIPresShell* otherShell = otherDoc->GetPrimaryShell();
+  if (!ourShell || !otherShell) {
+    return NS_ERROR_NOT_IMPLEMENTED;
+  }
+
+  if (mInSwap || aOther->mInSwap) {
+    return NS_ERROR_NOT_IMPLEMENTED;
+  }
+  mInSwap = aOther->mInSwap = PR_TRUE;
+
+  // Fire pagehide events.  Note that we do NOT fire these in the normal way,
+  // but just fire them on the chrome event handlers.
+  FirePageHideEvent(ourTreeItem, ourChromeEventHandler);
+  FirePageHideEvent(otherTreeItem, otherChromeEventHandler);
+  
+  nsIFrame* ourFrame = ourShell->GetPrimaryFrameFor(ourContent);
+  nsIFrame* otherFrame = otherShell->GetPrimaryFrameFor(otherContent);
+  if (!ourFrame || !otherFrame) {
+    mInSwap = aOther->mInSwap = PR_FALSE;
+    FirePageShowEvent(ourTreeItem, ourChromeEventHandler);
+    FirePageShowEvent(otherTreeItem, otherChromeEventHandler);
+    return NS_ERROR_NOT_IMPLEMENTED;
+  }
+
+  nsIFrameFrame* ourFrameFrame = nsnull;
+  CallQueryInterface(ourFrame, &ourFrameFrame);
+  if (!ourFrameFrame) {
+    mInSwap = aOther->mInSwap = PR_FALSE;
+    FirePageShowEvent(ourTreeItem, ourChromeEventHandler);
+    FirePageShowEvent(otherTreeItem, otherChromeEventHandler);
+    return NS_ERROR_NOT_IMPLEMENTED;
+  }
+
+  // OK.  First begin to swap the docshells in the two nsIFrames
+  rv = ourFrameFrame->BeginSwapDocShells(otherFrame);
+  if (NS_FAILED(rv)) {
+    mInSwap = aOther->mInSwap = PR_FALSE;
+    FirePageShowEvent(ourTreeItem, ourChromeEventHandler);
+    FirePageShowEvent(otherTreeItem, otherChromeEventHandler);
+    return rv;
+  }
+
+  // Now move the docshells to the right docshell trees.  Note that this
+  // resets their treeowners to null.
+  ourParentItem->RemoveChild(ourTreeItem);
+  otherParentItem->RemoveChild(otherTreeItem);
+  if (ourType == nsIDocShellTreeItem::typeContent) {
+    ourOwner->ContentShellRemoved(ourTreeItem);
+    otherOwner->ContentShellRemoved(otherTreeItem);
+  }
+  
+  ourParentItem->AddChild(otherTreeItem);
+  otherParentItem->AddChild(ourTreeItem);
+
+  // Restore the correct treeowners
+  SetTreeOwnerAndChromeEventHandlerOnDocshellTree(ourTreeItem, otherOwner,
+                                                  otherChromeEventHandler);
+  SetTreeOwnerAndChromeEventHandlerOnDocshellTree(otherTreeItem, ourOwner,
+                                                  ourChromeEventHandler);
+
+  AddTreeItemToTreeOwner(ourTreeItem, otherContent, otherOwner,
+                         nsIDocShellTreeItem::typeChrome, nsnull);
+  AddTreeItemToTreeOwner(otherTreeItem, ourContent, ourOwner,
+                         nsIDocShellTreeItem::typeChrome, nsnull);
+
+  // SetSubDocumentFor nulls out parent documents on the old child doc if a
+  // new non-null document is passed in, so just go ahead and remove both
+  // kids before reinserting in the parent subdoc maps, to avoid
+  // complications.
+  ourParentDocument->SetSubDocumentFor(ourContent, nsnull);
+  otherParentDocument->SetSubDocumentFor(otherContent, nsnull);
+  ourParentDocument->SetSubDocumentFor(ourContent, otherChildDocument);
+  otherParentDocument->SetSubDocumentFor(otherContent, ourChildDocument);
+
+  ourWindow->SetFrameElementInternal(otherFrameElement);
+  otherWindow->SetFrameElementInternal(ourFrameElement);
+
+  mOwnerContent = otherContent;
+  aOther->mOwnerContent = ourContent;
+
+  aFirstToSwap.swap(aSecondToSwap);
+
+  // We shouldn't have changed frames, but be really careful about it
+  if (ourFrame == ourShell->GetPrimaryFrameFor(ourContent) &&
+      otherFrame == otherShell->GetPrimaryFrameFor(otherContent)) {
+    ourFrameFrame->EndSwapDocShells(otherFrame);
+  }
+
+  ourParentDocument->FlushPendingNotifications(Flush_Layout);
+  otherParentDocument->FlushPendingNotifications(Flush_Layout);
+  
+  FirePageShowEvent(ourTreeItem, otherChromeEventHandler);
+  FirePageShowEvent(otherTreeItem, ourChromeEventHandler);
+
+  mInSwap = aOther->mInSwap = PR_FALSE;
+  return NS_OK;
+}
+
 NS_IMETHODIMP
 nsFrameLoader::Destroy()
 {
   if (mDestroyCalled) {
     return NS_OK;
   }
   mDestroyCalled = PR_TRUE;
 
@@ -397,62 +765,23 @@ nsFrameLoader::EnsureDocShell()
     // nsSubDocumentFrame::AttributeChanged.  We should fix that.
 
     nsCOMPtr<nsIDocShellTreeItem> parentAsItem =
       do_QueryInterface(parentAsNode);
 
     PRInt32 parentType;
     parentAsItem->GetItemType(&parentType);
 
-    nsAutoString value;
-    PRBool isContent = PR_FALSE;
-
-    if (mOwnerContent->IsNodeOfType(nsINode::eXUL)) {
-      mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::type, value);
-    }
-
-    // we accept "content" and "content-xxx" values.
-    // at time of writing, we expect "xxx" to be "primary" or "targetable", but
-    // someday it might be an integer expressing priority or something else.
-
-    isContent = value.LowerCaseEqualsLiteral("content") ||
-      StringBeginsWith(value, NS_LITERAL_STRING("content-"),
-                       nsCaseInsensitiveStringComparator());
-
-    if (isContent) {
-      // The web shell's type is content.
-
-      docShellAsItem->SetItemType(nsIDocShellTreeItem::typeContent);
-    } else {
-      // Inherit our type from our parent webshell.  If it is
-      // chrome, we'll be chrome.  If it is content, we'll be
-      // content.
-
-      docShellAsItem->SetItemType(parentType);
-    }
-
-    parentAsNode->AddChild(docShellAsItem);
-
-    if (parentType == nsIDocShellTreeItem::typeChrome && isContent) {
-      mIsTopLevelContent = PR_TRUE;
-      
-      // XXXbz why is this in content code, exactly?  We should handle
-      // this some other way.....  Not sure how yet.
-      nsCOMPtr<nsIDocShellTreeOwner> parentTreeOwner;
-      parentAsItem->GetTreeOwner(getter_AddRefs(parentTreeOwner));
-
-      PRBool is_primary = value.LowerCaseEqualsLiteral("content-primary");
-
-      if (parentTreeOwner) {
-        PRBool is_targetable = is_primary ||
-          value.LowerCaseEqualsLiteral("content-targetable");
-        parentTreeOwner->ContentShellAdded(docShellAsItem, is_primary,
-                                            is_targetable, value);
-      }
-    }
+    // XXXbz why is this in content code, exactly?  We should handle
+    // this some other way.....  Not sure how yet.
+    nsCOMPtr<nsIDocShellTreeOwner> parentTreeOwner;
+    parentAsItem->GetTreeOwner(getter_AddRefs(parentTreeOwner));
+    mIsTopLevelContent =
+      AddTreeItemToTreeOwner(docShellAsItem, mOwnerContent, parentTreeOwner,
+                             parentType, parentAsNode);
 
     // Make sure all shells have links back to the content element
     // in the nearest enclosing chrome shell.
     nsCOMPtr<nsIDOMEventTarget> chromeEventHandler;
 
     if (parentType == nsIDocShellTreeItem::typeChrome) {
       // Our parent shell is a chrome shell. It is therefore our nearest
       // enclosing chrome shell.
--- a/content/base/src/nsFrameLoader.h
+++ b/content/base/src/nsFrameLoader.h
@@ -55,39 +55,48 @@ class nsIURI;
 class nsFrameLoader : public nsIFrameLoader
 {
 public:
   nsFrameLoader(nsIContent *aOwner) :
     mOwnerContent(aOwner),
     mDepthTooGreat(PR_FALSE),
     mIsTopLevelContent(PR_FALSE),
     mDestroyCalled(PR_FALSE),
-    mInDestructor(PR_FALSE)
+    mInDestructor(PR_FALSE),
+    mInSwap(PR_FALSE)
   {}
 
   ~nsFrameLoader() {
     mInDestructor = PR_TRUE;
     nsFrameLoader::Destroy();
   }
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS(nsFrameLoader)
   NS_DECL_NSIFRAMELOADER
   NS_HIDDEN_(nsresult) CheckForRecursiveLoad(nsIURI* aURI);
   nsresult ReallyStartLoading();
   void Finalize();
   nsIDocShell* GetExistingDocShell() { return mDocShell; }
+
+  // The guts of an nsIFrameLoaderOwner::SwapFrameLoader implementation.  A
+  // frame loader owner needs to call this, and pass in the two references to
+  // nsRefPtrs for frame loaders that need to be swapped.
+  nsresult SwapWithOtherLoader(nsFrameLoader* aOther,
+                               nsRefPtr<nsFrameLoader>& aFirstToSwap,
+                               nsRefPtr<nsFrameLoader>& aSecondToSwap);
 private:
 
   NS_HIDDEN_(nsresult) EnsureDocShell();
   NS_HIDDEN_(void) GetURL(nsString& aURL);
   nsresult CheckURILoad(nsIURI* aURI);
 
   nsCOMPtr<nsIDocShell> mDocShell;
   nsCOMPtr<nsIURI> mURIToLoad;
   nsIContent *mOwnerContent; // WEAK
-  PRPackedBool mDepthTooGreat;
-  PRPackedBool mIsTopLevelContent;
-  PRPackedBool mDestroyCalled;
-  PRPackedBool mInDestructor;
+  PRPackedBool mDepthTooGreat : 1;
+  PRPackedBool mIsTopLevelContent : 1;
+  PRPackedBool mDestroyCalled : 1;
+  PRPackedBool mInDestructor : 1;
+  PRPackedBool mInSwap : 1;
 };
 
 #endif
--- a/content/base/src/nsImageLoadingContent.cpp
+++ b/content/base/src/nsImageLoadingContent.cpp
@@ -481,16 +481,32 @@ nsImageLoadingContent::LoadImage(const n
     return NS_OK;
   }
 
   nsCOMPtr<nsIURI> imageURI;
   nsresult rv = StringToURI(aNewURI, doc, getter_AddRefs(imageURI));
   NS_ENSURE_SUCCESS(rv, rv);
   // XXXbiesi fire onerror if that failed?
 
+  PRBool equal;
+
+  if (aNewURI.IsEmpty() &&
+      doc->GetDocumentURI() &&
+      NS_SUCCEEDED(doc->GetDocumentURI()->Equals(imageURI, &equal)) && 
+      equal)  {
+
+    // Loading an embedded img from the same URI as the document URI will not work
+    // as a resource cannot recursively embed itself. Attempting to do so generally
+    // results in having to pre-emptively close down an in-flight HTTP transaction 
+    // and then incurring the significant cost of establishing a new TCP channel.
+    // This is generally triggered from <img src=""> 
+    // In light of that, just skip loading it..
+    return NS_OK;
+  }
+
   NS_TryToSetImmutable(imageURI);
 
   return LoadImage(imageURI, aForce, aNotify, doc);
 }
 
 nsresult
 nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
                                  PRBool aForce,
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -665,16 +665,22 @@ nsObjectLoadingContent::OnDataAvailable(
 NS_IMETHODIMP
 nsObjectLoadingContent::GetFrameLoader(nsIFrameLoader** aFrameLoader)
 {
   *aFrameLoader = mFrameLoader;
   NS_IF_ADDREF(*aFrameLoader);
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsObjectLoadingContent::SwapFrameLoaders(nsIFrameLoaderOwner* aOtherLoader)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
 // nsIObjectLoadingContent
 NS_IMETHODIMP
 nsObjectLoadingContent::GetActualType(nsACString& aType)
 {
   aType = mContentType;
   return NS_OK;
 }
 
--- a/content/base/src/nsScriptLoader.cpp
+++ b/content/base/src/nsScriptLoader.cpp
@@ -93,16 +93,17 @@ public:
   }
   void FireScriptEvaluated(nsresult aResult)
   {
     mElement->ScriptEvaluated(aResult, mElement, mIsInline);
   }
 
   nsCOMPtr<nsIScriptElement> mElement;
   PRPackedBool mLoading;             // Are we still waiting for a load to complete?
+  PRPackedBool mDefer;               // Is execution defered?
   PRPackedBool mIsInline;            // Is the script inline or loaded?
   nsString mScriptText;              // Holds script for loaded scripts
   PRUint32 mJSVersion;
   nsCOMPtr<nsIURI> mURI;
   PRInt32 mLineNo;
 };
 
 // The nsScriptLoadRequest is passed as the context to necko, and thus
@@ -120,18 +121,18 @@ nsScriptLoader::nsScriptLoader(nsIDocume
     mEnabled(PR_TRUE)
 {
 }
 
 nsScriptLoader::~nsScriptLoader()
 {
   mObservers.Clear();
 
-  for (PRInt32 i = 0; i < mPendingRequests.Count(); i++) {
-    mPendingRequests[i]->FireScriptAvailable(NS_ERROR_ABORT);
+  for (PRInt32 i = 0; i < mRequests.Count(); i++) {
+    mRequests[i]->FireScriptAvailable(NS_ERROR_ABORT);
   }
 
   // Unblock the kids, in case any of them moved to a different document
   // subtree in the meantime and therefore aren't actually going away.
   for (PRUint32 j = 0; j < mPendingChildLoaders.Length(); ++j) {
     mPendingChildLoaders[j]->RemoveExecuteBlocker();
   }  
 }
@@ -374,16 +375,20 @@ nsScriptLoader::ProcessScriptElement(nsI
 
   nsCOMPtr<nsIContent> eltContent(do_QueryInterface(aElement));
   eltContent->SetScriptTypeID(typeID);
 
   // Create a request object for this script
   nsRefPtr<nsScriptLoadRequest> request = new nsScriptLoadRequest(aElement, version);
   NS_ENSURE_TRUE(request, NS_ERROR_OUT_OF_MEMORY);
 
+  request->mDefer = mDeferEnabled && aElement->GetScriptDeferred();
+
+  PRBool hadPendingRequests = !!GetFirstPendingRequest();
+
   // First check to see if this is an external script
   nsCOMPtr<nsIURI> scriptURI = aElement->GetScriptURI();
   if (scriptURI) {
     // Check that the containing page is allowed to load this URI.
     rv = nsContentUtils::GetSecurityManager()->
       CheckLoadURIWithPrincipal(mDocument->NodePrincipal(), scriptURI,
                                 nsIScriptSecurityManager::ALLOW_CHROME);
 
@@ -443,30 +448,33 @@ nsScriptLoader::ProcessScriptElement(nsI
     request->mLoading = PR_FALSE;
     request->mIsInline = PR_TRUE;
     request->mURI = mDocument->GetDocumentURI();
 
     request->mLineNo = aElement->GetScriptLineNumber();
 
     // If we've got existing pending requests, add ourselves
     // to this list.
-    if (mPendingRequests.Count() == 0 && ReadyToExecuteScripts() &&
-        nsContentUtils::IsSafeToRunScript()) {
+    if (!request->mDefer && !hadPendingRequests &&
+        ReadyToExecuteScripts() && nsContentUtils::IsSafeToRunScript()) {
       return ProcessRequest(request);
     }
   }
 
-  // Add the request to our pending requests list
-  NS_ENSURE_TRUE(mPendingRequests.AppendObject(request),
+  // Add the request to our requests list
+  NS_ENSURE_TRUE(mRequests.AppendObject(request),
                  NS_ERROR_OUT_OF_MEMORY);
 
+  if (request->mDefer) {
+    return NS_OK;
+  }
+
   // If there weren't any pending requests before, and this one is
   // ready to execute, do that as soon as it's safe.
-  if (mPendingRequests.Count() == 1 && !request->mLoading &&
-      ReadyToExecuteScripts()) {
+  if (!request->mLoading && !hadPendingRequests && ReadyToExecuteScripts()) {
     nsContentUtils::AddScriptRunner(new nsRunnableMethod<nsScriptLoader>(this,
       &nsScriptLoader::ProcessPendingRequests));
   }
 
   // Added as pending request, now we can send blocking back
   return NS_ERROR_HTMLPARSER_BLOCK;
 }
 
@@ -607,34 +615,47 @@ nsScriptLoader::EvaluateScript(nsScriptL
                    "JS_ReportPendingException wasn't called");
       ncc->SetExceptionWasThrown(PR_FALSE);
     }
     ::JS_EndRequest(cx);
   }
   return rv;
 }
 
+nsScriptLoadRequest*
+nsScriptLoader::GetFirstPendingRequest()
+{
+  for (PRInt32 i = 0; i < mRequests.Count(); ++i) {
+    if (!mRequests[i]->mDefer) {
+      return mRequests[i];
+    }
+  }
+
+  return nsnull;
+}
+
 void
 nsScriptLoader::ProcessPendingRequestsAsync()
 {
-  if (mPendingRequests.Count() || !mPendingChildLoaders.IsEmpty()) {
+  if (GetFirstPendingRequest() || !mPendingChildLoaders.IsEmpty()) {
     nsCOMPtr<nsIRunnable> ev = new nsRunnableMethod<nsScriptLoader>(this,
       &nsScriptLoader::ProcessPendingRequests);
 
     NS_DispatchToCurrentThread(ev);
   }
 }
 
 void
 nsScriptLoader::ProcessPendingRequests()
 {
   nsRefPtr<nsScriptLoadRequest> request;
-  while (mPendingRequests.Count() && ReadyToExecuteScripts() &&
-         !(request = mPendingRequests[0])->mLoading) {
-    mPendingRequests.RemoveObjectAt(0);
+  while (ReadyToExecuteScripts() &&
+         (request = GetFirstPendingRequest()) &&
+         !request->mLoading) {
+    mRequests.RemoveObject(request);
     ProcessRequest(request);
   }
 
   while (!mPendingChildLoaders.IsEmpty() && ReadyToExecuteScripts()) {
     nsRefPtr<nsScriptLoader> child = mPendingChildLoaders[0];
     mPendingChildLoaders.RemoveElementAt(0);
     child->RemoveExecuteBlocker();
   }
@@ -795,17 +816,17 @@ nsScriptLoader::OnStreamComplete(nsIStre
 {
   nsScriptLoadRequest* request = static_cast<nsScriptLoadRequest*>(aContext);
   NS_ASSERTION(request, "null request in stream complete handler");
   NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
 
   nsresult rv = PrepareLoadedRequest(request, aLoader, aStatus, aStringLen,
                                      aString);
   if (NS_FAILED(rv)) {
-    mPendingRequests.RemoveObject(request);
+    mRequests.RemoveObject(request);
     FireScriptAvailable(rv, request);
   }
 
   // Process our request and/or any pending ones
   ProcessPendingRequests();
 
   return NS_OK;
 }
@@ -858,17 +879,17 @@ nsScriptLoader::PrepareLoadedRequest(nsS
       return NS_ERROR_NOT_AVAILABLE;
     }
   }
 
   // This assertion could fire errorously if we ran out of memory when
   // inserting the request in the array. However it's an unlikely case
   // so if you see this assertion it is likely something else that is
   // wrong, especially if you see it more than once.
-  NS_ASSERTION(mPendingRequests.IndexOf(aRequest) >= 0,
+  NS_ASSERTION(mRequests.IndexOf(aRequest) >= 0,
                "aRequest should be pending!");
 
   // Mark this as loaded
   aRequest->mLoading = PR_FALSE;
 
   return NS_OK;
 }
 
@@ -896,8 +917,19 @@ nsScriptLoader::ShouldExecuteScript(nsID
   NS_ASSERTION(channelPrincipal, "Gotta have a principal here!");
 
   // If the channel principal isn't at least as powerful as the
   // document principal, then we don't execute the script.
   PRBool subsumes;
   rv = channelPrincipal->Subsumes(docPrincipal, &subsumes);
   return NS_SUCCEEDED(rv) && subsumes;
 }
+
+void
+nsScriptLoader::EndDeferringScripts()
+{
+  mDeferEnabled = PR_FALSE;
+  for (PRUint32 i = 0; i < mRequests.Count(); ++i) {
+    mRequests[i]->mDefer = PR_FALSE;
+  }
+
+  ProcessPendingRequests();
+}
--- a/content/base/src/nsScriptLoader.h
+++ b/content/base/src/nsScriptLoader.h
@@ -182,16 +182,34 @@ public:
 
   /**
    * Check whether it's OK to execute a script loaded via aChannel in
    * aDocument.
    */
   static PRBool ShouldExecuteScript(nsIDocument* aDocument,
                                     nsIChannel* aChannel);
 
+  /**
+   * Starts deferring deferred scripts and puts them in the mDeferredRequests
+   * queue instead.
+   */
+  void BeginDeferringScripts()
+  {
+    mDeferEnabled = PR_TRUE;
+  }
+
+  /**
+   * Stops defering scripts and immediately processes the mDeferredRequests
+   * queue.
+   *
+   * WARNING: This function will syncronously execute content scripts, so be
+   * prepared that the world might change around you.
+   */
+  void EndDeferringScripts();
+
 protected:
   /**
    * Process any pending requests asyncronously (i.e. off an event) if there
    * are any. Note that this is a no-op if there aren't any currently pending
    * requests.
    */
   virtual void ProcessPendingRequestsAsync();
 
@@ -224,19 +242,23 @@ protected:
                           const nsAFlatString& aScript);
 
   nsresult PrepareLoadedRequest(nsScriptLoadRequest* aRequest,
                                 nsIStreamLoader* aLoader,
                                 nsresult aStatus,
                                 PRUint32 aStringLen,
                                 const PRUint8* aString);
 
+  // Returns the first pending (non deferred) request
+  nsScriptLoadRequest* GetFirstPendingRequest();
+
   nsIDocument* mDocument;                   // [WEAK]
   nsCOMArray<nsIScriptLoaderObserver> mObservers;
-  nsCOMArray<nsScriptLoadRequest> mPendingRequests;
+  nsCOMArray<nsScriptLoadRequest> mRequests;
   nsCOMPtr<nsIScriptElement> mCurrentScript;
   // XXXbz do we want to cycle-collect these or something?  Not sure.
   nsTArray< nsRefPtr<nsScriptLoader> > mPendingChildLoaders;
   PRUint32 mBlockerCount;
   PRPackedBool mEnabled;
+  PRPackedBool mDeferEnabled;
 };
 
 #endif //__nsScriptLoader_h__
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -79,16 +79,17 @@
 #include "nsIScriptableUConv.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsIContentPolicy.h"
 #include "nsContentPolicyUtils.h"
 #include "nsContentErrors.h"
 #include "nsLayoutStatics.h"
 #include "nsDOMError.h"
 #include "nsIHTMLDocument.h"
+#include "nsIDOM3Document.h"
 #include "nsWhitespaceTokenizer.h"
 #include "nsIMultiPartChannel.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsIStorageStream.h"
 #include "nsIPromptFactory.h"
 #include "nsIWindowWatcher.h"
 
 #define LOAD_STR "load"
@@ -697,19 +698,25 @@ nsXMLHttpRequest::ConvertBodyToText(nsAS
 
   PRInt32 dataLen = mResponseBody.Length();
   if (!dataLen)
     return NS_OK;
 
   nsresult rv = NS_OK;
 
   nsCAutoString dataCharset;
-  nsCOMPtr<nsIDocument> document(do_QueryInterface(mDocument));
+  nsCOMPtr<nsIDOM3Document> document(do_QueryInterface(mDocument));
   if (document) {
-    dataCharset = document->GetDocumentCharacterSet();
+    nsAutoString inputEncoding;
+    document->GetInputEncoding(inputEncoding);
+    if (DOMStringIsNull(inputEncoding)) {
+      dataCharset.AssignLiteral("UTF-8");
+    } else {
+      CopyUTF16toUTF8(inputEncoding, dataCharset);
+    }
   } else {
     if (NS_FAILED(DetectCharset(dataCharset)) || dataCharset.IsEmpty()) {
       // MS documentation states UTF-8 is default for responseText
       dataCharset.AssignLiteral("UTF-8");
     }
   }
 
   if (dataCharset.EqualsLiteral("ASCII")) {
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -187,16 +187,18 @@ include $(topsrcdir)/config/rules.mk
 		test_bug444722.html \
 		test_text_replaceWholeText.html \
 		test_text_wholeText.html \
 		wholeTexty-helper.xml \
 		test_bug444030.xhtml \
 		test_NodeIterator_basics_filters.xhtml \
 		test_NodeIterator_mutations_1.xhtml \
 		test_NodeIterator_mutations_2.html \
+		test_bug28293.html \
+		file_bug28293.sjs \
 		$(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
 
 check::
 	@$(EXIT_ON_ERROR) \
 	for f in $(subst .cpp,,$(CPP_UNIT_TESTS)); do \
new file mode 100644
--- /dev/null
+++ b/content/base/test/file_bug28293.sjs
@@ -0,0 +1,5 @@
+function handleRequest(request, response)
+{
+  response.setHeader("Content-Type", "text/plain", false);
+  response.write(decodeURIComponent(request.queryString));
+}
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_bug28293.html
@@ -0,0 +1,99 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=28293
+-->
+<head>
+  <title>Test for Bug 28293</title>
+  <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>        
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  <script>
+res = 'A';
+
+SimpleTest.waitForExplicitFinish();
+onload = function () {
+
+  res+='2';
+
+  s = document.createElement('script');
+  s.textContent="res+='g';";
+  s.defer = true;
+  document.body.appendChild(s);
+
+  res+='3';
+
+  s = document.createElement('script');
+  s.src="file_bug28293.sjs?res+='h';";
+  s.defer = true;
+  document.body.appendChild(s);
+
+  s = document.createElement('script');
+  s.textContent="res+='i';done()";
+  s.defer = true;
+  document.body.appendChild(s);
+
+  res+='4';
+}
+
+function done() {
+  is(res, "ABCDEFGHIJ1abcdefM2g34hi", "scripts executed in the wrong order");
+  ok(!fHadExecuted, "Dynamic script executed too late");
+  SimpleTest.finish();
+}
+</script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=28293">Mozilla Bug 28293</a>
+
+<script defer>
+res += 'a';
+</script>
+<script defer src="data:text/plain,res+='b'"></script>
+<script defer>
+res += 'c';
+</script>
+<script>
+res += 'B';
+</script>
+<script>
+res += 'C';
+
+s = document.createElement('script');
+s.src="file_bug28293.sjs?res+='d';";
+s.defer = true;
+document.body.appendChild(s);
+
+s = document.createElement('script');
+s.textContent="res+='D';";
+document.body.appendChild(s);
+
+res += 'E';
+</script>
+<script>
+res += 'F';
+document.addEventListener("DOMContentLoaded", function() {
+  res += '1'
+  s = document.createElement('script');
+  s.src="file_bug28293.sjs?res+='M';";
+  document.body.appendChild(s);
+}, false);
+res += 'G';
+</script>
+<script defer>
+res += 'e';
+</script>
+<script src="file_bug28293.sjs?res+='H';"></script>
+<script>
+res += 'I';
+s = document.createElement('script');
+s.src="file_bug28293.sjs?fHadExecuted=(res.indexOf('f')>=0);";
+document.body.appendChild(s);
+res += 'J';
+</script>
+<script defer>
+res += 'f';
+</script>
+
+</body>
+</html>
--- a/content/canvas/src/nsCanvasRenderingContext2D.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp
@@ -371,16 +371,22 @@ protected:
 
     // yay thebes
     nsRefPtr<gfxContext> mThebes;
     nsRefPtr<gfxASurface> mSurface;
 
     PRUint32 mSaveCount;
 
     /**
+     * Flag to avoid duplicate calls to InvalidateFrame. Set to true whenever
+     * Redraw is called, reset to false when Render is called.
+     */
+    PRBool mIsFrameInvalid;
+
+    /**
      * Draws a rectangle in the given style; used by FillRect and StrokeRect.
      */
     nsresult DrawRect(const gfxRect& rect, Style style);
 
     // text
     enum TextAlign {
         TEXT_ALIGN_START,
         TEXT_ALIGN_END,
@@ -546,31 +552,32 @@ NS_NewCanvasRenderingContext2D(nsIDOMCan
         return NS_ERROR_OUT_OF_MEMORY;
 
     *aResult = ctx.forget().get();
     return NS_OK;
 }
 
 nsCanvasRenderingContext2D::nsCanvasRenderingContext2D()
     : mValid(PR_FALSE), mOpaque(PR_FALSE), mCanvasElement(nsnull),
-      mSaveCount(0), mStyleStack(20)
+      mSaveCount(0), mIsFrameInvalid(PR_FALSE), mStyleStack(20)
 {
 }
 
 nsCanvasRenderingContext2D::~nsCanvasRenderingContext2D()
 {
     Destroy();
 }
 
 void
 nsCanvasRenderingContext2D::Destroy()
 {
     mSurface = nsnull;
     mThebes = nsnull;
     mValid = PR_FALSE;
+    mIsFrameInvalid = PR_FALSE;
 }
 
 nsresult
 nsCanvasRenderingContext2D::SetStyleFromVariant(nsIVariant* aStyle, Style aWhichStyle)
 {
     nsresult rv;
     nscolor color;
 
@@ -732,17 +739,22 @@ nsCanvasRenderingContext2D::ApplyStyle(S
 }
 
 nsresult
 nsCanvasRenderingContext2D::Redraw()
 {
     if (!mCanvasElement)
         return NS_OK;
 
-    return mCanvasElement->InvalidateFrame();
+    if (!mIsFrameInvalid) {
+        mIsFrameInvalid = PR_TRUE;
+        return mCanvasElement->InvalidateFrame();
+    }
+
+    return NS_OK;
 }
 
 void
 nsCanvasRenderingContext2D::SetThebesColor(nscolor c)
 {
     gfxRGBA color(c);
     color.a *= CurrentState().globalAlpha;
 
@@ -850,16 +862,17 @@ nsCanvasRenderingContext2D::Render(gfxCo
     // pixel alignment for this stuff!
     ctx->NewPath();
     ctx->PixelSnappedRectangleAndSetPattern(gfxRect(0, 0, mWidth, mHeight), pat);
     ctx->Fill();
 
     if (mOpaque)
         ctx->SetOperator(op);
 
+    mIsFrameInvalid = PR_FALSE;
     return rv;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::GetInputStream(const char *aMimeType,
                                            const PRUnichar *aEncoderOptions,
                                            nsIInputStream **aStream)
 {
@@ -1373,17 +1386,17 @@ nsCanvasRenderingContext2D::Stroke()
     mThebes->Stroke();
     return Redraw();
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::Clip()
 {
     mThebes->Clip();
-    return Redraw();
+    return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::MoveTo(float x, float y)
 {
     if (!FloatValidate(x,y))
         return NS_ERROR_DOM_SYNTAX_ERR;
 
--- a/content/events/public/nsIPrivateCompositionEvent.h
+++ b/content/events/public/nsIPrivateCompositionEvent.h
@@ -36,28 +36,26 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsIPrivateCompositionEvent_h__
 #define nsIPrivateCompositionEvent_h__
 
 #include "nsEvent.h"
 #include "nsISupports.h"
 
-// {889792DC-22D8-4d1a-AC3D-58AD7DEBA17B}
+// {901B82D5-67C0-45ad-86AE-AB9A6BD74111}
 #define NS_IPRIVATECOMPOSITIONEVENT_IID	\
-{ 0x889792dc, 0x22d8, 0x4d1a, \
-{ 0xac, 0x3d, 0x58, 0xad, 0x7d, 0xeb, 0xa1, 0x7b }}
+{ 0x901b82d5, 0x67c0, 0x45ad, \
+{ 0x86, 0xae, 0xab, 0x9a, 0x6b, 0xd7, 0x41, 0x11 } }
 
 class nsIPrivateCompositionEvent : public nsISupports {
 
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IPRIVATECOMPOSITIONEVENT_IID)
 
   NS_IMETHOD GetCompositionReply(struct nsTextEventReply** aReply) = 0;
-  NS_IMETHOD GetReconversionReply(nsReconversionEventReply** aReply) = 0;
-  NS_IMETHOD GetQueryCaretRectReply(nsQueryCaretRectEventReply** aReply) = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIPrivateCompositionEvent,
                               NS_IPRIVATECOMPOSITIONEVENT_IID)
 
 #endif // nsIPrivateCompositionEvent_h__
 
--- a/content/events/src/nsDOMEvent.cpp
+++ b/content/events/src/nsDOMEvent.cpp
@@ -783,22 +783,16 @@ NS_METHOD nsDOMEvent::DuplicatePrivateDa
       break;
     }
     case NS_COMPOSITION_EVENT:
     {
       newEvent = new nsCompositionEvent(PR_FALSE, msg, nsnull);
       isInputEvent = PR_TRUE;
       break;
     }
-    case NS_RECONVERSION_EVENT:
-    {
-      newEvent = new nsReconversionEvent(PR_FALSE, msg, nsnull);
-      isInputEvent = PR_TRUE;
-      break;
-    }
     case NS_MOUSE_SCROLL_EVENT:
     {
       nsMouseScrollEvent* mouseScrollEvent =
         new nsMouseScrollEvent(PR_FALSE, msg, nsnull);
       NS_ENSURE_TRUE(mouseScrollEvent, NS_ERROR_OUT_OF_MEMORY);
       isInputEvent = PR_TRUE;
       nsMouseScrollEvent* oldMouseScrollEvent =
         static_cast<nsMouseScrollEvent*>(mEvent);
@@ -880,22 +874,16 @@ NS_METHOD nsDOMEvent::DuplicatePrivateDa
       break;
     }
     case NS_UI_EVENT:
     {
       newEvent = new nsUIEvent(PR_FALSE, msg,
                                static_cast<nsUIEvent*>(mEvent)->detail);
       break;
     }
-    case NS_QUERYCARETRECT_EVENT:
-    {
-      newEvent = new nsQueryCaretRectEvent(PR_FALSE, msg, nsnull);
-      isInputEvent = PR_TRUE;
-      break;
-    }
     case NS_PAGETRANSITION_EVENT:
     {
       newEvent =
         new nsPageTransitionEvent(PR_FALSE, msg,
                                   ((nsPageTransitionEvent*) mEvent)->persisted);
       break;
     }
 #ifdef MOZ_SVG
--- a/content/events/src/nsDOMUIEvent.cpp
+++ b/content/events/src/nsDOMUIEvent.cpp
@@ -365,52 +365,27 @@ nsDOMUIEvent::GetPreventDefault(PRBool* 
   NS_ENSURE_ARG_POINTER(aReturn);
   *aReturn = mEvent && (mEvent->flags & NS_EVENT_FLAG_NO_DEFAULT);
 
   return NS_OK;
 }
 
 NS_METHOD nsDOMUIEvent::GetCompositionReply(nsTextEventReply** aReply)
 {
-  if((mEvent->eventStructType == NS_RECONVERSION_EVENT) ||
-     (mEvent->message == NS_COMPOSITION_START) ||
+  if((mEvent->message == NS_COMPOSITION_START) ||
      (mEvent->message == NS_COMPOSITION_QUERY))
   {
     *aReply = &(static_cast<nsCompositionEvent*>(mEvent)->theReply);
     return NS_OK;
   }
   *aReply = nsnull;
   return NS_ERROR_FAILURE;
 }
 
 NS_METHOD
-nsDOMUIEvent::GetReconversionReply(nsReconversionEventReply** aReply)
-{
-  if (mEvent->eventStructType == NS_RECONVERSION_EVENT)
-  {
-    *aReply = &(static_cast<nsReconversionEvent*>(mEvent)->theReply);
-    return NS_OK;
-  }
-  *aReply = nsnull;
-  return NS_ERROR_FAILURE;
-}
-
-NS_METHOD
-nsDOMUIEvent::GetQueryCaretRectReply(nsQueryCaretRectEventReply** aReply)
-{
-  if (mEvent->eventStructType == NS_QUERYCARETRECT_EVENT)
-  {
-    *aReply = &(static_cast<nsQueryCaretRectEvent*>(mEvent)->theReply);
-    return NS_OK;
-  }
-  *aReply = nsnull;
-  return NS_ERROR_FAILURE;
-}
-
-NS_METHOD
 nsDOMUIEvent::DuplicatePrivateData()
 {
   mClientPoint = GetClientPoint();
   mLayerPoint = GetLayerPoint();
   mPagePoint = GetPagePoint();
   // GetScreenPoint converts mEvent->refPoint to right coordinates.
   nsPoint screenPoint = GetScreenPoint();
   nsresult rv = nsDOMEvent::DuplicatePrivateData();
--- a/content/events/src/nsDOMUIEvent.h
+++ b/content/events/src/nsDOMUIEvent.h
@@ -62,18 +62,16 @@ public:
   // nsIDOMNSUIEvent Interface
   NS_DECL_NSIDOMNSUIEVENT
 
   // nsIPrivateDOMEvent interface
   NS_IMETHOD DuplicatePrivateData();
   
   // nsIPrivateCompositionEvent interface
   NS_IMETHOD GetCompositionReply(nsTextEventReply** aReply);
-  NS_IMETHOD GetReconversionReply(nsReconversionEventReply** aReply);
-  NS_IMETHOD GetQueryCaretRectReply(nsQueryCaretRectEventReply** aReply);
   
   // Forward to nsDOMEvent
   NS_FORWARD_TO_NSDOMEVENT
 
 protected:
 
   // Internal helper functions
   nsPoint GetClientPoint();
--- a/content/events/src/nsEventDispatcher.cpp
+++ b/content/events/src/nsEventDispatcher.cpp
@@ -557,18 +557,16 @@ nsEventDispatcher::CreateEvent(nsPresCon
 
   if (aEvent) {
     switch(aEvent->eventStructType) {
     case NS_MUTATION_EVENT:
       return NS_NewDOMMutationEvent(aDOMEvent, aPresContext,
                                     static_cast<nsMutationEvent*>(aEvent));
     case NS_GUI_EVENT:
     case NS_COMPOSITION_EVENT:
-    case NS_RECONVERSION_EVENT:
-    case NS_QUERYCARETRECT_EVENT:
     case NS_SCROLLPORT_EVENT:
       return NS_NewDOMUIEvent(aDOMEvent, aPresContext,
                               static_cast<nsGUIEvent*>(aEvent));
     case NS_KEY_EVENT:
       return NS_NewDOMKeyboardEvent(aDOMEvent, aPresContext,
                                     static_cast<nsKeyEvent*>(aEvent));
     case NS_MOUSE_EVENT:
     case NS_MOUSE_SCROLL_EVENT:
--- a/content/events/src/nsEventListenerManager.cpp
+++ b/content/events/src/nsEventListenerManager.cpp
@@ -220,21 +220,17 @@ static const EventDispatchData sContextM
 };
 
 static const EventDispatchData sCompositionEvents[] = {
   { NS_COMPOSITION_START,
     HANDLER(&nsIDOMCompositionListener::HandleStartComposition)  },
   { NS_COMPOSITION_END,
     HANDLER(&nsIDOMCompositionListener::HandleEndComposition)    },
   { NS_COMPOSITION_QUERY,
-    HANDLER(&nsIDOMCompositionListener::HandleQueryComposition)  },
-  { NS_RECONVERSION_QUERY,
-    HANDLER(&nsIDOMCompositionListener::HandleQueryReconversion) },
-  { NS_QUERYCARETRECT,
-    HANDLER(&nsIDOMCompositionListener::HandleQueryCaretRect)    }
+    HANDLER(&nsIDOMCompositionListener::HandleQueryComposition)  }
 };
 
 static const EventDispatchData sTextEvents[] = {
   { NS_TEXT_TEXT, HANDLER(&nsIDOMTextListener::HandleText) }
 };
 
 static const EventDispatchData sKeyEvents[] = {
   { NS_KEY_UP,    HANDLER(&nsIDOMKeyListener::KeyUp)    },
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -2996,16 +2996,23 @@ nsGenericHTMLFrameElement::EnsureFrameLo
 
 NS_IMETHODIMP
 nsGenericHTMLFrameElement::GetFrameLoader(nsIFrameLoader **aFrameLoader)
 {
   NS_IF_ADDREF(*aFrameLoader = mFrameLoader);
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsGenericHTMLFrameElement::SwapFrameLoaders(nsIFrameLoaderOwner* aOtherOwner)
+{
+  // We don't support this yet
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
 nsresult
 nsGenericHTMLFrameElement::LoadSrc()
 {
   nsresult rv = EnsureFrameLoader();
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!mFrameLoader) {
     return NS_OK;
--- a/content/html/content/src/nsHTMLMediaElement.cpp
+++ b/content/html/content/src/nsHTMLMediaElement.cpp
@@ -403,16 +403,18 @@ nsHTMLMediaElement::nsHTMLMediaElement(n
     mMuted(PR_FALSE),
     mMutedVolume(0.0),
     mIsDoneAddingChildren(!aFromParser)
 {
 }
 
 nsHTMLMediaElement::~nsHTMLMediaElement()
 {
+  if (mDecoder) 
+    mDecoder->Stop();
 }
 
 NS_IMETHODIMP
 nsHTMLMediaElement::Play(void)
 {
   if (!mDecoder)
     return NS_OK;
 
@@ -508,16 +510,19 @@ nsresult nsHTMLMediaElement::BindToTree(
   }
 
   return rv;
 }
 
 void nsHTMLMediaElement::UnbindFromTree(PRBool aDeep,
                                         PRBool aNullParent)
 {
+  if (!mPaused && mNetworkState != nsIDOMHTMLMediaElement::EMPTY)
+    Pause();
+
   nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
 }
 
 
 nsresult nsHTMLMediaElement::PickMediaElement(nsAString& aChosenMediaResource)
 {
   // Implements:
   // http://www.whatwg.org/specs/web-apps/current-work/#pick-a
--- a/content/html/content/src/nsHTMLScriptElement.cpp
+++ b/content/html/content/src/nsHTMLScriptElement.cpp
@@ -332,17 +332,18 @@ public:
 
   // nsIDOMHTMLScriptElement
   NS_DECL_NSIDOMHTMLSCRIPTELEMENT
 
   // nsIScriptElement
   virtual void GetScriptType(nsAString& type);
   virtual already_AddRefed<nsIURI> GetScriptURI();
   virtual void GetScriptText(nsAString& text);
-  virtual void GetScriptCharset(nsAString& charset); 
+  virtual void GetScriptCharset(nsAString& charset);
+  virtual PRBool GetScriptDeferred();
 
   // nsIContent
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               PRBool aCompileEventHandlers);
 
   virtual nsresult GetInnerHTML(nsAString& aInnerHTML);
   virtual nsresult SetInnerHTML(const nsAString& aInnerHTML);
@@ -520,16 +521,25 @@ nsHTMLScriptElement::GetScriptText(nsASt
 
 void
 nsHTMLScriptElement::GetScriptCharset(nsAString& charset)
 {
   GetCharset(charset);
 }
 
 PRBool
+nsHTMLScriptElement::GetScriptDeferred()
+{
+  PRBool defer;
+  GetDefer(&defer);
+
+  return defer;
+}
+
+PRBool
 nsHTMLScriptElement::HasScriptContent()
 {
   return HasAttr(kNameSpaceID_None, nsGkAtoms::src) ||
          nsContentUtils::HasNonEmptyTextContent(this);
 }
 
 nsresult
 nsHTMLScriptElement::MaybeProcessScript()
--- a/content/html/content/src/nsHTMLVideoElement.cpp
+++ b/content/html/content/src/nsHTMLVideoElement.cpp
@@ -138,20 +138,20 @@ nsresult nsHTMLVideoElement::BindToTree(
                                         aParent, 
                                         aBindingParent, 
                                         aCompileEventHandlers);
 }
 
 void nsHTMLVideoElement::UnbindFromTree(PRBool aDeep,
                                         PRBool aNullParent)
 {
+  nsHTMLMediaElement::UnbindFromTree(aDeep, aNullParent);
+
   if (mDecoder) 
     mDecoder->ElementUnavailable();
-
-  nsHTMLMediaElement::UnbindFromTree(aDeep, aNullParent);
 }
 
 nsresult nsHTMLVideoElement::InitializeDecoder(nsAString& aChosenMediaResource)
 {
   if (mDecoder) 
     mDecoder->ElementAvailable(this);
 
   return nsHTMLMediaElement::InitializeDecoder(aChosenMediaResource);
--- a/content/media/video/public/nsOggDecoder.h
+++ b/content/media/video/public/nsOggDecoder.h
@@ -312,16 +312,19 @@ private:
   // A load of the media resource is currently in progress. It is 
   // complete when the media metadata is loaded.
   PRPackedBool mLoadInProgress;
 
   // A boolean that indicates that once the load has completed loading
   // the metadata then it should start playing.
   PRPackedBool mPlayAfterLoad;
 
+  // True if we are registered with the observer service for shutdown.
+  PRPackedBool mNotifyOnShutdown;
+
   /******
    * The following member variables can be accessed from any thread.
    ******/
   
   // Threads to handle decoding of Ogg data. Methods on these are
   // called from the main thread only, but they can be read from other
   // threads safely to see if they have been created/set.
   nsCOMPtr<nsIThread> mDecodeThread;
--- a/content/media/video/src/nsOggDecoder.cpp
+++ b/content/media/video/src/nsOggDecoder.cpp
@@ -255,16 +255,17 @@ float nsOggDecoder::GetDuration()
 }
 
 nsOggDecoder::nsOggDecoder() :
   nsVideoDecoder(),
   mBytesDownloaded(0),
   mVideoNextFrameTime(0.0),
   mLoadInProgress(PR_FALSE),
   mPlayAfterLoad(PR_FALSE),
+  mNotifyOnShutdown(PR_FALSE),
   mVideoCurrentFrameTime(0.0),
   mInitialVolume(1.0),
   mAudioRate(0),
   mAudioChannels(0),
   mAudioTrack(-1),
   mVideoTrack(-1),
   mPlayer(0),
   mReader(0),
@@ -281,25 +282,16 @@ nsOggDecoder::nsOggDecoder() :
 PRBool nsOggDecoder::Init() 
 {
   mFirstFrameLock = PR_NewLock();  
   mFirstFrameCondVar = mFirstFrameLock ? PR_NewCondVar(mFirstFrameLock) : nsnull ;
 
   mDecodeEvent = new nsVideoDecodeEvent(this);
   mPresentationEvent = new nsVideoPresentationEvent(this);
 
-  nsCOMPtr<nsIObserverService> observerService =
-    do_GetService("@mozilla.org/observer-service;1");
-  if (observerService) {
-    observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_FALSE);
-  }
-  else {
-    NS_WARNING("Could not get an observer service. Video decoding events may not shutdown cleanly.");
-  }
-
   return mFirstFrameLock &&
     mFirstFrameCondVar &&
     mDecodeEvent && mDecodeEvent->Init() &&
     mPresentationEvent && mPresentationEvent->Init() &&
     nsVideoDecoder::Init();
 }
 
 void nsOggDecoder::Shutdown() 
@@ -468,16 +460,30 @@ nsresult nsOggDecoder::Play()
   }
   else if (!mPlayer) {
     Load(mURI);
   }
   else {
     StartPlaybackThreads();
   }
 
+  if (!mNotifyOnShutdown) {
+    nsCOMPtr<nsIObserverService> observerService =
+      do_GetService("@mozilla.org/observer-service;1");
+    if (observerService) {
+      mNotifyOnShutdown = 
+        NS_SUCCEEDED(observerService->AddObserver(this, 
+                                                  NS_XPCOM_SHUTDOWN_OBSERVER_ID, 
+                                                  PR_FALSE));
+    }
+    else {
+      NS_WARNING("Could not get an observer service. Video decoding events may not shutdown cleanly.");
+    }
+  }
+
   return NS_OK;
 } 
 
 nsresult nsOggDecoder::Seek(float time)
 {
   return NS_ERROR_NOT_IMPLEMENTED;  
 }
 
@@ -509,16 +515,25 @@ void nsOggDecoder::Stop()
   }
   CloseAudioStream();
   if (mPlayer){
     oggplay_close(mPlayer);
     mPlayer = nsnull;
   }
   mPaused = PR_TRUE;
   mVideoCurrentFrameTime = 0.0;
+
+  if (mNotifyOnShutdown) {
+    nsCOMPtr<nsIObserverService> observerService =
+      do_GetService("@mozilla.org/observer-service;1");
+    if (observerService) {
+      mNotifyOnShutdown = PR_FALSE;
+      observerService->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
+    }
+  }
 }
 
 void nsOggDecoder::HandleVideoData(int track_num, OggPlayVideoData* video_data) {
   int y_width;
   int y_height;
   oggplay_get_video_y_size(mPlayer, track_num, &y_width, &y_height);
 
   int uv_width;
--- a/content/media/video/src/nsVideoDecoder.cpp
+++ b/content/media/video/src/nsVideoDecoder.cpp
@@ -168,17 +168,16 @@ nsresult nsVideoDecoder::StartProgress()
                                               350, // Number of milliseconds defined in spec
                                               nsITimer::TYPE_REPEATING_PRECISE);
   }
   return rv;
 }
 
 nsresult nsVideoDecoder::StopProgress()
 {
-  return NS_OK;
   nsresult rv = NS_OK;
   if (mProgressTimer) {
     rv = mProgressTimer->Cancel();
     mProgressTimer = nsnull;
   }
   return rv;
 }
 
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..093158432ac64090f3572fa7167da8e102b94515
GIT binary patch
literal 28942
zc$}=d1ymeO*DeYKcMlfaCAhl>cXxMp4NidI1b26LcXtgkxZB_a3up4apPu!vd+xdG
z?w;Py_NtcYsj6uO3kwx62(W+9Qj<IXA4H8pvj!J3w{o#GGcpDH0QPS>{!iuqKnnj=
z8<sZyui6TyJ|Dno16(c59Gs0lfZUj1C}7}1U|?5ZVBlke6<{bLLjSH&+xu4)u>Y(A
z4#J~BJQzfl_kWQ_;NJzwKt4??N6XI&&KAVBR>rD-S&5~HS(upEm{^%PiCKwRh?)MB
z3i>;vdy4w8ZOR6xsZ2^5)g|+g`MYvbAqgz=cVpBL64-xt1^t;zHfX<`a`Y74JCia#
zOgA}HNk|5roEuUg#>8=%1rg%7o;FfMGl>i~2+Wfp96Z+)Cp6Dc9TT#TS^_l$?1~5Z
z192}se2`%rDNJClAr|FMoB?*IlByymWF5T(S_m2>AIb;E4Hm?p*+vF<h=5!&*nTEY
zLYTm9Q(S1_I7Lh-a3MvM54~4>e;D<jh`-oh_CJgStTqokD42D&w|9rRpkTmpdk&-~
zsRZnx87;88eb^x}Rw<NNcAX1ib%nwX#~Q$dJaG3&2~!OndZ2=qaA!s%33}k*;9w?E
zDx~~_fdye8;9$A?qy3+W85|s3IItfg@NWqI2SEM<Ai@6zNbtV_8scw&{RhB)*nMr8
zMPkM17Kz?Ijp%AKCk062Zwop{km_&$9P_g-!!y?~J{N)9H++aGmN{ZtTM8RiqtW;4
z2;a{dWSguW`Wf_bv|vE3l!HZIklTZqu3(KXG32GZka);N6$Bb4!nosB!WV>Y8*$ra
zHq0&4L_?nXa9-=bF=7@_EN{z5O~Bo3SZPYxw-A%#3SNY|;5~mH>c!`JQ1cf|x5+hk
z{G<!|ApvQC{&gsSnHy$<^wU($BWh!GnDO{5ehGy$wNFcyly|vwh*u_+^s?<o{2|!t
z-g%+@Yf(Tu@V(x|%N8?ubz9plYXqB)IlR|Ql1w7s%5?4hRC(h(hF$<AF$kpbVPE0i
zyCTp*Ffi|r|8a#Z$LhO(uqJ&EJooJm+30uoW2jYc#gL(FHx9U^@+dD9LbtiU)Gxu1
zX@Wk|s*SM55B(9Avl~m+!=)xA4RJhOZ>&_)KR&d-KYu|sy}|uWwDpk#<*qqD2~va0
z_`WiKd?bPKq9ZQDT3}MbXg24KMF&Zo8m*tc65#bvcq?cpLaO`Im4U^l1ZvXv%Taq|
z8MZoOlE7oHo!I-?0v{RL7nYq!d%KUHPCA*O?kg9C+)$9Z^%P66s%E%(#k{5St;k*%
z$lz`fjx-EKpB7r1hg^=K*x4GnoWE24xIp)+mcTzm(jD-T8b3F2M7wwiZVhBzqez@C
zS4m4e#;)Cf$;yDj@S%@q4|}-%vD?7pe9F(F`*mbUwaN(0&j$zY#-9D+qr4HedRxHN
zk2<l<F~ZQwt*i2QnO)AT-|~BG*zlM3z3h}61*@hJCE}Ht{U&}Q<r2DC7I42gVPN}>
z!`5CtXZ@_6N18Z-<BLKG!J;Aa2+e!J%vP@(+)Gg+X=^n{qPDAPkooZruPe`NK8MaC
zV&%TPmofcz<!3$KC&u-)b)u9OOZihH<opF?ql@D-{x*@ezjw^%N;<xN_e0Gq8Z>I?
z1)0ipk)DF!jZST&EwVGL)P~p_$Vbjn`syOykVmv2^R<b>G?DF|Ef|sSR~HT=l+0hj
z$`j)$Wtne2c)-+Y^E@H64Vr<iYc;0uuK3s2sgcv^&$N9ApNswIU*C}b#Ous7h{v&P
zd!UpgQmzv)Rbb~ltkWG5IMDw9Px&ft+?bWc;KL&zhDGDZj}zTwy1>KK(}6Twp`E?U
zriVfiC-=S)9G-reeT$JmxhVR9XDF$Bv@LI;HeHK9_V%0s<(uzL^r22pR>4Zz(2r_1
z*KZgyjoEX7auSZ(3<lu0vFp>&k#KN2ay8vXj$~2Y&Xx5=^jhs90%oDKu>eu9wpgSy
z`o>N;6^>;&vYEsY%j`KWKR4PKE$9f4Nx|f+C$Ct6Aad=FU8o}`bC}bIqt~)h?J%d+
zix13&Q%%XTSq56hKx9Nmal$?4uPe?$`Ee}x)@jAgvm?j=aV=w_ShVahpD2lA^{7R}
zbaT6Eddi$e_;Z?4@$1FR*fGC$&P@2SPX_%ih+ah6sB>G#(3Zh=%9JTzZtm*qft;9^
zUj17EQPlPU2cBOje>AsS5TXF;a_j3ox>RX=naT03e-y4Bh%s#N+zB#8WBsP9RTy6a
z<d!-pr+#RfbJSS?ic#!`nXeUDamYHp4<wzEX=!d2QG3EZqca)~#jUGOv8KEm5|ro(
zJ1li-M%5kAW}<&AGUQksH&5Gh_7S6Q3-ErDJfkD?Sl$~?it>-2DTGy5mp~XxW19+W
zZUww6AukjaL=Re!xDFj6*0D`BH|m^6=F)ufFm5b-e-+uK{0%Qzo36A7dCny`vC}n7
z|5RB^N={+NQTKRoW{st+Yqk}L^XI^%(rFog3A&wy;pA>K51H~!(-xAEQ?R8qx6Sz^
zbD=(6@tS>ni1prc;$Nl<fWp~&_BT{fZ1M<*Gq+;3Gn;^oe>Bqm*hS#ix^Zl5n!3QT
zHeLXkQg9$A29u+%sj$8t<tZ46)|#!5Iar<mN!7Ear3ozEfC6u>Ot*-FOPTNpc6xT}
z1*N4bPT(IVu)$E(zrm@IQYA0f0;?h62&6^!&wfAB7S`93a9^#fAu{TkMajOU9n=Na
zcowOg2@CzX67v>>d~sXOFqc1Bz9}3;K4LBg4wOnpJZTs*#sHH`naI%_Q`dEGhADx1
zziCQ6ZYvB4<A=t_XE;gx_2Yxln(GtUX6Pc0x9KaRN>vxpx^?w&Wf!<5*7ibT)aSqt
zfs(h6y%GmxCvR$Bwnky4dB5!r89A%%$*x-)vC@BS$=zfWwt4T^>mTo<-AQI(<yc}x
zI4VfWLM01TqoAGw+@pb$MZs?*gf1}kTsIeMHqIO%SX@2eMV1Lk&{sP3m{yC8Q*kW4
z5729y>)9YY-$m@leIwK^&J8;fOiV?G1KqxrZ6<(FpHQ^?o+IQg7=sdW=(RLZ7d3bM
zmS_Szk9Ne=FE#g;ES&mjO2g+jeTm5w<B~u(MKK1;@JkEI%kGfrJI^;VunFw64C}Pe
zN15lZZCcvtAp%175u{Q2t!_W>_VcV>`~K>@3&Ii56$`V|$q27S%3mZ>xYIOlP>Aaj
zG#Be=v)d!3uT8;Qo6=U%kIo-zWS(Or-vS(Y5FIVzZO<-cf2~NqI2ZKD(0S38OI#<2
zqJeF@;%v{5uC8pPU026G97y^ntKX=pMwW3YEP_RNQd*@o*B_7(kX)M?ZyI=iK97lg
zgsK}*PN_DSrLX=l)xRHxD51hOxvu4q6WkN;3UhmVK%1<NQW~{<mCHrWC=EKu!pXY+
z%eks!`pN^FlUFjw#OB{|Bs_xBII<I1hiT2rr=%)MQu{*B-n>pTd3y1^oY*<v>#WjP
z5vH2j^$WxD;HfI;ij=`SW5J$SUP`pt=Y9`!v5xEOwJI%|!YU;|=AUWm%jUau=e!x$
z+ErvD)>&o$enKyo{(rc70slQp{WFgKGfFiI?l=cm0*#}M9qi4(=>IW({WF9H|3@S^
z*#AtT4)(5Q_O1-7UXErw#O_w6W)6&hk5`f4{~lOF{%2!<M%g#mj+fwn`@sG=EdJBn
zA72a@gCE-a|4#G}bPE~Gm-M<CZBH(jM}VQIsE>ji&COm-O-(*Gj~nd3jxCR5MtV_w
z&Ca?8NNf1z+N1Yg@Gv4!?jX47v85{QUf0N20P|VwN5a-#`fXe$Xft@8wO^T$w1}3|
zj>1=SijPFYhG*SS$a}v8AKdPnhI|52aP0kcUt4RO^pEy=y~FMiKbAUhh^}-4{rbE<
z-(mqL#vg-qgKmZnzIm<pqMC+RK-t7@L$^A-!wj@w+0(9HQtL{*zrTDH=GI3z`<?<T
zIqo)M6BAGXW~>*mgF${tvH?c`LFwSQ9W6HTqn}nYnY9-g?o{&0zI|7wx<yavbNl1h
z-xVu*D%H(;>NNoM%g#?W%Nms()fHa>>g`oP-G-r+${PMnjUc*+^tZu@h@3|Z;#S17
zmS6`4x4{{m<QAr?N2WICpRtd+{qJp|PA}i}W!sW_E3#K`t6A+XHf1k6)4W*QZ_GCV
z!w8Wr5DrM2PMs-UIjvtYaXM;{%&n%+6^*mLclk|*&e7#-K-!aq*x4DlTy`J%&9uK{
zFE0&3_%Qk8byR3tuUL4WRpKqfFL&_T7^MSJKh1Q%ySy;bE-yFPxEu1_+h}B0Pe2eJ
z+n+AuHLY&8pFuYTHC0cq{WNbehj9V+Z2X>tZ)&R22Bf0!YcCyD)c1zB<F_}3Rk?dq
zxA#>UR@pQ(H{({V25!6n9|apAs_bmkTg*Sqs5g0?p4XCGhFw+}Rp@1%RoB{R(rKSx
zRE2?>^$>V@n>p{T(9vG1S`D~es?zuFVDZVVG6EPb*Q$TAGd%YCee~d@zTCl80o1Vg
z2v5=r8N{r)7j#AaidDt5Mk>K<9I4W(Wxp9Pc5ybT5d*mF9P*0FTR}(su^QzFH8IPX
zYXf7wKDm-sBdq^b(31d?=cefRb3^NA4qe+I?mG^(462IR24vl|hWqNz8+xtE#@E}1
z*fF|rLt$H9EH|c3lPh5olfurS2WLN4=+b2TM)Bi#d2Ae5_02mcmp9EDst0&3h9{!q
zR`5S_=uq0OvY1Y#BSf`)wEx`a<bjCexD#|^wm-TT^M^klxQ$<4w&^*yCxsP}JZ%26
zMDNA$=${TX%dXa&PS`}Hd^BwB2t(wu^J3uwQtHdbR%_^1gYv%6$mm;yLnJ`!@(hF_
zgw_}0S>YluAw3cp`t|C#-$4&@*6)72obb%an?o{$8EU}ZA%utV<-EjW#em%qCrn_(
zZ#e&LGx;%<VPy<xD)R_Sh2Oi93ba(2&$5Z<B(0{`H|Zqubiev^;8XZ0H6GVeBzP&b
zQIl54#iARi&_&`c($vDHV_|S^BDiX?73TK>Dn(Mmq;J@={{H?OAzp*DT3n}E95o;i
z0#!NZUHa>0To=jvV<F=g_1dLMfh3C;`j;y~uONg!T{v;LYZ|SH*RzQyCnkwmd@m9N
ze$kJ6?;_r8Qtwxgcb0dS`NK|_$Nt(TKH<06Z@j(CKLY)xV`c)RGXr{&yrUviLYG5-
zTqp8AJ$dt(2hgemj36LkQ3sF6ck*DVxT(1LgaWbdM#x7<;DW7U6i`XP32}M@v9>P(
ztwPbS-$eZ%H*S8#ycPiaqAJ&Ka~qizkje(|GV#tD9L$cpD_)z*6Iz~7gHuRRL8-{P
zMJKcSqQ`9Du&`%^-R+<QMH$rs=fW>3fygBRhd@P55zp@wU797?<vC%j4k0F60qpY1
zL&-zRfI?wmg_#*32gmu*E&&}QqAjl8I)kp6y_vnqf2D>(2Mg!!;UbWj(uaPhEiZq0
zDSCP7{uYWJAtsU{BU3cLC7e5J$u%r8s)aye0$*O<{rklKH!z<>EMEz=Xny|0wPn_l
z4G)<)t{z)tRI|Ulyr!q!pr_;bn-X=B7>#RVyB@<G9ujo$cTfYM7^d>_3gBf5@bZ}y
zQ<?$|UXS5(ii{t0P?*T*7us^dzbgBEP7Vx4jEfLUko`bR%b1FY1yQw(SB~SR!(_Dn
zvIqTv0zH^Xnj#FAxVM-S8ans`%wu1G-th-wQ^euEpxi!3!z%n9l=nR$OC*$ST#NcH
zHEaa5Vnp-^rNVsm?cP~KOC~lPJTPd{KN;cB2*FT&LEC+fV0a%)Kq&xh1T0ledLcOB
zgb1DB55j@Dy>q#yOf1kI(C~jE3xq5U*`P0@pd#}J!TKT?gK|~jb8(}@S;3Q|bSgez
zsgo?(_I;o0d2dcfc?iRy{g88x0)D&z{Q-h^ep9!u)|i?Z6X&aZ?{Jj_qD1pgb9|@_
zQXIr@V$m;$>CskIf!lmA0e2rh-yDn+;6x&dLz8acM1rk5RW;+HM&OB&3gICYH^T&6
z5k^mRws}C42BX;{isSvX1G&H9qJvQ@=81&DWBv_Tut^HKzTONoq__{**-^(`?`^Gi
zq6w%7=YU!vKD|1Fo~m`w?cG|~i#diSl1Q%dXTyPlmla;4;bH)7j21J~M)Jy-)XL7*
z&X$GyNqg5K1)XmPG$C*y0_uBqFy=KyV@!HX;ZBEldkQu21keR|7!eEKOYP(t<Y}%+
z@ZJ1C1kadfAV>rvh?GD%8*N%V8n+cae{l#X&<}eh6P-{E4%Xh@-tK>O{r`8+czjxA
zvs@O{uuW&fWN71~7D|JFY-{t$w4BY7XeE<~CMl4J7Gtwq!t;Z+T-dan1F3jy{{|g4
zYqtNkEl=Sg&KcHfPg~Aa9!7nHj)v*S?zfFZC58t3Ifa)f5jR(fgXD=yQlOWd&Stfj
zTJx_=Vxd5!|EvuHSX7dKXq8rT{yNvjFvnj9zeM9t#LhlxYwBn48Lx=Z?d%M1iMxu4
z2}ND3w^*MEfx&*GaJ8JRDE5GE-`L!M&B|vOULHF!j;g6kQ3>eJCQu;knDPwf2VG>=
zL_mlAhKW6(Gr|w(Gxc<omX_^>Kx&LL%tFfOvw3QrmbO%(UY4nuN|b7lnM<i9mF<$5
zbfBy(yX4-nE+eCk(`aOG9~ml9Y_9BkO;GkFn8@JWI+NXbwW<+GW3GI|s^{o376N(>
zA3NU`EXu_T5-ZRs7#b00aeEE~#fY*<I85f(!8Cz5Ok@NWqt6Zl?rF^$Z|qumos?kZ
zLcuGO#|9>36TfZI2r=rwK`BC_!(aM9XbEDlIK+m7`Jg8X4$B@P$se!qpW3YP5yEg{
zxu5_F^l)TT3uMn>he5}^f$tJz(1@zW%sAh1zQf?8e<$E_Jg^vEok&cvK-QE<y__ca
zPF8@0`#qD(Ssps|^M7xsA$(3F*nquO0m4ZN&g+5`xd2tkIhUD|oEy5qMl0|uWM7<d
zv|@z)#y;0RzmuSopeF_<13l_~)N6aL=2sjyCf;(Q3dJ?|t0(&+wVAxEm3!ra_6^j~
zR}FYF^_s|U0WI!8Bsc9U^l#-oU(*~ImS_V}s=&FTxnkWf);sz5_^{N}z6uHoLZF5P
z3gs$t+5<WU1_t`n)HH5yZ?8yTEivJtKK$Q=0#TsUUSB~9`1VLF5reIrow;JJA~h!c
zmwji!HWpKAO!yC^Xt3Xt;GrP?lp%{B-S<uV%MJxWg8EJDF9GC{B#XZ>9R+2=hKP`W
z0xL4s*H=vXV(~gwxTl+Fv81b%G%M8`d^S~@nwwoRcgs}E)#$Jyhb+2)&CP!-YP3J3
zhm0FGUu<kFfLlHOZ!g!1rK+?a5kmWq0c$BGG;qx}B76ZcQf4O}W+$E2<Fd3R3}{d6
z^e~r1Jq3@KMDY`_s<c=L0Ur?xyx`Es$qGAWcL{v1LP_O_TNyc1+!*N(R|tx>oJjLj
z9wo~m2|lBJmqy?=KkrK6x00bS&FS%fJ>s4;!3F(V(`hd!6%qY^F>p_s!qR#x&xMQT
zO%t{HzyEH}v$*Sgx;=P~-AY-h5hLMIPEl81e!4xHcm!@e-=EFFibyN}u(Pvs$PqB;
z`FggJkD8EFVPm7c^YVB}GCGjA=JW2tYEbv`>!o8P76Y&fN@Zn!c?7<6bb4Ozd3em^
z2)KasH^AOVG~o7V8j)w=qc1M8b6nJ3kSZG1J}K4a8w%`P$)PY21-OTv399B`vJ7S*
zS{@3NAat3c1vlE9XbidM=x(UqfXutWzD7U8%Z2aL)lBBZ5vVrQ<4}QsFQ`$F{13p6
z63<`xw+ezC%SLU6|C=D}DC0El+XEsIRgmFO#He<8pzS}i!v>6M|0CNEDQv(%z*l+W
zRS`A$tM5z3TW!ir4gqBl$bSkB3dv(il|wk1DFp>BxKdPq9A!Wul@j%`f*Ty^*}BF*
z=6op50~<cZ3=Tvlu;Y|rL?hThW)Ngs?HF>T+b4|JqpsX5BEeO5R=C@GB?yfj2}Ir^
zj5sXVgkB68?o5}85P$x}LR<VqSdSj{ihs#Yz?cv?^ymY6T5c?NYG2z7)nK>T0xOXM
zYXxqwYt#E};41M6nqRe>KToWd5K`R|?w&=loBe|IO#T?*B~i5I{Zj^`sm{(Qd-uIe
zxk&m4tttq5Kr>Ij$1SfDY2`GKNb=`_|Lw>!L?^BDCe{UB`A~sJ`Fi&k#Qk=RxmkY0
zm&e<s`#TQ*Be=#KAK3TZiuSO<6v>2KDf^)g>~ozu`~JcpSmH&e_g4gWhMx<WM|_Au
z0hmg+Tje6<mG2c_PkdXMq@={Ob-%CKe6M=k@;ks(635c~7Vf0IR9f|wm6cdbO!(W1
zPa&!>eywA0u;yTNt*0rW;mzjdk)H_gclJ2}@eT}RoGqbpaKBC|XGe$6@5{^P9j>f{
zm+j&z2bpn+oN3lCt!1M7M#id?)xJmjIS~$|o8p~OUQjxthwGy)@eaflUf4Gb`(~Y?
zjy9^8E~BK4j`n7x&zs+;QIk@<usYX!#`PwUhCnHQ!gNNBKskSxKxO<GHMIM{`wz!I
z16tz#vOlknHvc0uki@Y;kJDi1>X+{4j{t=5foVb$-{0$#5q$!Jb?7LC!eYgfj}>JV
zkSmGdH77rj2}~Y|*yeXDUJtC?*ypB-_&iW`Li8US5MF0s4p$9seb}CX9u0Z&!q=<y
z#pI>skdJ!10@^g~bh=M7oSr$Ta)bWW1p2Y6-&7Xi(pX`c{fl1LTU69gO|5DkD2t4L
zy_4hK8^*Q*hSPN|l^s0DrjK0OHZDDQv(l@&Pj!W-lYa9P<C3=Sjas?gQ|$;*avp1N
zGxBE1dvG)Igct=s?LB4G349kEoie4n**nNxJ371h7M=dr(#XFST>iNdQ+gl9jQ-CR
z5tx6ijVwVxNIjnQZRd%y7NW7TYA<&`c4;p+u(GnUSJ?o4ma1$(;(wZ{xX=D!W^s90
zs+>MFWo2a&v%geMI^vt`L&NWAlU4@ZV3Qyzsfc^}@&tGYh8ltj>cQXtGLpc8VI+cR
zVPRoX1-mP`gQ`jJQ;kIv5%TMqeOJw=#cho65;ShE*Si~w4oxNUOChA#7~XaP*~6Ax
zOwz;s^|rB4)NXKGzl0EUY2^@%_FP3UNHbgsrFilLDe}w9fd6+&Ag+X1g8W4Q7)X0`
zB2W10VZoiC-~p24FVBy-6MR||qyVearU_CUyzNqC?aFU}d8wo#YM*wgq{7K!Ggg{3
z*>Q6fmb9dK0Rdhld7_AI7Z%gu!z0Da;Ak6+ZB|;pzXM8Ef25TO;mmD>{Yw1qd(5-U
zJU0Cx$!TEwSN0DB4^vPzp+$0M5HQ0^GEce?)cubj=0flWC9J5bm|t3~{7f5}Us_HX
zk#Ct~Mn;4CWn4m;rRy(%!V*_fRl^XQW0PiyPx@Z?FZW-HC@72ezq0-^<NZ}mRSlHO
zCWj$bK!Yo-$Oiw%_rJCA4~x>j3Xf1zS-=o9ZYncWJLl{aZ@0TKspzFzpnEn|nd|_=
z1qfvUzqX=EXfl$x!SV!=6cjA%zLV+q<8wJU1<OaY*VqI5Eu^CyA<&YGi)5HTKk#<r
z3>C0f8r$BgW%BdP2X-QLn;XR_wT?<t780|$l%_GI^VH_qF>p{&X9EWJaw#y5&S+q0
z<-CYsm5&s3Pkzb#^3j3x{TLIURBR4;=yb)*;YujaW>z0+mp^CM#k72s;AziYmU=FS
zgliCX5|PLn&76T-mw{WlNNT&<rc$<eYR1kf$jf{QuxzHHl3n_|Cx1|NUN=A>uhqn<
zz&S)Ct(;UuBkz)V#0vn-8x^Npm3MUD!3>4*b~7i^EM#o$9^7mjzJh@fLFVXlNl`rS
zd=2kCir(;68O#)L{7f_}MMQ<;3I+xM%=UqS;gmjlI6@A9LHI<3!L%4fIU-YWeOzwX
z!dV<EOZRr7pENgN#Z8->6tln`w*5;<o$Qxp5&-{orhCPi7Ld|};je96TNY?IV4Hv3
ztmyg)M)(c8>Z5qB$Iv+wrw;ie9ANb-J^-VtBNqd+`x-w+>M*)@K&~e&@p^f$D<P?E
zEJ767FrBUZ66af{<vc<5Bv9I%{Gh{pMNvq^#DkwFa|egG^a~1h{8-yrJYXUE6~!b*
z(T*!?ge<-jMvE!%^FwFWFr!VsdmgTM3-Mb4!OQF?S494LAq(vL1VDPJXq!uGmwm{N
zAMeVp!`ZH+5r=4>AbMv!W#DWl%i&t@qd`~4AJU7vd_L<zS%L9@P)vFxyxbcm?%@jt
zH&%-E+(zCPV12vd^l3;-<n;J2()RG^Xz}m??Hv`>?Wg7C!7JJ;$=;lC8`7ReZ8^40
zUV7%`?G-=6HsTMhN;f9Q=T)Ms<-&d@8_VV_DNA{ir{w>|^w-;^$Y%in(8J-~Ly9~O
z5-<w}2Hw#Q28ILxL;RS<bxP3g7VSQ{o1J4Y7edMnW!aF77yT>aGwU>3ejqf@X`nu6
z7bq1iL4y)((^w!+uU{&U$8<lhZd*BhHfob(TuS({BvXyH>J{Q934=0}tSQl+s%ZXM
z&AkkzlB^Q7<Rl!bMs*u5HCh+FHPTIy7+U@e-$UITgO_$tirYqCX1cvI4Dr0;vz+P8
zbmzV&z-{SFvQ_aU3!vL{!i7*}&;NOnvpFR*00X}F`%ror8gW<=?a4A6^i3K0ke?<-
z%}4nK)p}=)G`33VC(;vBzUYJcgucL?dMiD*l{5fgG&k5-Z3ujh)J|xMy)#*3ekbf~
z9<0Bn=s=zLS67v>TUv2*D|^!Aeso-J0hfc%WZIZ}5xVoQ+PhsR^1`w7e5z36eLS(r
zu^-y|MYi=5Y04*nAG>31yx8dne$MfT$a7Y_@$KpyjqN`v@GGo1%sRe*V<uxEEJ>hJ
z+;eesL#$PY+-*S}Ql>-pfP%2lQaCL!{*vEFd!oHYF#f|Op4E=G@N!ab!HDphYn}D`
z1et#OuWn4~lSC{xsoBOVHMbv?8e&(k6y)k{-U@DhX(4C!obBDt3qK~Y@(>rHAeO2O
zJ*BLC(gqVr6V}GcCr)U2#`Dn|g{<tj!ENLvNK(|GZ+>O@XwTU?c-fVy1f&%;@f5*3
zazH<bow*kB#==pQiCfrE(R>tYZzHV?PPe8b55c0SG>A5X1hb_^q)|>(wC`K~O%4XP
zf>|rwT;A_(tKOXOTmD-ImLIx0ocTVLj3zERtTOHjzb8qU&gmU;qMTF`>4b7XAh>YW
zMhUT$_NFt$gVuq#rVp0&npL^<f%8z6WDV>IYB6~If&x{NnFktuByvF3SNkA%76>^&
zl8Mc+d_95pL1TyfO_%T5AXH)4AS80E!6;NGlcr64Fg+5vvJ7R*djJ^Em$as?^UKA^
zEe(qzOXHS%U*K7Rfxrj=%pKf9rH_Ej)b`Z%6+DHnYskWH@E|hVNjG17$;~i@$h0g1
zvm}fzlq?1IA(f=1kbvOe<2HnGEA!JJ&a3qOf`F|{rpfI$=9etjnGCGhY2uOHh3d3h
z<GQDm>eN?h4^V(czOIi8Mu|!mviQ>UG>V#+4pJwA0msdd$>;>CS;S18nktr}n%n`#
zpMb@M;3aMGR;`_C`1J{_SQ6oHEJG&eYHCnQSZZGaaI!Xo0@c)%z=WtO#(|<?Lt*F4
znj>KDV9>qbwJ?U~Fa%uTzdFUFP6oa8`8-2QwXgR^3PZeZk4FE@OpDO51q-jlGGP;A
zocV0Nkn~W|$`x1(5yw%+Y2k9n!9mBXsII$kPU#q02qQ_^yZ)?)J+#JWQt)VL=@Gs_
zZCdoa3LzonBOVDMn++pI08OxFk_zDw!-%OdZD664=&($!<@v@&${-RFM95*69i0PY
zk_|i&ld8>E%k8D(q=;i+i)i`~$W2oyJ7a^uQOn@t%HV@wUGb10MG6_NVee2+QIYl;
zf=w$iNwGeKeo+k-BBym3WadTG4*@aV&@bA)f2@*5%GjOanCfGPGdjlZ#PkdUm<;`E
z4YfmvibII<)koaDmTY)PN8F>@pfivt8B53~vcb^5!O+vy)$?b+&D;k0p>H$y8KeqE
zVhKs?v3KmTpQauEtiO6qJ7ecrV;9ctjl`n1AUL)l_#SaxAtg$3Pm3)6SNuq<XeOwE
zJJ5-4)rln82-!r;6g>)`9zNUK&xArk68WG{hzK24?CeB_(L8p1WOsMrj?P9dBFXI~
z4E9a#!qZcPd=HU9BpvZKFfXqZbukb5DYOvhnkp6Qoops0JUVCVY1(OLXJ;?-=!2-J
zs2{9$XpMkxC!g2t0m!yDFfdZX-8(zGrTOPLZ?3M7CI;5mlqq>Pzh@_$E2e+T3i&CQ
zSfKCwn61yJ5gskcYnv_Rz9qk+oSJ{VOYZ73?R9IL8LN<5<KrGfatp_l5W>5~d|Y_v
z`71WCZukszq<o+$XN@1wV3UxLkRJs!13lt<LcHDs%|g3?Hba};f2O3dKqGaME3Xrd
zhNC?Xo_4AM?AO@v5~4H%Js01Y8X}aMnPjGep+f_>>fP{zVZFoy*xjEPL?c^)H>>3o
zS0&RH@JK3SbCr$9>wA;MJ;dV4q!WzJELPeFjumB6UekVEuw$YnDlu`V2sGJ!?_WJv
zMjm@F9(@H%$|jOWQVDVRx4MaP(ggV;#;!wZE;U$-(-%6tt6p~M(lWw(&lm3RC4A4G
zkl)L$oDWKFVvj#Z^AIJfkj&+DmC>ywwS)LZJBYd_DnRsav9LvofLx38HQqFe`|5Tu
z3M7wV-_G!TsTWURILh8R%7);31bW`ibid5--2yvrXEt{yG{o8ws9uhG&MX$#IO%qI
zYZF}+3e+_m!X&{6jnc1Fk;xF=$aPaF#+)^yRv(+l%q|o*7vDvj?Ro@%eCnwRb1FC7
z7U1DVNjYJJX%korjuyWDwMP-w`WYc;yA{2oW2N{Ate3{gMMnor*UQL6qwM{D5Me1a
zG!n-gGsJkGRpqzeC;j)fl}V=gQS+XM=N5`Pr(a$;cZ08f{(d-5Mo8yiS{4K_HvTLb
zZA`cqCp9DHt4(i)F~KmCd^=BuyLZ6kY=JGol?I^2=1kYb>SM#b-edNeiVA@2p8XTg
z)tC3BCHIT1PaR9RQyO}%C(8yAVS-#weRopngZq<+Ejd{nw#Q@MFVZL~QB*2)SGBrw
z_b1<aU%Z}7NhojP9SAWUg16tg+658$nhpH;qt-<^bpn}K&u0kbk%JC7e#7nofQPBS
zJ6{b}%GC3##I+-vu&ikp*W*=;c;&QYl7r?fx-<Z%9xsN5KE@~6N2w*)8TUk5hI4$v
z?LR<)YNZuQ>bX)X?2<N;vHnJNKBG%s&|M_FoGv~b)nikip7MtV^k>mbL2=6eh*vKE
zXG^r@|D#E{N^Bgvj9LwPZ*NHrFF%0!`uh5`JX&!H>;n-IVR--;IPC{Mrwp-^Rq*g_
z6f7aQg%Wu%IOl_j@^UcwEG{sLiSn}V{^OrcG;D;U)d%1;?vOsv9NSKUkJ%-^Wv^MM
zClqY9i<-Q!^S|&E7_H}sFQuzky_V$eE+FmWUuw0ER6c8?)->ehNiro=v1?m5E?Jc?
zs1;Ypsi*%-MWFrLlBxwV^7(qT{`{%=^XC9Qt|87?gHv5#*`5dyKA!C=NUp2vz{lg@
zVEaq%z{mMD>ufrf!H&-%n?^r8oW9y%K4n|>Wo!5^%HXj5V;KIIcG6&GVq$`s3wF8Z
zx35*%Wc>8p>Yn2|^Wycwp1W)7P)xtt<RK1Jsqgd2B^1s0CH_e%nvxV|7?<A<NqzkT
z1P)0C4e8I>P=m{h468;+P0Y6(z3pt@2R?Hoh>Wb%3%TF+K<bh+^}IAz?(X3*MpVoJ
zJ(W+IPR&JU)E3>b%f*`mQdh3_sO>qrab0)23~zc%Y8rrNieJ(aKOdC7GI`O+2J5ZE
zJ_uvmH>kss_z000P9b62_DwAV)-CL^n%!6787++G-BFAv5dd}E@GSZ{+;DQ0p+;Pn
zLu|YT{=;j$mKO!hF>Ac0Y8sJm?g8k(f%k9JNOUr_JON-ta%?gya(wUazhQoFEm)R!
zfPrJ?(lbBJ*Jw4IXDD$nTQzXkuB;>Ia3HTG#hF!_rOWm;Uv68-OtvXhKCyDtqmo2)
zn`iFCa$MxTZJdM)NRM=6H}4eUi3F+u1=)hXq|nbJ5zmttO;gDvTcH-m3wRZJg3N5e
zGugBNwpg}AsoR-;RbK&$9X!e4FBnIigwXL%>B1w{XS@{a(Uye$?s4@vM2qqx?ly>9
z&2#zey926QRwko0TJW})wEBc|P0-0Gbu$Tahkq}Tfd9u5$)DFugt*!}|KshEz`vp2
ztKLF9Us3!eeNn*#DS~|92e|bd6Uw!E<IJNEQ5W^^Nwv!C2jq~r<tGxvV{R1YhbtR(
z$K6E^HS4$@^J;b-7Dn}sM}wHTZc#-`PR-fNyG(7_F&4e+RdCbz12BCkZ%mDn(L)8-
zQQZuy!=5Bf9~ZKWOaPo*z~e8cWRGEm457nnHb9QWVp^r<z;T;U7}EG>ZIS`%JQujB
z>_Z}%F8j+;H3onl0H6liLA3NYsv)&_sDbWZ4!<S!DR<lQ@)bSniZcm?@}N*WB#fua
z)fG#RM;u;Ja#UhBd1=5FGL#B!PWB!7%H7gdsbJ=IT|%jv^%k!vki&j!gmVlhDk!Ka
zXaWrE@CgfRAJzX0H628Gjcz1}f<OcYUtR`VT3Sj?O$?<b(>Ouj)YsQ{b8zZBg<eaT
za$<5L#c8>AC#O;LY*6&9MV=siR^3K5|He2!Mqb_i%oNDbVs$Oedm;UW;uRp*++0>V
z*R+V#y*Ou0y&%elT|w4GQ;{*J(qM13R@#YV4OAj_Nwg}NDpM>B3tK$mhkz|pn&Z~9
z#L6}F(w8ja^G`W(RMaDqzUz?zeg5?CkJL&{O@)D>CK=g^@f^n_@Z&_n6Nl*iu0}d8
z5JVsZef}*aLqo&NchSw~8XEf1&3DoG7Ff4TxLGRMsnya3<C{@tHPg_3+FGZjmHVN_
zU*3IdD1v?eYoWz#$vVbOt|oIAL3lWBDGR7$))*%*O@ldxL17?NBAu}E#dNmjx~Dam
zy0q{~3W{*awPSj*?GCdPf9-`vHF|z5?!HAh+Bi{tN{+z|v1C48!`cp(Hq^(B9o%l$
znojgGD+NYOY4)D+7$E_=+I?+Fsm5w753)NH#c0EUG10z1!#Jl*fHp{dWwwYBh|f@_
z{c-%OT+xRm|BGX8IelW~H7dh6_NSk`9pwNb?&X3X&b66GNv-Q%zRGsvGE3*GKOHg@
z!L=-eHx~t+Jlso5ndM%-PE?eY*BsFB+TChorf}*x+L=|a=&y8q{Hpg<ep(I8^APsd
z`&xcV)|LU-9@KIi>7E7e9wmMBITqyR6BoS0=ejuLCiHmzWL?4yq+5mB+tynEo(F&b
zCiv$Y_6i0DQC*2&QExx=Bt8yCkt}O!R6f6%o>2Y^m($G<?<SjV0-wyY7$M}{O7~J;
z{^dn!9o4&?DVX?u>5_-$NU*C!<SEHc{uw&<*&x24XMuFIo<0i1im{l=LS<>qqu<cH
zEs7!RKd%M{tHe3lVR9$vIe$Jy`Jw3OK#o%?0CMu*<`Z3QSzQPNiauY+a9Vbiy?t)x
zKv?&dKGCp$x>2zb_DvBq)AmY8%6Ms7C~&ReUVV)8p5sR@5j7xLK66F4{6@0JPQL%V
zB;y{c{i9@)%|cXeQ<X%on&Te&A=ci#4E+K=uReFHdjX+asS#ggL*;-SpC{O;bx%!Y
zc<4*|#|2i#HGIWVM!(H*J^zD^TCDS*)SM`t6PDw0DTc~tj?vG7J+lkWDcmM?@7d1!
z)XMk(N2s6t(_e`SJdAaJnY2X8!Fc&iRUi3v9(fH%*b3hGyhSF{t~GBbAnSd48P}Ue
zk}7YAL_Ss)Py7lx>(6PEzjb*7XO53JpY{SbTn-;usb+NE-y9xx?vXWnX0}o&qm-6S
z@m;v^%W^|$42F$4AHP0&{7Lojcz^%5^ltM0K2jBAsRmdAJ$15*IXz_7mef4l+s|s$
z)I40f)D(UFR<l2`nzPQT-ttOnBw@L%ut_#vw?IxWX<^$SosPI7lclp7u=43sCzRUH
zLm3KjoJKdFhBp7<5zW7*8cbY^BCgU>6WXE8jiv4;2NUEFvB}q@&W+Wj1kh!2$%iN|
zr(8d!NZ8$GPfe|JrXNLZd<U%fH=BJF<k3|S!0mQR;m<PWWY@IMJpT1`bHfAMZZ6p(
z?AyJhJ<nFt4Ny}*sj%Cc;a5B|6V@m;dC-g5ySjD}pW-h(re;l(B6C%u%x}^VceCKv
znwg18<HS^@Eg*1(!GY<v&UU?!NSm~7kObmhvK|uEwLQh6mvV~gn~OW$f4~0hjXXVV
zlEIxKfaj8V2VL<A6N((Z?cDNpbl1W&wo^bq8e1)1Jhh!jaymw@>vWxM#HAg+X0?5&
zbqP7fLM;@nt$ZAIwW1fIF&83f=Ccj53%){q?#0UJObU>Lh_$|hMQQ2U0nt8*V7Pqf
zo->9)6`y-AH#VDfQD3h*`4Dk;&?1R2ozjE8n=<h^k!5m-zV7pN1Ky&0c^zTxbxw($
zdGkUC_E#i8jq=)t9sgkm*HlVN$=r$*c~Y#ayPuU^>2<Z|>3U1L!?I`9i-(6@Gq$-o
zZ<5|Lh0=Jrx%xAeUv`3y=3Szoufq}5@Hm1D(lRF@d8z(-({%Mr*_4`=06#j{9R)sJ
z-xV+~>-@!Aa?0F+!^|Uz4FQoYOM`uZLBZXkjJxesj~6i5b~==L!_DyaY0{3m{h_&O
zRUn*4udQfuM8vzE)6?Iz6s1AWU~2Mwj(TRf%DMmrT~Ltm)gP8_#g1+?nU!)Xbvdgd
zlDCsLtadtx3`nN?cIu;t1WmQdD{(ZO<kNh_S=lLlvsy~3y*8nW+d0Cm{G&UHQ+Yn~
z+v(IY*M*$y=Mt~9uDt~h4DE=!Bdrusw1l&)wj;*!w$j9-8UxAJHP#tMFSK&6X`k<J
z3cxSdJ6SGyN#O%xzN%<hT8S(UCGz2H7R&3m9xAQJOQq!(MRqPg-;E=Q+zIV<w$2yH
zQ=1CzYq}F6)@VC3{h6)YLp`jtPv<{vl{oyXy5lQ2`Q!z8E(YzoM!3_X%O<T#7DgH>
zPY$G+SC3eWAUyz5YnK91OFr&73eL-o4f&HRQZdOnQ4KoYQZ2lN#k^cq)ypqdO%9lC
z>xAooj3s-{#Bdw$p-GE^eXHuxCxWmJ&aCRy<~rku26rj@7aOe}yDIa}&4&|0hZ(oR
zm_~bB?X;9b(`FOT&HdDkE`r@D8@sXWhpZd5)TF+e0xSOYM;r99>GZCPuDO!SbwAE7
z{rgs9nIX?D%l6dGEq`D8XR~(hq2{HE<Hv(pU`yMf{emlQw6TL9&&B7IDxbB@`^!V-
zN)-fjgAnce(rlf`ye^aU7VGtl32P^c?h@Bek4;wG7y^>+YaI<1YUT=4MP9;PJ4riD
zM7Dl6ywbc~yAO<<4jwY=4!hcV&E1@*_iP%C#mhPTIqYTAGqUq*7wg_V3NiKSwquOL
z4s7*-{Cuq1Q{5G-Y$v=Ie)_;V=y{stHyZ%I?8$J0doioun$FszoQ;*dm(}C~J5`VA
zLQ_wKi{;GaI<}X$_DIjib{UrpZ!75T9=5v|e*V)b|LQ0^&*Y<Gg8tN*D22_4E?}RI
zRq_1AntFE2g3gNF*jD|r<rj8fYrDH#Xkn9${bLm)hCWsLya$r`{GC+xv4w-j!j?g-
zLrW=p?X32^$xo8t#YRE~3WT6V&eG3vOkuw!682|ph;yGlli6~+zoHRLTWp8m{@e_L
zTJ7kCo)aH7>LghPW8`1R&vq6*L7Ye-suoIh$<tFw3JHSc!(#vNje8`Rb+CLmmyQA<
z7s4wE-s(tp82)rDDQSdal45-2+m~uX>sLr)(eyxRtE^u@Xzd0b@z-lGf4bS8ta#IB
z{OMS{K_BE8M}uyzYBGj<N{wBsz6x?#u#dAjY;0qmG871I<QXrD(|ZR8$8f#EDUKqy
zW7y#q#E1!A=Xen5QQJIGr(ZS+VkOZ%FLyNx$aifjRuKb_jz2-w*&}+c9*-uDH$0&%
zK3iRI;(v{_ta4pqPnC0l`t`L7=@_z`m_B?t{fAClQOkYSCuA1i{U*DUL#N^m1daxo
z4~Ut;d0F`E_InDwUW5^vc(IbpVb80AlBvGhQ_glK`oVVxvyHV4zmPBbXr5+KHn|*l
zIamV6zX;5G?Te4HKzDFuvw6aNuO3Y$XiEJ3eygPtCSiN*FxbIYu`P&$@`+{t?gU9J
zvf<+R9Ts81A<FGlq2Ax$%RJ2uruavsQs7p*#XKK^)sbF;6CX?ZqN?TzVRs<P0ljX;
z7yNp9tQCcf>U$?he*QJXh81D52f++D_9Cmj^3(f=*sj-cS?*`t5w%aBApQI4JQI-2
zr}lgrvsmN4>H|A?KE5xkvdN%mNlcrp%#%3%2zqFOQ!ppVPOWoaRyMj^nQ!Aze#)NC
z6^`xaZ_a+ZoPWW9P)9P{e6*rGjH#c0%NMD+!sN`)Q0q%y0E89G%sIXt{TjCa6!u;L
zOid$p=-C9)!P}!|zgyhf0K{|5Su!7o;@KzxQO$tdpKmcYt1$`kfIdHhgDplc*b_W=
zdLzQ!I2k_KK4qgIws--3;?PNj#4evvRLe&e6o(!cc6@TyO<C(7he*LIe))-W5LCq1
zNd_gC*L7-3HNTEd)6bV=;5y_H`ve+{X1@fY5Cpzt#+P)MP`d*Kzw_6;<sa-<?(uIg
zoNZ>mh7dK#lM<l{|3-xsAE5Nby(n@G-yK<N9~uy!>@h_>KYYAg(Hoh$gY_O*@f7*y
z7Oa%*qB(6}c>SA8>c)K{_9ArAVSzdO$Zu72ghfiyJu9Ct7E|u5(&DLo5@1K#{Zbhb
z-b1qJa<&jNE7SdkVoU>pYVp;5%!GSHOF99Va_$K{<y)~}Td4~!`SKd%$B!2Ll8Gwo
z??n=F>3)}NT{4_xL*OHPyJ^y^@B99qefQYi!Kc6T>J4OV>6YJ$zkZ@wBAeERmo^3;
zwg>jy65Qe6!y^X>JiOHv>)w5gRQ%8!IOYb0m>Vc}Fn!KFWY!e^>(;<5DRei3_!MD%
z=)!s%cawO+c5J`fuH1A)2On!Q+|n+my&)Z*6@LEG!d7v5HpiZKBWb1pkn>ES9qgP~
zc=$prC{&|uuQ74NP-id*zxmZPh(BAQ6z>P%gP@nNu*XLB3UqWa2QqPC@Xf=vvTKpg
zb82x~qwV^*A>8k&<~db1?H1p><~!CLh7!alz0ETN%tkN+RDN(82kB&!r$t;EMVEE1
z;M9v&K_B7BN3NQOZ)5JyRYy(k?+G(NPd>@Wa3=qOY?$4ytcsMcebircX2j=+`C(#R
zaQTxw3T|iJaqe?*h$mcr!fq3cY|aqW23>A+O9f6X69gf<Uq3p^MV0dQz2EwnDULz(
zd?!H8UBls%$%sVJ2M&9rbR%^;uO>e8`Tg{QeA~yRL$>D$Ty@{7ExvSj;0XjAEHQqA
z`Rtc^sQVHlv2GL28tf%{?2`$w&|Nok@t=L<>`*kJnsDF9XwW!#kygaN?QoejAD@`n
z8yS2In0#*<eDcrFI*QO0v~+}?X%TP<FF!m+Rmd6}Hr~1rU`6W4ym}P?{-%!=^#5%z
zvJvZb1#FEO00KfZdpR}ijvC_XzMA+C*#cX+gWE18nnj^{J+}n+5U1Nrx(wS4J(6Im
zj~w;=Qr3P#-*??_*6E?h8km2yU07I~!5boUcfh+JV~+CjsE#0<`3dwMV#?Onch8f*
z2I`z}FHChwv=^`by*TmVKNctcya79GiMxUJ{=WRr)rs!E`177;&6g4T&xz6Qavr&h
zem-ms4(&sg6LyN7cK4TQfct45g{C{!am1-IfVj68H(l)5l*`!s-F(yc)kLju_YUog
z3WgMlT|u=>K!>qb`dY-6&-wSZ?}q{xu9sO;1_Ie07O{)_G9^3_my?f0bDy&TN7Ay|
zvJ*O$o9mO-Gon~oCwyx>#~Gd(01xx!t}eeWlg&h*XN$G<jYu=wBhGZd^e<~xc6$xl
z`<Fz13M=U*s(OB_#%tWyL~E+3y5mJJKSCm(jS-8+bs1m}XLVLF729UcYEs6@K@E}o
zxQmT`cS_q2?iwHW)8lK30{85;s9z1%>nGVS7u5-E{^rjH>3(eIYqpOm4l+LK32PS>
zIzGqiTMdbrEO$B*m-by$gf<=v4M2aLsl&y7?S+>#u9czNVw)xQ0<nxGGi)Ef#)qt~
zU4c!99`iN!?np)!DxV9XYLl*)h79x>bgSZLlkTx28GnAx+b;`vrYaqyNz>=^0!_E-
zUwvHlc<8((-QSK^Z0`X*tWAE2$L{Sc3BP8p-5X?$7zBx;O=Ih&TPpCnR+_3PRvGLn
zfqtK!ydNDVrYfuE-j3hC`aZv%RGyHnY3#vCzfG^6IzOzhOr7P=NSon(RkI(XYCPMI
zlD+sr+E_DR)NS8&9MaA6Y`0)@H2!XLa`3#=)t02>Rpwi%-%~F|>u_}i+>9DCD_rS*
zNq9PZ;CrD>R48^BE_!JKjyX`AE4e>t@lv*|>z|kRv_Aq&6#Pm|r}7$8<OiLAR=F=$
z^fr7WC1+Qg#}Td#XjIX0Sx@yEJ)C=;GcJXPD;>mYj2YL0J$66nB8oY(s(xixlHWHt
z%s*pQ#2K*XXAmwgAE=Gm71aw$cUhe+S6JGZfy3$#Gin%`9ac!?3fI*RtVAu}h!Y#-
z(a&%2iS|AARgo}G<yDPy?nfp1cA@z9-Q31@%a?kn2K;;EgG2BgSp-`51q=z(gQ&kY
z+;Luvk)QDZ)e*O(nqSvq@a(q<Zw5GZU?NUVL%i;k)hXo6H`#fzAe<U5zlWZPkZRry
zW{$I`1WCB{{d5!d5CQ`DWIjfPRWVLVMwUY`s;472)4N0&Yk=EUxfaFoYIKBGZ}^O9
z-%a@aU7vMY9{JFWm>`c=cF|-boU8R$r0x5kC=oxOD`uxc>m97bFEd{5FXr;@pATsC
zCVHCu9H;EG+Y{tx{MKxCdR?~#_Y-6ePaS``)OUv-!`LP^c#5duVR$BvOgC1a(6DX#
zq(UXH=zfsBLlFw`aFqt&apfGGOh+6~N941A1S@o+zSv31(eb9n3wCo`71B79kI%}r
zAWo4K;_P1byU4L^u<tb`QjM?cIEjM*#)uXSP#YND?8&#ku+_5U!<vuTtRL;s_By__
zM&8-i@T1%1sJ|hs_n5iD6s+ZEoT&pa1c8F-W^2goe%Eb1r2P2J@bCOya%TEQzcyYK
z2x4!E7R-N(S5Ej}_&N0`JRk~G9s8n?ByO?p{?rBVNXqfKp`hFuu2lDY(H+}j_|zyg
zYTPc_phl&eSFulD<c|@;$oo2LH8Ptj_nckeweZ<&vnp?<?D}G_=XZLwPL~-xaUUlh
z4jC>Fjq$X~)Y%T!h_elDOa59#omR``3rU3MsnWYj0?K;kn`#y1#GT8E$0vTp$GEQS
z_NEl$3L@gP*QmY@$w$^bKK!i_k2xvG#8|QXp-=BW3+?@`ohi{y`*U*OJflc81Xj+b
zJkS#LT1~&OTkC&E6|W3eSGJYPi^vU5w`H3r=ek$e8YT7N^bxGXT5#PCmlxg|wwyU1
zi4C5I_B@Sw{l+ffBYDCUS0BbG@1zp1TSs_#Xwi&-?dz{0kWyLb6L!9Ml=+02_~7Ke
zs4YM^H7Mx7^e+5C?|xFUD(*r2mS5M}6{s+U<3p1%JGj()ZE~AkIaJby?K3G)S?L*s
z`@Rw8Gh=R?t$~&R(-Pxy_+k42#xG(jn;F<HFLaOH`PS4Z;4kzRC--tXj+mKwdxLCy
z1nb59v`5&_{%Iemx3_vRswy)n>7GZZUY=h6dQmX%@VY%p<xoKhFy@x+$k;k-W0lIG
zk(KPW0f_D`N`^Qf{*c_>lu6Ogo_fUA9k2{BV$6(yAKanhv?9QuGF5=fNj7yn_V)Ek
z=G|!VgFv_=%Y&w-45sotS9IwVJQVePJF{E8-Qj(W`*67=Ou?x!D?^bmowr}g?f_WK
zq1xD^njHtv8*;R3fCdyoAETQ7IC$=+@_SYmo~^9@l-btv6Q4E|EVm{my39GUQ803o
z%}+e>Y3qM=ao*8vINsmyP&(0SDQdJe>O-l$scOxlXl<cYVns@9lC-6i)~FRT)a)>7
z1`+8(jfhc#khE5;2tpzfJfH9LJHPXM&-2F}|J^_C{o{RK=br1MnRDXN+fTe;uzl8=
zB@}J?fqT+2nQRDr-iwXt_rFr?q7}DD&MMBdGD7)1SpTg-e(5WhI#l-01;<a`8+V4z
z5<kdD3w0YyheBdEw-T`|BQECPnGcsbY^{FV1-3;Fk%%q$Q-c&ae6oFI0xPrK-5zDK
z^?c>*#ZMAzHF2DXb;irNG+lX!pfHY9p{y9W_(%EFQ?zMQV2Hi&KM?Uxd4_woD-G{c
z3M7q$99mtGszXN4dB)?g5{E{Nfm(9WVTjgBLwxzJ!`5^sP?fe$|1s>~Wyt21D@oa(
z<#iotbu*as;4F|BCB@HWz4kX`V`4XXLhc~KBZ`_I0QKDB+vBMHWKDEuM1%O@NA@h=
zS56yIU}mk;nnn+d4k=>tYeW`Z$!zGh&_qayQuX45!tv+3g4Z$H8$mCjj^{}h_uYB<
zIySIv;U9f<c|)S2U}c3ytMj?K%KO4Y^R!K#e><9qn5XzvVaU>9iGU`)Bz9`dS4lJr
z?sO#nn#%D&(ybIc*Q5d*P7+>Q(mx<+hvs4h(~nb%6s34%zrnukE=<!<>qmLld$#bq
zHiyz7UuI$VSFDpcI>T%+S<HQZs)rXVUmcawKS-L3onZv^E345QNBm9dLiF`THT}q+
zNd?P|dFXK;)yk|Q&;!*c&YzdtPj!uK!-z?;h?tNH+%Q1YWH}L66SO3AEvc$Vt?r_~
zOxm!agk=Y6RIDIhwfKkTo678-*xi8TU~6I1I>q3}+XvG0vjqgzI%ObLAOaOo9r=Lb
z+VP8(^Ogu!y){mq+}z92M^QQzV$fA!akO4=sH;uh^+H0vd1H(z(z&wHV%e|KV7a_3
zqG?&!v|U}QM&c8*6#wXRQWG=k)}tVZj=y77Zsra)tS+LHh`7}BQJ{mUGqU5idw`2X
zptm4Bs_TqBKgH34-wR>o%*@Qp8l3f@W)qVF9`|y|HCK)C2$(jPz0lLq-RMYEk6D`i
z{jH!~m#Un+db0`Lm9N$pMqFz!{)+|%*pyC3v{Gq~!pNEdV9;jA$V_K$;pi9*aH;uP
zm%O(fHG(LpHs0J^taOoPU1T50B=%Oj%KEb(w=a(T@Po8-!&o)5%Lwg&7R&j@g0;Ge
z&Q;u^MZOJ;H9Q}^oHs=4&!v96DP1H;m6~$=s5Cu}8JrZvkjmS@)8myoN<miY!=K9l
zH6W#%tWuo9@5R;f{g~nK4V(gf5kuV3r-A|FOGThMA59qR^Z24t*W%7(Anv9#w0vCu
zuaf-_(iD|`!HI)GVN>)Y3o{PG2&ss$o%={w2<tjrJZ3Hi{ClB=Ox#-*?|`w_G4hHP
zQ@`oslPBie<*=~2wx$CXbLtK$YJG`>AOrP-Qag9B;?q6fHaijW^ze4`#d&dycaNy!
zh?tyUu|e62IWVy%2?LI{ampbzw=_=MOkW3kBt%cj>rZn034XCqjT(iK8t1=anv1^v
z%!U*4({Th7M;!WHe0>tcUf#DZiQTkX<8bq@-|qyOJDu~<s2b{;1No<{{_yGV59Rj(
z++seL{9+S-rr)u)a}^PhxZ4$VHEsg@D@Y_H!10Ec+oKbF{wZ57kM92$uOW+ZooR&r
zIet&*$`2==Uq_q;wp;QJ9gcHdn!H$l#I0nKiwkES_V>r<iABl0KI6zn;LXCXGEjlJ
zOsi+LonIraFKGA{C`n1)T?(dG*gX1mo>TGqmJ2HDn7i)IQv*@Mn|yP0)ri$h$$nv3
zL^m#`-<~rL4O<!_fnO5Q#<=dUK_7(Q9S*B|bJ$D7;TPlMxE2u2w0Ha8n(1twT7MsY
zC{$J=<t8+);`s(yG2-sp2Pw9qK4lB(+_YA8H}bbJy}UW-L$r=&G+x&co*6CIeXOZ3
zD)58;3)<g`&Nzy`R&a1_?~6Zd_u?%LeLo5yE#fRYw098ChZw$bd9OTiY4;4=Nz_Qq
z*re>nsz~`Cnc=E1xWSqJZ$E}SYP@3A@f$<qQvn-w#j8<1byX4?1j0(EZp2eRS<~CQ
zUqu`7)`!ACaaYx_t)W<IZrC2n!dY-zh>Q!rFL4R$tdzh5wtkyHN;~KI*nckR*GZ7m
zxT8N~`_AH#NXCd{)z#usiSM4riIi9}QAPj4FqiHVNM-otAA_+2zUu`d?}Zv++dZ#_
zdG<e(Uf)~4o`Ce5l^An)_Kg(yh~JXzd6hf<XQE_-<GQ!@;eB87wO(<w1jc(4T5Ud~
zBIfy0LBE19sf~;OrRvr;t#@_w`}q`$m^3FmJk~)VDey4|*cg7B!p^HQAG{pc;IsHo
zU-+av^*q}axLnWVdVouie{Chc%tz6}5{ZrO4BQxOz*$Ga>P(;FEd2riMLMr)9l$A8
zB96_TY`RM3#0(`KSDUap#<!Soagzf@lWr%L?Hx^9oqTimWccRNx*?FN6na_`Lc#8)
z*?XU93DVs+7_P(aAEaAUr%T2U|A{-WHEt{RBwK2C2fxk7^=Fb#S?$kB87XeYXOy1u
zPJLhSt9&f~bG+iMKJW#k-5dQ%Qz^;rO*HjwJZT5GZlpMH&!C?6+d@ja^3F_c+T)j=
zuhcXPUQGiH+kg{4yY=6GcW`RRJKj8Y9jLk{t1rTtG`XJWYk$$B;HNUzGouZoW4w(a
z=#vps_G4DgIp$=s((3f{$9NA+_W>$g%1HL7oQcY_Ouox~?qlwf%z5B<r?~yYH$s6D
z_*;mmF8sT<c~a@Lp{Hq5$_NcHt_KYGTbL{bm)0YGsu!&p20D0U&MS-ysrpdRgQed*
z+p~C-#X=nQ)GJRUGoMQyb!~nCK_K}boThCT8|7YBN~T{DmT=@vOmh1fp8sj&cJ&lx
z9b_6sGQ29QQ_Voq>*aK{4>vz6KhjtqyG!>w(@Bw08M4%6_h$xG^(XXMWchiYau=0A
z;8}oZ^nG6H&9Pn>@20t_N_Z6>F$jmS<%W<EzXP++26pV7wn&knX$ZmC;CuEa#ZP68
zqf1|X5*f0){W5#hmU}()ADnidui=(IJ%FZ*-{84{mK=U_CZK>hq>E~?PTgPgYoMdq
zFE+%hk|CgMWY~RS+Q=+%<mX9)*oYvFW^V<LqS?ZOLm<|fZFt)KkSZw`Y<_rW1Y0uP
z>q_R#a1o_6k)T^igCDziqC^Lnki1<S{K`w7S2!-%aY^o5+PnIACI-(`<w`86Khg?2
z=~2AUHb>a_b0D9Zmi{yYv+4a8(sB6Bz~jie9BUt+10f}ldv~c_%bqOLXZ(=erG?L3
zEa;Wu#2Bgn0Tw6z3s`Xf8&5|cYyHnP1?qo^1@S*lP!=`crf_s~9}<OywfdypUFKbn
zTfoXe#8Zf$N<?ol*mzqmlNDRMc#YD5>j!PQ7r2k`R*Auo!_IG4+M+T2Asf;IfH9%L
zjyTQ5(RYzgJ3#&UN9F9;$J{sKf-#g}oae6Tx}+1+@GoCeF!jfLS|jtw4yi|M7S(WC
zx1_6%97WzwG}zw^SNeO1D8f>n9`WwL$3KHay}|an_ZNx%5v5q3-Gu3)l#|%Q-gvD-
zX6#a>jChWy%mCDVdy;;ZY-vWN4&L`R8UO`pprf)xej>BConZ7dk<Pr~?auZ=yiJjJ
z-aLINtvT6W!6B6$PFxFgKacbYZ$Ui54fR$N?v09_jtru>?<m*YsQWdgj;5}VQ$n*9
z@@8x*e=dqp!`THlc;B_H&$U+X>*o$;CI`D>4F>gnR|WU-RHyoTBG86T?O1_kf3uCr
zd>u=&Ll$DoVZ_w{AddSKZ)-4Fi+62V7$5CP8Tw4jZjQQEHX|eTfT^;y{blus5*FOz
zy1K}*%TFt%&0sI422*Rai-E+QENk;LLH6}J7Z*sPid|$G1;(zCqYkpxXy&OidTR?^
z?Ih54bf!z&z+}fLv|ToOT!w*+T^0!NadmZ!T&H6(a+j8^B<kSGu1(vS805D1cq(16
zAZQUFjG9yrP)0h#9=H^Rhh|s%4chpCWi`fQCRnTH%OL-VO29z7wK`GcP21?yZq<$b
z{=E#QSY_Z~3gh?pUi%R{YvIrDYF3Ga{0<_smk5}3V>_))Y`Qj6>5R2XMM5AdYBhSg
za;Z*rMt%f93sByh{+UK?RPne(N$4bdfMQ*3T%2pvM@5)QFzPOH-cnX<KIvz^W8VCt
z-`ORTaRT^arZ@$Rw{Q-%4FIq_?tWhNlM6$Ic4A#eMhE+6ILq|ty?a@fO(=$Aho3&F
z4(u4;WEmn`W5JkbD^^5WmX@=aA!@HJX(=lnFb*BB&q7+x#xSDv>l)<&a%PU3hLo5P
z>8&R8PB=@xyQ96oPZM2iCE^kH<L0lVDD741t(`?uQwO5ErM||)yT;>VK(EyAH_&FZ
zHAS-;P>VB+C46*OO6!tt+5u1Mo6D9X>2TLfGlL0+!7(%bnjL~@LV7^|fVap3ssOZ`
zZ>3*PLF&sSgToTrXF}el_!+D&=335Xb^%1p0;m!*JSZk!G-Pk|i4D|AlZG|kJaKxg
zV>Y_`)t-9&Mu6|F^l|R)=5yc&W3~ZZ-PRu*FaAGiBRT?<j9=`0envDcHsYA_bFSUV
z*pi?3l)Jfgm1ch)dua3{=uEGGUVPMXw@Rba<3|*Mc9UlePV~k|Pgj@RA(v5}3CpD!
zSiRi!e2u_fy7ge;(YB3`?AxP;3X`koypAVOlC3nijlPyh--U03Q-O&4qkL~kd?I4i
zoVn2+cBGD|Rr=Q9TGc?>*JbjK7Eoj;<YB^IEFE><v&nw0tjMjO{xMajRqXiTX59i>
zcIgH;W$W7jhp%$T$<6-i>gsSwIDF53tMg*GX~E?w8$&%z#|n{ZW%p2R>De(5@uafG
zfz${-_IUynYX_QDi;VH)S;W~W2Yq;2;8tLXOi`i*B^eFflpUG8=AJs~@#Y#ii92hX
z{SPflGxSkYjhZ8E?nHWpX5=rtRngIOe_j8<qsy!55|etL8)SfY*{**GtflNoGl4gw
z_+p`ZzXyJCRCs*xtxfv@C)vx4{vHNCyAb01@pdFj^SFDkbz0p%dkd~(kP`%pI!S$s
z5w-|OvpJS>*!ehfH3cj2Fe|bbu*SeB1@AU}kv=E8Op-h6es?qUCG5`3lz!jU-0<s<
zmtMRoz7ADT!;xhYuFzAFnRyjxp(zEKgZ+N(-*pZ9@`S&2Yk^CVhc;Z|TQ^g)7SW+8
zS^M#}->RBE@4I6O_CnB*wJKHSm#40c6jLT7>0A4LLK-PB{-0UXH)~c$R33G7I5)2X
z4MybHl13NXQ9|jt)wXBr%feo-rS8-348$%qHBT(b64G<>Sj2|JM}-zVOb`^8b6q3+
zMZT3s&n7!*!_Q)$;RQS^?$>5||5ZY*eerqImu?b6cjT^#e=+7#@bQ-!PT$183%|`I
zx6x|b1!mH$=5oz&19zO;ExYg7Gr&*uxe?#!<M$)=k*^<*lnNT=F7p8uJYsuhyX_wv
zk=#|c;i1JRH#huso%amgb8X&Ap!`$|J|U}$SGf<VRY@wco-e$xcy>pqe&YUkXFe_}
zj&fio(&w1J)LoyX&PcO8Tl~SaB}ZYxSgR3m6@hcJ5#Qv%E_hl&**(wvN(BQY65AVY
z_Z~7YtDfp1i;aDwvx^6d>IyEK5&mI*{<z)0Xco409>-p(cMpa?2_|>ETkTxXV&wv^
zUpWM%SxasCG2qHFo7G+)BJ1hD`C*mX|1J?~Klz_|yf2}M&mM_0EIwSHU_z8a^`_u(
zLiBThWYM2pUPcNp<glpu-e+8g)gZ}Yte7*;uYT}7X2-&A4#)oVGH18~huXeEVkQ^Z
z!wnA6bA{_fkm5E(vsIEkt#`4n)XR_B=crgx9@qG?rQ%E*lso%TIZugpVi2hC7gMwT
zR7plr_UPBRt|`pIc|EGsl?wC9y)9v?A^Ao$I^op=kYY%&uLfU6aX1yPaa;M=si#>8
z(22hF7(NWP=IGx~dwLfEevbfy`2|yXY|2GjG&+O{t>53P4H|_vH{DRoLiJiF_R-nx
zpSB)ijx@s#^C0gF;L@Pa-L}NTJbyWHvYXw3giT|`Ahe{au$Zj#Cc<OowIOJF&{DIf
zO2@UoVV-vVFprQ3pHw)?@->aux)Q?Qv9L8Cw}0fVn;33Q@{rRc%<1QQ&CWYic$wyj
zK%b$_Ah2lsA$u||S&lBwQ*!1>oT4J&;H7q}00rk--^hagc{(WBtZ`e@b@uoNX@+Ls
zNe!9@8NG92>I<YOd+kOqPq+k8U}Jqc)`D@HK@dJ=`fO64HQcg=D|pGb^4j3xf;>6R
z!{8vKi+aTFP&%e08#ho);cOVMg|C^W*Sqdh6Z)tH4SgiY9s?KyC31r%LHZc3n2cA0
z?kV4TXryTR!NT~N`YXlLUd-9kJu+9H<tCEk2#*aSBf}|ksfvuFCl24Q9h*Z6hddtW
zSPy&C6Qr4%mRVgW&T|`4GCLOsT4#%0FCxPbX@F@o6%}JflcpwuOJfEaHR`EB0Yd64
zBe?Yx_ULbPSn!++b~er_%O$*BeGMvZ;w2#yMiBVWMXq{UUo`DkP+XoWKVwvCQsVPL
zePM2(X)C~Xoj{7g-?$RU6rSyG4ru;6eubsm81CG}qD5Sb67|t87)%~-e0ceTS8%wV
zyRMzAE<vesL1S>>cc<-CfX+H&rZR7AvU<@cH3S=!4GRyz772P-qNuycS5`0R%@X?R
z=lt6N{)-s{jW>&1Afa7Js1C4{T_~e-8x{2iyu23>61jvE9GG4_SnbvO*wY+CP67AM
zXzHLry>mau-An-tHnC^+ox1i%$4)DoeswT82HZ5KS-X&9?l6FXW?zUXANQ~+u#EVK
zzceU4=~_0^+Mz=FKxloNVb-fD(h;DH`8cO36czt_v9W!vLw2WQX_BhonCk7jGWFZt
zwt*0Uqu&p;k?=063h^q1sJ2Zmc5FR?SP|WuG8|Vh5iY91@(_${v<Fld5QQ1=)AWDw
zfRx=FV5MF;h!oqV`p?Z^Fh!qrqW$NZXpT7r07Hj7T4@<X1Z=XKW2#-gZPT<8QlY$R
zsobwiEK6$vc5>RX%MpQqZTyX0flT2YCCwa+_bB!=r3O<VbJ|KyMi$oh?i%x-@Piyl
z2git9BszeG7pg0z)#fi_r25n{F)gI<8ZFMq=)1m5r$*_3rlh8tfV+Z-v0dAWV#i5g
zV8ewhKuvFji?Ky>_7uaTj?ix7h_(yBch#i3SUGwq!7$W4WD7=o{k};yGbaTT1dq;$
zfGFW)h&v1-Z-|xo@I}VXO8z?~kIudVcOM=3>A?;VpNLB#Or;=X2Lp&PuL)<)wHN`d
zXhJ=YHR?GX1DHTi)IVm41O6^R#eQ|VpJIxa-yXi@j9bcXEg>0=PqwMU>1+iiwnuL|
zTo}(la4oK;^A2?EV4@bwS?k|Upx{rlq%qJvsa>^cB`>R3G8VAFx>mEMml*e3Q>h_f
zkrh*u;{Q-hLb{9oE1K>~7U<&fdaR5InQ+UtQ<VJg>zc3gl3wWN$M2=4e2?qqQZfkN
zpAKrBzhpm*y1Z_H92wEN_>Z78=>9QYDP-X7heu_%23GO2pLWkY*L}7y5O~sV4%5AF
zBx`0qqny#h-|zcEFPHCpuv=`&dw~;1X)m5T+1#>xwrxE{8@@fHs-foKY?-jeVY3ew
zVJRnu^kOk}wsnSM1cQ;eZT)j{kuov%-<<{f=YAhC?Mbo&srV;aWo%{Xc9>^ayDY2U
z*lP|pFa{fbbz_~2Gzwb!BQe#zvRZx>8a?|ylYUiI<LhmMrp4@V5LX-;sl~MgZXwF|
zMxyTj7Ao%=@bvv^7k!AD!+%f7u(^a=%JR7D8;!VUp>8s<%ZlRoeC<WU&O{zvZpoV1
zYnR9ix6$Hps7n&v)Q&k2k|<fCn5ymk(G4&!E4g|Co6CFc*|}$WXMpd}yUs4F{Jrz%
zLR8=N9(z8G6FZ6kf0MbKLY9y)kZ?azCHeF57m3SfGiE}}HD8CqS-u3+nqEJvTD;jt
zrV>KaFt({eZwJeyJr8x1{ld4Ph;@I+-K&OciP9KpY03h$<?3)B#J*TSEH_C{!}nff
z_TpE65gL)`_xv;(aGyWQFxW;tZb9L(l5W)xW+|Sn<J>h_ZnyNRKhFncF7+zc^Qu4n
z(lw)s<4uyp35-_9H&wz*8OF8kiS?1o4U4y5Rhv52p8jEJ9Sj(Zwn+E=Q7w6+Ev_N@
zz^)5h@+x)BOT&NE1z-|suV1?qt}6+DaOd0;ilYKhFlc(+%z4igi3=;B7+kZathBHG
za&O}?T)27f%ol_WgS#^I^(_+k-n%$G#qChvU3N&)y}6k$ZoT^^k`Zc@EOi(C16rsT
zTX>t_XE}Le?Yf@y=3a5S9$_d_GRU-5jSfM#-BCTM=3Z~Vj;=B@v8;3Lakg&E*Eb)c
z4W<S^`zcF~zrj?(M=r}%``Cx7vL&{GgzaM|0g=^)n(76G@HYTsgPvdE#tlL@n~(wp
zPYruE5*>#FzI=H>^S_vJc|B#<9MP=<((Evnsdn$}d2?B>=~_Yh{oso;erTb$FS$J#
zw!W(VzAlo*z;d8U44z37d+`k?=ek+V91-uWk%^nW3Vl1xZY-WiZhH)~T#B^1sb!HK
z`3LTOjOXCN=3MEiKXmp-_tb;+paTe$t+xwx+5Z7Yq`mG%UndUaF3XA^@b0X9Vb5}j
z@lo(=qG^iw<UW&B?AyXXKJ@K4U9Bf)vq}?s-d?#fV~PGFeVnvUndOxna7<RFbsBx$
zaPZ~ViTl74#5VR1+6p0OeTe0R$Cfp`;Mnu4LsGu@8g*0*LNYUwndqrP@}V>;yrQGL
z7RvqV!T-e-CwTq~SNtb`?3uUmKmRdK{4cQh^RLaE*3`qXp)02ai0Ct468S@7`B(2W
z*o7~i>Iohv+vRd-swrY5Cdt7tBc|}6<Y2(nkss7)se$mO$&v9DD^%<BMPNi#Q8x3&
z(}M*PJHVps>FH=LVQs8}|4S|&lxDm8z#4PLiq+Bw$uY3Yt(>ulksky`@15OmyT?tQ
zvQ`dZMJa0GW+-%9%l?IrAta0NYcYr76LNi5K3%2vlQKS~_PxwA&`5>*?wsSk_lUC&
zk_KOHsdp`Uf5(;>1TH*krgHZD2DOXVgJ<H`y%Y3Qu3M-%_zP|yN$hIffD5lA+hv_!
z><(o|bh@MU@HH=4OZ6ax*u(Gn_7QH2LF)<5n3+N6B-WmNZQK(fIzIRSosIFmIdc%x
z8F#tzrcKe|D~%8{sd+TKlS6#$m1Eer#<<Ol=Y>D));`kQV!<ryBwFsDIM?9Oo@MxE
z|7Z*3`ziUDk~M1cy(sMC$>4*AJ`1>JX6E{ljs8`hxj#OqFnZBl^EK<6Mu*J)SNhCH
z&J#WGamTDzqs^*JJidLy<B%exoIsx*i0R?nPMf>^*0gm%Nd;+VZ#YX&gHw&$X4k;7
zJTsKHN6v7thrE&Vy6q?yDM>%sUDC~!FA?(cYhGKwy(@GJf}?``^p~-+`Qs$?-Kiz!
zEvjNT$jza^UIYaWaDa#0ROsBrha)w~qCg}antj5?K2*)pZ(-2wFH*tkv-M*B#yZuT
zTHdag8h2fHHTAk^bI~>#;!RqQ-T}Fz1DPnSu40nt^(N5GEBogPnM5I|sOG1FfQP3{
zcGQ8U>by0wb;?;01)JqWSo4?)a`C>ZG`J?;fMV9&?`i-DgC<wwrn>tyrktxI>u#*E
z5;QXW)@E#Ua<pZ|eJ=0Msim0eRwX+w678VTPD|Sv<$Kw4I$)Pj!RA&(O`mVgUFKx3
z>E-}`8RH=msie6>jR{(sh6M%8I$jxX2(q#zj!{{ogPD6lUNFXJ=KK65qbhw({WLU)
zI=hTnOuH~et@hJjl@%M5r!I!0q7B1hnrp<u)JgTg)(q<K_JC_=VlG|8Km#6H<v^k+
zV+|HnTgFS5YCHm$UPongq|%_xqgDB^RbBO!sB-dWKsBm~Q+A(aKPk-KU1pB4DdvTE
zUnNL(^JkZ-h{{brpMr=gqx0o{VVwnOSIqMtB9cCrPy@s@roZd<+v;@<7hma?+Rm8H
z2Q~&o$-6jC=?(-eig?FRmBwll+=JKw;HrCXz>QNjCfyu=Kt?aU+r(6>M$Za?#wIm!
z0)QiH2La~PnxMzcSV%<xtxh9ZmcBr#g+%v*R@??$yXIIS(L2nL#{Gsz!x@iSqM4gd
zXZtPTQizi(AAJgwQK-6{tbFU#h3t=+<zq4n{^Z8annAdDuhx$Ft&SWQ>w;YW1;0oF
z{*nY%oj#=o9SllySN4;ZK`|hEbfQJXXL8$OhYjSyg*vG%B8idFlVfD5l&Mu09k!zc
z&DtZFY>%Q8X4l}gUW0GSVDAQgEROb!tg)c_qkTjN+Wow#?1d=J^#!xcuC<noy}M*R
zuuJwe+M~pVpw=!J`0E3mS&slvTDe1VzblN~0FrTN^)iaQv1$lQsju<_2lPsfjPE~~
z2o!!oRU85&c6x+!eiv+Lw#L*~eK4?FzBR2J{P1QoxA=F)Nxu}<Ly=GCUj2+U`EQ{#
z_??@g`<y#jN!<7{&j-K}C4FWrGKOo&Vs@b?J(%&~x}Y-0<XD4XH7j=Gmqp&pxkt~7
z7lwD%>82w#39@}Y+^q}GnzmXREsenAB45S1WX$h->Hv=nJXm-{J@z!_>VspE5iFm{
zH{^4l9;`oIn7hn)TCjsQNi~Q($c;xS1Gmu++;~dc?o{^P64AUrQ<8f^!ymm$N5A;v
z)M&W`KJTi4ZqKp0&)S?<l(;qSAZYyjID6JS!k)sf%%sSCBQWV*W28Iz<xkn|$A{_Y
z+wzL%p5D#4%Ra-6mpT4zPs82@aobJRJNH|L^Kw-&KX*-b{<fv#usLzKJLz;j7+?Hd
zXemI?=(gkgcg;<7@(rAlNuF?L5tsY9XUBuM753!JCmt6241bHfrLeHG%N1hi;!XK6
z+U?g8sk&qUR?m+j+&*${cTXg4Lo$<HR{SxL9>zI7AF8#D243KQ2!odupZxAin71i~
z-wyN?+!n-T9n=Ynd6pmiBA*L7{CCTK_=Fg^<$L^!X=aH2m7c`eKkFM~%eQMABN%~C
zNRcKd-P;^bMhz(sB7hvok7$@z8WR7H2Zm5XIrS|sW%uRzK+<9D+;KI}*B>v6cb!0Y
ze*JA+Hey$(Tdbu!(-W}{i&<%w!X`9&{k?Em`3yrzhey>0rWSEIZ@nuaK?$fD&5w7&
z0J7l0f|tz*6c_X`4?1()qt|2Y#TVbJB~f@E#<|_@^M8JD2_%@l{<59;YzFd+tpOdm
zVasRTc>YW2C_usX(7O%kWJ`TvkP*|p^IhmqVhFW5;%~_ew2TpeCMfuRaI&eYU9^63
zwp>3rf%hxyYqx&zu<jOhS@wrx+tt^sV-i+;U9HO1e^_&-{pS*|YMfhJ)cs4?jN4XG
z@7s5`xe#mT(3!T*JaliKGfuatBE06W{+4@F=jlzL#z1Ig$g;Y=<lD&Zo>_{Xy6JSh
zC`;>*eDI3D`=7$?G>XDGI8{b30wQEbCs`$>tl4)%h{jh!SqX2Hr^h-Z@61nI^l=Gv
z6?#-z9XlthBX-4(63=hV`Myct*;|Vr@pa4lg4>RL378R;ZKdDpnF(i}y!!I81qQl`
z7Op?0qFucmL{G(P!0D9KbC5FY2lL<%tFz*~+A!gsSGy)%@55G|UY>f?m)aQ59U>eo
zp`KMgo$kMS2-k-fyIsgTP&QGfD^Cw@@HHLr4BNh_MSZ0xmV5g-^CEEY=pWr#yFP(k
zW)TM;(Y6`tJVchM4z5a>{wDgq<JCS@?Lwaiah2HjP#SW90!a(m_XzSs{^AK))ZP82
zuHrcR#?o5zee!9sKg7tU4N#ZtSB-(A4=<X=>=Wa{M5=Oz4N56GFRa*|fG21Mi$&VB
zxX|)SZnkZB^2fzKcqonCki6MbHU7qv`4J+c;wuZuI4v%Fuim}w-_gRY$J|?I^g&v>
zus*}uwigyY4aYE>O}15=vQdvb3Sd8gZE@(De&qgS75M!>u{msdv}6C=nz0g038PLz
z!~QlM*%K041|jkekvC}lNOuL4$}(x?@T<@FgBZ?)&LX!*e~S(0ry#|Y!~d#Kj02~|
zHLS6sy!H<0=(RFFPBel-d%}9%wJuf7rXRa;eP%6YL>S?F$tW2QULXn(OCIqkQIEG_
z+q6HaY(R=Q#K0wDscI+qQ2W&GfgDPD45&XOd7R(F?~kKoIS@Ozx6!5aiCK*GCOpuF
zx`Z1>d)z;o*U`eE_Ixl5-c||C&Ia!R);6NgtQ2>k??f<aNMtO9(`mb3b*b^^f}TVH
zKK2#E6~gA^+M1`3a$5mxIIYurmQF^=x6WhNVD8{2C=zuZp0Ose!JLRtx?1c`%rbCL
zrU~bD&J=o}Ld;b2%xySK1EH@Q8z_l|1uAKQ@_pRvyeWzsuBCM&6xhSHx3DG3(>Qsv
zKy+z(o&mgDr3*~H2SMaT+nThym=_BK&AMks5_Oy3fE}d<*^w2SdKv}{RC(16FK`=`
z1dQ!WEAD+Iusj^294uP(w9a*~r+d^f8dTk!PsKcu*C<macsW<S%T%F7qyYwWf6Rj;
zGqEw(!;{J$Lh|EkFbXrv)flqn3c_?%eYIlI-+`t%GCvZMrxsd`M{4Z*X_o=Ekqf`w
z>s0hf@@N9SK(k%}1Ok5|V$kS*P(NUeSp`7|QrW>f7|wLY%{B<kb-12VHw*e(XM%5#
zCPs~#JcQQy*hyF^?6Bt>Pep}3)rZGgu~h6e1qhYNxC&I~JDfDCLK(v{Z40A$r`!i*
zxI?$d2u$d*X5`MuW6jSrZKE--!ZN?v&BnhcOxS)MQ&ViHsx={eHdIK}2ztJBq`OYK
z$j^GUba`=$Uh1wR7g004fTq44pP~e_t0q>P?r#eu$wT__;_ch46>!AtY8BB>cG$1B
ze{2}A8QwYt(jA#{!3vJpTpS(FobE1=)(UXojE@x2ZFB&&oJL01Bxsdb7TupqXgBL_
z)|vy!sYV+b%i(~;9#!Wn2ch6fVoU9u-D2a<G_BfDT4l3zRdw!qY726o-Z%yFUvO<6
zl}3<Tr<jvF%}q5HSneDeNL|~t8Q#o55v@(hAO>srnuO-W(&u;KqxOhV7l%#-mnCG>
z+?XF?B#-KPqp)+4@S9=}rbhp&&={>g&;_fln$ZF21Y)+Kh+Lag#ZF&ECg5TwD0ZuH
zw9FMCzw`GV5=yRNyZc3%@5H15R;+Y)Dd9Uv5T&8*jb8gG7}S<BXtpRy2Y9W4EI14_
za|T?OKYVk!vml^!lQm3sLV;Z(-mE+A?!0M1n=aM>2q`|o+cmS`v8VE^rf%A4A54fw
zNA)<A(P@$BzqeG5l79BmycEB<nsPOI*hhmfR{7%Gx$ha58n9$ETHL?+$%}rz_N#O=
z#W*8N`V2H$^g?f&X7%VD_x=*h=?hmU0y0I%5=3SdP9@TikGM+^=eHij7Rz?WKL7u9
zjlrMesI+^R6P;u)bB;;4lieiG1+W``xp|(sNGv!X@AUlS-y`({PZm_Q|9LrZcRKfK
zQHtPUohvxL`1miC6N%TKfg@uIbv#p*3!g9WKA~F_+!cv@^M{Ka8y@T-w)ZVdPPz|=
z@@Vo5U-~T=z1CO)gXJyi9C#z%>qYawSg!x33RQpB>5+6DP!qDt8l8%gUa0X7eb%?!
z21cL}eNa(IW2jD_A8*R-AFu=HFFRETU85s$3NO-KJk2KriKR~H(OcA4CF$)xD%N+7
z+>RhvkNE6$!8dZRoXa)L4_K&J*l`~mX7LR~+kxFhG}ksoJdNjXvv|p4RImQ>P=7D=
zpmUd9pvS+287#(H^Ak$r`5p6A&d%sn$j0xX{u*v~ax|uT`frKP?h6Difqaq-LicDl
zPw`pJT={$Xd^ki})3nGiY+LBBdG!^$_n(hxD7RkT-IU<Nj#Gh5d>s~9hfID(PEUXx
zSA|V(sQcu-E{?a;<`apaAMk8=MtSqV1@=I7CTq`i^i15J8DtKfw-E3{vhNH`NKP!L
zKZf*MNuU*f9~kdf#EbX-@-W$OjyhkvOO}i&a^6fWs!d~=u)XIq+OtCL5a?VdBcxlD
zY5c!wQ8YE6gz@<Fl7@Oo8h~!0DijFa%GVsh$a=1C4u8IZ9E1?|s9JA?eZIrXgXSi-
zgrMsw3AOL;an%&;jG=i$M1(-<(Os0lK+jUaC%I<fLlIGpj!GS63g_pX5*ni_;$|j=
zoM8Jek8%E9JC$zj!vu*rZ|1-2c!6EjW{HFn6`-}BSR>b0*L#AktlmJGhd}jtt*awu
z(R=P+uB-W7Mciq}EEd0(o@~(7>Mx_L(trF|F-W}2w~aPS4igCSoH6CH!ySf^M^;br
zE7v};k}X@ny`F<lv^hy;n5AEgZbWiq%JyEHh}=xyslpAetO$}@<ccTFenFM;dswvd
b3319{?)f`EH^5kUhA>sh?BveV1f~B2`qzoq
--- a/content/media/video/test/Makefile.in
+++ b/content/media/video/test/Makefile.in
@@ -47,13 +47,15 @@ include $(topsrcdir)/config/rules.mk
                 test_constants.html \
                 test_controls.html \
                 test_currentTime.html \
                 test_defaultPlaybackRate.html \
                 test_networkState.html \
                 test_paused.html \
                 test_playbackRate.html \
                 test_readyState.html \
-		test_start.html \
-		$(NULL)
+                test_start.html \
+#               test_bug448534.html \
+                320x240.ogg \
+                $(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/content/media/video/test/test_bug448534.html
@@ -0,0 +1,51 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=448534
+-->
+
+<head>
+  <title>Test for Bug 448534</title>
+  <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=448535">Mozilla Bug 448534</a>
+<!-- Ogg video obtained from Theora test suite: http://v2v.cc/~j/theora_testsuite/ -->
+<video id='v' 
+       src='320x240.ogg' 
+       onplay='return started();' 
+       onpause='return stopped();'></video>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+var v = $('v');
+var played = false;
+var passed = false;
+function started() {
+  ok(!v.paused, "Video should not be paused while playing");
+  v.parentNode.removeChild(v);
+  played = true;
+  return false;
+}
+
+function stopped() {
+  ok(v.paused, "Video should be paused after removing from the Document");
+  passed = true;
+  return false;
+}
+
+setTimeout(function () {
+             ok(played, "Video did not send play event");
+             ok(passed, "Video was not paused when removed from the Document");
+             SimpleTest.finish();
+             return false;
+           }, 6000); 
+
+v.play();
+
+SimpleTest.waitForExplicitFinish();
+</script>
+</pre>
+</body>
+</html>
--- a/content/svg/content/src/nsSVGAElement.cpp
+++ b/content/svg/content/src/nsSVGAElement.cpp
@@ -251,35 +251,31 @@ nsSVGAElement::IsLink(nsIURI** aURI) con
       FindAttrValueIn(kNameSpaceID_XLink, nsGkAtoms::show,
                       sShowVals, eCaseMatters) !=
                       nsIContent::ATTR_VALUE_NO_MATCH &&
       FindAttrValueIn(kNameSpaceID_XLink, nsGkAtoms::actuate,
                       sActuateVals, eCaseMatters) !=
                       nsIContent::ATTR_VALUE_NO_MATCH) {
     nsCOMPtr<nsIURI> baseURI = GetBaseURI();
     // Get absolute URI
-    // XXX: should really be using href->GetStringValue(), but nsSVGElement::
-    // ParseAttribute has set the nsAttrValue type to eSVGValue, so we need
-    // to use the more expensive ToString (generates, rather than fetches).
-    nsAutoString hrefStr;
-    href->ToString(hrefStr);
-    nsContentUtils::NewURIWithDocumentCharset(aURI, hrefStr,
+    nsContentUtils::NewURIWithDocumentCharset(aURI,
+                                              mStringAttributes[HREF].GetAnimValue(),
                                               GetOwnerDoc(), baseURI);
     // must promise out param is non-null if we return true
     return !!*aURI;
   }
 
   *aURI = nsnull;
   return PR_FALSE;
 }
 
 void
 nsSVGAElement::GetLinkTarget(nsAString& aTarget)
 {
-  GetAttr(kNameSpaceID_None, nsGkAtoms::target, aTarget);
+  aTarget = mStringAttributes[TARGET].GetAnimValue();
   if (aTarget.IsEmpty()) {
 
     static nsIContent::AttrValuesArray sShowVals[] =
       { &nsGkAtoms::_new, &nsGkAtoms::replace, nsnull };
 
     switch (FindAttrValueIn(kNameSpaceID_XLink, nsGkAtoms::show,
                             sShowVals, eCaseMatters)) {
     case 0:
--- a/content/svg/content/src/nsSVGElement.cpp
+++ b/content/svg/content/src/nsSVGElement.cpp
@@ -636,16 +636,34 @@ nsSVGElement::ResetOldStyleBaseType(nsIS
   nsCOMPtr<nsIDOMSVGAnimatedTransformList> tl = do_QueryInterface(svg_value);
   if (tl) {
     nsCOMPtr<nsIDOMSVGTransformList> transform;
     tl->GetBaseVal(getter_AddRefs(transform));
     transform->Clear();
   }
 }
 
+nsChangeHint
+nsSVGElement::GetAttributeChangeHint(const nsIAtom* aAttribute,
+                                     PRInt32 aModType) const
+{
+  nsChangeHint retval =
+    nsSVGElementBase::GetAttributeChangeHint(aAttribute, aModType);
+
+  if (aAttribute == nsGkAtoms::requiredFeatures ||
+      aAttribute == nsGkAtoms::requiredExtensions ||
+      aAttribute == nsGkAtoms::systemLanguage) {
+    // It would be nice to only reconstruct the frame if the value returned by
+    // NS_SVG_PassesConditionalProcessingTests has changed, but we don't know
+    // that
+    NS_UpdateHint(retval, nsChangeHint_ReconstructFrame);
+  }
+  return retval;
+}
+
 PRBool
 nsSVGElement::IsNodeOfType(PRUint32 aFlags) const
 {
   return !(aFlags & ~(eCONTENT | eELEMENT | eSVG));
 }
 
 already_AddRefed<nsIURI>
 nsSVGElement::GetBaseURI() const
--- a/content/svg/content/src/nsSVGElement.h
+++ b/content/svg/content/src/nsSVGElement.h
@@ -82,16 +82,19 @@ public:
 
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               PRBool aCompileEventHandlers);
 
   virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
                              PRBool aNotify);
 
+  virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
+                                              PRInt32 aModType) const;
+
   virtual PRBool IsNodeOfType(PRUint32 aFlags) const;
 
   virtual already_AddRefed<nsIURI> GetBaseURI() const;
 
   NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker);
 
   static const MappedAttributeEntry sFillStrokeMap[];
   static const MappedAttributeEntry sGraphicsMap[];
--- a/content/svg/content/src/nsSVGFeatures.cpp
+++ b/content/svg/content/src/nsSVGFeatures.cpp
@@ -184,16 +184,20 @@ ElementSupportsAttributes(const nsIAtom 
  * and are specified on the given element. Returns true if this element
  * should be rendered, false if it should not.
  *
  * @param aContent the element to test
  */
 PRBool
 NS_SVG_PassesConditionalProcessingTests(nsIContent *aContent)
 {
+  if (!aContent->IsNodeOfType(nsINode::eELEMENT)) {
+    return PR_FALSE;
+  }
+
   if (!ElementSupportsAttributes(aContent->Tag(), ATTRS_CONDITIONAL)) {
     return PR_TRUE;
   }
 
   // Required Features
   nsAutoString value;
   if (aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::requiredFeatures, value)) {
     if (value.IsEmpty() || !HaveFeatures(value)) {
--- a/content/svg/content/src/nsSVGFilters.cpp
+++ b/content/svg/content/src/nsSVGFilters.cpp
@@ -58,16 +58,17 @@
 #include "nsIFrame.h"
 #include "gfxContext.h"
 #include "nsSVGLengthList.h"
 #include "nsIDOMSVGURIReference.h"
 #include "nsImageLoadingContent.h"
 #include "imgIContainer.h"
 #include "gfxIImageFrame.h"
 #include "nsIImage.h"
+#include "nsNetUtil.h"
 #include "nsSVGAnimatedPreserveAspectRatio.h"
 #include "nsSVGPreserveAspectRatio.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsSVGMatrix.h"
 #include "nsSVGFilterElement.h"
 #include "nsSVGString.h"
 
 #if defined(XP_WIN)
@@ -5189,21 +5190,22 @@ public:
   NS_DECL_NSIDOMSVGFEIMAGEELEMENT
   NS_DECL_NSIDOMSVGURIREFERENCE
 
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGFEImageElementBase::)
 
   NS_FORWARD_NSIDOMNODE(nsSVGFEImageElementBase::)
   NS_FORWARD_NSIDOMELEMENT(nsSVGFEImageElementBase::)
 
+  // nsSVGElement
+  virtual void DidChangeString(PRUint8 aAttrEnum, PRBool aDoSetAttr);
+
+  // nsIContent
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
-  virtual nsresult AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
-                                const nsAString* aValue, PRBool aNotify);
-
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               PRBool aCompileEventHandlers);
   virtual PRInt32 IntrinsicState() const;
 
   // imgIDecoderObserver
   NS_IMETHOD OnStopDecode(imgIRequest *aRequest, nsresult status,
                           const PRUnichar *statusArg);
@@ -5213,16 +5215,18 @@ public:
   // imgIContainerObserver
   NS_IMETHOD OnStartContainer(imgIRequest *aRequest,
                               imgIContainer *aContainer);
 
 private:
   // Invalidate users of the filter containing this element.
   void Invalidate();
 
+  nsresult LoadSVGImage(PRBool aForce, PRBool aNotify);
+
 protected:
   virtual PRBool OperatesOnSRGB(nsSVGFilterInstance*,
                                 PRUint32, Image*) { return PR_TRUE; }
 
   virtual StringAttributesInfo GetStringInfo();
 
   enum { RESULT, HREF };
   nsSVGString mStringAttributes[2];
@@ -5288,53 +5292,50 @@ nsSVGFEImageElement::Init()
                            mPreserveAspectRatio);
     NS_ENSURE_SUCCESS(rv,rv);
   }
 
   return rv;
 }
 
 //----------------------------------------------------------------------
-// nsIContent methods:
 
 nsresult
-nsSVGFEImageElement::AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
-                                  const nsAString* aValue, PRBool aNotify)
-{
-  if (aNamespaceID == kNameSpaceID_XLink && aName == nsGkAtoms::href) {
-    nsAutoString href;
-    if (GetAttr(kNameSpaceID_XLink, nsGkAtoms::href, href)) {
-      // Note: no need to notify here; since we're just now being bound
-      // we don't have any frames or anything yet.
-      LoadImage(href, PR_FALSE, PR_FALSE);
-    }
-  }
-
-  return nsSVGFEImageElementBase::AfterSetAttr(aNamespaceID, aName,
-                                               aValue, aNotify);
-}
+nsSVGFEImageElement::LoadSVGImage(PRBool aForce, PRBool aNotify)
+{
+  // resolve href attribute
+  nsCOMPtr<nsIURI> baseURI = GetBaseURI();
+
+  nsAutoString href(mStringAttributes[HREF].GetAnimValue());
+  href.Trim(" \t\n\r");
+
+  if (baseURI && !href.IsEmpty())
+    NS_MakeAbsoluteURI(href, href, baseURI);
+
+  return LoadImage(href, aForce, aNotify);
+}
+
+//----------------------------------------------------------------------
+// nsIContent methods:
 
 nsresult
 nsSVGFEImageElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                                 nsIContent* aBindingParent,
                                 PRBool aCompileEventHandlers)
 {
   nsresult rv = nsSVGFEImageElementBase::BindToTree(aDocument, aParent,
                                                     aBindingParent,
                                                     aCompileEventHandlers);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Our base URI may have changed; claim that our URI changed, and the
   // nsImageLoadingContent will decide whether a new image load is warranted.
-  nsAutoString href;
-  if (GetAttr(kNameSpaceID_XLink, nsGkAtoms::href, href)) {
-    // Note: no need to notify here; since we're just now being bound
-    // we don't have any frames or anything yet.
-    LoadImage(href, PR_FALSE, PR_FALSE);
-  }
+  // Note: no need to notify here; since we're just now being bound
+  // we don't have any frames or anything yet.
+  LoadSVGImage(PR_FALSE, PR_FALSE);
 
   return rv;
 }
 
 PRInt32
 nsSVGFEImageElement::IntrinsicState() const
 {
   return nsSVGFEImageElementBase::IntrinsicState() |
@@ -5428,16 +5429,26 @@ nsSVGFEImageElement::ComputeTargetBBox(c
 
 nsSVGElement::StringAttributesInfo
 nsSVGFEImageElement::GetStringInfo()
 {
   return StringAttributesInfo(mStringAttributes, sStringInfo,
                               NS_ARRAY_LENGTH(sStringInfo));
 }
 
+void
+nsSVGFEImageElement::DidChangeString(PRUint8 aAttrEnum, PRBool aDoSetAttr)
+{
+  nsSVGFEImageElementBase::DidChangeString(aAttrEnum, aDoSetAttr);
+
+  if (aAttrEnum == HREF) {
+    LoadSVGImage(PR_TRUE, PR_TRUE);
+  }
+}
+
 //----------------------------------------------------------------------
 // imgIDecoderObserver methods
 
 NS_IMETHODIMP
 nsSVGFEImageElement::OnStopDecode(imgIRequest *aRequest,
                                   nsresult status,
                                   const PRUnichar *statusArg)
 {
@@ -5650,18 +5661,16 @@ nsSVGFEDisplacementMapElement::Filter(ns
 #endif
 
   float scale = mNumberAttributes[SCALE].GetAnimValue();
   if (scale == 0.0f) {
     CopyRect(aTarget, aSources[0], rect);
     return NS_OK;
   }
 
-  NS_ASSERTION(instance->GetSurfaceRect().Size() == instance->GetFilterSpaceSize(),
-               "Surface size optimization should have been disabled, see ComputeNeededSourceBBoxes");
   PRInt32 width = instance->GetSurfaceWidth();
   PRInt32 height = instance->GetSurfaceHeight();
 
   PRUint8* sourceData = aSources[0]->mImage->Data();
   PRUint8* displacementData = aSources[1]->mImage->Data();
   PRUint8* targetData = aTarget->mImage->Data();
   PRUint32 stride = aTarget->mImage->Stride();
 
--- a/content/svg/content/src/nsSVGImageElement.cpp
+++ b/content/svg/content/src/nsSVGImageElement.cpp
@@ -94,17 +94,17 @@ public:
   NS_IMETHODIMP_(PRBool) IsAttributeMapped(const nsIAtom* name) const;
 
   // nsSVGPathGeometryElement methods:
   virtual void ConstructPath(gfxContext *aCtx);
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
 protected:
-  void GetSrc(nsAString& src);
+  nsresult LoadSVGImage(PRBool aForce, PRBool aNotify);
 
   virtual LengthAttributesInfo GetLengthInfo();
   virtual StringAttributesInfo GetStringInfo();
 
   enum { X, Y, WIDTH, HEIGHT };
   nsSVGLength2 mLengthAttributes[4];
   static LengthInfo sLengthInfo[4];
 
@@ -250,49 +250,42 @@ nsSVGImageElement::GetLengthInfo()
 }
 
 void
 nsSVGImageElement::DidChangeString(PRUint8 aAttrEnum, PRBool aDoSetAttr)
 {
   nsSVGImageElementBase::DidChangeString(aAttrEnum, aDoSetAttr);
 
   if (aAttrEnum == HREF) {
-    nsAutoString href;
-    GetSrc(href);
-
-#ifdef DEBUG_tor
-    fprintf(stderr, "nsSVGImageElement - URI <%s>\n", ToNewCString(href));
-#endif
-
     // If caller is not chrome and dom.disable_image_src_set is true,
     // prevent setting image.src by exiting early
     if (nsContentUtils::GetBoolPref("dom.disable_image_src_set") &&
         !nsContentUtils::IsCallerChrome()) {
       return;
     }
 
-    LoadImage(href, PR_TRUE, PR_TRUE);
+    LoadSVGImage(PR_TRUE, PR_TRUE);
   }
 }
 
 //----------------------------------------------------------------------
 
-void nsSVGImageElement::GetSrc(nsAString& src)
+nsresult
+nsSVGImageElement::LoadSVGImage(PRBool aForce, PRBool aNotify)
 {
   // resolve href attribute
-
   nsCOMPtr<nsIURI> baseURI = GetBaseURI();
 
-  nsAutoString relURIStr(mStringAttributes[HREF].GetAnimValue());
-  relURIStr.Trim(" \t\n\r");
+  nsAutoString href(mStringAttributes[HREF].GetAnimValue());
+  href.Trim(" \t\n\r");
 
-  if (baseURI && !relURIStr.IsEmpty()) 
-    NS_MakeAbsoluteURI(src, relURIStr, baseURI);
-  else
-    src = relURIStr;
+  if (baseURI && !href.IsEmpty())
+    NS_MakeAbsoluteURI(href, href, baseURI);
+
+  return LoadImage(href, aForce, aNotify);
 }
 
 //----------------------------------------------------------------------
 // nsIContent methods:
 
 nsresult
 nsSVGImageElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
@@ -300,22 +293,19 @@ nsSVGImageElement::BindToTree(nsIDocumen
 {
   nsresult rv = nsSVGImageElementBase::BindToTree(aDocument, aParent,
                                                   aBindingParent,
                                                   aCompileEventHandlers);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Our base URI may have changed; claim that our URI changed, and the
   // nsImageLoadingContent will decide whether a new image load is warranted.
-  nsAutoString href;
-  if (GetAttr(kNameSpaceID_XLink, nsGkAtoms::href, href)) {
-    // Note: no need to notify here; since we're just now being bound
-    // we don't have any frames or anything yet.
-    LoadImage(href, PR_FALSE, PR_FALSE);
-  }
+  // Note: no need to notify here; since we're just now being bound
+  // we don't have any frames or anything yet.
+  LoadSVGImage(PR_FALSE, PR_FALSE);
 
   return rv;
 }
 
 PRInt32
 nsSVGImageElement::IntrinsicState() const
 {
   return nsSVGImageElementBase::IntrinsicState() |
--- a/content/svg/content/src/nsSVGScriptElement.cpp
+++ b/content/svg/content/src/nsSVGScriptElement.cpp
@@ -73,17 +73,18 @@ public:
   NS_FORWARD_NSIDOMNODE(nsSVGScriptElementBase::)
   NS_FORWARD_NSIDOMELEMENT(nsSVGScriptElementBase::)
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGScriptElementBase::)
 
   // nsIScriptElement
   virtual void GetScriptType(nsAString& type);
   virtual already_AddRefed<nsIURI> GetScriptURI();
   virtual void GetScriptText(nsAString& text);
-  virtual void GetScriptCharset(nsAString& charset); 
+  virtual void GetScriptCharset(nsAString& charset);
+  virtual PRBool GetScriptDeferred();
 
   // nsScriptElement
   virtual PRBool HasScriptContent();
 
   // nsSVGElement specializations:
   virtual void DidChangeString(PRUint8 aAttrEnum, PRBool aDoSetAttr);
 
   // nsIContent specializations:
@@ -207,16 +208,22 @@ nsSVGScriptElement::GetScriptText(nsAStr
 }
 
 void
 nsSVGScriptElement::GetScriptCharset(nsAString& charset)
 {
   charset.Truncate();
 }
 
+PRBool
+nsSVGScriptElement::GetScriptDeferred()
+{
+  return PR_FALSE;
+}
+
 //----------------------------------------------------------------------
 // nsScriptElement methods
 
 PRBool
 nsSVGScriptElement::HasScriptContent()
 {
   return !mStringAttributes[HREF].GetAnimValue().IsEmpty() ||
          nsContentUtils::HasNonEmptyTextContent(this);
--- a/content/svg/content/src/nsSVGSwitchElement.cpp
+++ b/content/svg/content/src/nsSVGSwitchElement.cpp
@@ -76,18 +76,17 @@ nsSVGSwitchElement::MaybeInvalidate()
 {
   // We don't reuse UpdateActiveChild() and check if mActiveChild has changed
   // to determine if we should call nsSVGUtils::UpdateGraphic. If we did that,
   // nsSVGUtils::UpdateGraphic would not invalidate the old mActiveChild area!
 
   PRUint32 count = GetChildCount();
   for (PRUint32 i = 0; i < count; i++) {
     nsIContent * child = GetChildAt(i);
-    if (child->IsNodeOfType(nsINode::eELEMENT) &&
-        NS_SVG_PassesConditionalProcessingTests(child)) {
+    if (NS_SVG_PassesConditionalProcessingTests(child)) {
 
       if (mActiveChild == child) {
         return;
       }
 
       nsIFrame *frame = GetPrimaryFrame();
       if (frame) {
         nsISVGChildFrame* svgFrame = nsnull;
@@ -103,18 +102,17 @@ nsSVGSwitchElement::MaybeInvalidate()
 }
 
 void
 nsSVGSwitchElement::UpdateActiveChild()
 {
   PRUint32 count = GetChildCount();
   for (PRUint32 i = 0; i < count; i++) {
     nsIContent * child = GetChildAt(i);
-    if (child->IsNodeOfType(nsINode::eELEMENT) &&
-        NS_SVG_PassesConditionalProcessingTests(child)) {
+    if (NS_SVG_PassesConditionalProcessingTests(child)) {
       mActiveChild = child;
       return;
     }
   }
   mActiveChild = nsnull;
 }
 
 //----------------------------------------------------------------------
--- a/content/xbl/public/nsIXBLService.h
+++ b/content/xbl/public/nsIXBLService.h
@@ -53,18 +53,18 @@ class nsPIDOMEventTarget;
 class nsIDOMNodeList;
 class nsXBLBinding;
 class nsIXBLDocumentInfo;
 class nsIURI;
 class nsIAtom;
 class nsIPrincipal;
 
 #define NS_IXBLSERVICE_IID      \
-{ 0x98b28f4e, 0x698f, 0x4f77,   \
- { 0xa8, 0x9e, 0x65, 0xf5, 0xd0, 0xde, 0x6a, 0xbf } }
+{ 0x8d3b37f5, 0xde7e, 0x4595,   \
+ { 0xb8, 0x56, 0xf7, 0x11, 0xe8, 0xe7, 0xb5, 0x59 } }
 
 class nsIXBLService : public nsISupports
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IXBLSERVICE_IID)
 
   // This function loads a particular XBL file and installs all of the bindings
   // onto the element.  aOriginPrincipal must not be null here.
@@ -85,14 +85,15 @@ public:
                                      nsIDocument* aBoundDocument,
                                      nsIURI* aBindingURI,
                                      nsIPrincipal* aOriginPrincipal,
                                      PRBool aForceSyncLoad,
                                      nsIXBLDocumentInfo** aResult) = 0;
 
   // Hooks up the global key event handlers to the document root.
   NS_IMETHOD AttachGlobalKeyHandler(nsPIDOMEventTarget* aTarget)=0;
+  NS_IMETHOD DetachGlobalKeyHandler(nsPIDOMEventTarget* aTarget)=0;
   
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIXBLService, NS_IXBLSERVICE_IID)
 
 #endif // nsIXBLService_h__
--- a/content/xbl/src/nsXBLService.cpp
+++ b/content/xbl/src/nsXBLService.cpp
@@ -694,16 +694,20 @@ nsXBLService::AttachGlobalKeyHandler(nsP
     // Only attach if we're really in a document
     nsCOMPtr<nsIDocument> doc = contentNode->GetCurrentDoc();
     if (doc)
       piTarget = do_QueryInterface(doc); // We're a XUL keyset. Attach to our document.
   }
     
   if (!piTarget)
     return NS_ERROR_FAILURE;
+
+  // the listener already exists, so skip this
+  if (contentNode && contentNode->GetProperty(nsGkAtoms::listener))
+    return NS_OK;
     
   nsCOMPtr<nsIDOMElement> elt(do_QueryInterface(contentNode));
 
   // Create the key handler
   nsXBLWindowKeyHandler* handler;
   NS_NewXBLWindowKeyHandler(elt, piTarget, &handler); // This addRef's
   if (!handler)
     return NS_ERROR_FAILURE;
@@ -715,18 +719,63 @@ nsXBLService::AttachGlobalKeyHandler(nsP
 
   target->AddGroupedEventListener(NS_LITERAL_STRING("keydown"), handler,
                                   PR_FALSE, systemGroup);
   target->AddGroupedEventListener(NS_LITERAL_STRING("keyup"), handler, 
                                   PR_FALSE, systemGroup);
   target->AddGroupedEventListener(NS_LITERAL_STRING("keypress"), handler, 
                                   PR_FALSE, systemGroup);
 
-  // Release.  Do this so that only the event receiver holds onto the key handler.
+  if (contentNode)
+    return contentNode->SetProperty(nsGkAtoms::listener, handler,
+                                    nsPropertyTable::SupportsDtorFunc, PR_TRUE);
+
+  // release the handler. The reference will be maintained by the event target,
+  // and, if there is a content node, the property.
   NS_RELEASE(handler);
+  return NS_OK;
+}
+
+//
+// DetachGlobalKeyHandler
+//
+// Removes a key handler added by DeatchGlobalKeyHandler.
+//
+NS_IMETHODIMP
+nsXBLService::DetachGlobalKeyHandler(nsPIDOMEventTarget* aTarget)
+{
+  nsCOMPtr<nsPIDOMEventTarget> piTarget = aTarget;
+  nsCOMPtr<nsIContent> contentNode(do_QueryInterface(aTarget));
+  if (!contentNode) // detaching is only supported for content nodes
+    return NS_ERROR_FAILURE;
+
+  // Only attach if we're really in a document
+  nsCOMPtr<nsIDocument> doc = contentNode->GetCurrentDoc();
+  if (doc)
+    piTarget = do_QueryInterface(doc);
+  if (!piTarget)
+    return NS_ERROR_FAILURE;
+
+  nsIDOMEventListener* handler =
+    static_cast<nsIDOMEventListener*>(contentNode->GetProperty(nsGkAtoms::listener));
+  if (!handler)
+    return NS_ERROR_FAILURE;
+
+  nsCOMPtr<nsIDOMEventGroup> systemGroup;
+  piTarget->GetSystemEventGroup(getter_AddRefs(systemGroup));
+  nsCOMPtr<nsIDOM3EventTarget> target = do_QueryInterface(piTarget);
+
+  target->RemoveGroupedEventListener(NS_LITERAL_STRING("keydown"), handler,
+                                     PR_FALSE, systemGroup);
+  target->RemoveGroupedEventListener(NS_LITERAL_STRING("keyup"), handler, 
+                                     PR_FALSE, systemGroup);
+  target->RemoveGroupedEventListener(NS_LITERAL_STRING("keypress"), handler, 
+                                     PR_FALSE, systemGroup);
+
+  contentNode->DeleteProperty(nsGkAtoms::listener);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXBLService::Observe(nsISupports* aSubject, const char* aTopic, const PRUnichar* aSomeData)
 {
   if (nsCRT::strcmp(aTopic, "memory-pressure") == 0)
--- a/content/xbl/src/nsXBLService.h
+++ b/content/xbl/src/nsXBLService.h
@@ -83,16 +83,17 @@ class nsXBLService : public nsIXBLServic
                                      nsIDocument* aBoundDocument,
                                      nsIURI* aBindingURI,
                                      nsIPrincipal* aOriginPrincipal,
                                      PRBool aForceSyncLoad,
                                      nsIXBLDocumentInfo** aResult);
 
   // Used by XUL key bindings and for window XBL.
   NS_IMETHOD AttachGlobalKeyHandler(nsPIDOMEventTarget* aTarget);
+  NS_IMETHOD DetachGlobalKeyHandler(nsPIDOMEventTarget* aTarget);
 
   NS_DECL_NSIOBSERVER
 
 public:
   nsXBLService();
   virtual ~nsXBLService();
 
 protected:
--- a/content/xbl/src/nsXBLWindowKeyHandler.cpp
+++ b/content/xbl/src/nsXBLWindowKeyHandler.cpp
@@ -351,16 +351,23 @@ nsXBLWindowKeyHandler::WalkHandlers(nsID
     if (mUserHandler) {
       WalkHandlersInternal(aKeyEvent, aEventType, mUserHandler);
       evt->GetPreventDefault(&prevent);
       if (prevent)
         return NS_OK; // Handled by the user bindings. Our work here is done.
     }
   }
 
+  nsCOMPtr<nsIContent> content = do_QueryInterface(el);
+  // skip keysets that are disabled
+  if (content && content->AttrValueIs(kNameSpaceID_None, nsGkAtoms::disabled,
+                                      nsGkAtoms::_true, eCaseMatters)) {
+    return NS_OK;
+  }
+
   WalkHandlersInternal(aKeyEvent, aEventType, mHandler);
 
   nsINativeKeyBindings *nativeBindings;
   if (isEditor && (nativeBindings = GetEditorKeyBindings())) {
     nsNativeKeyEvent nativeEvent;
     // get the DOM window we're attached to
     nsCOMPtr<nsIControllers> controllers;
     nsCOMPtr<nsPIWindowRoot> root = do_QueryInterface(mTarget);
--- a/content/xslt/src/xslt/txMozillaXMLOutput.cpp
+++ b/content/xslt/src/xslt/txMozillaXMLOutput.cpp
@@ -759,17 +759,16 @@ txMozillaXMLOutput::startHTMLElement(nsI
     }
 
     return NS_OK;
 }
 
 nsresult
 txMozillaXMLOutput::endHTMLElement(nsIContent* aElement)
 {
-    nsresult rv;
     nsIAtom *atom = aElement->Tag();
 
     if (mTableState == ADDED_TBODY) {
         NS_ASSERTION(atom == txHTMLAtoms::tbody,
                      "Element flagged as added tbody isn't a tbody");
         PRUint32 last = mCurrentNodeStack.Count() - 1;
         NS_ASSERTION(last != (PRUint32)-1, "empty stack");
 
@@ -804,20 +803,21 @@ txMozillaXMLOutput::endHTMLElement(nsICo
         nsCOMPtr<nsIDocument> doc = do_QueryInterface(mDocument);
         NS_ASSERTION(doc, "document doesn't implement nsIDocument");
         nsAutoString value;
         aElement->GetAttr(kNameSpaceID_None, txHTMLAtoms::target, value);
         doc->SetBaseTarget(value);
 
         aElement->GetAttr(kNameSpaceID_None, txHTMLAtoms::href, value);
         nsCOMPtr<nsIURI> baseURI;
-        rv = NS_NewURI(getter_AddRefs(baseURI), value, nsnull);
-        NS_ENSURE_SUCCESS(rv, rv);
+        NS_NewURI(getter_AddRefs(baseURI), value, nsnull);
 
-        doc->SetBaseURI(baseURI); // The document checks if it is legal to set this base
+        if (baseURI) {
+            doc->SetBaseURI(baseURI); // The document checks if it is legal to set this base
+        }
     }
     else if (mCreatingNewDocument && atom == txHTMLAtoms::meta) {
         // handle HTTP-EQUIV data
         nsAutoString httpEquiv;
         aElement->GetAttr(kNameSpaceID_None, txHTMLAtoms::httpEquiv, httpEquiv);
         if (!httpEquiv.IsEmpty()) {
             nsAutoString value;
             aElement->GetAttr(kNameSpaceID_None, txHTMLAtoms::content, value);
--- a/content/xul/content/src/nsXULElement.cpp
+++ b/content/xul/content/src/nsXULElement.cpp
@@ -162,18 +162,16 @@
   (nsXULElement::eChildrenMustBeRebuilt << XUL_ELEMENT_LAZY_STATE_OFFSET)
 
 #define XUL_ELEMENT_TEMPLATE_CONTENTS_BUILT \
   (nsXULElement::eTemplateContentsBuilt << XUL_ELEMENT_LAZY_STATE_OFFSET)
 
 #define XUL_ELEMENT_CONTAINER_CONTENTS_BUILT \
   (nsXULElement::eContainerContentsBuilt << XUL_ELEMENT_LAZY_STATE_OFFSET)
 
-class nsIDocShell;
-
 // Global object maintenance
 nsICSSParser* nsXULPrototypeElement::sCSSParser = nsnull;
 nsIXBLService * nsXULElement::gXBLService = nsnull;
 nsICSSOMFactory* nsXULElement::gCSSOMFactory = nsnull;
 
 /**
  * A tearoff class for nsXULElement to implement nsIScriptEventHandlerOwner.
  */
@@ -2113,16 +2111,46 @@ nsXULElement::GetFrameLoader(nsIFrameLoa
     *aFrameLoader = nsnull;
     nsXULSlots* slots = static_cast<nsXULSlots*>(GetExistingSlots());
     if (slots) {
         NS_IF_ADDREF(*aFrameLoader = slots->mFrameLoader);
     }
     return NS_OK;
 }
 
+nsresult
+nsXULElement::SwapFrameLoaders(nsIFrameLoaderOwner* aOtherOwner)
+{
+    nsCOMPtr<nsIContent> otherContent(do_QueryInterface(aOtherOwner));
+    NS_ENSURE_TRUE(otherContent, NS_ERROR_NOT_IMPLEMENTED);
+
+    nsXULElement* otherEl = FromContent(otherContent);
+    NS_ENSURE_TRUE(otherEl, NS_ERROR_NOT_IMPLEMENTED);
+
+    if (otherEl == this) {
+        // nothing to do
+        return NS_OK;
+    }
+
+    nsXULSlots *ourSlots = static_cast<nsXULSlots*>(GetExistingDOMSlots());
+    nsXULSlots *otherSlots =
+        static_cast<nsXULSlots*>(otherEl->GetExistingDOMSlots());
+    if (!ourSlots || !ourSlots->mFrameLoader ||
+        !otherSlots || !otherSlots->mFrameLoader) {
+        // Can't handle swapping when there is nothing to swap... yet.
+        return NS_ERROR_NOT_IMPLEMENTED;
+    }
+
+    return
+        ourSlots->mFrameLoader->SwapWithOtherLoader(otherSlots->mFrameLoader,
+                                                    ourSlots->mFrameLoader,
+                                                    otherSlots->mFrameLoader);
+}
+
+
 NS_IMETHODIMP
 nsXULElement::GetParentTree(nsIDOMXULMultiSelectControlElement** aTreeElement)
 {
     for (nsIContent* current = GetParent(); current;
          current = current->GetParent()) {
         if (current->NodeInfo()->Equals(nsGkAtoms::listbox,
                                         kNameSpaceID_XUL)) {
             CallQueryInterface(current, aTreeElement);
--- a/content/xul/content/src/nsXULElement.h
+++ b/content/xul/content/src/nsXULElement.h
@@ -620,18 +620,18 @@ public:
     // nsIDOMXULElement
     NS_DECL_NSIDOMXULELEMENT
 
     virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
     virtual PRInt32 IntrinsicState() const;
 
     nsresult GetStyle(nsIDOMCSSStyleDeclaration** aStyle);
 
-    
     nsresult GetFrameLoader(nsIFrameLoader** aFrameLoader);
+    nsresult SwapFrameLoaders(nsIFrameLoaderOwner* aOtherOwner);
 
     virtual void RecompileScriptEventListeners();
 
     // This function should ONLY be used by BindToTree implementations.
     // The function exists solely because XUL elements store the binding
     // parent as a member instead of in the slots, as nsGenericElement does.
     void SetXULBindingParent(nsIContent* aBindingParent)
     {
@@ -659,17 +659,17 @@ protected:
     nsresult AddPopupListener(nsIAtom* aName);
 
     class nsXULSlots : public nsGenericElement::nsDOMSlots
     {
     public:
        nsXULSlots(PtrBits aFlags);
        virtual ~nsXULSlots();
 
-       nsCOMPtr<nsIFrameLoader> mFrameLoader;
+       nsRefPtr<nsFrameLoader> mFrameLoader;
     };
 
     virtual nsINode::nsSlots* CreateSlots();
 
     nsresult LoadSrc();
 
     // Required fields
     nsRefPtr<nsXULPrototypeElement>     mPrototype;
--- a/content/xul/document/src/nsXULDocument.cpp
+++ b/content/xul/document/src/nsXULDocument.cpp
@@ -436,16 +436,18 @@ nsXULDocument::StartDocumentLoad(const c
     mStillWalking = PR_TRUE;
     mMayStartLayout = PR_FALSE;
     mDocumentLoadGroup = do_GetWeakReference(aLoadGroup);
 
     mDocumentTitle.SetIsVoid(PR_TRUE);
 
     mChannel = aChannel;
 
+    mHaveInputEncoding = PR_TRUE;
+
     // Get the URI.  Note that this should match nsDocShell::OnLoadingSite
     nsresult rv =
         NS_GetFinalChannelURI(aChannel, getter_AddRefs(mDocumentURI));
     NS_ENSURE_SUCCESS(rv, rv);
     
     rv = ResetStylesheetsToURI(mDocumentURI);
     if (NS_FAILED(rv)) return rv;
 
@@ -1726,16 +1728,24 @@ nsXULDocument::RemoveSubtreeFromDocument
     if (!aElement->IsNodeOfType(nsINode::eELEMENT)) {
         return NS_OK;
     }
 
     // Do a bunch of cleanup to remove an element from the XUL
     // document.
     nsresult rv;
 
+    if (aElement->NodeInfo()->Equals(nsGkAtoms::keyset, kNameSpaceID_XUL)) {
+        nsCOMPtr<nsIXBLService> xblService(do_GetService("@mozilla.org/xbl;1"));
+        if (xblService) {
+            nsCOMPtr<nsPIDOMEventTarget> piTarget(do_QueryInterface(aElement));
+            xblService->DetachGlobalKeyHandler(piTarget);
+        }
+    }
+
     // 1. Remove any children from the document.
     PRUint32 count = aElement->GetChildCount();
 
     while (count-- > 0) {
         rv = RemoveSubtreeFromDocument(aElement->GetChildAt(count));
         if (NS_FAILED(rv))
             return rv;
     }
--- a/db/mork/src/morkRow.cpp
+++ b/db/mork/src/morkRow.cpp
@@ -940,17 +940,17 @@ morkRow::NewRowCellCursor(morkEnv* ev, m
         nsIMdbHeap* heap = store->mPort_Heap;
         morkRowCellCursor* cursor = new(*heap, ev)
           morkRowCellCursor(ev, morkUsage::kHeap, heap, rowObj);
          
         if ( cursor )
         {
           if ( ev->Good() )
           {
-            cursor->mCursor_Pos = inPos;
+            cursor->mRowCellCursor_Col = inPos;
             outCursor = cursor;
           }
           else
             cursor->CutStrongRef(ev->mEnv_SelfAsMdbEnv);
         }
         rowObj->Release(); // always cut ref (cursor has its own)
       }
     }
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -1185,22 +1185,20 @@ nsDocShell::GetContentViewer(nsIContentV
 NS_IMETHODIMP
 nsDocShell::SetChromeEventHandler(nsIDOMEventTarget* aChromeEventHandler)
 {
     nsCOMPtr<nsPIDOMEventTarget> piTarget =
       do_QueryInterface(aChromeEventHandler);
     // Weak reference. Don't addref.
     mChromeEventHandler = piTarget;
 
-    NS_ASSERTION(!mScriptGlobal,
-                 "SetChromeEventHandler() called after the script global "
-                 "object was created! This means that the script global "
-                 "object in this docshell won't get the right chrome event "
-                 "handler. You really don't want to see this assert, FIX "
-                 "YOUR CODE!");
+    nsCOMPtr<nsPIDOMWindow> win(do_QueryInterface(mScriptGlobal));
+    if (win) {
+        win->SetChromeEventHandler(piTarget);
+    }
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocShell::GetChromeEventHandler(nsIDOMEventTarget** aChromeEventHandler)
 {
     NS_ENSURE_ARG_POINTER(aChromeEventHandler);
--- a/dom/locales/en-US/chrome/layout/css.properties
+++ b/dom/locales/en-US/chrome/layout/css.properties
@@ -37,18 +37,18 @@
 MimeNotCss=The stylesheet %1$S was not loaded because its MIME type, "%2$S", is not "text/css".
 MimeNotCssWarn=The stylesheet %1$S was loaded as CSS even though its MIME type, "%2$S", is not "text/css".
 
 PEUnexpEOF2=Unexpected end of file while searching for %1$S.
 PEParseRuleWSOnly=Whitespace-only string given to be parsed as rule.
 PEDeclDropped=Declaration dropped.
 PEDeclSkipped=Skipped to next declaration.
 PEUnknownProperty=Unknown property '%1$S'.
-PEPropertyParsingError=Error in parsing value for property '%1$S'.
-PEExpectEndProperty=Expected end of value for property but found '%1$S'.
+PEValueParsingError=Error in parsing value for '%1$S'.
+PEExpectEndValue=Expected end of value but found '%1$S'.
 PESkipAtRuleEOF=end of unknown at-rule
 PEUnknownAtRule=Unrecognized at-rule or error parsing at-rule '%1$S'.
 PECharsetRuleEOF=charset string in @charset rule
 PECharsetRuleNotString=Expected charset string but found '%1$S'.
 PEGatherMediaEOF=end of media list in @import or @media rule
 PEGatherMediaNotComma=Expected ',' in media list but found '%1$S'.
 PEGatherMediaNotIdent=Expected identifier in media list but found '%1$S'.
 PEImportNotURI=Expected URI in @import rule but found '%1$S'.
@@ -122,13 +122,15 @@ PEParseDeclarationDeclExpected=Expected 
 PEEndOfDeclEOF=end of declaration
 PEImportantEOF=important
 PEExpectedImportant=Expected 'important' but found '%1$S'.
 PEBadDeclEnd=Expected ';' to terminate declaration but found '%1$S'.
 PEBadDeclOrRuleEnd2=Expected ';' or '}' to terminate declaration but found '%1$S'.
 PEInaccessibleProperty2=Cannot specify value for internal property.
 PECommentEOF=end of comment
 SEUnterminatedString=Found unclosed string '%1$S'.
+PEFontDescExpected=Expected font descriptor but found '%1$S'.
+PEUnknownFontDesc=Unknown descriptor '%1$S' in @font-face rule.
 PEMQExpectedExpressionStart=Expected '(' to start media query expression but found '%1$S'.
 PEMQExpressionEOF=contents of media query expression
 PEMQExpectedFeatureName=Expected media feature name but found '%1$S'.
 PEMQExpectedFeatureNameEnd=Expected ':' or ')' after media feature name but found '%1$S'.
 PEMQExpectedFeatureValue=Found invalid value for media feature.
--- a/dom/public/base/nsPIDOMWindow.h
+++ b/dom/public/base/nsPIDOMWindow.h
@@ -91,16 +91,18 @@ public:
   virtual nsresult Activate() = 0;
   virtual nsresult Deactivate() = 0;
 
   nsPIDOMEventTarget* GetChromeEventHandler() const
   {
     return mChromeEventHandler;
   }
 
+  virtual void SetChromeEventHandler(nsPIDOMEventTarget* aChromeEventHandler) = 0;
+
   PRBool HasMutationListeners(PRUint32 aMutationEventType) const
   {
     const nsPIDOMWindow *win;
 
     if (IsOuterWindow()) {
       win = GetCurrentInnerWindow();
 
       if (!win) {
@@ -396,16 +398,20 @@ protected:
     : mFrameElement(nsnull), mDocShell(nsnull), mModalStateDepth(0),
       mRunningTimeout(nsnull), mMutationBits(0), mIsDocumentLoaded(PR_FALSE),
       mIsHandlingResizeEvent(PR_FALSE), mIsInnerWindow(aOuterWindow != nsnull),
       mIsModalContentWindow(PR_FALSE), mInnerWindow(nsnull),
       mOuterWindow(aOuterWindow)
   {
   }
 
+  void SetChromeEventHandlerInternal(nsPIDOMEventTarget* aChromeEventHandler) {
+    mChromeEventHandler = aChromeEventHandler;
+  }
+
   // These two variables are special in that they're set to the same
   // value on both the outer window and the current inner window. Make
   // sure you keep them in sync!
   nsCOMPtr<nsPIDOMEventTarget> mChromeEventHandler; // strong
   nsCOMPtr<nsIDOMDocument> mDocument; // strong
 
   // These members are only used on outer windows.
   nsIDOMElement *mFrameElement; // weak
--- a/dom/public/coreEvents/nsIDOMCompositionListener.h
+++ b/dom/public/coreEvents/nsIDOMCompositionListener.h
@@ -39,31 +39,29 @@
 #define nsIDOMCompositionListener_h__
 
 #include "nsIDOMEvent.h"
 #include "nsIDOMEventListener.h"
 
 /*
  * Key pressed / released / typed listener interface.
  */
-// {F14B6491-E95B-11d2-9E85-0060089FE59B}
+// {93A5A335-AA51-4d32-977D-3680B7722AD5}
 #define NS_IDOMCOMPOSITIONLISTENER_IID	\
-{ 0xf14b6491, 0xe95b, 0x11d2, \
-{ 0x9e, 0x85, 0x0, 0x60, 0x8, 0x9f, 0xe5, 0x9b } }
+{ 0x93a5a335, 0xaa51, 0x4d32, \
+{ 0x97, 0x7d, 0x36, 0x80, 0xb7, 0x72, 0x2a, 0xd5 } }
 
 
 class nsIDOMCompositionListener : public nsIDOMEventListener {
 
 public:
 
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDOMCOMPOSITIONLISTENER_IID)
 
   NS_IMETHOD HandleStartComposition(nsIDOMEvent* aCompositionEvent) = 0;
   NS_IMETHOD HandleEndComposition(nsIDOMEvent* aCompositionEvent) = 0;
   NS_IMETHOD HandleQueryComposition(nsIDOMEvent* aCompositionEvent) = 0;
-  NS_IMETHOD HandleQueryReconversion(nsIDOMEvent* aCompositionEvent) = 0;
-  NS_IMETHOD HandleQueryCaretRect(nsIDOMEvent* aCompositionEvent) = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIDOMCompositionListener,
                               NS_IDOMCOMPOSITIONLISTENER_IID)
 
 #endif // nsIDOMCompositionListener_h__
--- a/dom/public/nsDOMClassInfoID.h
+++ b/dom/public/nsDOMClassInfoID.h
@@ -423,16 +423,20 @@ enum nsDOMClassInfoID {
   // event used for cross-domain message-passing and for server-sent events in
   // HTML5
   eDOMClassInfo_MessageEvent_id,
 
   // Geolocation
   eDOMClassInfo_Geolocation_id,
   eDOMClassInfo_Geolocator_id,
 
+  // @font-face in CSS
+  eDOMClassInfo_CSSFontFaceRule_id,
+  eDOMClassInfo_CSSFontFaceStyleDecl_id,
+
   // WhatWG Video Element
 #if defined(MOZ_MEDIA)
   eDOMClassInfo_HTMLVideoElement_id,
   eDOMClassInfo_HTMLSourceElement_id,
   eDOMClassInfo_ProgressEvent_id,
   eDOMClassInfo_HTMLMediaError_id,
   eDOMClassInfo_HTMLAudioElement_id,
 #endif
--- a/dom/src/base/nsDOMClassInfo.cpp
+++ b/dom/src/base/nsDOMClassInfo.cpp
@@ -320,16 +320,17 @@
 #include "nsIDOMHTMLAudioElement.h"
 #include "nsIDOMProgressEvent.h"
 #endif
 #include "nsIDOMNSUIEvent.h"
 #include "nsIDOMCSS2Properties.h"
 #include "nsIDOMCSSCharsetRule.h"
 #include "nsIDOMCSSImportRule.h"
 #include "nsIDOMCSSMediaRule.h"
+#include "nsIDOMCSSFontFaceRule.h"
 #include "nsIDOMCSSMozDocumentRule.h"
 #include "nsIDOMCSSPrimitiveValue.h"
 #include "nsIDOMCSSStyleRule.h"
 #include "nsIDOMCSSStyleSheet.h"
 #include "nsIDOMCSSValueList.h"
 #include "nsIDOMRange.h"
 #include "nsIDOMNSRange.h"
 #include "nsIDOMRangeException.h"
@@ -809,17 +810,17 @@ static nsDOMClassInfoData sClassInfoData
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(StyleSheetList, nsDOMGenericSH,
                            ARRAY_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(CSSStyleSheet, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(CSSStyleDeclaration, nsCSSStyleDeclSH,
                            ARRAY_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(ComputedCSSStyleDeclaration, nsCSSStyleDeclSH,
-                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+                           ARRAY_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(ROCSSPrimitiveValue, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   // Range classes
   NS_DEFINE_CLASSINFO_DATA(Range, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(Selection, nsDOMGenericSH,
                            DEFAULT_SCRIPTABLE_FLAGS)
@@ -1248,16 +1249,21 @@ static nsDOMClassInfoData sClassInfoData
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(Geolocation, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
  
    NS_DEFINE_CLASSINFO_DATA(Geolocator, nsDOMGenericSH,
                             DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
+  NS_DEFINE_CLASSINFO_DATA(CSSFontFaceRule, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(CSSFontFaceStyleDecl, nsCSSStyleDeclSH,
+                           ARRAY_SCRIPTABLE_FLAGS)
+
 #if defined(MOZ_MEDIA) 
   NS_DEFINE_CLASSINFO_DATA(HTMLVideoElement, nsHTMLElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(HTMLSourceElement, nsHTMLElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(ProgressEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(HTMLMediaError, nsDOMGenericSH,
@@ -3435,16 +3441,25 @@ nsDOMClassInfo::Init()
   DOM_CLASSINFO_MAP_BEGIN(Geolocation, nsIDOMGeolocation)
      DOM_CLASSINFO_MAP_ENTRY(nsIDOMGeolocation)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(Geolocator, nsIDOMGeolocator)
      DOM_CLASSINFO_MAP_ENTRY(nsIDOMGeolocator)
   DOM_CLASSINFO_MAP_END
 
+  DOM_CLASSINFO_MAP_BEGIN(CSSFontFaceRule, nsIDOMCSSFontFaceRule)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSFontFaceRule)
+  DOM_CLASSINFO_MAP_END
+
+  DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(CSSFontFaceStyleDecl,
+                                      nsIDOMCSSStyleDeclaration)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSStyleDeclaration)
+  DOM_CLASSINFO_MAP_END
+
 #if defined(MOZ_MEDIA)
   DOM_CLASSINFO_MAP_BEGIN(HTMLVideoElement, nsIDOMHTMLVideoElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLVideoElement)
     DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(HTMLSourceElement, nsIDOMHTMLSourceElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLSourceElement)
--- a/dom/src/base/nsGlobalWindow.cpp
+++ b/dom/src/base/nsGlobalWindow.cpp
@@ -6805,16 +6805,37 @@ nsGlobalWindow::Activate()
 nsresult
 nsGlobalWindow::Deactivate()
 {
   FORWARD_TO_OUTER(Deactivate, (), NS_ERROR_NOT_INITIALIZED);
 
   return FireWidgetEvent(mDocShell, NS_DEACTIVATE);
 }
 
+void
+nsGlobalWindow::SetChromeEventHandler(nsPIDOMEventTarget* aChromeEventHandler)
+{
+  SetChromeEventHandlerInternal(aChromeEventHandler);
+  if (IsOuterWindow()) {
+    // update the chrome event handler on all our inner windows
+    for (nsGlobalWindow *inner = (nsGlobalWindow *)PR_LIST_HEAD(this);
+         inner != this;
+         inner = (nsGlobalWindow*)PR_NEXT_LINK(inner)) {
+      NS_ASSERTION(inner->mOuterWindow == this, "bad outer window pointer");
+      inner->SetChromeEventHandlerInternal(aChromeEventHandler);
+    }
+  } else if (mOuterWindow) {
+    // Need the cast to be able to call the protected method on a
+    // superclass. We could make the method public instead, but it's really
+    // better this way.
+    static_cast<nsGlobalWindow*>(mOuterWindow)->
+      SetChromeEventHandlerInternal(aChromeEventHandler);
+  }
+}
+
 nsIFocusController*
 nsGlobalWindow::GetRootFocusController()
 {
   nsIDOMWindowInternal* rootWindow = nsGlobalWindow::GetPrivateRoot();
   nsCOMPtr<nsIFocusController> fc;
 
   nsCOMPtr<nsPIDOMWindow> piWin(do_QueryInterface(rootWindow));
   if (piWin) {
--- a/dom/src/base/nsGlobalWindow.h
+++ b/dom/src/base/nsGlobalWindow.h
@@ -285,16 +285,17 @@ public:
 
   // nsIDOMNSEventTarget
   NS_DECL_NSIDOMNSEVENTTARGET
 
   // nsPIDOMWindow
   virtual NS_HIDDEN_(nsPIDOMWindow*) GetPrivateRoot();
   virtual NS_HIDDEN_(nsresult) Activate();
   virtual NS_HIDDEN_(nsresult) Deactivate();
+  virtual NS_HIDDEN_(void) SetChromeEventHandler(nsPIDOMEventTarget* aChromeEventHandler);
   virtual NS_HIDDEN_(nsIFocusController*) GetRootFocusController();
 
   virtual NS_HIDDEN_(void) SetOpenerScriptPrincipal(nsIPrincipal* aPrincipal);
   virtual NS_HIDDEN_(nsIPrincipal*) GetOpenerScriptPrincipal();
 
   virtual NS_HIDDEN_(PopupControlState) PushPopupControlState(PopupControlState state, PRBool aForce) const;
   virtual NS_HIDDEN_(void) PopPopupControlState(PopupControlState state) const;
   virtual NS_HIDDEN_(PopupControlState) GetPopupControlState() const;
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/ajax/jquery/ChangeLog.txt
@@ -0,0 +1,98 @@
+== jQuery ChangeLog ==
+
+== 1.2.2 ==
+
+* show is now element aware (uses default display type instead of just forcing block)
+* New special events api: jQuery.events.special
+* ready is now a real event and can be bound, unbound and triggered.
+* mouseenter and mouseleave now work on all supported browsers
+* The hover helper method now uses the mouseenter and mouseleave events
+* New offset test suite test/offset.html (requires your pop-up blocker to be disabled)
+* Refactored the width and height methods (fixes lots of bugs)
+* Fixed event memory leaks in IE (html, remove, empty also no longer leak memory)
+* Fixed window/document width/height values
+* Fixed event.pageX and event.pageY in IE
+
+== 1.2 ==
+
+=== 1.1.3 ===
+* Always create an ActiveXObject when it is available instead of the XMLHttpRequest, even in IE7
+* Removed XMLHttpRequest shadowing, may break code that relies on existence of that function for browser checking
+* ...
+
+=== 1.1.2 ===
+
+* Event handlers (like element.onclick) are now removed when no more functions are bound to the event.
+* Fixed DOM Manipulations for form elements.
+* Fixed jQuery.isFunction to return false on nodes.
+* Fixed jQuery.className.has, escaping regex characters in className (for metadata)
+* Fixed an issue in IE where an event on a cloned element is fired during a .clone() inside of an event handler.
+* Fixed IE ID selectors selecting by the name attribute.
+* Change: Events are now internally stored in elem.$events rather than elem.events (due to a nasty bug relating to DOM 0 expandos).
+* .attr('href') is now consistent in all browsers.
+* @href is now consistent in all browsers.
+* Fixed the slideDown flickering bug.
+* Having a \r endline in $("...") caused a never-ending loop.
+* Fixed IE6 AJAX memory leak
+* Fixed bug in pushStack, reporting an element at [0] in a jQuery object with length 0
+
+=== 1.1.1 ===
+
+* Setting the numerical value of a css property failed, for example: .css("opacity",0.5) (also occurred with zIndex, fontWeight)
+* Calling $(..., jqobj) with a context of a jQuery object failed.
+* Accessing a property on an element that doesn't exist caused an error, for example: $("#foobar").attr("id")
+* Calling .load() without a callback caused an error.
+* You couldn't cancel an event that was triggered using .trigger() or .click() (for example).
+* .add()ing a single DOM element to a jQuery object was broken.
+* Passing in undefined values to a $.post() caused weird errors to occur.
+* Accessing child nodes within an xml document didn't work properly.
+* jQuery.isFunction() was unable to reliably determine a function, in a cross-browser way.
+* Triggering a .click() failed in IE.
+* Triggered click handlers were executed twice in most browsers.
+* A newline passed into $(...) caused Firefox to go into a never-ending loop.
+* Calling $.post() without any data caused an error.
+* Calling a descendant selector after a child selector caused strange results, for example: $("ul > li ul")
+* Triggered events did not occur if an event handler was not bound for that event.
+
+== 1.1 ==
+
+* Massive speed-ups (4x-10x) in the selector engine.
+* You can now unbind event handlers from within themselves
+* Added new .one( "type", fn ) method
+* text(String) now escapes HTML
+* Added attr(String,Function) to calculate the value
+* Performming .click(), .blur(), .focus(), .submit() will actually trigger the browsers default action for those events.
+* Added global settings for AJAX (in addition to timeout), use $.ajaxSetup() to modify them
+* Implemented a better error handling for ajax requests. Exceptions caused by dropping connections are now handled, too.
+* Improved event fixing (Opera provides event.srcElement, must ignore it if target is available; only create pageX if clientX is available)
+* Fixed nth-child selectors to start on the right number
+* jQuery is no longer destructive. Doing var a = $("a"); a.find("span"); does not change the original "a" variable.
+* Fixed synchronous requests
+* Fixed ID with context selectors (eg. div #id doesn't ignore "div" anymore)
+* Fixed docs for html(): Now mentions that is not available for XML documents
+* Improved AJAX docs (eg. more examples for $.ajax)
+* Documented filter(Function), a very powerful approach for custom filtering
+* Improved docs for FX module, merging method descriptions and marking optional arguments
+* Improved docs for append, prepend, before and after, merging the three pairs into one
+* Improved show/hide animations to show only hidden and hide only visible elements
+* Removed .oneEvent() and .unEvent() helper methods.
+* Removed all CSS helper methods.
+* Removed most attribute helper methods.
+* Removed the (undocumented) .find( "selector", fn ) for all destructive methods.
+* $.get, $.getIfModified, $.post, $.getScript and $.getJSON now all pass through the XMLHttpRequest as returned by $.ajax
+
+== 1.0.4 ==
+
+* Tons of bug fixes
+* Extensions to $.ajax: $.ajax accepts additonal options: beforeSend, async and processData; returns XMLHttpRequest to allow manual aborting of requests, see docs for details
+* AJAX module: the public $.ajax API is now used internally (for $.get/$.post etc.); loading scripts works now much more reliable on all browers except Safari
+* New global ajax handler: ajaxSend - called before an ajax request is sent
+* Extensions to global ajax handlers: ajaxSend, ajaxSuccess, ajaxError and ajaxComplete get XMLHttpRequest and settings passed as arguments
+* Extensions to event handling: pageX and pageY are available x-browser (IE does not provide native pageX/Y)
+* Improved docs: $(String) method has now two seperate descriptions, one for selecting elements, one for creating (html on-the-fly)
+* FX module: Most inline stlyes added by animations are now removed when the animation is complete, eg. height style when animating height (exception: display styles)
+* Added note to attr(String, Object) about issues with setting the name property on input elements
+* Seperated internal stuff from get() into set()
+* Merged the two API examples for each() into one more precise example
+* Improved docs for $.browser and added docs for $.boxModel
+* Docs for the jQuery constructor $() were improved: There is now $(String expression[, Object context]) and $(String html)
--- a/dom/tests/mochitest/ajax/jquery/MIT-LICENSE.txt
+++ b/dom/tests/mochitest/ajax/jquery/MIT-LICENSE.txt
@@ -1,9 +1,9 @@
-Copyright (c) 2007 John Resig, http://jquery.com/
+Copyright (c) 2008 John Resig, http://jquery.com/
 
 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
 "Software"), to deal in the Software without restriction, including
 without limitation the rights to use, copy, modify, merge, publish,
 distribute, sublicense, and/or sell copies of the Software, and to
 permit persons to whom the Software is furnished to do so, subject to
 the following conditions:
--- a/dom/tests/mochitest/ajax/jquery/Makefile.in
+++ b/dom/tests/mochitest/ajax/jquery/Makefile.in
@@ -40,23 +40,20 @@ topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir	= dom/tests/mochitest/ajax/jquery
 
 include $(DEPTH)/config/autoconf.mk
 
 DIRS	= \
 	dist \
-	src \
 	test \
 	$(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
 _TEST_FILES	= \
-	GPL-LICENSE.txt \
 	manifest.json \
-	MIT-LICENSE.txt \
 	test_jQuery.html \
 	$(NULL)
 
 libs::	$(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
--- a/dom/tests/mochitest/ajax/jquery/dist/jquery.js
+++ b/dom/tests/mochitest/ajax/jquery/dist/jquery.js
@@ -1,2528 +1,1546 @@
-// prevent execution of jQuery if included more than once
-if(typeof window.jQuery == "undefined") {
+(function(){
 /*
- * jQuery 1.1.3a - New Wave Javascript
+ * jQuery 1.2.6 - New Wave Javascript
  *
- * Copyright (c) 2007 John Resig (jquery.com)
+ * Copyright (c) 2008 John Resig (jquery.com)
  * Dual licensed under the MIT (MIT-LICENSE.txt)
  * and GPL (GPL-LICENSE.txt) licenses.
  *
- * $Date: 2007/06/29 15:10:42 $
- * $Rev: 1961 $
+ * $Date: 2008-05-24 11:09:21 -0700 (Sat, 24 May 2008) $
+ * $Rev: 5683 $
  */
 
-// Global undefined variable
-window.undefined = window.undefined;
-
-/**
- * Create a new jQuery Object
- *
- * @constructor
- * @private
- * @name jQuery
- * @param String|Function|Element|Array<Element>|jQuery a selector
- * @param jQuery|Element|Array<Element> c context
- * @cat Core
- */
-var jQuery = function(a,c) {
-	// If the context is global, return a new object
-	if ( window == this )
-		return new jQuery(a,c);
-	
-	return this.init(a,c);
-};
-
+// Map over jQuery in case of overwrite
+var _jQuery = window.jQuery,
 // Map over the $ in case of overwrite
-if ( typeof $ != "undefined" )
-	jQuery._$ = $;
-	
-// Map the jQuery namespace to the '$' one
-var $ = jQuery;
-
-/**
- * This function accepts a string containing a CSS or
- * basic XPath selector which is then used to match a set of elements.
- *
- * The core functionality of jQuery centers around this function.
- * Everything in jQuery is based upon this, or uses this in some way.
- * The most basic use of this function is to pass in an expression
- * (usually consisting of CSS or XPath), which then finds all matching
- * elements.
- *
- * By default, if no context is specified, $() looks for DOM elements within the context of the
- * current HTML document. If you do specify a context, such as a DOM
- * element or jQuery object, the expression will be matched against
- * the contents of that context.
- *
- * See [[DOM/Traversing/Selectors]] for the allowed CSS/XPath syntax for expressions.
- *
- * @example $("div > p")
- * @desc Finds all p elements that are children of a div element.
- * @before <p>one</p> <div><p>two</p></div> <p>three</p>
- * @result [ <p>two</p> ]
- *
- * @example $("input:radio", document.forms[0])
- * @desc Searches for all inputs of type radio within the first form in the document
- *
- * @example $("div", xml.responseXML)
- * @desc This finds all div elements within the specified XML document.
- *
- * @name $
- * @param String expr An expression to search with
- * @param Element|jQuery context (optional) A DOM Element, Document or jQuery to use as context
- * @cat Core
- * @type jQuery
- * @see $(Element)
- * @see $(Element<Array>)
- */
- 
-/**
- * Create DOM elements on-the-fly from the provided String of raw HTML.
- *
- * @example $("<div><p>Hello</p></div>").appendTo("body")
- * @desc Creates a div element (and all of its contents) dynamically, 
- * and appends it to the body element. Internally, an
- * element is created and its innerHTML property set to the given markup.
- * It is therefore both quite flexible and limited. 
- *
- * @name $
- * @param String html A string of HTML to create on the fly.
- * @cat Core
- * @type jQuery
- * @see appendTo(String)
- */
-
-/**
- * Wrap jQuery functionality around a single or multiple DOM Element(s).
- *
- * This function also accepts XML Documents and Window objects
- * as valid arguments (even though they are not DOM Elements).
- *
- * @example $(document.body).css( "background", "black" );
- * @desc Sets the background color of the page to black.
- *
- * @example $( myForm.elements ).hide()
- * @desc Hides all the input elements within a form
- *
- * @name $
- * @param Element|Array<Element> elems DOM element(s) to be encapsulated by a jQuery object.
- * @cat Core
- * @type jQuery
- */
-
-/**
- * A shorthand for $(document).ready(), allowing you to bind a function
- * to be executed when the DOM document has finished loading. This function
- * behaves just like $(document).ready(), in that it should be used to wrap
- * other $() operations on your page that depend on the DOM being ready to be
- * operated on. While this function is, technically, chainable - there really
- * isn't much use for chaining against it.
- *
- * You can have as many $(document).ready events on your page as you like.
- *
- * See ready(Function) for details about the ready event. 
- * 
- * @example $(function(){
- *   // Document is ready
- * });
- * @desc Executes the function when the DOM is ready to be used.
- *
- * @example jQuery(function($) {
- *   // Your code using failsafe $ alias here...
- * });
- * @desc Uses both the shortcut for $(document).ready() and the argument
- * to write failsafe jQuery code using the $ alias, without relying on the
- * global alias.
- *
- * @name $
- * @param Function fn The function to execute when the DOM is ready.
- * @cat Core
- * @type jQuery
- * @see ready(Function)
- */
+	_$ = window.$;
+
+var jQuery = window.jQuery = window.$ = function( selector, context ) {
+	// The jQuery object is actually just the init constructor 'enhanced'
+	return new jQuery.fn.init( selector, context );
+};
+
+// A simple way to check for HTML strings or ID strings
+// (both of which we optimize for)
+var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/,
+
+// Is it a simple selector
+	isSimple = /^.[^:#\[\.]*$/,
+
+// Will speed up references to undefined, and allows munging its name.
+	undefined;
 
 jQuery.fn = jQuery.prototype = {
-	/**
-	 * Initialize a new jQuery object
-	 *
-	 * @private
-	 * @name init
-	 * @param String|Function|Element|Array<Element>|jQuery a selector
-	 * @param jQuery|Element|Array<Element> c context
-	 * @cat Core
-	 */
-	init: function(a,c) {
+	init: function( selector, context ) {
 		// Make sure that a selection was provided
-		a = a || document;
+		selector = selector || document;
+
+		// Handle $(DOMElement)
+		if ( selector.nodeType ) {
+			this[0] = selector;
+			this.length = 1;
+			return this;
+		}
+		// Handle HTML strings
+		if ( typeof selector == "string" ) {
+			// Are we dealing with HTML string or an ID?
+			var match = quickExpr.exec( selector );
+
+			// Verify a match, and that no context was specified for #id
+			if ( match && (match[1] || !context) ) {
+
+				// HANDLE: $(html) -> $(array)
+				if ( match[1] )
+					selector = jQuery.clean( [ match[1] ], context );
+
+				// HANDLE: $("#id")
+				else {
+					var elem = document.getElementById( match[3] );
+
+					// Make sure an element was located
+					if ( elem ){
+						// Handle the case where IE and Opera return items
+						// by name instead of ID
+						if ( elem.id != match[3] )
+							return jQuery().find( selector );
+
+						// Otherwise, we inject the element directly into the jQuery object
+						return jQuery( elem );
+					}
+					selector = [];
+				}
+
+			// HANDLE: $(expr, [context])
+			// (which is just equivalent to: $(content).find(expr)
+			} else
+				return jQuery( context ).find( selector );
 
 		// HANDLE: $(function)
 		// Shortcut for document ready
-		if ( jQuery.isFunction(a) )
-			return new jQuery(document)[ jQuery.fn.ready ? "ready" : "load" ]( a );
-
-		// Handle HTML strings
-		if ( typeof a  == "string" ) {
-			// HANDLE: $(html) -> $(array)
-			var m = /^[^<]*(<(.|\s)+>)[^>]*$/.exec(a);
-			if ( m )
-				a = jQuery.clean( [ m[1] ] );
-
-			// HANDLE: $(expr)
-			else
-				return new jQuery( c ).find( a );
-		}
-
-		return this.setArray(
-			// HANDLE: $(array)
-			a.constructor == Array && a ||
-
-			// HANDLE: $(arraylike)
-			// Watch for when an array-like object is passed as the selector
-			(a.jquery || a.length && a != window && !a.nodeType && a[0] != undefined && a[0].nodeType) && jQuery.makeArray( a ) ||
-
-			// HANDLE: $(*)
-			[ a ] );
+		} else if ( jQuery.isFunction( selector ) )
+			return jQuery( document )[ jQuery.fn.ready ? "ready" : "load" ]( selector );
+
+		return this.setArray(jQuery.makeArray(selector));
 	},
-	
-	/**
-	 * The current version of jQuery.
-	 *
-	 * @private
-	 * @property
-	 * @name jquery
-	 * @type String
-	 * @cat Core
-	 */
-	jquery: "1.1.3a",
-
-	/**
-	 * The number of elements currently matched. The size function will return the same value.
-	 *
-	 * @example $("img").length;
-	 * @before <img src="test1.jpg"/> <img src="test2.jpg"/>
-	 * @result 2
-	 *
-	 * @property
-	 * @name length
-	 * @type Number
-	 * @cat Core
-	 */
-
-	/**
-	 * Get the number of elements currently matched. This returns the same
-	 * number as the 'length' property of the jQuery object.
-	 *
-	 * @example $("img").size();
-	 * @before <img src="test1.jpg"/> <img src="test2.jpg"/>
-	 * @result 2
-	 *
-	 * @name size
-	 * @type Number
-	 * @cat Core
-	 */
+
+	// The current version of jQuery being used
+	jquery: "1.2.6",
+
+	// The number of elements contained in the matched element set
 	size: function() {
 		return this.length;
 	},
-	
+
+	// The number of elements contained in the matched element set
 	length: 0,
 
-	/**
-	 * Access all matched DOM elements. This serves as a backwards-compatible
-	 * way of accessing all matched elements (other than the jQuery object
-	 * itself, which is, in fact, an array of elements).
-	 *
-	 * It is useful if you need to operate on the DOM elements themselves instead of using built-in jQuery functions.
-	 *
-	 * @example $("img").get();
-	 * @before <img src="test1.jpg"/> <img src="test2.jpg"/>
-	 * @result [ <img src="test1.jpg"/> <img src="test2.jpg"/> ]
-	 * @desc Selects all images in the document and returns the DOM Elements as an Array
-	 *
-	 * @name get
-	 * @type Array<Element>
-	 * @cat Core
-	 */
-
-	/**
-	 * Access a single matched DOM element at a specified index in the matched set.
-	 * This allows you to extract the actual DOM element and operate on it
-	 * directly without necessarily using jQuery functionality on it.
-	 *
-	 * @example $("img").get(0);
-	 * @before <img src="test1.jpg"/> <img src="test2.jpg"/>
-	 * @result <img src="test1.jpg"/>
-	 * @desc Selects all images in the document and returns the first one
-	 *
-	 * @name get
-	 * @type Element
-	 * @param Number num Access the element in the Nth position.
-	 * @cat Core
-	 */
+	// Get the Nth element in the matched element set OR
+	// Get the whole matched element set as a clean array
 	get: function( num ) {
 		return num == undefined ?
 
 			// Return a 'clean' array
 			jQuery.makeArray( this ) :
 
 			// Return just the object
-			this[num];
+			this[ num ];
 	},
-	
-	/**
-	 * Set the jQuery object to an array of elements, while maintaining
-	 * the stack.
-	 *
-	 * @example $("img").pushStack([ document.body ]);
-	 * @result $("img").pushStack() == [ document.body ]
-	 *
-	 * @private
-	 * @name pushStack
-	 * @type jQuery
-	 * @param Elements elems An array of elements
-	 * @cat Core
-	 */
-	pushStack: function( a ) {
-		var ret = jQuery(a);
+
+	// Take an array of elements and push it onto the stack
+	// (returning the new matched element set)
+	pushStack: function( elems ) {
+		// Build a new jQuery matched element set
+		var ret = jQuery( elems );
+
+		// Add the old object onto the stack (as a reference)
 		ret.prevObject = this;
+
+		// Return the newly-formed element set
 		return ret;
 	},
-	
-	/**
-	 * Set the jQuery object to an array of elements. This operation is
-	 * completely destructive - be sure to use .pushStack() if you wish to maintain
-	 * the jQuery stack.
-	 *
-	 * @example $("img").setArray([ document.body ]);
-	 * @result $("img").setArray() == [ document.body ]
-	 *
-	 * @private
-	 * @name setArray
-	 * @type jQuery
-	 * @param Elements elems An array of elements
-	 * @cat Core
-	 */
-	setArray: function( a ) {
+
+	// Force the current matched set of elements to become
+	// the specified array of elements (destroying the stack in the process)
+	// You should use pushStack() in order to do this, but maintain the stack
+	setArray: function( elems ) {
+		// Resetting the length to 0, then using the native Array push
+		// is a super-fast way to populate an object with array-like properties
 		this.length = 0;
-		[].push.apply( this, a );
+		Array.prototype.push.apply( this, elems );
+
 		return this;
 	},
 
-	/**
-	 * Execute a function within the context of every matched element.
-	 * This means that every time the passed-in function is executed
-	 * (which is once for every element matched) the 'this' keyword
-	 * points to the specific DOM element.
-	 *
-	 * Additionally, the function, when executed, is passed a single
-	 * argument representing the position of the element in the matched
-	 * set (integer, zero-index).
-	 *
-	 * @example $("img").each(function(i){
-	 *   this.src = "test" + i + ".jpg";
-	 * });
-	 * @before <img/><img/>
-	 * @result <img src="test0.jpg"/><img src="test1.jpg"/>
-	 * @desc Iterates over two images and sets their src property
-	 *
-	 * @name each
-	 * @type jQuery
-	 * @param Function fn A function to execute
-	 * @cat Core
-	 */
-	each: function( fn, args ) {
-		return jQuery.each( this, fn, args );
+	// Execute a callback for every element in the matched set.
+	// (You can seed the arguments with an array of args, but this is
+	// only used internally.)
+	each: function( callback, args ) {
+		return jQuery.each( this, callback, args );
 	},
 
-	/**
-	 * Searches every matched element for the object and returns
-	 * the index of the element, if found, starting with zero. 
-	 * Returns -1 if the object wasn't found.
-	 *
-	 * @example $("*").index( $('#foobar')[0] ) 
-	 * @before <div id="foobar"><b></b><span id="foo"></span></div>
-	 * @result 0
-	 * @desc Returns the index for the element with ID foobar
-	 *
-	 * @example $("*").index( $('#foo')[0] ) 
-	 * @before <div id="foobar"><b></b><span id="foo"></span></div>
-	 * @result 2
-	 * @desc Returns the index for the element with ID foo within another element
-	 *
-	 * @example $("*").index( $('#bar')[0] ) 
-	 * @before <div id="foobar"><b></b><span id="foo"></span></div>
-	 * @result -1
-	 * @desc Returns -1, as there is no element with ID bar
-	 *
-	 * @name index
-	 * @type Number
-	 * @param Element subject Object to search for
-	 * @cat Core
-	 */
-	index: function( obj ) {
-		var pos = -1;
-		this.each(function(i){
-			if ( this == obj ) pos = i;
-		});
-		return pos;
+	// Determine the position of an element within
+	// the matched set of elements
+	index: function( elem ) {
+		var ret = -1;
+
+		// Locate the position of the desired element
+		return jQuery.inArray(
+			// If it receives a jQuery object, the first element is used
+			elem && elem.jquery ? elem[0] : elem
+		, this );
 	},
 
-	/**
-	 * Access a property on the first matched element.
-	 * This method makes it easy to retrieve a property value
-	 * from the first matched element.
-	 *
-	 * If the element does not have an attribute with such a
- 	 * name, undefined is returned.
-	 *
-	 * @example $("img").attr("src");
-	 * @before <img src="test.jpg"/>
-	 * @result test.jpg
-	 * @desc Returns the src attribute from the first image in the document.
-	 *
-	 * @name attr
-	 * @type Object
-	 * @param String name The name of the property to access.
-	 * @cat DOM/Attributes
-	 */
-
-	/**
-	 * Set a key/value object as properties to all matched elements.
-	 *
-	 * This serves as the best way to set a large number of properties
-	 * on all matched elements.
-	 *
-	 * @example $("img").attr({ src: "test.jpg", alt: "Test Image" });
-	 * @before <img/>
-	 * @result <img src="test.jpg" alt="Test Image"/>
-	 * @desc Sets src and alt attributes to all images.
-	 *
-	 * @name attr
-	 * @type jQuery
-	 * @param Map properties Key/value pairs to set as object properties.
-	 * @cat DOM/Attributes
-	 */
-
-	/**
-	 * Set a single property to a value, on all matched elements.
-	 *
-	 * Note that you can't set the name property of input elements in IE.
-	 * Use $(html) or .append(html) or .html(html) to create elements
-	 * on the fly including the name property.
-	 *
-	 * @example $("img").attr("src","test.jpg");
-	 * @before <img/>
-	 * @result <img src="test.jpg"/>
-	 * @desc Sets src attribute to all images.
-	 *
-	 * @name attr
-	 * @type jQuery
-	 * @param String key The name of the property to set.
-	 * @param Object value The value to set the property to.
-	 * @cat DOM/Attributes
-	 */
-	 
-	/**
-	 * Set a single property to a computed value, on all matched elements.
-	 *
-	 * Instead of supplying a string value as described
-	 * [[DOM/Attributes#attr.28_key.2C_value_.29|above]],
-	 * a function is provided that computes the value.
-	 *
-	 * @example $("img").attr("title", function() { return this.src });
-	 * @before <img src="test.jpg" />
-	 * @result <img src="test.jpg" title="test.jpg" />
-	 * @desc Sets title attribute from src attribute.
-	 *
-	 * @example $("img").attr("title", function(index) { return this.title + (i + 1); });
-	 * @before <img title="pic" /><img title="pic" /><img title="pic" />
-	 * @result <img title="pic1" /><img title="pic2" /><img title="pic3" />
-	 * @desc Enumerate title attribute.
-	 *
-	 * @name attr
-	 * @type jQuery
-	 * @param String key The name of the property to set.
-	 * @param Function value A function returning the value to set.
-	 * 	 	  Scope: Current element, argument: Index of current element
-	 * @cat DOM/Attributes
-	 */
-	attr: function( key, value, type ) {
-		var obj = key;
-		
+	attr: function( name, value, type ) {
+		var options = name;
+
 		// Look for the case where we're accessing a style value
-		if ( key.constructor == String )
-			if ( value == undefined )
-				return this.length && jQuery[ type || "attr" ]( this[0], key ) || undefined;
+		if ( name.constructor == String )
+			if ( value === undefined )
+				return this[0] && jQuery[ type || "attr" ]( this[0], name );
+
 			else {
-				obj = {};
-				obj[ key ] = value;
+				options = {};
+				options[ name ] = value;
 			}
-		
+
 		// Check to see if we're setting style values
-		return this.each(function(index){
+		return this.each(function(i){
 			// Set all the styles
-			for ( var prop in obj )
+			for ( name in options )
 				jQuery.attr(
-					type ? this.style : this,
-					prop, jQuery.prop(this, obj[prop], type, index, prop)
+					type ?
+						this.style :
+						this,
+					name, jQuery.prop( this, options[ name ], type, i, name )
 				);
 		});
 	},
 
-	/**
-	 * Access a style property on the first matched element.
-	 * This method makes it easy to retrieve a style property value
-	 * from the first matched element.
-	 *
-	 * @example $("p").css("color");
-	 * @before <p style="color:red;">Test Paragraph.</p>
-	 * @result "red"
-	 * @desc Retrieves the color style of the first paragraph
-	 *
-	 * @example $("p").css("font-weight");
-	 * @before <p style="font-weight: bold;">Test Paragraph.</p>
-	 * @result "bold"
-	 * @desc Retrieves the font-weight style of the first paragraph.
-	 *
-	 * @name css
-	 * @type String
-	 * @param String name The name of the property to access.
-	 * @cat CSS
-	 */
-
-	/**
-	 * Set a key/value object as style properties to all matched elements.
-	 *
-	 * This serves as the best way to set a large number of style properties
-	 * on all matched elements.
-	 *
-	 * @example $("p").css({ color: "red", background: "blue" });
-	 * @before <p>Test Paragraph.</p>
-	 * @result <p style="color:red; background:blue;">Test Paragraph.</p>
-	 * @desc Sets color and background styles to all p elements.
-	 *
-	 * @name css
-	 * @type jQuery
-	 * @param Map properties Key/value pairs to set as style properties.
-	 * @cat CSS
-	 */
-
-	/**
-	 * Set a single style property to a value, on all matched elements.
-	 * If a number is provided, it is automatically converted into a pixel value.
-	 *
-	 * @example $("p").css("color","red");
-	 * @before <p>Test Paragraph.</p>
-	 * @result <p style="color:red;">Test Paragraph.</p>
-	 * @desc Changes the color of all paragraphs to red
-	 *
-	 * @example $("p").css("left",30);
-	 * @before <p>Test Paragraph.</p>
-	 * @result <p style="left:30px;">Test Paragraph.</p>
-	 * @desc Changes the left of all paragraphs to "30px"
-	 *
-	 * @name css
-	 * @type jQuery
-	 * @param String key The name of the property to set.
-	 * @param String|Number value The value to set the property to.
-	 * @cat CSS
-	 */
 	css: function( key, value ) {
+		// ignore negative width and height values
+		if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
+			value = undefined;
 		return this.attr( key, value, "curCSS" );
 	},
 
-	/**
-	 * Get the text contents of all matched elements. The result is
-	 * a string that contains the combined text contents of all matched
-	 * elements. This method works on both HTML and XML documents.
-	 *
-	 * @example $("p").text();
-	 * @before <p><b>Test</b> Paragraph.</p><p>Paraparagraph</p>
-	 * @result Test Paragraph.Paraparagraph
-	 * @desc Gets the concatenated text of all paragraphs
-	 *
-	 * @name text
-	 * @type String
-	 * @cat DOM/Attributes
-	 */
-
-	/**
-	 * Set the text contents of all matched elements.
-	 *
-	 * Similar to html(), but escapes HTML (replace "<" and ">" with their
-	 * HTML entities).
-	 *
-	 * @example $("p").text("<b>Some</b> new text.");
-	 * @before <p>Test Paragraph.</p>
-	 * @result <p>&lt;b&gt;Some&lt;/b&gt; new text.</p>
-	 * @desc Sets the text of all paragraphs.
-	 *
-	 * @example $("p").text("<b>Some</b> new text.", true);
-	 * @before <p>Test Paragraph.</p>
-	 * @result <p>Some new text.</p>
-	 * @desc Sets the text of all paragraphs.
-	 *
-	 * @name text
-	 * @type String
-	 * @param String val The text value to set the contents of the element to.
-	 * @cat DOM/Attributes
-	 */
-	text: function(e) {
-		if ( typeof e == "string" )
-			return this.empty().append( document.createTextNode( e ) );
-
-		var t = "";
-		jQuery.each( e || this, function(){
+	text: function( text ) {
+		if ( typeof text != "object" && text != null )
+			return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
+
+		var ret = "";
+
+		jQuery.each( text || this, function(){
 			jQuery.each( this.childNodes, function(){
 				if ( this.nodeType != 8 )
-					t += this.nodeType != 1 ?
-						this.nodeValue : jQuery.fn.text([ this ]);
+					ret += this.nodeType != 1 ?
+						this.nodeValue :
+						jQuery.fn.text( [ this ] );
 			});
 		});
-		return t;
+
+		return ret;
 	},
 
-	/**
-	 * Wrap all matched elements with a structure of other elements.
-	 * This wrapping process is most useful for injecting additional
-	 * stucture into a document, without ruining the original semantic
-	 * qualities of a document.
-	 *
-	 * This works by going through the first element
-	 * provided (which is generated, on the fly, from the provided HTML)
-	 * and finds the deepest ancestor element within its
-	 * structure - it is that element that will en-wrap everything else.
-	 *
-	 * This does not work with elements that contain text. Any necessary text
-	 * must be added after the wrapping is done.
-	 *
-	 * @example $("p").wrap("<div class='wrap'></div>");
-	 * @before <p>Test Paragraph.</p>
-	 * @result <div class='wrap'><p>Test Paragraph.</p></div>
-	 * 
-	 * @name wrap
-	 * @type jQuery
-	 * @param String html A string of HTML, that will be created on the fly and wrapped around the target.
-	 * @cat DOM/Manipulation
-	 */
-
-	/**
-	 * Wrap all matched elements with a structure of other elements.
-	 * This wrapping process is most useful for injecting additional
-	 * stucture into a document, without ruining the original semantic
-	 * qualities of a document.
-	 *
-	 * This works by going through the first element
-	 * provided and finding the deepest ancestor element within its
-	 * structure - it is that element that will en-wrap everything else.
-	 *
- 	 * This does not work with elements that contain text. Any necessary text
-	 * must be added after the wrapping is done.
-	 *
-	 * @example $("p").wrap( document.getElementById('content') );
-	 * @before <p>Test Paragraph.</p><div id="content"></div>
-	 * @result <div id="content"><p>Test Paragraph.</p></div>
-	 *
-	 * @name wrap
-	 * @type jQuery
-	 * @param Element elem A DOM element that will be wrapped around the target.
-	 * @cat DOM/Manipulation
-	 */
-	wrap: function() {
-		// The elements to wrap the target around
-		var a, args = arguments;
-
-		// Wrap each of the matched elements individually
+	wrapAll: function( html ) {
+		if ( this[0] )
+			// The elements to wrap the target around
+			jQuery( html, this[0].ownerDocument )
+				.clone()
+				.insertBefore( this[0] )
+				.map(function(){
+					var elem = this;
+
+					while ( elem.firstChild )
+						elem = elem.firstChild;
+
+					return elem;
+				})
+				.append(this);
+
+		return this;
+	},
+
+	wrapInner: function( html ) {
 		return this.each(function(){
-			if ( !a )
-				a = jQuery.clean(args, this.ownerDocument);
-
-			// Clone the structure that we're using to wrap
-			var b = a[0].cloneNode(true);
-
-			// Insert it before the element to be wrapped
-			this.parentNode.insertBefore( b, this );
-
-			// Find the deepest point in the wrap structure
-			while ( b.firstChild )
-				b = b.firstChild;
-
-			// Move the matched element to within the wrap structure
-			b.appendChild( this );
+			jQuery( this ).contents().wrapAll( html );
 		});
 	},
 
-	/**
-	 * Append content to the inside of every matched element.
-	 *
-	 * This operation is similar to doing an appendChild to all the
-	 * specified elements, adding them into the document.
-	 *
-	 * @example $("p").append("<b>Hello</b>");
-	 * @before <p>I would like to say: </p>
-	 * @result <p>I would like to say: <b>Hello</b></p>
-	 * @desc Appends some HTML to all paragraphs.
-	 *
-	 * @example $("p").append( $("#foo")[0] );
-	 * @before <p>I would like to say: </p><b id="foo">Hello</b>
-	 * @result <p>I would like to say: <b id="foo">Hello</b></p>
-	 * @desc Appends an Element to all paragraphs.
-	 *
-	 * @example $("p").append( $("b") );
-	 * @before <p>I would like to say: </p><b>Hello</b>
-	 * @result <p>I would like to say: <b>Hello</b></p>
-	 * @desc Appends a jQuery object (similar to an Array of DOM Elements) to all paragraphs.
-	 *
-	 * @name append
-	 * @type jQuery
-	 * @param <Content> content Content to append to the target
-	 * @cat DOM/Manipulation
-	 * @see prepend(<Content>)
-	 * @see before(<Content>)
-	 * @see after(<Content>)
-	 */
+	wrap: function( html ) {
+		return this.each(function(){
+			jQuery( this ).wrapAll( html );
+		});
+	},
+
 	append: function() {
-		return this.domManip(arguments, true, 1, function(a){
-			this.appendChild( a );
+		return this.domManip(arguments, true, false, function(elem){
+			if (this.nodeType == 1)
+				this.appendChild( elem );
 		});
 	},
 
-	/**
-	 * Prepend content to the inside of every matched element.
-	 *
-	 * This operation is the best way to insert elements
-	 * inside, at the beginning, of all matched elements.
-	 *
-	 * @example $("p").prepend("<b>Hello</b>");
-	 * @before <p>I would like to say: </p>
-	 * @result <p><b>Hello</b>I would like to say: </p>
-	 * @desc Prepends some HTML to all paragraphs.
-	 *
-	 * @example $("p").prepend( $("#foo")[0] );
-	 * @before <p>I would like to say: </p><b id="foo">Hello</b>
-	 * @result <p><b id="foo">Hello</b>I would like to say: </p>
-	 * @desc Prepends an Element to all paragraphs.
-	 *	
-	 * @example $("p").prepend( $("b") );
-	 * @before <p>I would like to say: </p><b>Hello</b>
-	 * @result <p><b>Hello</b>I would like to say: </p>
-	 * @desc Prepends a jQuery object (similar to an Array of DOM Elements) to all paragraphs.
-	 *
-	 * @name prepend
-	 * @type jQuery
-	 * @param <Content> content Content to prepend to the target.
-	 * @cat DOM/Manipulation
-	 * @see append(<Content>)
-	 * @see before(<Content>)
-	 * @see after(<Content>)
-	 */
 	prepend: function() {
-		return this.domManip(arguments, true, -1, function(a){
-			this.insertBefore( a, this.firstChild );
+		return this.domManip(arguments, true, true, function(elem){
+			if (this.nodeType == 1)
+				this.insertBefore( elem, this.firstChild );
 		});
 	},
-	
-	/**
-	 * Insert content before each of the matched elements.
-	 *
-	 * @example $("p").before("<b>Hello</b>");
-	 * @before <p>I would like to say: </p>
-	 * @result <b>Hello</b><p>I would like to say: </p>
-	 * @desc Inserts some HTML before all paragraphs.
-	 *
-	 * @example $("p").before( $("#foo")[0] );
-	 * @before <p>I would like to say: </p><b id="foo">Hello</b>
-	 * @result <b id="foo">Hello</b><p>I would like to say: </p>
-	 * @desc Inserts an Element before all paragraphs.
-	 *
-	 * @example $("p").before( $("b") );
-	 * @before <p>I would like to say: </p><b>Hello</b>
-	 * @result <b>Hello</b><p>I would like to say: </p>
-	 * @desc Inserts a jQuery object (similar to an Array of DOM Elements) before all paragraphs.
-	 *
-	 * @name before
-	 * @type jQuery
-	 * @param <Content> content Content to insert before each target.
-	 * @cat DOM/Manipulation
-	 * @see append(<Content>)
-	 * @see prepend(<Content>)
-	 * @see after(<Content>)
-	 */
+
 	before: function() {
-		return this.domManip(arguments, false, 1, function(a){
-			this.parentNode.insertBefore( a, this );
+		return this.domManip(arguments, false, false, function(elem){
+			this.parentNode.insertBefore( elem, this );
 		});
 	},
 
-	/**
-	 * Insert content after each of the matched elements.
-	 *
-	 * @example $("p").after("<b>Hello</b>");
-	 * @before <p>I would like to say: </p>
-	 * @result <p>I would like to say: </p><b>Hello</b>
-	 * @desc Inserts some HTML after all paragraphs.
-	 *
-	 * @example $("p").after( $("#foo")[0] );
-	 * @before <b id="foo">Hello</b><p>I would like to say: </p>
-	 * @result <p>I would like to say: </p><b id="foo">Hello</b>
-	 * @desc Inserts an Element after all paragraphs.
-	 *
-	 * @example $("p").after( $("b") );
-	 * @before <b>Hello</b><p>I would like to say: </p>
-	 * @result <p>I would like to say: </p><b>Hello</b>
-	 * @desc Inserts a jQuery object (similar to an Array of DOM Elements) after all paragraphs.
-	 *
-	 * @name after
-	 * @type jQuery
-	 * @param <Content> content Content to insert after each target.
-	 * @cat DOM/Manipulation
-	 * @see append(<Content>)
-	 * @see prepend(<Content>)
-	 * @see before(<Content>)
-	 */
 	after: function() {
-		return this.domManip(arguments, false, -1, function(a){
-			this.parentNode.insertBefore( a, this.nextSibling );
+		return this.domManip(arguments, false, true, function(elem){
+			this.parentNode.insertBefore( elem, this.nextSibling );
 		});
 	},
 
-	/**
-	 * Revert the most recent 'destructive' operation, changing the set of matched elements
-	 * to its previous state (right before the destructive operation).
-	 *
-	 * If there was no destructive operation before, an empty set is returned.
-	 *
-	 * A 'destructive' operation is any operation that changes the set of
-	 * matched jQuery elements. These functions are: <code>add</code>,
-	 * <code>children</code>, <code>clone</code>, <code>filter</code>,
-	 * <code>find</code>, <code>not</code>, <code>next</code>,
-	 * <code>parent</code>, <code>parents</code>, <code>prev</code> and <code>siblings</code>.
-	 *
-	 * @example $("p").find("span").end();
-	 * @before <p><span>Hello</span>, how are you?</p>
-	 * @result [ <p>...</p> ]
-	 * @desc Selects all paragraphs, finds span elements inside these, and reverts the
-	 * selection back to the paragraphs.
-	 *
-	 * @name end
-	 * @type jQuery
-	 * @cat DOM/Traversing
-	 */
 	end: function() {
-		return this.prevObject || jQuery([]);
+		return this.prevObject || jQuery( [] );
+	},
+
+	find: function( selector ) {
+		var elems = jQuery.map(this, function(elem){
+			return jQuery.find( selector, elem );
+		});
+
+		return this.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ?
+			jQuery.unique( elems ) :
+			elems );
 	},
 
-	/**
-	 * Searches for all elements that match the specified expression.
-	 
-	 * This method is a good way to find additional descendant
-	 * elements with which to process.
-	 *
-	 * All searching is done using a jQuery expression. The expression can be
-	 * written using CSS 1-3 Selector syntax, or basic XPath.
-	 *
-	 * @example $("p").find("span");
-	 * @before <p><span>Hello</span>, how are you?</p>
-	 * @result [ <span>Hello</span> ]
-	 * @desc Starts with all paragraphs and searches for descendant span
-	 * elements, same as $("p span")
-	 *
-	 * @name find
-	 * @type jQuery
-	 * @param String expr An expression to search with.
-	 * @cat DOM/Traversing
-	 */
-	find: function(t) {
-		return this.pushStack( jQuery.unique( jQuery.map( this, function(a){
-			return jQuery.find(t,a);
-		}) ), t );
-	},
-
-	/**
-	 * Clone matched DOM Elements and select the clones. 
-	 *
-	 * This is useful for moving copies of the elements to another
-	 * location in the DOM.
-	 *
-	 * @example $("b").clone().prependTo("p");
-	 * @before <b>Hello</b><p>, how are you?</p>
-	 * @result <b>Hello</b><p><b>Hello</b>, how are you?</p>
-	 * @desc Clones all b elements (and selects the clones) and prepends them to all paragraphs.
-	 *
-	 * @name clone
-	 * @type jQuery
-	 * @param Boolean deep (Optional) Set to false if you don't want to clone all descendant nodes, in addition to the element itself.
-	 * @cat DOM/Manipulation
-	 */
-	clone: function(deep) {
-		// Need to remove events on the element and its descendants
-		var $this = this.add(this.find("*"));
-		$this.each(function() {
-			this._$events = {};
-			for (var type in this.$events)
-				this._$events[type] = jQuery.extend({},this.$events[type]);
-		}).unbind();
-
+	clone: function( events ) {
 		// Do the clone
-		var r = this.pushStack( jQuery.map( this, function(a){
-			return a.cloneNode( deep != undefined ? deep : true );
-		}) );
-
-		// Add the events back to the original and its descendants
-		$this.each(function() {
-			var events = this._$events;
-			for (var type in events)
-				for (var handler in events[type])
-					jQuery.event.add(this, type, events[type][handler], events[type][handler].data);
-			this._$events = null;
+		var ret = this.map(function(){
+			if ( jQuery.browser.msie && !jQuery.isXMLDoc(this) ) {
+				// IE copies events bound via attachEvent when
+				// using cloneNode. Calling detachEvent on the
+				// clone will also remove the events from the orignal
+				// In order to get around this, we use innerHTML.
+				// Unfortunately, this means some modifications to
+				// attributes in IE that are actually only stored
+				// as properties will not be copied (such as the
+				// the name attribute on an input).
+				var clone = this.cloneNode(true),
+					container = document.createElement("div");
+				container.appendChild(clone);
+				return jQuery.clean([container.innerHTML])[0];
+			} else
+				return this.cloneNode(true);
 		});
 
+		// Need to set the expando to null on the cloned set if it exists
+		// removeData doesn't work here, IE removes it from the original as well
+		// this is primarily for IE but the data expando shouldn't be copied over in any browser
+		var clone = ret.find("*").andSelf().each(function(){
+			if ( this[ expando ] != undefined )
+				this[ expando ] = null;
+		});
+
+		// Copy the events from the original to the clone
+		if ( events === true )
+			this.find("*").andSelf().each(function(i){
+				if (this.nodeType == 3)
+					return;
+				var events = jQuery.data( this, "events" );
+
+				for ( var type in events )
+					for ( var handler in events[ type ] )
+						jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data );
+			});
+
 		// Return the cloned set
-		return r;
+		return ret;
 	},
 
-	/**
-	 * Removes all elements from the set of matched elements that do not
-	 * match the specified expression(s). This method is used to narrow down
-	 * the results of a search.
-	 *
-	 * Provide a comma-separated list of expressions to apply multiple filters at once.
-	 *
-	 * @example $("p").filter(".selected")
-	 * @before <p class="selected">Hello</p><p>How are you?</p>
-	 * @result [ <p class="selected">Hello</p> ]
-	 * @desc Selects all paragraphs and removes those without a class "selected".
-	 *
-	 * @example $("p").filter(".selected, :first")
-	 * @before <p>Hello</p><p>Hello Again</p><p class="selected">And Again</p>
-	 * @result [ <p>Hello</p>, <p class="selected">And Again</p> ]
-	 * @desc Selects all paragraphs and removes those without class "selected" and being the first one.
-	 *
-	 * @name filter
-	 * @type jQuery
-	 * @param String expression Expression(s) to search with.
-	 * @cat DOM/Traversing
-	 */
-	 
-	/**
-	 * Removes all elements from the set of matched elements that do not
-	 * pass the specified filter. This method is used to narrow down
-	 * the results of a search.
-	 *
-	 * @example $("p").filter(function(index) {
-	 *   return $("ol", this).length == 0;
-	 * })
-	 * @before <p><ol><li>Hello</li></ol></p><p>How are you?</p>
-	 * @result [ <p>How are you?</p> ]
-	 * @desc Remove all elements that have a child ol element
-	 *
-	 * @name filter
-	 * @type jQuery
-	 * @param Function filter A function to use for filtering
-	 * @cat DOM/Traversing
-	 */
-	filter: function(t) {
+	filter: function( selector ) {
 		return this.pushStack(
-			jQuery.isFunction( t ) &&
-			jQuery.grep(this, function(el, index){
-				return t.apply(el, [index])
+			jQuery.isFunction( selector ) &&
+			jQuery.grep(this, function(elem, i){
+				return selector.call( elem, i );
 			}) ||
 
-			jQuery.multiFilter(t,this) );
+			jQuery.multiFilter( selector, this ) );
 	},
 
-	/**
-	 * Removes the specified Element from the set of matched elements. This
-	 * method is used to remove a single Element from a jQuery object.
-	 *
-	 * @example $("p").not( $("#selected")[0] )
-	 * @before <p>Hello</p><p id="selected">Hello Again</p>
-	 * @result [ <p>Hello</p> ]
-	 * @desc Removes the element with the ID "selected" from the set of all paragraphs.
-	 *
-	 * @name not
-	 * @type jQuery
-	 * @param Element el An element to remove from the set
-	 * @cat DOM/Traversing
-	 */
-
-	/**
-	 * Removes elements matching the specified expression from the set
-	 * of matched elements. This method is used to remove one or more
-	 * elements from a jQuery object.
-	 *
-	 * @example $("p").not("#selected")
-	 * @before <p>Hello</p><p id="selected">Hello Again</p>
-	 * @result [ <p>Hello</p> ]
-	 * @desc Removes the element with the ID "selected" from the set of all paragraphs.
-	 *
-	 * @name not
-	 * @type jQuery
-	 * @param String expr An expression with which to remove matching elements
-	 * @cat DOM/Traversing
-	 */
-
-	/**
-	 * Removes any elements inside the array of elements from the set
-	 * of matched elements. This method is used to remove one or more
-	 * elements from a jQuery object.
-	 *
-	 * Please note: the expression cannot use a reference to the
-	 * element name. See the two examples below.
-	 *
-	 * @example $("p").not( $("div p.selected") )
-	 * @before <div><p>Hello</p><p class="selected">Hello Again</p></div>
-	 * @result [ <p>Hello</p> ]
-	 * @desc Removes all elements that match "div p.selected" from the total set of all paragraphs.
-	 *
-	 * @name not
-	 * @type jQuery
-	 * @param jQuery elems A set of elements to remove from the jQuery set of matched elements.
-	 * @cat DOM/Traversing
-	 */
-	not: function(t) {
-		return this.pushStack(
-			t.constructor == String &&
-			jQuery.multiFilter(t, this, true) ||
-
-			jQuery.grep(this, function(a) {
-				return ( t.constructor == Array || t.jquery )
-					? jQuery.inArray( a, t ) < 0
-					: a != t;
-			})
-		);
+	not: function( selector ) {
+		if ( selector.constructor == String )
+			// test special case where just one selector is passed in
+			if ( isSimple.test( selector ) )
+				return this.pushStack( jQuery.multiFilter( selector, this, true ) );
+			else
+				selector = jQuery.multiFilter( selector, this );
+
+		var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
+		return this.filter(function() {
+			return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
+		});
+	},
+
+	add: function( selector ) {
+		return this.pushStack( jQuery.unique( jQuery.merge(
+			this.get(),
+			typeof selector == 'string' ?
+				jQuery( selector ) :
+				jQuery.makeArray( selector )
+		)));
+	},
+
+	is: function( selector ) {
+		return !!selector && jQuery.multiFilter( selector, this ).length > 0;
+	},
+
+	hasClass: function( selector ) {
+		return this.is( "." + selector );
 	},
 
-	/**
-	 * Adds more elements, matched by the given expression,
-	 * to the set of matched elements.
-	 *
-	 * @example $("p").add("span")
-	 * @before (HTML) <p>Hello</p><span>Hello Again</span>
-	 * @result (jQuery object matching 2 elements) [ <p>Hello</p>, <span>Hello Again</span> ]
-	 * @desc Compare the above result to the result of <code>$('p')</code>,
-	 * which would just result in <code><nowiki>[ <p>Hello</p> ]</nowiki></code>.
-	 * Using add(), matched elements of <code>$('span')</code> are simply
-	 * added to the returned jQuery-object.
-	 *
-	 * @name add
-	 * @type jQuery
-	 * @param String expr An expression whose matched elements are added
-	 * @cat DOM/Traversing
-	 */
-	 
-	/**
-	 * Adds more elements, created on the fly, to the set of
-	 * matched elements.
-	 *
-	 * @example $("p").add("<span>Again</span>")
-	 * @before <p>Hello</p>
-	 * @result [ <p>Hello</p>, <span>Again</span> ]
-	 *
-	 * @name add
-	 * @type jQuery
-	 * @param String html A string of HTML to create on the fly.
-	 * @cat DOM/Traversing
-	 */
-
-	/**
-	 * Adds one or more Elements to the set of matched elements.
-	 *
-	 * @example $("p").add( document.getElementById("a") )
-	 * @before <p>Hello</p><p><span id="a">Hello Again</span></p>
-	 * @result [ <p>Hello</p>, <span id="a">Hello Again</span> ]
-	 *
-	 * @example $("p").add( document.forms[0].elements )
-	 * @before <p>Hello</p><p><form><input/><button/></form>
-	 * @result [ <p>Hello</p>, <input/>, <button/> ]
-	 *
-	 * @name add
-	 * @type jQuery
-	 * @param Element|Array<Element> elements One or more Elements to add
-	 * @cat DOM/Traversing
-	 */
-	add: function(t) {
-		return this.pushStack( jQuery.merge(
-			this.get(),
-			t.constructor == String ?
-				jQuery(t).get() :
-				t.length != undefined && (!t.nodeName || t.nodeName == "FORM") ?
-					t : [t] )
-		);
-	},
-
-	/**
-	 * Checks the current selection against an expression and returns true,
-	 * if at least one element of the selection fits the given expression.
-	 *
-	 * Does return false, if no element fits or the expression is not valid.
-	 *
-	 * filter(String) is used internally, therefore all rules that apply there
-	 * apply here, too.
-	 *
-	 * @example $("input[@type='checkbox']").parent().is("form")
-	 * @before <form><input type="checkbox" /></form>
-	 * @result true
-	 * @desc Returns true, because the parent of the input is a form element
-	 * 
-	 * @example $("input[@type='checkbox']").parent().is("form")
-	 * @before <form><p><input type="checkbox" /></p></form>
-	 * @result false
-	 * @desc Returns false, because the parent of the input is a p element
-	 *
-	 * @name is
-	 * @type Boolean
-	 * @param String expr The expression with which to filter
-	 * @cat DOM/Traversing
-	 */
-	is: function(expr) {
-		return expr ? jQuery.multiFilter(expr,this).length > 0 : false;
-	},
-	
-	/**
-	 * Get the content of the value attribute of the first matched element.
-	 *
-	 * Use caution when relying on this function to check the value of
-	 * multiple-select elements and checkboxes in a form. While it will
-	 * still work as intended, it may not accurately represent the value
-	 * the server will receive because these elements may send an array
-	 * of values. For more robust handling of field values, see the
-	 * [http://www.malsup.com/jquery/form/#fields fieldValue function of the Form Plugin].
-	 *
-	 * @example $("input").val();
-	 * @before <input type="text" value="some text"/>
-	 * @result "some text"
-	 *
-	 * @name val
-	 * @type String
-	 * @cat DOM/Attributes
-	 */
-	
-	/**
-	 * 	Set the value attribute of every matched element.
-	 *
-	 * @example $("input").val("test");
-	 * @before <input type="text" value="some text"/>
-	 * @result <input type="text" value="test"/>
-	 *
-	 * @name val
-	 * @type jQuery
-	 * @param String val Set the property to the specified value.
-	 * @cat DOM/Attributes
-	 */
-	val: function( val ) {
-		return val == undefined ?
-			( this.length ? this[0].value : null ) :
-			this.attr( "value", val );
-	},
-	
-	/**
-	 * Get the html contents of the first matched element.
-	 * This property is not available on XML documents.
-	 *
-	 * @example $("div").html();
-	 * @before <div><input/></div>
-	 * @result <input/>
-	 *
-	 * @name html
-	 * @type String
-	 * @cat DOM/Attributes
-	 */
-	
-	/**
-	 * Set the html contents of every matched element.
-	 * This property is not available on XML documents.
-	 *
-	 * @example $("div").html("<b>new stuff</b>");
-	 * @before <div><input/></div>
-	 * @result <div><b>new stuff</b></div>
-	 *
-	 * @name html
-	 * @type jQuery
-	 * @param String val Set the html contents to the specified value.
-	 * @cat DOM/Attributes
-	 */
-	html: function( val ) {
-		return val == undefined ?
-			( this.length ? this[0].innerHTML : null ) :
-			this.empty().append( val );
-	},
-	
-	/**
-	 * @private
-	 * @name domManip
-	 * @param Array args
-	 * @param Boolean table Insert TBODY in TABLEs if one is not found.
-	 * @param Number dir If dir<0, process args in reverse order.
-	 * @param Function fn The function doing the DOM manipulation.
-	 * @type jQuery
-	 * @cat Core
-	 */
-	domManip: function(args, table, dir, fn){
-		var clone = this.length > 1, a; 
+	val: function( value ) {
+		if ( value == undefined ) {
+
+			if ( this.length ) {
+				var elem = this[0];
+
+				// We need to handle select boxes special
+				if ( jQuery.nodeName( elem, "select" ) ) {
+					var index = elem.selectedIndex,
+						values = [],
+						options = elem.options,
+						one = elem.type == "select-one";
+
+					// Nothing was selected
+					if ( index < 0 )
+						return null;
+
+					// Loop through all the selected options
+					for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
+						var option = options[ i ];
+
+						if ( option.selected ) {
+							// Get the specifc value for the option
+							value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value;
+
+							// We don't need an array for one selects
+							if ( one )
+								return value;
+
+							// Multi-Selects return an array
+							values.push( value );
+						}
+					}
+
+					return values;
+
+				// Everything else, we just grab the value
+				} else
+					return (this[0].value || "").replace(/\r/g, "");
+
+			}
+
+			return undefined;
+		}
+
+		if( value.constructor == Number )
+			value += '';
 
 		return this.each(function(){
-			if ( !a ) {
-				a = jQuery.clean(args, this.ownerDocument);
-				if ( dir < 0 )
-					a.reverse();
+			if ( this.nodeType != 1 )
+				return;
+
+			if ( value.constructor == Array && /radio|checkbox/.test( this.type ) )
+				this.checked = (jQuery.inArray(this.value, value) >= 0 ||
+					jQuery.inArray(this.name, value) >= 0);
+
+			else if ( jQuery.nodeName( this, "select" ) ) {
+				var values = jQuery.makeArray(value);
+
+				jQuery( "option", this ).each(function(){
+					this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
+						jQuery.inArray( this.text, values ) >= 0);
+				});
+
+				if ( !values.length )
+					this.selectedIndex = -1;
+
+			} else
+				this.value = value;
+		});
+	},
+
+	html: function( value ) {
+		return value == undefined ?
+			(this[0] ?
+				this[0].innerHTML :
+				null) :
+			this.empty().append( value );
+	},
+
+	replaceWith: function( value ) {
+		return this.after( value ).remove();
+	},
+
+	eq: function( i ) {
+		return this.slice( i, i + 1 );
+	},
+
+	slice: function() {
+		return this.pushStack( Array.prototype.slice.apply( this, arguments ) );
+	},
+
+	map: function( callback ) {
+		return this.pushStack( jQuery.map(this, function(elem, i){
+			return callback.call( elem, i, elem );
+		}));
+	},
+
+	andSelf: function() {
+		return this.add( this.prevObject );
+	},
+
+	data: function( key, value ){
+		var parts = key.split(".");
+		parts[1] = parts[1] ? "." + parts[1] : "";
+
+		if ( value === undefined ) {
+			var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
+
+			if ( data === undefined && this.length )
+				data = jQuery.data( this[0], key );
+
+			return data === undefined && parts[1] ?
+				this.data( parts[0] ) :
+				data;
+		} else
+			return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
+				jQuery.data( this, key, value );
+			});
+	},
+
+	removeData: function( key ){
+		return this.each(function(){
+			jQuery.removeData( this, key );
+		});
+	},
+
+	domManip: function( args, table, reverse, callback ) {
+		var clone = this.length > 1, elems;
+
+		return this.each(function(){
+			if ( !elems ) {
+				elems = jQuery.clean( args, this.ownerDocument );
+
+				if ( reverse )
+					elems.reverse();
 			}
 
 			var obj = this;
 
-			if ( table && jQuery.nodeName(this, "table") && jQuery.nodeName(a[0], "tr") )
-				obj = this.getElementsByTagName("tbody")[0] || this.appendChild(document.createElement("tbody"));
-
-			jQuery.each( a, function(){
-				fn.apply( obj, [ clone ? this.cloneNode(true) : this ] );
+			if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) )
+				obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") );
+
+			var scripts = jQuery( [] );
+
+			jQuery.each(elems, function(){
+				var elem = clone ?
+					jQuery( this ).clone( true )[0] :
+					this;
+
+				// execute all scripts after the elements have been injected
+				if ( jQuery.nodeName( elem, "script" ) )
+					scripts = scripts.add( elem );
+				else {
+					// Remove any inner scripts for later evaluation
+					if ( elem.nodeType == 1 )
+						scripts = scripts.add( jQuery( "script", elem ).remove() );
+
+					// Inject the elements into the document
+					callback.call( obj, elem );
+				}
 			});
 
+			scripts.each( evalScript );
 		});
 	}
 };
 
-/**
- * Extends the jQuery object itself. Can be used to add functions into
- * the jQuery namespace and to [[Plugins/Authoring|add plugin methods]] (plugins).
- * 
- * @example jQuery.fn.extend({
- *   check: function() {
- *     return this.each(function() { this.checked = true; });
- *   },
- *   uncheck: function() {
- *     return this.each(function() { this.checked = false; });
- *   }
- * });
- * $("input[@type=checkbox]").check();
- * $("input[@type=radio]").uncheck();
- * @desc Adds two plugin methods.
- *
- * @example jQuery.extend({
- *   min: function(a, b) { return a < b ? a : b; },
- *   max: function(a, b) { return a > b ? a : b; }
- * });
- * @desc Adds two functions into the jQuery namespace
- *
- * @name $.extend
- * @param Object prop The object that will be merged into the jQuery object
- * @type Object
- * @cat Core
- */
-
-/**
- * Extend one object with one or more others, returning the original,
- * modified, object. This is a great utility for simple inheritance.
- * 
- * @example var settings = { validate: false, limit: 5, name: "foo" };
- * var options = { validate: true, name: "bar" };
- * jQuery.extend(settings, options);
- * @result settings == { validate: true, limit: 5, name: "bar" }
- * @desc Merge settings and options, modifying settings
- *
- * @example var defaults = { validate: false, limit: 5, name: "foo" };
- * var options = { validate: true, name: "bar" };
- * var settings = jQuery.extend({}, defaults, options);
- * @result settings == { validate: true, limit: 5, name: "bar" }
- * @desc Merge defaults and options, without modifying the defaults
- *
- * @name $.extend
- * @param Object target The object to extend
- * @param Object prop1 The object that will be merged into the first.
- * @param Object propN (optional) More objects to merge into the first
- * @type Object
- * @cat JavaScript
- */
+// Give the init function the jQuery prototype for later instantiation
+jQuery.fn.init.prototype = jQuery.fn;
+
+function evalScript( i, elem ) {
+	if ( elem.src )
+		jQuery.ajax({
+			url: elem.src,
+			async: false,
+			dataType: "script"
+		});
+
+	else
+		jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
+
+	if ( elem.parentNode )
+		elem.parentNode.removeChild( elem );
+}
+
+function now(){
+	return +new Date;
+}
+
 jQuery.extend = jQuery.fn.extend = function() {
 	// copy reference to target object
-	var target = arguments[0], a = 1;
+	var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
+
+	// Handle a deep copy situation
+	if ( target.constructor == Boolean ) {
+		deep = target;
+		target = arguments[1] || {};
+		// skip the boolean and the target
+		i = 2;
+	}
+
+	// Handle case when target is a string or something (possible in deep copy)
+	if ( typeof target != "object" && typeof target != "function" )
+		target = {};
 
 	// extend jQuery itself if only one argument is passed
-	if ( arguments.length == 1 ) {
+	if ( length == i ) {
 		target = this;
-		a = 0;
+		--i;
 	}
-	var prop;
-	while ( (prop = arguments[a++]) != null )
-		// Extend the base object
-		for ( var i in prop ) target[i] = prop[i];
+
+	for ( ; i < length; i++ )
+		// Only deal with non-null/undefined values
+		if ( (options = arguments[ i ]) != null )
+			// Extend the base object
+			for ( var name in options ) {
+				var src = target[ name ], copy = options[ name ];
+
+				// Prevent never-ending loop
+				if ( target === copy )
+					continue;
+
+				// Recurse if we're merging object values
+				if ( deep && copy && typeof copy == "object" && !copy.nodeType )
+					target[ name ] = jQuery.extend( deep, 
+						// Never move original objects, clone them
+						src || ( copy.length != null ? [ ] : { } )
+					, copy );
+
+				// Don't bring in undefined values
+				else if ( copy !== undefined )
+					target[ name ] = copy;
+
+			}
 
 	// Return the modified object
 	return target;
 };
 
+var expando = "jQuery" + now(), uuid = 0, windowData = {},
+	// exclude the following css properties to add px
+	exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
+	// cache defaultView
+	defaultView = document.defaultView || {};
+
 jQuery.extend({
-	/**
-	 * Run this function to give control of the $ variable back
-	 * to whichever library first implemented it. This helps to make 
-	 * sure that jQuery doesn't conflict with the $ object
-	 * of other libraries.
-	 *
-	 * By using this function, you will only be able to access jQuery
-	 * using the 'jQuery' variable. For example, where you used to do
-	 * $("div p"), you now must do jQuery("div p").
-	 *
-	 * @example jQuery.noConflict();
-	 * // Do something with jQuery
-	 * jQuery("div p").hide();
-	 * // Do something with another library's $()
-	 * $("content").style.display = 'none';
-	 * @desc Maps the original object that was referenced by $ back to $
-	 *
-	 * @example jQuery.noConflict();
-	 * (function($) { 
-	 *   $(function() {
-	 *     // more code using $ as alias to jQuery
-	 *   });
-	 * })(jQuery);
-	 * // other code using $ as an alias to the other library
-	 * @desc Reverts the $ alias and then creates and executes a
-	 * function to provide the $ as a jQuery alias inside the functions
-	 * scope. Inside the function the original $ object is not available.
-	 * This works well for most plugins that don't rely on any other library.
-	 * 
-	 *
-	 * @name $.noConflict
-	 * @type undefined
-	 * @cat Core 
-	 */
-	noConflict: function() {
-		if ( jQuery._$ )
-			$ = jQuery._$;
+	noConflict: function( deep ) {
+		window.$ = _$;
+
+		if ( deep )
+			window.jQuery = _jQuery;
+
 		return jQuery;
 	},
 
-	// This may seem like some crazy code, but trust me when I say that this
-	// is the only cross-browser way to do this. --John
+	// See test/unit/core.js for details concerning this function.
 	isFunction: function( fn ) {
-		return !!fn && typeof fn != "string" && !fn.nodeName && 
-			fn.constructor != Array && /function/i.test( fn + "" );
+		return !!fn && typeof fn != "string" && !fn.nodeName &&
+			fn.constructor != Array && /^[\s[]?function/.test( fn + "" );
+	},
+
+	// check if an element is in a (or is an) XML document
+	isXMLDoc: function( elem ) {
+		return elem.documentElement && !elem.body ||
+			elem.tagName && elem.ownerDocument && !elem.ownerDocument.body;
 	},
-	
-	// check if an element is in a XML document
-	isXMLDoc: function(elem) {
-		return elem.tagName && elem.ownerDocument && !elem.ownerDocument.body;
+
+	// Evalulates a script in a global context
+	globalEval: function( data ) {
+		data = jQuery.trim( data );
+
+		if ( data ) {
+			// Inspired by code by Andrea Giammarchi
+			// http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
+			var head = document.getElementsByTagName("head")[0] || document.documentElement,
+				script = document.createElement("script");
+
+			script.type = "text/javascript";
+			if ( jQuery.browser.msie )
+				script.text = data;
+			else
+				script.appendChild( document.createTextNode( data ) );
+
+			// Use insertBefore instead of appendChild  to circumvent an IE6 bug.
+			// This arises when a base node is used (#2709).
+			head.insertBefore( script, head.firstChild );
+			head.removeChild( script );
+		}
 	},
 
 	nodeName: function( elem, name ) {
 		return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
 	},
 
-	/**
-	 * A generic iterator function, which can be used to seamlessly
-	 * iterate over both objects and arrays. This function is not the same
-	 * as $().each() - which is used to iterate, exclusively, over a jQuery
-	 * object. This function can be used to iterate over anything.
-	 *
-	 * The callback has two arguments:the key (objects) or index (arrays) as first
-	 * the first, and the value as the second.
-	 *
-	 * @example $.each( [0,1,2], function(i, n){
-	 *   alert( "Item #" + i + ": " + n );
-	 * });
-	 * @desc This is an example of iterating over the items in an array,
-	 * accessing both the current item and its index.
-	 *
-	 * @example $.each( { name: "John", lang: "JS" }, function(i, n){
-	 *   alert( "Name: " + i + ", Value: " + n );
-	 * });
-	 *
-	 * @desc This is an example of iterating over the properties in an
-	 * Object, accessing both the current item and its key.
-	 *
-	 * @name $.each
-	 * @param Object obj The object, or array, to iterate over.
-	 * @param Function fn The function that will be executed on every object.
-	 * @type Object
-	 * @cat JavaScript
-	 */
+	cache: {},
+
+	data: function( elem, name, data ) {
+		elem = elem == window ?
+			windowData :
+			elem;
+
+		var id = elem[ expando ];
+
+		// Compute a unique ID for the element
+		if ( !id )
+			id = elem[ expando ] = ++uuid;
+
+		// Only generate the data cache if we're
+		// trying to access or manipulate it
+		if ( name && !jQuery.cache[ id ] )
+			jQuery.cache[ id ] = {};
+
+		// Prevent overriding the named cache with undefined values
+		if ( data !== undefined )
+			jQuery.cache[ id ][ name ] = data;
+
+		// Return the named cache data, or the ID for the element
+		return name ?
+			jQuery.cache[ id ][ name ] :
+			id;
+	},
+
+	removeData: function( elem, name ) {
+		elem = elem == window ?
+			windowData :
+			elem;
+
+		var id = elem[ expando ];
+
+		// If we want to remove a specific section of the element's data
+		if ( name ) {
+			if ( jQuery.cache[ id ] ) {
+				// Remove the section of cache data
+				delete jQuery.cache[ id ][ name ];
+
+				// If we've removed all the data, remove the element's cache
+				name = "";
+
+				for ( name in jQuery.cache[ id ] )
+					break;
+
+				if ( !name )
+					jQuery.removeData( elem );
+			}
+
+		// Otherwise, we want to remove all of the element's data
+		} else {
+			// Clean up the element expando
+			try {
+				delete elem[ expando ];
+			} catch(e){
+				// IE has trouble directly removing the expando
+				// but it's ok with using removeAttribute
+				if ( elem.removeAttribute )
+					elem.removeAttribute( expando );
+			}
+
+			// Completely remove the data cache
+			delete jQuery.cache[ id ];
+		}
+	},
+
 	// args is for internal usage only
-	each: function( obj, fn, args ) {
-		if ( obj.length == undefined )
-			for ( var i in obj )
-				fn.apply( obj[i], args || [i, obj[i]] );
-		else
-			for ( var i = 0, ol = obj.length; i < ol; i++ )
-				if ( fn.apply( obj[i], args || [i, obj[i]] ) === false ) break;
-		return obj;
+	each: function( object, callback, args ) {
+		var name, i = 0, length = object.length;
+
+		if ( args ) {
+			if ( length == undefined ) {
+				for ( name in object )
+					if ( callback.apply( object[ name ], args ) === false )
+						break;
+			} else
+				for ( ; i < length; )
+					if ( callback.apply( object[ i++ ], args ) === false )
+						break;
+
+		// A special, fast, case for the most common use of each
+		} else {
+			if ( length == undefined ) {
+				for ( name in object )
+					if ( callback.call( object[ name ], name, object[ name ] ) === false )
+						break;
+			} else
+				for ( var value = object[0];
+					i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
+		}
+
+		return object;
 	},
-	
-	prop: function(elem, value, type, index, prop){
-			// Handle executable functions
-			if ( jQuery.isFunction( value ) )
-				value = value.call( elem, [index] );
-				
-			// exclude the following css properties to add px
-			var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i;
-
-			// Handle passing in a number to a CSS property
-			return value && value.constructor == Number && type == "curCSS" && !exclude.test(prop) ?
-				value + "px" :
-				value;
+
+	prop: function( elem, value, type, i, name ) {
+		// Handle executable functions
+		if ( jQuery.isFunction( value ) )
+			value = value.call( elem, i );
+
+		// Handle passing in a number to a CSS property
+		return value && value.constructor == Number && type == "curCSS" && !exclude.test( name ) ?
+			value + "px" :
+			value;
 	},
 
 	className: {
 		// internal only, use addClass("class")
-		add: function( elem, c ){
-			jQuery.each( c.split(/\s+/), function(i, cur){
-				if ( !jQuery.className.has( elem.className, cur ) )
-					elem.className += ( elem.className ? " " : "" ) + cur;
+		add: function( elem, classNames ) {
+			jQuery.each((classNames || "").split(/\s+/), function(i, className){
+				if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
+					elem.className += (elem.className ? " " : "") + className;
 			});
 		},
 
 		// internal only, use removeClass("class")
-		remove: function( elem, c ){
-			elem.className = c != undefined ?
-				jQuery.grep( elem.className.split(/\s+/), function(cur){
-					return !jQuery.className.has( c, cur );	
-				}).join(" ") : "";
+		remove: function( elem, classNames ) {
+			if (elem.nodeType == 1)
+				elem.className = classNames != undefined ?
+					jQuery.grep(elem.className.split(/\s+/), function(className){
+						return !jQuery.className.has( classNames, className );
+					}).join(" ") :
+					"";
 		},
 
-		// internal only, use is(".class")
-		has: function( t, c ) {
-			return jQuery.inArray( c, (t.className || t).toString().split(/\s+/) ) > -1;
+		// internal only, use hasClass("class")
+		has: function( elem, className ) {
+			return jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
 		}
 	},
 
-	/**
-	 * Swap in/out style options.
-	 * @private
-	 */
-	swap: function(e,o,f) {
-		for ( var i in o ) {
-			e.style["old"+i] = e.style[i];
-			e.style[i] = o[i];
+	// A method for quickly swapping in/out CSS properties to get correct calculations
+	swap: function( elem, options, callback ) {
+		var old = {};
+		// Remember the old values, and insert the new ones
+		for ( var name in options ) {
+			old[ name ] = elem.style[ name ];
+			elem.style[ name ] = options[ name ];
+		}
+
+		callback.call( elem );
+
+		// Revert the old values
+		for ( var name in options )
+			elem.style[ name ] = old[ name ];
+	},
+
+	css: function( elem, name, force ) {
+		if ( name == "width" || name == "height" ) {
+			var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "