Merge mozilla-central to tracemonkey.
authorRobert Sayre <sayrer@gmail.com>
Sat, 05 Jun 2010 19:13:45 -0400
changeset 43291 09ad04b1a53e3311f7f3aea9f7eb307ea8a1d655
parent 43290 ec31975e7669b9dd194dafab8056e51916e1f063 (current diff)
parent 43105 661a75f690120fd61308e7cec893e866dd9c0e87 (diff)
child 43292 2e63bd6e4e8ee721157503b7b64da26a66528c07
push id13641
push userrsayre@mozilla.com
push dateSun, 06 Jun 2010 19:08:23 +0000
treeherdermozilla-central@5b3604a3cfbe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone1.9.3a5pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-central to tracemonkey.
content/html/content/public/nsIFormSubmission.h
content/media/test/320x240.allow-origin.ogv
content/media/test/320x240.allow-origin.ogv^headers^
content/media/test/test_bug468190.html
content/media/test/test_bug468190_wav.html
content/media/test/test_bug476973.html
content/media/test/test_bug486646.html
content/media/test/test_bug495145_wav.html
content/media/test/test_bug495319.html
content/media/test/test_duration1.html
content/media/test/test_ended1.html
content/media/test/test_ended2.html
content/media/test/test_onloadedmetadata.html
content/media/test/test_play.html
content/media/test/test_progress1.html
content/media/test/test_progress2.html
content/media/test/test_progress3.html
content/media/test/test_progress4.html
content/media/test/test_timeupdate1.html
content/media/test/test_timeupdate2.html
content/media/test/test_wav_onloadedmetadata.html
content/media/test/test_wav_standalone.html
content/media/test/test_wav_timeupdate1.html
content/media/test/test_wav_timeupdate2.html
content/media/test/test_wav_trunc_seek.html
extensions/cookie/test/unit/test_cookies.js
gfx/layers/opengl/LayerManagerOGLShaders.h
js/src/jsdbgapi.cpp
js/src/jsiter.cpp
js/src/jsnativestack.cpp
js/src/jsstr.cpp
js/src/jstracer.cpp
js/src/jstypedarray.cpp
js/src/shell/js.cpp
js/src/xpconnect/src/XPCWrapper.cpp
js/src/xpconnect/src/xpcthreadcontext.cpp
memory/jemalloc/crtvc8sp1.diff
memory/jemalloc/crtvc9sp1.diff
toolkit/components/satchel/src/nsStorageFormHistory.cpp
toolkit/components/satchel/src/nsStorageFormHistory.h
toolkit/themes/pinstripe/mozapps/plugins/pluginCrashed.png
toolkit/themes/pinstripe/mozapps/plugins/pluginOutdated-16.png
toolkit/themes/winstripe/mozapps/plugins/pluginCrashed-aero.png
toolkit/themes/winstripe/mozapps/plugins/pluginCrashed.png
--- a/Makefile.in
+++ b/Makefile.in
@@ -69,22 +69,16 @@ tier_base_dirs += \
 	memory \
 	$(NULL)
 endif
 
 ifdef COMPILE_ENVIRONMENT
 include $(topsrcdir)/$(MOZ_BUILD_APP)/build.mk
 endif
 
-TIERS += testharness
-
-# test harnesses
-ifdef ENABLE_TESTS
-tier_testharness_dirs += testing/xpcshell
-endif
 
 include $(topsrcdir)/config/config.mk
 
 GARBAGE_DIRS += dist _javagen _profile _tests staticlib
 DIST_GARBAGE = config.cache config.log config.status config-defs.h \
    dependencies.beos config/autoconf.mk \
    unallmakefiles mozilla-config.h \
    netwerk/necko-config.h xpcom/xpcom-config.h xpcom/xpcom-private.h \
--- a/accessible/public/nsIAccessibleDocument.idl
+++ b/accessible/public/nsIAccessibleDocument.idl
@@ -53,17 +53,17 @@ interface nsIDOMWindow;
  * You can QueryInterface to nsIAccessibleDocument from
  * the nsIAccessible or nsIAccessNode for the root node
  * of a document. You can also get one from 
  * nsIAccessNode::GetAccessibleDocument() or 
  * nsIAccessibleEvent::GetAccessibleDocument()
  *
  * @status UNDER_REVIEW
  */
-[scriptable, uuid(471909e7-0ea4-4ce0-bf31-a1372b2b285c)]
+[scriptable, uuid(03c6ce8a-aa40-4484-9282-e6579c56e054)]
 interface nsIAccessibleDocument : nsISupports
 {
   /**
    * The URL of the document
    */
   readonly attribute AString URL;
 
   /**
@@ -96,21 +96,9 @@ interface nsIAccessibleDocument : nsISup
    */
   AString getNameSpaceURIForID(in short nameSpaceID);
 
   /**
    * The window handle for the OS window the document is being displayed in.
    * For example, in Windows you can static cast it to an HWND.
    */
   [noscript] readonly attribute voidPtr windowHandle;
-
-  /**
-   * Returns the first accessible parent of a DOM node.
-   * Guaranteed not to return nsnull if the DOM node is in a document.
-   * @param aDOMNode The DOM node we need an accessible for.
-   * @param aCanCreate Can accessibles be created or must it be the first 
-   *                   cached accessible in the parent chain?
-   * @return An first nsIAccessible found by crawling up the DOM node
-   *         to the document root.
-   */
-  nsIAccessible getAccessibleInParentChain(in nsIDOMNode aDOMNode,
-                                           in boolean aCanCreate);
 };
--- a/accessible/src/base/nsAccEvent.cpp
+++ b/accessible/src/base/nsAccEvent.cpp
@@ -309,21 +309,26 @@ nsAccReorderEvent::HasAccessibleInReason
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccStateChangeEvent
 ////////////////////////////////////////////////////////////////////////////////
 
 NS_IMPL_ISUPPORTS_INHERITED1(nsAccStateChangeEvent, nsAccEvent,
                              nsIAccessibleStateChangeEvent)
 
+// Note: we pass in eAllowDupes to the base class because we don't currently
+// support correct state change coalescence (XXX Bug 569356). Also we need to
+// decide how to coalesce events created via accessible (instead of node).
 nsAccStateChangeEvent::
   nsAccStateChangeEvent(nsIAccessible *aAccessible,
                         PRUint32 aState, PRBool aIsExtraState,
-                        PRBool aIsEnabled):
-  nsAccEvent(::nsIAccessibleEvent::EVENT_STATE_CHANGE, aAccessible),
+                        PRBool aIsEnabled, PRBool aIsAsynch,
+                        EIsFromUserInput aIsFromUserInput):
+  nsAccEvent(nsIAccessibleEvent::EVENT_STATE_CHANGE, aAccessible, aIsAsynch,
+             aIsFromUserInput, eAllowDupes),
   mState(aState), mIsExtraState(aIsExtraState), mIsEnabled(aIsEnabled)
 {
 }
 
 nsAccStateChangeEvent::
   nsAccStateChangeEvent(nsIDOMNode *aNode,
                         PRUint32 aState, PRBool aIsExtraState,
                         PRBool aIsEnabled):
@@ -374,22 +379,30 @@ nsAccStateChangeEvent::IsEnabled(PRBool 
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccTextChangeEvent
 ////////////////////////////////////////////////////////////////////////////////
 
 NS_IMPL_ISUPPORTS_INHERITED1(nsAccTextChangeEvent, nsAccEvent,
                              nsIAccessibleTextChangeEvent)
 
+// Note: we pass in eAllowDupes to the base class because we don't support text
+// events coalescence. We fire delayed text change events in nsDocAccessible but
+// we continue to base the event off the accessible object rather than just the
+// node. This means we won't try to create an accessible based on the node when
+// we are ready to fire the event and so we will no longer assert at that point
+// if the node was removed from the document. Either way, the AT won't work with
+// a defunct accessible so the behaviour should be equivalent.
+// XXX revisit this when coalescence is faster (eCoalesceFromSameSubtree)
 nsAccTextChangeEvent::
   nsAccTextChangeEvent(nsIAccessible *aAccessible,
                        PRInt32 aStart, PRUint32 aLength, PRBool aIsInserted,
                        PRBool aIsAsynch, EIsFromUserInput aIsFromUserInput) :
   nsAccEvent(aIsInserted ? nsIAccessibleEvent::EVENT_TEXT_INSERTED : nsIAccessibleEvent::EVENT_TEXT_REMOVED,
-             aAccessible, aIsAsynch, aIsFromUserInput),
+             aAccessible, aIsAsynch, aIsFromUserInput, eAllowDupes),
   mStart(aStart), mLength(aLength), mIsInserted(aIsInserted)
 {
 #ifdef XP_WIN
   nsCOMPtr<nsIAccessibleText> textAccessible = do_QueryInterface(aAccessible);
   NS_ASSERTION(textAccessible, "Should not be firing test change event for non-text accessible!!!");
   if (textAccessible) {
     textAccessible->GetText(aStart, aStart + aLength, mModifiedText);
   }
--- a/accessible/src/base/nsAccEvent.h
+++ b/accessible/src/base/nsAccEvent.h
@@ -193,17 +193,18 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsAccReord
 
 
 class nsAccStateChangeEvent: public nsAccEvent,
                              public nsIAccessibleStateChangeEvent
 {
 public:
   nsAccStateChangeEvent(nsIAccessible *aAccessible,
                         PRUint32 aState, PRBool aIsExtraState,
-                        PRBool aIsEnabled);
+                        PRBool aIsEnabled, PRBool aIsAsynch = PR_FALSE,
+                        EIsFromUserInput aIsFromUserInput = eAutoDetect);
 
   nsAccStateChangeEvent(nsIDOMNode *aNode,
                         PRUint32 aState, PRBool aIsExtraState,
                         PRBool aIsEnabled);
 
   nsAccStateChangeEvent(nsIDOMNode *aNode,
                         PRUint32 aState, PRBool aIsExtraState);
 
--- a/accessible/src/base/nsAccUtils.cpp
+++ b/accessible/src/base/nsAccUtils.cpp
@@ -547,56 +547,56 @@ nsAccUtils::IsARIASelected(nsIAccessible
 
 already_AddRefed<nsIAccessibleText>
 nsAccUtils::GetTextAccessibleFromSelection(nsISelection *aSelection,
                                            nsIDOMNode **aNode)
 {
   // Get accessible from selection's focus DOM point (the DOM point where
   // selection is ended).
 
-  nsCOMPtr<nsIDOMNode> focusNode;
-  aSelection->GetFocusNode(getter_AddRefs(focusNode));
-  if (!focusNode)
+  nsCOMPtr<nsIDOMNode> focusDOMNode;
+  aSelection->GetFocusNode(getter_AddRefs(focusDOMNode));
+  if (!focusDOMNode)
     return nsnull;
 
   PRInt32 focusOffset = 0;
   aSelection->GetFocusOffset(&focusOffset);
 
-  nsCOMPtr<nsIDOMNode> resultNode =
+  nsCOMPtr<nsINode> focusNode(do_QueryInterface(focusDOMNode));
+  nsCOMPtr<nsINode> resultNode =
     nsCoreUtils::GetDOMNodeFromDOMPoint(focusNode, focusOffset);
 
   // Get text accessible containing the result node.
   while (resultNode) {
     // Make sure to get the correct starting node for selection events inside
     // XBL content trees.
-    nsCOMPtr<nsIDOMNode> relevantNode;
-    GetAccService()->GetRelevantContentNodeFor(resultNode, 
-                                               getter_AddRefs(relevantNode));
-    if (relevantNode)
-      resultNode.swap(relevantNode);
+    nsCOMPtr<nsIDOMNode> resultDOMNode(do_QueryInterface(resultNode));
+    nsCOMPtr<nsIDOMNode> relevantDOMNode;
+    GetAccService()->GetRelevantContentNodeFor(resultDOMNode,
+                                               getter_AddRefs(relevantDOMNode));
+    if (relevantDOMNode) {
+      resultNode = do_QueryInterface(relevantDOMNode);
+      resultDOMNode.swap(relevantDOMNode);
+    }
 
-    nsCOMPtr<nsIContent> content = do_QueryInterface(resultNode);
-    if (!content || !content->IsNodeOfType(nsINode::eTEXT)) {
-      nsCOMPtr<nsIAccessible> accessible;
-      GetAccService()->GetAccessibleFor(resultNode, getter_AddRefs(accessible));
+    if (!resultNode || !resultNode->IsNodeOfType(nsINode::eTEXT)) {
+      nsAccessible *accessible = GetAccService()->GetAccessible(resultDOMNode);
       if (accessible) {
         nsIAccessibleText *textAcc = nsnull;
         CallQueryInterface(accessible, &textAcc);
         if (textAcc) {
           if (aNode)
-            NS_ADDREF(*aNode = resultNode);
+            resultDOMNode.forget(aNode);
 
           return textAcc;
         }
       }
     }
 
-    nsCOMPtr<nsIDOMNode> parentNode;
-    resultNode->GetParentNode(getter_AddRefs(parentNode));
-    resultNode.swap(parentNode);
+    resultNode = resultNode->GetParent();
   }
 
   NS_NOTREACHED("No nsIAccessibleText for selection change event!");
 
   return nsnull;
 }
 
 nsresult
@@ -815,45 +815,46 @@ nsAccUtils::IsTextInterfaceSupportCorrec
     if (!text)
       return PR_FALSE;
   }
 
   return PR_TRUE; 
 }
 #endif
 
-PRInt32
-nsAccUtils::TextLength(nsIAccessible *aAccessible)
+PRUint32
+nsAccUtils::TextLength(nsAccessible *aAccessible)
 {
   if (!IsText(aAccessible))
     return 1;
-  
-  nsRefPtr<nsAccessNode> accNode = do_QueryObject(aAccessible);
-  
-  nsIFrame *frame = accNode->GetFrame();
+
+  nsIFrame *frame = aAccessible->GetFrame();
   if (frame && frame->GetType() == nsAccessibilityAtoms::textFrame) {
     // Ensure that correct text length is calculated (with non-rendered
     // whitespace chars not counted).
     nsIContent *content = frame->GetContent();
     if (content) {
       PRUint32 length;
       nsresult rv = nsHyperTextAccessible::
         ContentToRenderedOffset(frame, content->TextLength(), &length);
-      return NS_SUCCEEDED(rv) ? static_cast<PRInt32>(length) : -1;
+      if (NS_FAILED(rv)) {
+        NS_NOTREACHED("Failed to get rendered offset!");
+        return 0;
+      }
+
+      return length;
     }
   }
-  
+
   // For list bullets (or anything other accessible which would compute its own
   // text. They don't have their own frame.
   // XXX In the future, list bullets may have frame and anon content, so 
   // we should be able to remove this at that point
-  nsRefPtr<nsAccessible> acc(do_QueryObject(aAccessible));
-
   nsAutoString text;
-  acc->AppendTextTo(text, 0, PR_UINT32_MAX); // Get all the text
+  aAccessible->AppendTextTo(text, 0, PR_UINT32_MAX); // Get all the text
   return text.Length();
 }
 
 PRBool
 nsAccUtils::MustPrune(nsIAccessible *aAccessible)
 { 
   PRUint32 role = nsAccUtils::Role(aAccessible);
 
--- a/accessible/src/base/nsAccUtils.h
+++ b/accessible/src/base/nsAccUtils.h
@@ -333,19 +333,19 @@ public:
   static PRBool IsText(nsIAccessible *aAcc)
   {
     PRUint32 role = Role(aAcc);
     return role == nsIAccessibleRole::ROLE_TEXT_LEAF ||
            role == nsIAccessibleRole::ROLE_STATICTEXT;
   }
 
   /**
-   * Return text length of the given accessible, return -1 on failure.
+   * Return text length of the given accessible, return 0 on failure.
    */
-  static PRInt32 TextLength(nsIAccessible *aAccessible);
+  static PRUint32 TextLength(nsAccessible *aAccessible);
 
   /**
    * Return true if the given accessible is embedded object.
    */
   static PRBool IsEmbeddedObject(nsIAccessible *aAcc)
   {
     PRUint32 role = Role(aAcc);
     return role != nsIAccessibleRole::ROLE_TEXT_LEAF &&
--- a/accessible/src/base/nsAccessNode.cpp
+++ b/accessible/src/base/nsAccessNode.cpp
@@ -153,17 +153,17 @@ nsAccessNode::Init()
     // No doc accessible yet for this node's document. 
     // There was probably an accessible event fired before the 
     // current document was ever asked for by the assistive technology.
     // Create a doc accessible so we can cache this node
     nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(mWeakShell));
     if (presShell) {
       nsCOMPtr<nsIDOMNode> docNode(do_QueryInterface(presShell->GetDocument()));
       if (docNode) {
-        nsRefPtr<nsAccessible> accessible =
+        nsAccessible *accessible =
           GetAccService()->GetAccessibleInWeakShell(docNode, mWeakShell);
         docAcc = do_QueryObject(accessible);
       }
     }
     NS_ASSERTION(docAcc, "Cannot cache new nsAccessNode");
     if (!docAcc) {
       return NS_ERROR_FAILURE;
     }
@@ -176,23 +176,20 @@ nsAccessNode::Init()
     return NS_ERROR_OUT_OF_MEMORY;
 
   // Make sure an ancestor in real content is cached
   // so that nsDocAccessible::RefreshNodes() can find the anonymous subtree to release when
   // the root node goes away
   nsCOMPtr<nsIContent> content = do_QueryInterface(mDOMNode);
   if (content && content->IsInAnonymousSubtree()) {
     // Specific examples of where this is used: <input type="file"> and <xul:findbar>
-    nsCOMPtr<nsIAccessible> parentAccessible;
-    docAcc->GetAccessibleInParentChain(mDOMNode, PR_TRUE,
-                                       getter_AddRefs(parentAccessible));
-    if (parentAccessible) {
-      PRInt32 childCountUnused;
-      parentAccessible->GetChildCount(&childCountUnused);
-    }
+    nsAccessible *parent = GetAccService()->GetContainerAccessible(mDOMNode,
+                                                                   PR_TRUE);
+    if (parent)
+      parent->EnsureChildren();
   }
 
 #ifdef DEBUG_A11Y
   mIsInitialized = PR_TRUE;
 #endif
 
   return NS_OK;
 }
@@ -503,22 +500,18 @@ nsAccessNode::ScrollToPoint(PRUint32 aCo
 nsresult
 nsAccessNode::MakeAccessNode(nsIDOMNode *aNode, nsIAccessNode **aAccessNode)
 {
   *aAccessNode = nsnull;
   
   nsCOMPtr<nsIAccessNode> accessNode =
     GetAccService()->GetCachedAccessNode(aNode, mWeakShell);
 
-  if (!accessNode) {
-    nsRefPtr<nsAccessible> accessible =
-      GetAccService()->GetAccessibleInWeakShell(aNode, mWeakShell);
-
-    accessNode = accessible;
-  }
+  if (!accessNode)
+    accessNode = GetAccService()->GetAccessibleInWeakShell(aNode, mWeakShell);
 
   if (accessNode) {
     NS_ADDREF(*aAccessNode = accessNode);
     return NS_OK;
   }
 
   nsAccessNode *newAccessNode = new nsAccessNode(aNode, mWeakShell);
   if (!newAccessNode) {
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -263,33 +263,30 @@ nsAccessibilityService::NotifyOfAnchorJu
 {
   nsIDocument *document = aTarget->GetCurrentDoc();
   nsCOMPtr<nsIDOMNode> documentNode(do_QueryInterface(document));
   if (!documentNode)
     return;
 
   nsCOMPtr<nsIDOMNode> targetNode(do_QueryInterface(aTarget));
 
-  nsCOMPtr<nsIAccessible> targetAcc;
-  GetAccessibleFor(targetNode, getter_AddRefs(targetAcc));
+  nsAccessible *targetAcc = GetAccessible(targetNode);
 
   // Getting the targetAcc above will have ensured accessible doc creation.
   // XXX Bug 561683
   nsRefPtr<nsDocAccessible> accessibleDoc =
     nsAccessNode::GetDocAccessibleFor(documentNode);
   if (!accessibleDoc)
     return;
 
   // If the jump target is not accessible then fire an event for nearest
   // accessible in parent chain.
   if (!targetAcc) {
-        accessibleDoc->GetAccessibleInParentChain(targetNode, PR_TRUE,
-                                                  getter_AddRefs(targetAcc));
-        nsCOMPtr<nsIAccessNode> accNode = do_QueryInterface(targetAcc);
-        accNode->GetDOMNode(getter_AddRefs(targetNode));
+    targetAcc = GetContainerAccessible(targetNode, PR_TRUE);
+    targetNode = targetAcc->GetDOMNode();
   }
 
   NS_ASSERTION(targetNode,
       "No accessible in parent chain!? Expect at least a document accessible.");
   if (!targetNode)
     return;
 
   // XXX note in rare cases the node could go away before we flush the queue,
@@ -1171,42 +1168,18 @@ nsAccessibilityService::GetStringRelatio
   * GetAccessibleFor - get an nsIAccessible from a DOM node
   */
 
 NS_IMETHODIMP
 nsAccessibilityService::GetAccessibleFor(nsIDOMNode *aNode,
                                          nsIAccessible **aAccessible)
 {
   NS_ENSURE_ARG_POINTER(aAccessible);
-  *aAccessible = nsnull;
 
-  NS_ENSURE_ARG(aNode);
-
-  nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
-  nsCOMPtr<nsIDocument> doc;
-  if (content) {
-    doc = content->GetDocument();
-  }
-  else {// Could be document node
-    doc = do_QueryInterface(aNode);
-  }
-  if (!doc)
-    return NS_ERROR_FAILURE;
-
-  // We use presentation shell #0 because we assume that is presentation of
-  // given node window.
-  nsIPresShell *presShell = doc->GetPrimaryShell();
-
-  nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(presShell));
-  nsRefPtr<nsAccessible> accessible =
-    GetAccessible(aNode, presShell, weakShell);
-
-  if (accessible)
-    CallQueryInterface(accessible.get(), aAccessible);
-  
+  NS_IF_ADDREF(*aAccessible = GetAccessible(aNode));
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAccessibilityService::GetAttachedAccessibleFor(nsIDOMNode *aNode,
                                                  nsIAccessible **aAccessible)
 {
   NS_ENSURE_ARG(aNode);
@@ -1235,25 +1208,89 @@ nsAccessibilityService::GetAccessibleInS
   nsRefPtr<nsAccessible> accessible =
     GetAccessible(aNode, aPresShell, weakShell);
   return accessible;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessibilityService public
 
-already_AddRefed<nsAccessible>
+nsAccessible *
+nsAccessibilityService::GetAccessible(nsIDOMNode *aNode)
+{
+  if (!aNode)
+    return nsnull;
+
+  nsIPresShell *presShell = nsCoreUtils::GetPresShellFor(aNode);
+  if (!presShell)
+    return nsnull;
+
+  nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(presShell));
+  nsRefPtr<nsAccessible> accessible = GetAccessible(aNode, presShell,
+                                                    weakShell);
+  return accessible;
+}
+
+nsAccessible *
 nsAccessibilityService::GetAccessibleInWeakShell(nsIDOMNode *aNode, 
                                                  nsIWeakReference *aWeakShell) 
 {
   if (!aNode || !aWeakShell)
     return nsnull;
 
   nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(aWeakShell));
-  return GetAccessible(aNode, presShell, aWeakShell);
+  nsRefPtr<nsAccessible> accessible = GetAccessible(aNode, presShell,
+                                                    aWeakShell);
+  return accessible;
+}
+
+nsAccessible *
+nsAccessibilityService::GetContainerAccessible(nsIDOMNode *aNode,
+                                               PRBool aCanCreate)
+{
+  if (!aNode)
+    return nsnull;
+
+  nsCOMPtr<nsINode> currNode(do_QueryInterface(aNode));
+  nsIDocument *document = currNode->GetCurrentDoc();
+  if (!document)
+    return nsnull;
+
+  nsIPresShell *presShell = document->GetPrimaryShell();
+  if (!presShell)
+    return nsnull;
+
+  nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(presShell));
+
+  nsAccessible *accessible = nsnull;
+  while (!accessible && (currNode = currNode->GetNodeParent())) {
+    nsCOMPtr<nsIDOMNode> currDOMNode(do_QueryInterface(currNode));
+
+    nsCOMPtr<nsIDOMNode> relevantDOMNode;
+    GetAccService()->GetRelevantContentNodeFor(currDOMNode,
+                                               getter_AddRefs(relevantDOMNode));
+    if (relevantDOMNode) {
+      currNode = do_QueryInterface(relevantDOMNode);
+      currDOMNode.swap(relevantDOMNode);
+    }
+
+    if (aCanCreate) {
+      accessible =
+        GetAccService()->GetAccessibleInWeakShell(currDOMNode, weakShell);
+
+    } else {
+      // Only return cached accessible, don't create anything.
+      nsRefPtr<nsAccessible> cachedAcc =
+        do_QueryObject(GetCachedAccessNode(currDOMNode, weakShell));
+
+      accessible = cachedAcc;
+    }
+  }
+
+  return accessible;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessibilityService private
 
 PRBool
 nsAccessibilityService::InitAccessible(nsAccessible *aAccessible,
                                        nsRoleMapEntry *aRoleMapEntry)
@@ -1487,17 +1524,17 @@ nsAccessibilityService::GetAccessible(ns
       nsIContent *tableContent = content;
       while ((tableContent = tableContent->GetParent()) != nsnull) {
         nsIFrame *tableFrame = tableContent->GetPrimaryFrame();
         if (!tableFrame)
           continue;
 
         if (tableFrame->GetType() == nsAccessibilityAtoms::tableOuterFrame) {
           nsCOMPtr<nsIDOMNode> tableNode(do_QueryInterface(tableContent));
-          nsRefPtr<nsAccessible> tableAccessible =
+          nsAccessible *tableAccessible =
             GetAccessibleInWeakShell(tableNode, aWeakShell);
 
           if (tableAccessible) {
             if (!roleMapEntry) {
               PRUint32 role = nsAccUtils::Role(tableAccessible);
               if (role != nsIAccessibleRole::ROLE_TABLE &&
                   role != nsIAccessibleRole::ROLE_TREE_TABLE) {
                 // No ARIA role and not in table: override role. For example,
--- a/accessible/src/base/nsAccessibilityService.h
+++ b/accessible/src/base/nsAccessibilityService.h
@@ -168,23 +168,37 @@ public:
    * @param  aIsHidden   [out, optional] indicates whether the node's frame is
    *                       hidden
    */
   already_AddRefed<nsAccessible>
     GetAccessible(nsIDOMNode *aNode, nsIPresShell *aPresShell,
                   nsIWeakReference *aWeakShell, PRBool *aIsHidden = nsnull);
 
   /**
+   * Return an accessible for the given DOM node.
+   */
+  nsAccessible *GetAccessible(nsIDOMNode *aNode);
+
+  /**
    * Return an accessible for a DOM node in the given pres shell.
    * 
    * @param aNode       [in] the given node.
    * @param aPresShell  [in] the presentation shell of the given node.
    */
-  already_AddRefed<nsAccessible>
-    GetAccessibleInWeakShell(nsIDOMNode *aNode, nsIWeakReference *aPresShell);
+  nsAccessible *GetAccessibleInWeakShell(nsIDOMNode *aNode,
+                                         nsIWeakReference *aPresShell);
+
+  /**
+   * Return the first accessible parent of a DOM node.
+   *
+   * @param aDOMNode    [in] the DOM node to get an accessible for
+   * @param aCanCreate  [in] specifies if accessible can be created if it didn't
+   *                     exist
+   */
+  nsAccessible *GetContainerAccessible(nsIDOMNode *aNode, PRBool aCanCreate);
 
   /**
    * Return an access node for the DOM node in the given presentation shell if
    * the access node already exists, otherwise null.
    *
    * @param  aNode       [in] the DOM node to get an access node for
    * @param  aPresShell  [in] the presentation shell which contains layout info
    *                       for the DOM node
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -854,23 +854,21 @@ nsAccessible::GetChildAtPoint(PRInt32 aX
   nsCOMPtr<nsIDOMNode> relevantNode;
   GetAccService()->GetRelevantContentNodeFor(node,
                                              getter_AddRefs(relevantNode));
   if (!relevantNode) {
     NS_IF_ADDREF(*aChild = fallbackAnswer);
     return NS_OK;
   }
 
-  nsCOMPtr<nsIAccessible> accessible;
-  GetAccService()->GetAccessibleFor(relevantNode, getter_AddRefs(accessible));
+  nsAccessible *accessible = GetAccService()->GetAccessible(relevantNode);
   if (!accessible) {
     // No accessible for the node with the point, so find the first
     // accessible in the DOM parent chain
-    accDocument->GetAccessibleInParentChain(relevantNode, PR_TRUE,
-                                            getter_AddRefs(accessible));
+    accessible = GetAccService()->GetContainerAccessible(relevantNode, PR_TRUE);
     if (!accessible) {
       NS_IF_ADDREF(*aChild = fallbackAnswer);
       return NS_OK;
     }
   }
 
   if (accessible == this) {
     // Manually walk through accessible children and see if the are within this
@@ -2708,32 +2706,29 @@ nsAccessible::GetSelected(PRBool *aSelec
 }
 
 nsresult
 nsAccessible::GetLinkOffset(PRInt32 *aStartOffset, PRInt32 *aEndOffset)
 {
   nsAccessible *parent = GetParent();
   NS_ENSURE_STATE(parent);
 
-  PRInt32 characterCount = 0;
+  PRUint32 characterCount = 0;
 
   PRInt32 childCount = parent->GetChildCount();
   for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) {
     nsAccessible *sibling = parent->GetChildAt(childIdx);
 
     if (sibling == this) {
       *aStartOffset = characterCount;
       *aEndOffset = characterCount + 1;
       return NS_OK;
     }
 
-    if (nsAccUtils::IsText(sibling))
-      characterCount += nsAccUtils::TextLength(sibling);
-    else
-      ++ characterCount;
+    characterCount += nsAccUtils::TextLength(sibling);
   }
 
   return NS_ERROR_FAILURE;
 }
 
 nsresult
 nsAccessible::AppendTextTo(nsAString& aText, PRUint32 aStartOffset, PRUint32 aLength)
 {
@@ -2820,37 +2815,36 @@ nsAccessible*
 nsAccessible::GetParent()
 {
   if (IsDefunct())
     return nsnull;
 
   if (mParent)
     return mParent;
 
+#ifdef DEBUG
   nsDocAccessible *docAccessible = GetDocAccessible();
   NS_ASSERTION(docAccessible, "No document accessible for valid accessible!");
-
-  if (!docAccessible)
+#endif
+
+  nsAccessible *parent = GetAccService()->GetContainerAccessible(mDOMNode,
+                                                                 PR_TRUE);
+  NS_ASSERTION(parent, "No accessible parent for valid accessible!");
+  if (!parent)
     return nsnull;
 
-  nsCOMPtr<nsIAccessible> parent;
-  docAccessible->GetAccessibleInParentChain(mDOMNode, PR_TRUE,
-                                            getter_AddRefs(parent));
-
-  nsRefPtr<nsAccessible> parentAcc = do_QueryObject(parent);
-
 #ifdef DEBUG
-  NS_ASSERTION(!parentAcc->IsDefunct(), "Defunct parent!");
-
-  parentAcc->EnsureChildren();
+  NS_ASSERTION(!parent->IsDefunct(), "Defunct parent!");
+
+  parent->EnsureChildren();
   if (parent != mParent)
     NS_WARNING("Bad accessible tree!");
 #endif
 
-  return parentAcc;
+  return parent;
 }
 
 nsAccessible*
 nsAccessible::GetChildAt(PRUint32 aIndex)
 {
   if (EnsureChildren())
     return nsnull;
 
@@ -2997,27 +2991,27 @@ nsAccessible::GetSiblingAtOffset(PRInt32
 
   nsAccessible *child = parent->GetChildAt(indexInParent + aOffset);
   if (aError && !child)
     *aError = NS_ERROR_UNEXPECTED;
 
   return child;
 }
 
-already_AddRefed<nsAccessible>
-nsAccessible::GetFirstAvailableAccessible(nsIDOMNode *aStartNode)
+nsAccessible *
+nsAccessible::GetFirstAvailableAccessible(nsIDOMNode *aStartNode) const
 {
   nsCOMPtr<nsIDOMTreeWalker> walker; 
   nsCOMPtr<nsIDOMNode> currentNode(aStartNode);
 
   while (currentNode) {
-    nsRefPtr<nsAccessible> accessible =
+    nsAccessible *accessible =
       GetAccService()->GetAccessibleInWeakShell(currentNode, mWeakShell);
     if (accessible)
-      return accessible.forget();
+      return accessible;
 
     if (!walker) {
       // Instantiate walker lazily since we won't need it in 90% of the cases
       // where the first DOM node we're given provides an accessible
       nsCOMPtr<nsIDOMDocument> document;
       currentNode->GetOwnerDocument(getter_AddRefs(document));
       nsCOMPtr<nsIDOMDocumentTraversal> trav = do_QueryInterface(document);
       NS_ASSERTION(trav, "No DOM document traversal for document");
--- a/accessible/src/base/nsAccessible.h
+++ b/accessible/src/base/nsAccessible.h
@@ -333,19 +333,18 @@ protected:
 
   /**
    * Return an accessible for the given DOM node, or if that node isn't
    * accessible, return the accessible for the next DOM node which has one
    * (based on forward depth first search).
    *
    * @param  aStartNode  [in] the DOM node to start from
    * @return              the resulting accessible
-   */   
-  already_AddRefed<nsAccessible>
-    GetFirstAvailableAccessible(nsIDOMNode *aStartNode);
+   */
+  nsAccessible *GetFirstAvailableAccessible(nsIDOMNode *aStartNode) const;
 
   // Hyperlink helpers
   virtual nsresult GetLinkOffset(PRInt32* aStartOffset, PRInt32* aEndOffset);
 
   //////////////////////////////////////////////////////////////////////////////
   // Action helpers
 
   /**
--- a/accessible/src/base/nsBaseWidgetAccessible.cpp
+++ b/accessible/src/base/nsBaseWidgetAccessible.cpp
@@ -102,32 +102,32 @@ nsLinkableAccessible::
 NS_IMPL_ISUPPORTS_INHERITED0(nsLinkableAccessible, nsAccessibleWrap)
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsLinkableAccessible. nsIAccessible
 
 NS_IMETHODIMP
 nsLinkableAccessible::TakeFocus()
 {
-  nsRefPtr<nsAccessible> actionAcc = GetActionAccessible();
+  nsAccessible *actionAcc = GetActionAccessible();
   if (actionAcc)
     return actionAcc->TakeFocus();
 
   return nsAccessibleWrap::TakeFocus();
 }
 
 nsresult
 nsLinkableAccessible::GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState)
 {
   nsresult rv = nsAccessibleWrap::GetStateInternal(aState, aExtraState);
   NS_ENSURE_A11Y_SUCCESS(rv, rv);
 
   if (mIsLink) {
     *aState |= nsIAccessibleStates::STATE_LINKED;
-    nsRefPtr<nsAccessible> actionAcc = GetActionAccessible();
+    nsAccessible *actionAcc = GetActionAccessible();
     if (nsAccUtils::State(actionAcc) & nsIAccessibleStates::STATE_TRAVERSED)
       *aState |= nsIAccessibleStates::STATE_TRAVERSED;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
@@ -135,17 +135,17 @@ nsLinkableAccessible::GetValue(nsAString
 {
   aValue.Truncate();
 
   nsAccessible::GetValue(aValue);
   if (!aValue.IsEmpty())
     return NS_OK;
 
   if (mIsLink) {
-    nsRefPtr<nsAccessible> actionAcc = GetActionAccessible();
+    nsAccessible *actionAcc = GetActionAccessible();
     if (actionAcc)
       return actionAcc->GetValue(aValue);
   }
 
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 
@@ -178,44 +178,44 @@ nsLinkableAccessible::GetActionName(PRUi
   return NS_ERROR_INVALID_ARG;
 }
 
 NS_IMETHODIMP
 nsLinkableAccessible::DoAction(PRUint8 aIndex)
 {
   if (aIndex != eAction_Jump)
     return NS_ERROR_INVALID_ARG;
-  
-  nsRefPtr<nsAccessible> actionAcc = GetActionAccessible();
+
+  nsAccessible *actionAcc = GetActionAccessible();
   if (actionAcc)
     return actionAcc->DoAction(aIndex);
   
   return nsAccessibleWrap::DoAction(aIndex);
 }
 
 NS_IMETHODIMP
 nsLinkableAccessible::GetKeyboardShortcut(nsAString& aKeyboardShortcut)
 {
   aKeyboardShortcut.Truncate();
 
-  nsRefPtr<nsAccessible> actionAcc = GetActionAccessible();
+  nsAccessible *actionAcc = GetActionAccessible();
   if (actionAcc)
     return actionAcc->GetKeyboardShortcut(aKeyboardShortcut);
 
   return nsAccessible::GetKeyboardShortcut(aKeyboardShortcut);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsLinkableAccessible. nsIAccessibleHyperLink
 
 NS_IMETHODIMP
 nsLinkableAccessible::GetURI(PRInt32 aIndex, nsIURI **aURI)
 {
   if (mIsLink) {
-    nsRefPtr<nsAccessible> actionAcc = GetActionAccessible();
+    nsAccessible *actionAcc = GetActionAccessible();
     if (actionAcc) {
       nsCOMPtr<nsIAccessibleHyperLink> hyperLinkAcc = do_QueryObject(actionAcc);
       NS_ASSERTION(hyperLinkAcc,
                    "nsIAccessibleHyperLink isn't implemented.");
 
       if (hyperLinkAcc)
         return hyperLinkAcc->GetURI(aIndex, aURI);
     }
@@ -256,17 +256,17 @@ nsLinkableAccessible::CacheActionContent
     return;
   }
 
   while ((walkUpContent = walkUpContent->GetParent())) {
     isOnclick = nsCoreUtils::HasClickListener(walkUpContent);
   
     nsCOMPtr<nsIDOMNode> walkUpNode(do_QueryInterface(walkUpContent));
 
-    nsRefPtr<nsAccessible> walkUpAcc =
+    nsAccessible *walkUpAcc =
       GetAccService()->GetAccessibleInWeakShell(walkUpNode, mWeakShell);
 
     if (nsAccUtils::Role(walkUpAcc) == nsIAccessibleRole::ROLE_LINK &&
         nsAccUtils::State(walkUpAcc) & nsIAccessibleStates::STATE_LINKED) {
       mIsLink = PR_TRUE;
       mActionContent = walkUpContent;
       return;
     }
@@ -274,18 +274,18 @@ nsLinkableAccessible::CacheActionContent
     if (isOnclick) {
       mActionContent = walkUpContent;
       mIsOnclick = PR_TRUE;
       return;
     }
   }
 }
 
-already_AddRefed<nsAccessible>
-nsLinkableAccessible::GetActionAccessible()
+nsAccessible *
+nsLinkableAccessible::GetActionAccessible() const
 {
   // Return accessible for the action content if it's different from node of
   // this accessible. If the action accessible is not null then it is used to
   // redirect methods calls otherwise we use method implementation from the
   // base class.
   nsCOMPtr<nsIDOMNode> actionNode(do_QueryInterface(mActionContent));
   if (!actionNode || mDOMNode == actionNode)
     return nsnull;
--- a/accessible/src/base/nsBaseWidgetAccessible.h
+++ b/accessible/src/base/nsBaseWidgetAccessible.h
@@ -105,17 +105,17 @@ public:
 
   // nsAccessible
   virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
 
 protected:
   /**
    * Return an accessible for cached action node.
    */
-  already_AddRefed<nsAccessible> GetActionAccessible();
+  nsAccessible *GetActionAccessible() const;
 
   /**
    * Cache action node.
    */
   virtual void CacheActionContent();
 
   nsCOMPtr<nsIContent> mActionContent;
   PRPackedBool mIsLink;
--- a/accessible/src/base/nsCoreUtils.cpp
+++ b/accessible/src/base/nsCoreUtils.cpp
@@ -265,39 +265,32 @@ nsCoreUtils::GetDOMElementFor(nsIDOMNode
 
     nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(node));
     domDoc->GetDocumentElement(&element);
   }
 
   return element;
 }
 
-already_AddRefed<nsIDOMNode>
-nsCoreUtils::GetDOMNodeFromDOMPoint(nsIDOMNode *aNode, PRUint32 aOffset)
+nsINode *
+nsCoreUtils::GetDOMNodeFromDOMPoint(nsINode *aNode, PRUint32 aOffset)
 {
-  nsIDOMNode *resultNode = nsnull;
-
-  nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
-  if (content && content->IsElement()) {
-
-    PRUint32 childCount = content->GetChildCount();
+  if (aNode && aNode->IsElement()) {
+    PRUint32 childCount = aNode->GetChildCount();
     NS_ASSERTION(aOffset >= 0 && aOffset <= childCount,
                  "Wrong offset of the DOM point!");
 
     // The offset can be after last child of container node that means DOM point
     // is placed immediately after the last child. In this case use the DOM node
     // from the given DOM point is used as result node.
-    if (aOffset != childCount) {
-      CallQueryInterface(content->GetChildAt(aOffset), &resultNode);
-      return resultNode;
-    }
+    if (aOffset != childCount)
+      return aNode->GetChildAt(aOffset);
   }
 
-  NS_IF_ADDREF(resultNode = aNode);
-  return resultNode;
+  return aNode;
 }
 
 nsIContent*
 nsCoreUtils::GetRoleContent(nsIDOMNode *aDOMNode)
 {
   nsCOMPtr<nsIContent> content(do_QueryInterface(aDOMNode));
   if (!content) {
     nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(aDOMNode));
--- a/accessible/src/base/nsCoreUtils.h
+++ b/accessible/src/base/nsCoreUtils.h
@@ -124,18 +124,18 @@ public:
    *
    * @param aNode  [in] the given DOM node
    */
   static already_AddRefed<nsIDOMElement> GetDOMElementFor(nsIDOMNode *aNode);
 
   /**
    * Return DOM node for the given DOM point.
    */
-  static already_AddRefed<nsIDOMNode> GetDOMNodeFromDOMPoint(nsIDOMNode *aNode,
-                                                             PRUint32 aOffset);
+  static nsINode *GetDOMNodeFromDOMPoint(nsINode *aNode, PRUint32 aOffset);
+
   /**
    * Return the nsIContent* to check for ARIA attributes on -- this may not
    * always be the DOM node for the accessible. Specifically, for doc
    * accessibles, it is not the document node, but either the root element or
    * <body> in HTML. Similar with GetDOMElementFor() method.
    *
    * @param aDOMNode  DOM node for the accessible that may be affected by ARIA
    * @return          the nsIContent which may have ARIA markup
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -978,20 +978,23 @@ void nsDocAccessible::ScrollPositionDidC
 ////////////////////////////////////////////////////////////////////////////////
 // nsIObserver
 
 NS_IMETHODIMP nsDocAccessible::Observe(nsISupports *aSubject, const char *aTopic,
                                        const PRUnichar *aData)
 {
   if (!nsCRT::strcmp(aTopic,"obs_documentCreated")) {    
     // State editable will now be set, readonly is now clear
+    // Normally we only fire delayed events created from the node, not an
+    // accessible object. See the nsAccStateChangeEvent constructor for details
+    // about this exceptional case.
     nsRefPtr<nsAccEvent> event =
       new nsAccStateChangeEvent(this, nsIAccessibleStates::EXT_STATE_EDITABLE,
                                 PR_TRUE, PR_TRUE);
-    nsEventShell::FireEvent(event);
+    FireDelayedAccessibleEvent(event);
   }
 
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIDocumentObserver
 
@@ -1450,19 +1453,19 @@ nsDocAccessible::FireTextChangeEventForT
   if (!mIsContentLoaded || !mDocument) {
     return;
   }
 
   nsCOMPtr<nsIDOMNode> node(do_QueryInterface(aContent));
   if (!node)
     return;
 
-  nsCOMPtr<nsIAccessible> accessible;
-  nsresult rv = GetAccessibleInParentChain(node, PR_TRUE, getter_AddRefs(accessible));
-  if (NS_FAILED(rv) || !accessible)
+  nsAccessible *accessible = GetAccService()->GetContainerAccessible(node,
+                                                                     PR_TRUE);
+  if (!accessible)
     return;
 
   nsRefPtr<nsHyperTextAccessible> textAccessible(do_QueryObject(accessible));
   if (!textAccessible)
     return;
 
   PRInt32 start = aInfo->mChangeStart;
 
@@ -1474,40 +1477,43 @@ nsDocAccessible::FireTextChangeEventForT
     aInfo->mChangeEnd - start; // text has been removed
 
   if (length > 0) {
     PRUint32 renderedStartOffset, renderedEndOffset;
     nsIFrame* frame = aContent->GetPrimaryFrame();
     if (!frame)
       return;
 
-    rv = textAccessible->ContentToRenderedOffset(frame, start,
-                                                 &renderedStartOffset);
+    nsresult rv = textAccessible->ContentToRenderedOffset(frame, start,
+                                                          &renderedStartOffset);
     if (NS_FAILED(rv))
       return;
 
     rv = textAccessible->ContentToRenderedOffset(frame, start + length,
                                                  &renderedEndOffset);
     if (NS_FAILED(rv))
       return;
 
+    // Normally we only fire delayed events created from the node, not an
+    // accessible object. See the nsAccTextChangeEvent constructor for details
+    // about this exceptional case.
     nsRefPtr<nsAccEvent> event =
       new nsAccTextChangeEvent(accessible, offset,
                                renderedEndOffset - renderedStartOffset,
                                aIsInserted, PR_FALSE);
-    nsEventShell::FireEvent(event);
+    FireDelayedAccessibleEvent(event);
 
     FireValueChangeForTextFields(accessible);
   }
 }
 
 already_AddRefed<nsAccEvent>
-nsDocAccessible::CreateTextChangeEventForNode(nsIAccessible *aContainerAccessible,
+nsDocAccessible::CreateTextChangeEventForNode(nsAccessible *aContainerAccessible,
                                               nsIDOMNode *aChangeNode,
-                                              nsIAccessible *aAccessibleForChangeNode,
+                                              nsAccessible *aAccessibleForChangeNode,
                                               PRBool aIsInserting,
                                               PRBool aIsAsynch,
                                               EIsFromUserInput aIsFromUserInput)
 {
   nsRefPtr<nsHyperTextAccessible> textAccessible =
     do_QueryObject(aContainerAccessible);
   if (!textAccessible) {
     return nsnull;
@@ -1601,18 +1607,19 @@ nsDocAccessible::FireDelayedAccessibleEv
     mEventQueue->Push(aEvent);
 
   return NS_OK;
 }
 
 void
 nsDocAccessible::ProcessPendingEvent(nsAccEvent *aEvent)
 {  
-  nsCOMPtr<nsIAccessible> accessible;
-  aEvent->GetAccessible(getter_AddRefs(accessible));
+  nsCOMPtr<nsIAccessible> acc;
+  aEvent->GetAccessible(getter_AddRefs(acc));
+  nsRefPtr<nsAccessible> accessible(do_QueryObject(acc));
 
   nsCOMPtr<nsIDOMNode> domNode;
   aEvent->GetDOMNode(getter_AddRefs(domNode));
 
   PRUint32 eventType = aEvent->GetEventType();
   EIsFromUserInput isFromUserInput =
     aEvent->IsFromUserInput() ? eFromUserInput : eNoUserInput;
 
@@ -1640,32 +1647,30 @@ nsDocAccessible::ProcessPendingEvent(nsA
         return;
       }
       gLastFocusedFrameType = newFrameType;
     }
   }
 
   if (eventType == nsIAccessibleEvent::EVENT_SHOW) {
 
-    nsCOMPtr<nsIAccessible> containerAccessible;
+    nsAccessible *containerAccessible = nsnull;
     if (accessible)
-      accessible->GetParent(getter_AddRefs(containerAccessible));
+      containerAccessible = accessible->GetParent();
 
     if (!containerAccessible) {
-      GetAccessibleInParentChain(domNode, PR_TRUE,
-                                 getter_AddRefs(containerAccessible));
+      containerAccessible = GetAccService()->GetContainerAccessible(domNode,
+                                                                    PR_TRUE);
       if (!containerAccessible)
         containerAccessible = this;
     }
 
     if (isAsync) {
       // For asynch show, delayed invalidatation of parent's children
-      nsRefPtr<nsAccessible> containerAcc = do_QueryObject(containerAccessible);
-      if (containerAcc)
-        containerAcc->InvalidateChildren();
+      containerAccessible->InvalidateChildren();
 
       // Some show events in the subtree may have been removed to 
       // avoid firing redundant events. But, we still need to make sure any
       // accessibles parenting those shown nodes lose their child references.
       InvalidateChildrenInSubtree(domNode);
     }
 
     // Also fire text changes if the node being created could affect the text in an nsIAccessibleText parent.
@@ -1695,17 +1700,17 @@ nsDocAccessible::ProcessPendingEvent(nsA
     if (eventType == nsIAccessibleEvent::EVENT_INTERNAL_LOAD) {
       nsRefPtr<nsDocAccessible> docAcc = do_QueryObject(accessible);
       NS_ASSERTION(docAcc, "No doc accessible for doc load event");
 
       if (docAcc)
         docAcc->FireDocLoadEvents(nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE);
     }
     else if (eventType == nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED) {
-      nsCOMPtr<nsIAccessibleText> accessibleText = do_QueryInterface(accessible);
+      nsCOMPtr<nsIAccessibleText> accessibleText = do_QueryObject(accessible);
       PRInt32 caretOffset;
       if (accessibleText && NS_SUCCEEDED(accessibleText->GetCaretOffset(&caretOffset))) {
 #ifdef DEBUG_A11Y
         PRUnichar chAtOffset;
         accessibleText->GetCharacterAtOffset(caretOffset, &chAtOffset);
         printf("\nCaret moved to %d with char %c", caretOffset, chAtOffset);
 #endif
 #ifdef DEBUG_CARET
@@ -1910,34 +1915,33 @@ nsDocAccessible::InvalidateCacheSubtree(
 
     nsIEventStateManager *esm = presShell->GetPresContext()->EventStateManager();
     NS_ENSURE_TRUE(esm,);
 
     if (!esm->IsHandlingUserInputExternal()) {
       // Changes during page load, but not caused by user input
       // Just invalidate accessible hierarchy and return,
       // otherwise the page load time slows down way too much
-      nsCOMPtr<nsIAccessible> containerAccessible;
-      GetAccessibleInParentChain(childNode, PR_FALSE, getter_AddRefs(containerAccessible));
+      nsAccessible *containerAccessible =
+        GetAccService()->GetContainerAccessible(childNode, PR_FALSE);
       if (!containerAccessible) {
         containerAccessible = this;
       }
 
-      nsRefPtr<nsAccessible> containerAcc = do_QueryObject(containerAccessible);
-      containerAcc->InvalidateChildren();
+      containerAccessible->InvalidateChildren();
       return;
     }     
     // else: user input, so we must fall through and for full handling,
     // e.g. fire the mutation events. Note: user input could cause DOM_CREATE
     // during page load if user typed into an input field or contentEditable area
   }
 
   // Update last change state information
-  nsCOMPtr<nsIAccessNode> childAccessNode = GetCachedAccessNode(childNode);
-  nsCOMPtr<nsIAccessible> childAccessible = do_QueryInterface(childAccessNode);
+  nsRefPtr<nsAccessible> childAccessible =
+    do_QueryObject(GetCachedAccessNode(childNode));
 
 #ifdef DEBUG_A11Y
   nsAutoString localName;
   childNode->GetLocalName(localName);
   const char *hasAccessible = childAccessible ? " (acc)" : "";
   if (aChangeType == nsIAccessibilityService::FRAME_HIDE)
     printf("[Hide %s %s]\n", NS_ConvertUTF16toUTF8(localName).get(), hasAccessible);
   else if (aChangeType == nsIAccessibilityService::FRAME_SHOW)
@@ -1947,18 +1951,18 @@ nsDocAccessible::InvalidateCacheSubtree(
   else if (aChangeType == nsIAccessibilityService::NODE_APPEND)
     printf("[Create %s %s]\n", NS_ConvertUTF16toUTF8(localName).get(), hasAccessible);
   else if (aChangeType == nsIAccessibilityService::NODE_REMOVE)
     printf("[Destroy  %s %s]\n", NS_ConvertUTF16toUTF8(localName).get(), hasAccessible);
   else if (aChangeType == nsIAccessibilityService::NODE_SIGNIFICANT_CHANGE)
     printf("[Type change %s %s]\n", NS_ConvertUTF16toUTF8(localName).get(), hasAccessible);
 #endif
 
-  nsCOMPtr<nsIAccessible> containerAccessible;
-  GetAccessibleInParentChain(childNode, PR_TRUE, getter_AddRefs(containerAccessible));
+  nsAccessible *containerAccessible =
+    GetAccService()->GetContainerAccessible(childNode, PR_TRUE);
   if (!containerAccessible) {
     containerAccessible = this;
   }
 
   if (!isShowing) {
     // Fire EVENT_HIDE.
     if (isHiding) {
       nsCOMPtr<nsIContent> content(do_QueryInterface(childNode));
@@ -1988,40 +1992,40 @@ nsDocAccessible::InvalidateCacheSubtree(
       return;
 
     if (childNode != mDOMNode) { // Fire text change unless the node being removed is for this doc
       // When a node is hidden or removed, the text in an ancestor hyper text will lose characters
       // At this point we still have the frame and accessible for this node if there was one
       // XXX Collate events when a range is deleted
       // XXX We need a way to ignore SplitNode and JoinNode() when they
       // do not affect the text within the hypertext
+      // Normally we only fire delayed events created from the node, not an
+      // accessible object. See the nsAccTextChangeEvent constructor for details
+      // about this exceptional case.
       nsRefPtr<nsAccEvent> textChangeEvent =
         CreateTextChangeEventForNode(containerAccessible, childNode, childAccessible,
                                      PR_FALSE, isAsynch);
       if (textChangeEvent) {
-        nsEventShell::FireEvent(textChangeEvent);
+        FireDelayedAccessibleEvent(textChangeEvent);
       }
     }
   }
 
   // We need to get an accessible for the mutation event's container node
   // If there is no accessible for that node, we need to keep moving up the parent
   // chain so there is some accessible.
   // We will use this accessible to fire the accessible mutation event.
   // We're guaranteed success, because we will eventually end up at the doc accessible,
   // and there is always one of those.
 
   if (aChild && !isHiding) {
     if (!isAsynch) {
       // DOM already updated with new objects -- invalidate parent's children now
       // For asynch we must wait until layout updates before we invalidate the children
-      nsRefPtr<nsAccessible> containerAcc = do_QueryObject(containerAccessible);
-      if (containerAcc)
-        containerAcc->InvalidateChildren();
-
+      containerAccessible->InvalidateChildren();
     }
 
     // Fire EVENT_SHOW, EVENT_MENUPOPUP_START for newly visible content.
 
     // Fire after a short timer, because we want to make sure the view has been
     // updated to make this accessible content visible. If we don't wait,
     // the assistive technology may receive the event and then retrieve
     // nsIAccessibleStates::STATE_INVISIBLE for the event's accessible object.
@@ -2078,56 +2082,16 @@ nsDocAccessible::InvalidateCacheSubtree(
     new nsAccReorderEvent(containerAccessible, isAsynch,
                           isUnconditionalEvent,
                           aChild ? childNode.get() : nsnull);
   NS_ENSURE_TRUE(reorderEvent,);
 
   FireDelayedAccessibleEvent(reorderEvent);
 }
 
-// nsIAccessibleDocument method
-NS_IMETHODIMP
-nsDocAccessible::GetAccessibleInParentChain(nsIDOMNode *aNode,
-                                            PRBool aCanCreate,
-                                            nsIAccessible **aAccessible)
-{
-  // Find accessible in parent chain of DOM nodes, or return null
-  *aAccessible = nsnull;
-  nsCOMPtr<nsIDOMNode> currentNode(aNode), parentNode;
-  nsCOMPtr<nsIAccessNode> accessNode;
-
-  do {
-    currentNode->GetParentNode(getter_AddRefs(parentNode));
-    currentNode = parentNode;
-    if (!currentNode) {
-      NS_ADDREF_THIS();
-      *aAccessible = this;
-      break;
-    }
-
-    nsCOMPtr<nsIDOMNode> relevantNode;
-    if (NS_SUCCEEDED(GetAccService()->GetRelevantContentNodeFor(currentNode, getter_AddRefs(relevantNode))) && relevantNode) {
-      currentNode = relevantNode;
-    }
-    if (aCanCreate) {
-      nsRefPtr<nsAccessible> acc =
-        GetAccService()->GetAccessibleInWeakShell(currentNode, mWeakShell);
-      if (acc)
-        CallQueryInterface(acc, aAccessible);
-    }
-    else { // Only return cached accessibles, don't create anything
-      nsAccessNode* accessNode = GetCachedAccessNode(currentNode);
-      if (accessNode)
-        CallQueryInterface(accessNode, aAccessible);
-    }
-  } while (!*aAccessible);
-
-  return NS_OK;
-}
-
 nsresult
 nsDocAccessible::FireShowHideEvents(nsIDOMNode *aDOMNode,
                                     PRBool aAvoidOnThisNode,
                                     PRUint32 aEventType,
                                     EEventFiringType aDelayedOrNormal,
                                     PRBool aIsAsyncChange,
                                     EIsFromUserInput aIsFromUserInput)
 {
--- a/accessible/src/base/nsDocAccessible.h
+++ b/accessible/src/base/nsDocAccessible.h
@@ -252,19 +252,19 @@ protected:
    * @param  aAccessible           [in] the accessible for that node, or nsnull
    *                                 if none exists
    * @param  aIsInserting          [in] is aChangeNode being created or shown
    *                                 (vs. removed or hidden)
    * @param  aIsAsync              [in] whether casual change is async
    * @param  aIsFromUserInput      [in] the event is known to be from user input
    */
   already_AddRefed<nsAccEvent>
-    CreateTextChangeEventForNode(nsIAccessible *aContainerAccessible,
+    CreateTextChangeEventForNode(nsAccessible *aContainerAccessible,
                                  nsIDOMNode *aNode,
-                                 nsIAccessible *aAccessible,
+                                 nsAccessible *aAccessible,
                                  PRBool aIsInserting,
                                  PRBool aIsAsynch,
                                  EIsFromUserInput aIsFromUserInput = eAutoDetect);
 
   /**
    * Used to define should the event be fired on a delay.
    */
   enum EEventFiringType {
--- a/accessible/src/base/nsTextAttrs.cpp
+++ b/accessible/src/base/nsTextAttrs.cpp
@@ -76,56 +76,84 @@ static nsCSSTextAttrMapItem gCSSTextAttr
   { "text-decoration",   "underline",     &nsAccessibilityAtoms::textUnderlineStyle,    "solid" },
   { "vertical-align",    kAnyValue,       &nsAccessibilityAtoms::textPosition,          kCopyValue }
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsTextAttrs
 
 nsTextAttrsMgr::nsTextAttrsMgr(nsHyperTextAccessible *aHyperTextAcc,
-                               nsIDOMNode *aHyperTextNode,
                                PRBool aIncludeDefAttrs,
-                               nsIDOMNode *aOffsetNode) :
-  mHyperTextAcc(aHyperTextAcc), mHyperTextNode(aHyperTextNode),
-  mIncludeDefAttrs(aIncludeDefAttrs), mOffsetNode(aOffsetNode)
+                               nsAccessible *aOffsetAcc,
+                               PRInt32 aOffsetAccIdx) :
+  mHyperTextAcc(aHyperTextAcc), mIncludeDefAttrs(aIncludeDefAttrs),
+  mOffsetAcc(aOffsetAcc), mOffsetAccIdx(aOffsetAccIdx)
 {
 }
 
 nsresult
 nsTextAttrsMgr::GetAttributes(nsIPersistentProperties *aAttributes,
                               PRInt32 *aStartHTOffset,
                               PRInt32 *aEndHTOffset)
 {
-  // 1. Hyper text accessible and its DOM node must be specified always.
-  // 2. Offset DOM node and result hyper text offsets must be specifed in
+  // 1. Hyper text accessible must be specified always.
+  // 2. Offset accessible and result hyper text offsets must be specified in
   // the case of text attributes.
-  // 3. Offset DOM node and result hyper text offsets must not be specifed but
-  // include default text attributes flag and attributes list must be specified
-  // in the case of default text attributes.
-  NS_PRECONDITION(mHyperTextAcc && mHyperTextNode &&
-                  ((mOffsetNode && aStartHTOffset && aEndHTOffset) ||
-                  (!mOffsetNode && !aStartHTOffset && !aEndHTOffset &&
+  // 3. Offset accessible and result hyper text offsets must not be specified
+  // but include default text attributes flag and attributes list must be
+  // specified in the case of default text attributes.
+  NS_PRECONDITION(mHyperTextAcc &&
+                  ((mOffsetAcc && mOffsetAccIdx != -1 &&
+                    aStartHTOffset && aEndHTOffset) ||
+                  (!mOffsetAcc && mOffsetAccIdx == -1 &&
+                    !aStartHTOffset && !aEndHTOffset &&
                    mIncludeDefAttrs && aAttributes)),
                   "Wrong usage of nsTextAttrsMgr!");
 
+  // Embedded objects are combined into own range with empty attributes set.
+  if (mOffsetAcc && nsAccUtils::IsEmbeddedObject(mOffsetAcc)) {
+    for (PRInt32 childIdx = mOffsetAccIdx - 1; childIdx >= 0; childIdx--) {
+      nsAccessible *currAcc = mHyperTextAcc->GetChildAt(childIdx);
+      if (!nsAccUtils::IsEmbeddedObject(currAcc))
+        break;
+
+      (*aStartHTOffset)--;
+    }
+
+    PRInt32 childCount = mHyperTextAcc->GetChildCount();
+    for (PRInt32 childIdx = mOffsetAccIdx + 1; childIdx < childCount;
+         childIdx++) {
+      nsAccessible *currAcc = mHyperTextAcc->GetChildAt(childIdx);
+      if (!nsAccUtils::IsEmbeddedObject(currAcc))
+        break;
+
+      (*aEndHTOffset)++;
+    }
+
+    return NS_OK;
+  }
+
+  nsIDOMNode *hyperTextNode = mHyperTextAcc->GetDOMNode();
   nsCOMPtr<nsIDOMElement> hyperTextElm =
-    nsCoreUtils::GetDOMElementFor(mHyperTextNode);
+    nsCoreUtils::GetDOMElementFor(mHyperTextAcc->GetDOMNode());
+  nsIFrame *rootFrame = nsCoreUtils::GetFrameFor(hyperTextElm);
+
+  nsIDOMNode *offsetNode = nsnull;
   nsCOMPtr<nsIDOMElement> offsetElm;
-  if (mOffsetNode)
-    offsetElm = nsCoreUtils::GetDOMElementFor(mOffsetNode);
-
-  nsIFrame *rootFrame = nsCoreUtils::GetFrameFor(hyperTextElm);
   nsIFrame *frame = nsnull;
-  if (offsetElm)
+  if (mOffsetAcc) {
+    offsetNode = mOffsetAcc->GetDOMNode();
+    offsetElm = nsCoreUtils::GetDOMElementFor(offsetNode);
     frame = nsCoreUtils::GetFrameFor(offsetElm);
+  }
 
   nsTPtrArray<nsITextAttr> textAttrArray(10);
 
   // "language" text attribute
-  nsLangTextAttr langTextAttr(mHyperTextAcc, mHyperTextNode, mOffsetNode);
+  nsLangTextAttr langTextAttr(mHyperTextAcc, hyperTextNode, offsetNode);
   textAttrArray.AppendElement(static_cast<nsITextAttr*>(&langTextAttr));
 
   // "color" text attribute
   nsCSSTextAttr colorTextAttr(0, hyperTextElm, offsetElm);
   textAttrArray.AppendElement(static_cast<nsITextAttr*>(&colorTextAttr));
 
   // "font-family" text attribute
   nsCSSTextAttr fontFamilyTextAttr(1, hyperTextElm, offsetElm);
@@ -169,232 +197,89 @@ nsTextAttrsMgr::GetAttributes(nsIPersist
       if (textAttr->GetValue(value, mIncludeDefAttrs))
         nsAccUtils::SetAccAttr(aAttributes, textAttr->GetName(), value);
     }
   }
 
   nsresult rv = NS_OK;
 
   // Expose text attributes range where they are applied if applicable.
-  if (mOffsetNode)
+  if (mOffsetAcc)
     rv = GetRange(textAttrArray, aStartHTOffset, aEndHTOffset);
 
   textAttrArray.Clear();
   return rv;
 }
 
 nsresult
 nsTextAttrsMgr::GetRange(const nsTPtrArray<nsITextAttr>& aTextAttrArray,
                          PRInt32 *aStartHTOffset, PRInt32 *aEndHTOffset)
 {
-  nsCOMPtr<nsIDOMElement> rootElm =
-    nsCoreUtils::GetDOMElementFor(mHyperTextNode);
-  NS_ENSURE_STATE(rootElm);
+  PRUint32 attrLen = aTextAttrArray.Length();
 
-  nsCOMPtr<nsIDOMNode> tmpNode(mOffsetNode);
-  nsCOMPtr<nsIDOMNode> currNode(mOffsetNode);
-
-  PRUint32 len = aTextAttrArray.Length();
+  // Navigate backward from anchor accessible to find start offset.
+  for (PRInt32 childIdx = mOffsetAccIdx - 1; childIdx >= 0; childIdx--) {
+    nsAccessible *currAcc = mHyperTextAcc->GetChildAt(childIdx);
 
-  // Navigate backwards and forwards from current node to the root node to
-  // calculate range bounds for the text attribute. Navigation sequence is the
-  // following:
-  // 1. Navigate through the siblings.
-  // 2. If the traversed sibling has children then navigate from its leaf child
-  //    to it through whole tree of the traversed sibling.
-  // 3. Get the parent and cycle algorithm until the root node.
+    // Stop on embedded accessible since embedded accessibles are combined into
+    // own range.
+    if (nsAccUtils::IsEmbeddedObject(currAcc))
+      break;
 
-  // Navigate backwards (find the start offset).
-  while (currNode && currNode != rootElm) {
-    nsCOMPtr<nsIDOMElement> currElm(nsCoreUtils::GetDOMElementFor(currNode));
+    nsCOMPtr<nsIDOMElement> currElm =
+      nsCoreUtils::GetDOMElementFor(currAcc->GetDOMNode());
     NS_ENSURE_STATE(currElm);
 
-    if (currNode != mOffsetNode) {
-      PRBool stop = PR_FALSE;
-      for (PRUint32 idx = 0; idx < len; idx++) {
-        nsITextAttr *textAttr = aTextAttrArray[idx];
-        if (!textAttr->Equal(currElm)) {
-
-          PRInt32 startHTOffset = 0;
-          nsAccessible *startAcc = mHyperTextAcc->
-            DOMPointToHypertextOffset(tmpNode, -1, &startHTOffset);
-
-          if (!startAcc)
-            startHTOffset = 0;
-
-          if (startHTOffset > *aStartHTOffset)
-            *aStartHTOffset = startHTOffset;
-
-          stop = PR_TRUE;
-          break;
-        }
-      }
-      if (stop)
-        break;
-    }
-
-    currNode->GetPreviousSibling(getter_AddRefs(tmpNode));
-    if (tmpNode) {
-      // Navigate through the subtree of traversed children to calculate
-      // left bound of the range.
-      FindStartOffsetInSubtree(aTextAttrArray, tmpNode, currNode,
-                               aStartHTOffset);
-    }
-
-    currNode->GetParentNode(getter_AddRefs(tmpNode));
-    currNode.swap(tmpNode);
-  }
-
-  // Navigate forwards (find the end offset).
-  PRBool moveIntoSubtree = PR_TRUE;
-  currNode = mOffsetNode;
-
-  while (currNode && currNode != rootElm) {
-    nsCOMPtr<nsIDOMElement> currElm(nsCoreUtils::GetDOMElementFor(currNode));
-    NS_ENSURE_STATE(currElm);
-
-    // Stop new end offset searching if the given text attribute changes its
-    // value.
-    PRBool stop = PR_FALSE;
-    for (PRUint32 idx = 0; idx < len; idx++) {
-      nsITextAttr *textAttr = aTextAttrArray[idx];
+    PRBool offsetFound = PR_FALSE;
+    for (PRUint32 attrIdx = 0; attrIdx < attrLen; attrIdx++) {
+      nsITextAttr *textAttr = aTextAttrArray[attrIdx];
       if (!textAttr->Equal(currElm)) {
-
-        PRInt32 endHTOffset = 0;
-        mHyperTextAcc->DOMPointToHypertextOffset(currNode, -1, &endHTOffset);
-
-        if (endHTOffset < *aEndHTOffset)
-          *aEndHTOffset = endHTOffset;
-
-        stop = PR_TRUE;
+        offsetFound = PR_TRUE;
         break;
       }
     }
 
-    if (stop)
+    if (offsetFound)
+      break;
+
+    *(aStartHTOffset) -= nsAccUtils::TextLength(currAcc);
+  }
+
+  // Navigate forward from anchor accessible to find end offset.
+  PRInt32 childLen = mHyperTextAcc->GetChildCount();
+  for (PRInt32 childIdx = mOffsetAccIdx + 1; childIdx < childLen; childIdx++) {
+    nsAccessible *currAcc = mHyperTextAcc->GetChildAt(childIdx);
+    if (nsAccUtils::IsEmbeddedObject(currAcc))
       break;
 
-    if (moveIntoSubtree) {
-      // Navigate through subtree of traversed node. We use 'moveIntoSubtree'
-      // flag to avoid traversing the same subtree twice.
-      currNode->GetFirstChild(getter_AddRefs(tmpNode));
-      if (tmpNode)
-        FindEndOffsetInSubtree(aTextAttrArray, tmpNode, aEndHTOffset);
+    nsCOMPtr<nsIDOMElement> currElm =
+      nsCoreUtils::GetDOMElementFor(currAcc->GetDOMNode());
+    NS_ENSURE_STATE(currElm);
+
+    PRBool offsetFound = PR_FALSE;
+    for (PRUint32 attrIdx = 0; attrIdx < attrLen; attrIdx++) {
+      nsITextAttr *textAttr = aTextAttrArray[attrIdx];
+
+      // Alter the end offset when text attribute changes its value and stop
+      // the search.
+      if (!textAttr->Equal(currElm)) {
+        offsetFound = PR_TRUE;
+        break;
+      }
     }
 
-    currNode->GetNextSibling(getter_AddRefs(tmpNode));
-    moveIntoSubtree = PR_TRUE;
-    if (!tmpNode) {
-      currNode->GetParentNode(getter_AddRefs(tmpNode));
-      moveIntoSubtree = PR_FALSE;
-    }
+    if (offsetFound)
+      break;
 
-    currNode.swap(tmpNode);
+    (*aEndHTOffset) += nsAccUtils::TextLength(currAcc);
   }
 
   return NS_OK;
 }
 
-PRBool
-nsTextAttrsMgr::FindEndOffsetInSubtree(const nsTPtrArray<nsITextAttr>& aTextAttrArray,
-                                       nsIDOMNode *aCurrNode,
-                                       PRInt32 *aHTOffset)
-{
-  if (!aCurrNode)
-    return PR_FALSE;
-
-  nsCOMPtr<nsIDOMElement> currElm(nsCoreUtils::GetDOMElementFor(aCurrNode));
-  if (!currElm)
-    return PR_FALSE;
-
-  // If the given text attribute (pointed by nsTextAttr object) changes its
-  // value on the traversed element then fit the end of range.
-  PRUint32 len = aTextAttrArray.Length();
-  for (PRUint32 idx = 0; idx < len; idx++) {
-    nsITextAttr *textAttr = aTextAttrArray[idx];
-    if (!textAttr->Equal(currElm)) {
-      PRInt32 endHTOffset = 0;
-      mHyperTextAcc->DOMPointToHypertextOffset(aCurrNode, -1, &endHTOffset);
-      if (endHTOffset < *aHTOffset)
-        *aHTOffset = endHTOffset;
-
-      return PR_TRUE;
-    }
-  }
-
-  // Deeply traverse into the tree to fit the end of range.
-  nsCOMPtr<nsIDOMNode> nextNode;
-  aCurrNode->GetFirstChild(getter_AddRefs(nextNode));
-  if (nextNode) {
-    PRBool res = FindEndOffsetInSubtree(aTextAttrArray, nextNode, aHTOffset);
-    if (res)
-      return res;
-  }
-
-  aCurrNode->GetNextSibling(getter_AddRefs(nextNode));
-  if (nextNode) {
-    if (FindEndOffsetInSubtree(aTextAttrArray, nextNode, aHTOffset))
-      return PR_TRUE;
-  }
-
-  return PR_FALSE;
-}
-
-PRBool
-nsTextAttrsMgr::FindStartOffsetInSubtree(const nsTPtrArray<nsITextAttr>& aTextAttrArray,
-                                         nsIDOMNode *aCurrNode,
-                                         nsIDOMNode *aPrevNode,
-                                         PRInt32 *aHTOffset)
-{
-  if (!aCurrNode)
-    return PR_FALSE;
-
-  // Find the closest element back to the traversed element.
-  nsCOMPtr<nsIDOMNode> nextNode;
-  aCurrNode->GetLastChild(getter_AddRefs(nextNode));
-  if (nextNode) {
-    if (FindStartOffsetInSubtree(aTextAttrArray, nextNode, aPrevNode, aHTOffset))
-      return PR_TRUE;
-  }
-
-  nsCOMPtr<nsIDOMElement> currElm(nsCoreUtils::GetDOMElementFor(aCurrNode));
-  if (!currElm)
-    return PR_FALSE;
-
-  // If the given text attribute (pointed by nsTextAttr object) changes its
-  // value on the traversed element then fit the start of range.
-  PRUint32 len = aTextAttrArray.Length();
-  for (PRUint32 idx = 0; idx < len; idx++) {
-    nsITextAttr *textAttr = aTextAttrArray[idx];
-    if (!textAttr->Equal(currElm)) {
-
-      PRInt32 startHTOffset = 0;
-      nsAccessible *startAcc = mHyperTextAcc->
-        DOMPointToHypertextOffset(aPrevNode, -1, &startHTOffset);
-
-      if (!startAcc)
-        startHTOffset = 0;
-
-      if (startHTOffset > *aHTOffset)
-        *aHTOffset = startHTOffset;
-
-      return PR_TRUE;
-    }
-  }
-
-  // Moving backwards to find the start of range.
-  aCurrNode->GetPreviousSibling(getter_AddRefs(nextNode));
-  if (nextNode) {
-    if (FindStartOffsetInSubtree(aTextAttrArray, nextNode, aCurrNode, aHTOffset))
-      return PR_TRUE;
-  }
-
-  return PR_FALSE;
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // nsLangTextAttr
 
 nsLangTextAttr::nsLangTextAttr(nsHyperTextAccessible *aRootAcc, 
                                nsIDOMNode *aRootNode, nsIDOMNode *aNode) :
   nsTextAttr<nsAutoString>(aNode == nsnull)
 {
   mRootContent = do_QueryInterface(aRootNode);
--- a/accessible/src/base/nsTextAttrs.h
+++ b/accessible/src/base/nsTextAttrs.h
@@ -64,32 +64,32 @@ class nsITextAttr;
  * @note "invalid: spelling" text attrbiute is implemented entirerly in
  *       nsHyperTextAccessible class.
  */
 class nsTextAttrsMgr
 {
 public:
   /**
    * Constructor. If instance of the class is intended to expose default text
-   * attributes then 'aIncludeDefAttrs' and 'oOffsetNode' argument must be
+   * attributes then 'aIncludeDefAttrs' and 'aOffsetNode' argument must be
    * skiped.
    *
    * @param aHyperTextAcc    hyper text accessible text attributes are
    *                         calculated for
    * @param aHyperTextNode   DOM node of the given hyper text accessbile
    * @param aIncludeDefAttrs [optional] indicates whether default text
    *                         attributes should be included into list of exposed
    *                         text attributes.
    * @param oOffsetNode      [optional] DOM node represents hyper text offset
    *                         inside hyper text accessible
    */
   nsTextAttrsMgr(nsHyperTextAccessible *aHyperTextAcc,
-                 nsIDOMNode *aHyperTextNode,
                  PRBool aIncludeDefAttrs = PR_TRUE,
-                 nsIDOMNode *oOffsetNode = nsnull);
+                 nsAccessible *aOffsetAcc = nsnull,
+                 PRInt32 aOffsetAccIdx = -1);
 
   /*
    * Return text attributes and hyper text offsets where these attributes are
    * applied. Offsets are calculated in the case of non default attributes.
    *
    * @note In the case of default attributes pointers on hyper text offsets
    *       must be skiped.
    *
@@ -110,51 +110,23 @@ protected:
    *
    * @param aTextAttrArray  [in] text attributes array
    * @param aStartHTOffset  [in, out] the start offset
    * @param aEndHTOffset    [in, out] the end offset
    */
    nsresult GetRange(const nsTPtrArray<nsITextAttr>& aTextAttrArray,
                      PRInt32 *aStartHTOffset, PRInt32 *aEndHTOffset);
 
-  /*
-   * Find new end offset for text attributes navigating through the tree. New
-   * end offset may be smaller if one of text attributes changes its value
-   * before the given end offset.
-   *
-   * @param  aTextAttrArray  [in] text attributes array
-   * @param  aCurrNode       [in] the first node of the tree
-   * @param  aHTOffset       [in, out] the end offset
-   * @return                 true if the end offset has been changed
-   */
-   PRBool FindEndOffsetInSubtree(const nsTPtrArray<nsITextAttr>& aTextAttrArray,
-                                 nsIDOMNode *aCurrNode, PRInt32 *aHTOffset);
-
-  /*
-   * Find the start offset for text attributes navigating through the tree. New
-   * start offset may be bigger if one of text attributes changes its value
-   * after the given start offset.
-   *
-   * @param  aTextAttrArray  [in] text attributes array
-   * @param  aCurrNode       [in] the node navigating through thee thee is
-   *                         started from
-   * @param  aPrevNode       [in] the previous node placed before the start node
-   * @param  aHTOffset       [in, out] the start offset
-   * @return                 true if the start offset has been changed
-   */
-   PRBool FindStartOffsetInSubtree(const nsTPtrArray<nsITextAttr>& aTextAttrArray,
-                                   nsIDOMNode *aCurrNode, nsIDOMNode *aPrevNode,
-                                   PRInt32 *aHTOffset);
-
 private:
   nsRefPtr<nsHyperTextAccessible> mHyperTextAcc;
-  nsCOMPtr<nsIDOMNode> mHyperTextNode;
 
   PRBool mIncludeDefAttrs;
-  nsCOMPtr<nsIDOMNode> mOffsetNode;
+
+  nsRefPtr<nsAccessible> mOffsetAcc;
+  PRInt32 mOffsetAccIdx;
 };
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // Private implementation details
 
 /**
  * Interface class of text attribute class implementations.
--- a/accessible/src/html/nsHTMLSelectAccessible.cpp
+++ b/accessible/src/html/nsHTMLSelectAccessible.cpp
@@ -115,29 +115,29 @@ void nsHTMLSelectableAccessible::iterato
     (*aSelectionCount)++;
 }
 
 void
 nsHTMLSelectableAccessible::iterator::AddAccessibleIfSelected(nsIMutableArray *aSelectedAccessibles, 
                                                               nsPresContext *aContext)
 {
   PRBool isSelected = PR_FALSE;
-  nsRefPtr<nsAccessible> tempAcc;
+  nsAccessible *optionAcc = nsnull;
 
   if (mOption) {
     mOption->GetSelected(&isSelected);
     if (isSelected) {
       nsCOMPtr<nsIDOMNode> optionNode(do_QueryInterface(mOption));
-      tempAcc = GetAccService()->GetAccessibleInWeakShell(optionNode,
-                                                          mWeakShell);
+      optionAcc = GetAccService()->GetAccessibleInWeakShell(optionNode,
+                                                            mWeakShell);
     }
   }
 
-  if (tempAcc)
-    aSelectedAccessibles->AppendElement(static_cast<nsIAccessible*>(tempAcc),
+  if (optionAcc)
+    aSelectedAccessibles->AppendElement(static_cast<nsIAccessible*>(optionAcc),
                                         PR_FALSE);
 }
 
 PRBool
 nsHTMLSelectableAccessible::iterator::GetAccessibleIfSelected(PRInt32 aIndex,
                                                               nsPresContext *aContext, 
                                                               nsIAccessible **aAccessible)
 {
@@ -145,20 +145,19 @@ nsHTMLSelectableAccessible::iterator::Ge
 
   *aAccessible = nsnull;
 
   if (mOption) {
     mOption->GetSelected(&isSelected);
     if (isSelected) {
       if (mSelCount == aIndex) {
         nsCOMPtr<nsIDOMNode> optionNode(do_QueryInterface(mOption));
-        nsRefPtr<nsAccessible> acc =
+        nsAccessible *accessible =
           GetAccService()->GetAccessibleInWeakShell(optionNode, mWeakShell);
-        if (acc)
-          CallQueryInterface(acc, aAccessible);
+        NS_IF_ADDREF(*aAccessible = accessible);
 
         return PR_TRUE;
       }
       mSelCount++;
     }
   }
 
   return PR_FALSE;
@@ -397,21 +396,21 @@ nsHTMLSelectListAccessible::CacheOptSibl
 
     nsCOMPtr<nsIAtom> tag = childContent->Tag();
     if (tag == nsAccessibilityAtoms::option ||
         tag == nsAccessibilityAtoms::optgroup) {
 
       // Get an accessible for option or optgroup and cache it.
       nsCOMPtr<nsIDOMNode> childNode(do_QueryInterface(childContent));
 
-      nsRefPtr<nsAccessible> acc =
+      nsAccessible *accessible =
         GetAccService()->GetAccessibleInWeakShell(childNode, mWeakShell);
-      if (acc) {
-        mChildren.AppendElement(acc);
-        acc->SetParent(this);
+      if (accessible) {
+        mChildren.AppendElement(accessible);
+        accessible->SetParent(this);
       }
 
       // Deep down into optgroup element.
       if (tag == nsAccessibilityAtoms::optgroup)
         CacheOptSiblings(childContent);
     }
   }
 }
@@ -431,17 +430,17 @@ nsHTMLSelectOptionAccessible::
   if (!parentNode)
     return;
 
   // If the parent node is a Combobox, then the option's accessible parent
   // is nsHTMLComboboxListAccessible, not the nsHTMLComboboxAccessible that
   // GetParent would normally return. This is because the 
   // nsHTMLComboboxListAccessible is inserted into the accessible hierarchy
   // where there is no DOM node for it.
-  nsRefPtr<nsAccessible> parentAcc =
+  nsAccessible *parentAcc =
     GetAccService()->GetAccessibleInWeakShell(parentNode, mWeakShell);
   if (!parentAcc)
     return;
 
   if (nsAccUtils::RoleInternal(parentAcc) == nsIAccessibleRole::ROLE_COMBOBOX) {
     PRInt32 childCount = parentAcc->GetChildCount();
     parentAcc = parentAcc->GetChildAt(childCount - 1);
   }
@@ -1004,21 +1003,21 @@ NS_IMETHODIMP nsHTMLComboboxAccessible::
   aDescription.Truncate();
   // First check to see if combo box itself has a description, perhaps through
   // tooltip (title attribute) or via aria-describedby
   nsAccessible::GetDescription(aDescription);
   if (!aDescription.IsEmpty()) {
     return NS_OK;
   }
   // Use description of currently focused option
-  nsRefPtr<nsAccessible> optionAcc = GetFocusedOptionAccessible();
-  return optionAcc ? optionAcc->GetDescription(aDescription) : NS_OK;
+  nsAccessible *option = GetFocusedOptionAccessible();
+  return option ? option->GetDescription(aDescription) : NS_OK;
 }
 
-already_AddRefed<nsAccessible>
+nsAccessible *
 nsHTMLComboboxAccessible::GetFocusedOptionAccessible()
 {
   if (IsDefunct())
     return nsnull;
 
   nsCOMPtr<nsIDOMNode> focusedOptionNode;
   nsHTMLSelectOptionAccessible::
     GetFocusedOptionNode(mDOMNode, getter_AddRefs(focusedOptionNode));
@@ -1033,18 +1032,18 @@ nsHTMLComboboxAccessible::GetFocusedOpti
 /**
   * MSAA/ATK accessible value != HTML value, especially not in combo boxes.
   * Our accessible value is the text label for of our ( first ) selected child.
   * The easiest way to get this is from the first child which is the readonly textfield.
   */
 NS_IMETHODIMP nsHTMLComboboxAccessible::GetValue(nsAString& aValue)
 {
   // Use accessible name of currently focused option.
-  nsRefPtr<nsAccessible> optionAcc = GetFocusedOptionAccessible();
-  return optionAcc ? optionAcc->GetName(aValue) : NS_OK;
+  nsAccessible *option = GetFocusedOptionAccessible();
+  return option ? option->GetName(aValue) : NS_OK;
 }
 
 /** Just one action ( click ). */
 NS_IMETHODIMP nsHTMLComboboxAccessible::GetNumActions(PRUint8 *aNumActions)
 {
   *aNumActions = 1;
   return NS_OK;
 }
--- a/accessible/src/html/nsHTMLSelectAccessible.h
+++ b/accessible/src/html/nsHTMLSelectAccessible.h
@@ -239,17 +239,17 @@ protected:
   // nsAccessible
   virtual void CacheChildren();
 
   // nsHTMLComboboxAccessible
 
   /**
    * Return focused option accessible.
    */
-  already_AddRefed<nsAccessible> GetFocusedOptionAccessible();
+  nsAccessible *GetFocusedOptionAccessible();
 
 private:
   nsRefPtr<nsHTMLComboboxListAccessible> mListAccessible;
 };
 
 /*
  * A class that represents the window that lives to the right
  * of the drop down button inside the Select. This is the window
--- a/accessible/src/html/nsHTMLTableAccessible.cpp
+++ b/accessible/src/html/nsHTMLTableAccessible.cpp
@@ -330,25 +330,25 @@ nsHTMLTableCellAccessible::GetHeaderCell
     NS_ENSURE_SUCCESS(rv, rv);
 
     PRUint32 count = 0;
     rv = headerCellElms->GetLength(&count);
     if (NS_SUCCEEDED(rv) && count > 0) {
       nsCOMPtr<nsIDOMNode> headerCellNode;
       for (PRUint32 idx = 0; idx < count; idx++) {
         headerCellNode = do_QueryElementAt(headerCellElms, idx, &rv);
-        nsRefPtr<nsAccessible> headerCell =
+        nsAccessible *headerCell =
           GetAccService()->GetAccessibleInWeakShell(headerCellNode, mWeakShell);
 
         if (headerCell &&
             (aRowOrColumnHeaderCell == nsAccUtils::eRowHeaderCells &&
              nsAccUtils::Role(headerCell) == nsIAccessibleRole::ROLE_ROWHEADER ||
              aRowOrColumnHeaderCell == nsAccUtils::eColumnHeaderCells &&
              nsAccUtils::Role(headerCell) == nsIAccessibleRole::ROLE_COLUMNHEADER))
-          headerCells->AppendElement(static_cast<nsIAccessible*>(headerCell.get()),
+          headerCells->AppendElement(static_cast<nsIAccessible*>(headerCell),
                                      PR_FALSE);
       }
     }
 
     NS_ADDREF(*aHeaderCells = headerCells);
     return NS_OK;
   }
 
@@ -733,19 +733,19 @@ nsHTMLTableAccessible::GetSelectedCells(
                                       *getter_AddRefs(cellElement),
                                       startRowIndex, startColIndex,
                                       rowSpan, colSpan,
                                       actualRowSpan, actualColSpan,
                                       isSelected);
 
       if (NS_SUCCEEDED(rv) && startRowIndex == rowIndex &&
           startColIndex == columnIndex && isSelected) {
-        nsRefPtr<nsAccessible> cell =
+        nsAccessible *cell =
           GetAccService()->GetAccessibleInWeakShell(cellElement, mWeakShell);
-        selCells->AppendElement(static_cast<nsIAccessible*>(cell.get()), PR_FALSE);
+        selCells->AppendElement(static_cast<nsIAccessible*>(cell), PR_FALSE);
       }
     }
   }
 
   NS_ADDREF(*aCells = selCells);
   return NS_OK;
 }
 
@@ -906,20 +906,20 @@ nsHTMLTableAccessible::GetSelectedRowInd
 NS_IMETHODIMP
 nsHTMLTableAccessible::GetCellAt(PRInt32 aRow, PRInt32 aColumn,
                                  nsIAccessible **aTableCellAccessible)
 {
   nsCOMPtr<nsIDOMElement> cellElement;
   nsresult rv = GetCellAt(aRow, aColumn, *getter_AddRefs(cellElement));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsRefPtr<nsAccessible> cellAcc =
+  nsAccessible *cell =
     GetAccService()->GetAccessibleInWeakShell(cellElement, mWeakShell);
-  if (cellAcc)
-    CallQueryInterface(cellAcc, aTableCellAccessible);
+  if (cell)
+    CallQueryInterface(cell, aTableCellAccessible);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHTMLTableAccessible::GetCellIndexAt(PRInt32 aRow, PRInt32 aColumn,
                                       PRInt32 *aIndex)
 {
--- a/accessible/src/html/nsHyperTextAccessible.cpp
+++ b/accessible/src/html/nsHyperTextAccessible.cpp
@@ -272,18 +272,18 @@ nsIntRect nsHyperTextAccessible::GetBoun
 
 /*
  * Gets the specified text.
  */
 nsIFrame*
 nsHyperTextAccessible::GetPosAndText(PRInt32& aStartOffset, PRInt32& aEndOffset,
                                      nsAString *aText, nsIFrame **aEndFrame,
                                      nsIntRect *aBoundsRect,
-                                     nsIAccessible **aStartAcc,
-                                     nsIAccessible **aEndAcc)
+                                     nsAccessible **aStartAcc,
+                                     nsAccessible **aEndAcc)
 {
   if (aStartOffset == nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT) {
     GetCharacterCount(&aStartOffset);
   }
   if (aStartOffset == nsIAccessibleText::TEXT_OFFSET_CARET) {
     GetCaretOffset(&aStartOffset);
   }
   if (aEndOffset == nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT) {
@@ -576,36 +576,36 @@ nsHyperTextAccessible::DOMPointToHyperte
         return nsnull;
       }
       findNode = do_QueryInterface(parentContent); // Case #2: there are no children
     }
   }
 
   // Get accessible for this findNode, or if that node isn't accessible, use the
   // accessible for the next DOM node which has one (based on forward depth first search)
-  nsRefPtr<nsAccessible> descendantAcc;
+  nsAccessible *descendantAcc = nsnull;
   if (findNode) {
     nsCOMPtr<nsIContent> findContent = do_QueryInterface(findNode);
     if (findContent->IsHTML() && 
         findContent->NodeInfo()->Equals(nsAccessibilityAtoms::br) &&
         findContent->AttrValueIs(kNameSpaceID_None,
                                  nsAccessibilityAtoms::mozeditorbogusnode,
                                  nsAccessibilityAtoms::_true,
                                  eIgnoreCase)) {
       // This <br> is the hacky "bogus node" used when there is no text in a control
       *aHyperTextOffset = 0;
       return nsnull;
     }
     descendantAcc = GetFirstAvailableAccessible(findNode);
   }
 
   // From the descendant, go up and get the immediate child of this hypertext
-  nsRefPtr<nsAccessible> childAccAtOffset;
+  nsAccessible *childAccAtOffset = nsnull;
   while (descendantAcc) {
-    nsRefPtr<nsAccessible> parentAcc = descendantAcc->GetParent();
+    nsAccessible *parentAcc = descendantAcc->GetParent();
     if (parentAcc == this) {
       childAccAtOffset = descendantAcc;
       break;
     }
 
     // This offset no longer applies because the passed-in text object is not a child
     // of the hypertext. This happens when there are nested hypertexts, e.g.
     // <div>abc<h1>def</h1>ghi</div>
@@ -618,47 +618,45 @@ nsHyperTextAccessible::DOMPointToHyperte
     // before the embedded object char if we end at the very beginning of the child.
     addTextOffset = addTextOffset > 0;
     }
     else {
       // Start offset, inclusive
       // Make sure the offset lands on the embedded object character in order to indicate
       // the true inner offset is inside the subtree for that link
       addTextOffset =
-        (nsAccUtils::TextLength(descendantAcc) == static_cast<PRInt32>(addTextOffset)) ? 1 : 0;
+        (nsAccUtils::TextLength(descendantAcc) == addTextOffset) ? 1 : 0;
     }
 
-    descendantAcc.swap(parentAcc);
+    descendantAcc = parentAcc;
   }
 
   // Loop through, adding offsets until we reach childAccessible
   // If childAccessible is null we will end up adding up the entire length of
   // the hypertext, which is good -- it just means our offset node
   // came after the last accessible child's node
   PRInt32 childCount = GetChildCount();
 
   PRInt32 childIdx = 0;
   nsAccessible *childAcc = nsnull;
   for (; childIdx < childCount; childIdx++) {
     childAcc = mChildren[childIdx];
     if (childAcc == childAccAtOffset)
       break;
 
-    PRInt32 textLength = nsAccUtils::TextLength(childAcc);
-    NS_ENSURE_TRUE(textLength >= 0, nsnull);
-    *aHyperTextOffset += textLength;
+    *aHyperTextOffset += nsAccUtils::TextLength(childAcc);
   }
 
   if (childIdx < childCount) {
     *aHyperTextOffset += addTextOffset;
     NS_ASSERTION(childAcc == childAccAtOffset,
                  "These should be equal whenever we exit loop and childAcc != nsnull");
 
     if (childIdx < childCount - 1 ||
-        static_cast<PRInt32>(addTextOffset) < nsAccUtils::TextLength(childAccAtOffset)) {
+        addTextOffset < nsAccUtils::TextLength(childAccAtOffset)) {
       // If not at end of last text node, we will return the accessible we were in
       return childAccAtOffset;
     }
   }
 
   return nsnull;
 }
 
@@ -713,17 +711,17 @@ nsHyperTextAccessible::HypertextOffsetsT
           NS_ADDREF(*aEndNode = editorRoot);
 
           return NS_OK;
         }
       }
     }
   }
 
-  nsCOMPtr<nsIAccessible> startAcc, endAcc;
+  nsRefPtr<nsAccessible> startAcc, endAcc;
   PRInt32 startOffset = aStartHTOffset, endOffset = aEndHTOffset;
   nsIFrame *startFrame = nsnull, *endFrame = nsnull;
 
   startFrame = GetPosAndText(startOffset, endOffset, nsnull, &endFrame, nsnull,
                              getter_AddRefs(startAcc), getter_AddRefs(endAcc));
   if (!startAcc || !endAcc)
     return NS_ERROR_FAILURE;
 
@@ -953,17 +951,17 @@ nsresult nsHyperTextAccessible::GetTextH
     default:  // Note, sentence support is deprecated and falls through to here
       return NS_ERROR_INVALID_ARG;
   }
 
   PRInt32 startOffset = aOffset + (aBoundaryType == BOUNDARY_LINE_END);  // Avoid getting the previous line
   PRInt32 endOffset = startOffset;
 
   // Convert offsets to frame-relative
-  nsCOMPtr<nsIAccessible> startAcc;
+  nsRefPtr<nsAccessible> startAcc;
   nsIFrame *startFrame = GetPosAndText(startOffset, endOffset, nsnull, nsnull,
                                        nsnull, getter_AddRefs(startAcc));
 
   if (!startFrame) {
     PRInt32 textLength;
     GetCharacterCount(&textLength);
     if (aBoundaryType == BOUNDARY_LINE_START && aOffset > 0 && aOffset == textLength) {
       // Asking for start of line, while on last character
@@ -999,17 +997,17 @@ nsresult nsHyperTextAccessible::GetTextH
     endOffset = aOffset;
   }
   else {
     // Start moving forward from the start so that we don't get 
     // 2 words/lines if the offset occurred on whitespace boundary
     // Careful, startOffset and endOffset are passed by reference to GetPosAndText() and changed
     // For BOUNDARY_LINE_END, make sure we start of this line
     startOffset = endOffset = finalStartOffset + (aBoundaryType == BOUNDARY_LINE_END);
-    nsCOMPtr<nsIAccessible> endAcc;
+    nsRefPtr<nsAccessible> endAcc;
     nsIFrame *endFrame = GetPosAndText(startOffset, endOffset, nsnull, nsnull,
                                        nsnull, getter_AddRefs(endAcc));
     if (nsAccUtils::Role(endAcc) == nsIAccessibleRole::ROLE_STATICTEXT) {
       // Static text like list bullets will ruin our forward calculation,
       // since the caret cannot be in the static text. Start just after the static text.
       startOffset = endOffset = finalStartOffset +
                                 (aBoundaryType == BOUNDARY_LINE_END) +
                                 nsAccUtils::TextLength(endAcc);
@@ -1079,123 +1077,103 @@ NS_IMETHODIMP nsHyperTextAccessible::Get
 //                                      out long rangeEndOffset);
 NS_IMETHODIMP
 nsHyperTextAccessible::GetTextAttributes(PRBool aIncludeDefAttrs,
                                          PRInt32 aOffset,
                                          PRInt32 *aStartOffset,
                                          PRInt32 *aEndOffset,
                                          nsIPersistentProperties **aAttributes)
 {
-  // 1. First we get spell check, then language, then the set of CSS-based
-  //    attributes.
+  // 1. Get each attribute and its ranges one after another.
   // 2. As we get each new attribute, we pass the current start and end offsets
   //    as in/out parameters. In other words, as attributes are collected,
   //    the attribute range itself can only stay the same or get smaller.
-  //
-  // Example:
-  //  Current: range 5-10
-  //  Adding:  range 7-12
-  //  Result:  range 7-10
 
   NS_ENSURE_ARG_POINTER(aStartOffset);
   *aStartOffset = 0;
 
   NS_ENSURE_ARG_POINTER(aEndOffset);
-  nsresult rv = GetCharacterCount(aEndOffset);
-  NS_ENSURE_SUCCESS(rv, rv);
+  *aEndOffset = 0;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   if (aAttributes) {
     *aAttributes = nsnull;
 
     nsCOMPtr<nsIPersistentProperties> attributes =
       do_CreateInstance(NS_PERSISTENTPROPERTIES_CONTRACTID);
     NS_ENSURE_TRUE(attributes, NS_ERROR_OUT_OF_MEMORY);
 
     NS_ADDREF(*aAttributes = attributes);
   }
 
-  // Offset 0 is correct offset when accessible has empty text. Include
-  // default attributes if they were requested, otherwise return empty set.
-  if (aOffset == 0) {
-    // XXX: bug 567321. We handle here the cases when there are no children
-    // or when existing children have zero length.
-    PRBool isEmpty = PR_TRUE;
-    PRInt32 childCount = GetChildCount();
-    for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) {
-      nsAccessible *child = mChildren[childIdx];
-      if (!nsAccUtils::IsText(child) || nsAccUtils::TextLength(child) > 0) {
-        isEmpty = PR_FALSE;
-        break;
-      }
-    }
-
-    if (isEmpty) {
+  PRInt32 offsetAccIdx = -1;
+  PRInt32 startOffset = 0, endOffset = 0;
+  nsAccessible *offsetAcc = GetAccessibleAtOffset(aOffset, &offsetAccIdx,
+                                                  &startOffset, &endOffset);
+  if (!offsetAcc) {
+    // Offset 0 is correct offset when accessible has empty text. Include
+    // default attributes if they were requested, otherwise return empty set.
+    if (aOffset == 0) {
       if (aIncludeDefAttrs) {
-        nsTextAttrsMgr textAttrsMgr(this, mDOMNode, PR_TRUE, nsnull);
+        nsTextAttrsMgr textAttrsMgr(this, PR_TRUE, nsnull, -1);
         return textAttrsMgr.GetAttributes(*aAttributes);
       }
-
       return NS_OK;
     }
+    return NS_ERROR_INVALID_ARG;
   }
 
-  // Get the frame and accessible at the given offset.
-  PRInt32 startOffset = aOffset, endOffset = aOffset;
-  nsCOMPtr<nsIAccessible> startAcc;
-  nsIFrame *startFrame = GetPosAndText(startOffset, endOffset,
-                                       nsnull, nsnull, nsnull,
-                                       getter_AddRefs(startAcc), nsnull);
+  PRInt32 offsetInAcc = aOffset - startOffset;
 
-  // No start frame or accessible means wrong given offset.
-  if (!startFrame || !startAcc)
-    return NS_ERROR_INVALID_ARG;
-
-  nsCOMPtr<nsIDOMNode> node;
-  PRInt32 nodeOffset = 0;
-  rv = GetDOMPointByFrameOffset(startFrame, startOffset, startAcc,
-                                getter_AddRefs(node), &nodeOffset);
+  nsTextAttrsMgr textAttrsMgr(this, aIncludeDefAttrs, offsetAcc, offsetAccIdx);
+  nsresult rv = textAttrsMgr.GetAttributes(*aAttributes, &startOffset,
+                                           &endOffset);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  // Set 'misspelled' text attribute.
-  rv = GetSpellTextAttribute(node, nodeOffset, aStartOffset, aEndOffset,
-                             aAttributes ? *aAttributes : nsnull);
-  NS_ENSURE_SUCCESS(rv, rv);
+  // Compute spelling attributes on text accessible only.
+  nsIFrame *offsetFrame = offsetAcc->GetFrame();
+  if (offsetFrame && offsetFrame->GetType() == nsAccessibilityAtoms::textFrame) {
+    nsCOMPtr<nsIDOMNode> node = offsetAcc->GetDOMNode();
+
+    PRInt32 nodeOffset = 0;
+    nsresult rv = RenderedToContentOffset(offsetFrame, offsetInAcc,
+                                          &nodeOffset);
+    NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCOMPtr<nsIContent> content(do_QueryInterface(node));
-  if (content && content->IsElement())
-    node = do_QueryInterface(content->GetChildAt(nodeOffset));
+    // Set 'misspelled' text attribute.
+    rv = GetSpellTextAttribute(node, nodeOffset, &startOffset, &endOffset,
+                               aAttributes ? *aAttributes : nsnull);
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
 
-  if (!node)
-    return NS_OK;
-
-  nsTextAttrsMgr textAttrsMgr(this, mDOMNode, aIncludeDefAttrs, node);
-  return textAttrsMgr.GetAttributes(*aAttributes, aStartOffset, aEndOffset);
+  *aStartOffset = startOffset;
+  *aEndOffset = endOffset;
+  return NS_OK;
 }
 
 // nsIPersistentProperties
 // nsIAccessibleText::defaultTextAttributes
 NS_IMETHODIMP
 nsHyperTextAccessible::GetDefaultTextAttributes(nsIPersistentProperties **aAttributes)
 {
   NS_ENSURE_ARG_POINTER(aAttributes);
   *aAttributes = nsnull;
 
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
   nsCOMPtr<nsIPersistentProperties> attributes =
     do_CreateInstance(NS_PERSISTENTPROPERTIES_CONTRACTID);
   NS_ENSURE_TRUE(attributes, NS_ERROR_OUT_OF_MEMORY);
 
   NS_ADDREF(*aAttributes = attributes);
 
-  if (!mDOMNode)
-    return NS_ERROR_FAILURE;
-
-  nsTextAttrsMgr textAttrsMgr(this, mDOMNode, PR_TRUE, nsnull);
+  nsTextAttrsMgr textAttrsMgr(this, PR_TRUE);
   return textAttrsMgr.GetAttributes(*aAttributes);
 }
 
 PRInt32
 nsHyperTextAccessible::GetLevelInternal()
 {
   nsCOMPtr<nsIContent> content = nsCoreUtils::GetRoleContent(mDOMNode);
   NS_ENSURE_TRUE(content, 0);
@@ -1349,19 +1327,18 @@ nsHyperTextAccessible::GetOffsetAtPoint(
           NS_ENSURE_SUCCESS(rv, rv);
           offset += addToOffset;
         }
         *aOffset = offset;
         return NS_OK;
       }
       frame = frame->GetNextContinuation();
     }
-    PRInt32 textLength = nsAccUtils::TextLength(childAcc);
-    NS_ENSURE_TRUE(textLength >= 0, NS_ERROR_FAILURE);
-    offset += textLength;
+
+    offset += nsAccUtils::TextLength(childAcc);
   }
 
   return NS_OK; // Not found, will return -1
 }
 
 // ------- nsIAccessibleHyperText ---------------
 NS_IMETHODIMP
 nsHyperTextAccessible::GetLinkCount(PRInt32 *aLinkCount)
@@ -1417,19 +1394,17 @@ nsHyperTextAccessible::GetLinkIndex(PRIn
   PRInt32 childCount = GetChildCount();
   for (PRInt32 childIdx = 0;
        childIdx < childCount && characterCount <= aCharIndex; childIdx++) {
     nsAccessible *childAcc = mChildren[childIdx];
 
     PRUint32 role = nsAccUtils::Role(childAcc);
     if (role == nsIAccessibleRole::ROLE_TEXT_LEAF ||
         role == nsIAccessibleRole::ROLE_STATICTEXT) {
-      PRInt32 textLength = nsAccUtils::TextLength(childAcc);
-      NS_ENSURE_TRUE(textLength >= 0, NS_ERROR_FAILURE);
-      characterCount += textLength;
+      characterCount += nsAccUtils::TextLength(childAcc);
     }
     else {
       if (characterCount ++ == aCharIndex) {
         *aLinkIndex = linkIndex;
         break;
       }
       if (role != nsIAccessibleRole::ROLE_WHITESPACE) {
         ++ linkIndex;
@@ -1635,37 +1610,37 @@ nsHyperTextAccessible::GetCaretOffset(PR
 
   // Turn the focus node and offset of the selection into caret hypretext
   // offset.
   nsCOMPtr<nsISelection> domSel;
   nsresult rv = GetSelections(nsISelectionController::SELECTION_NORMAL,
                               nsnull, getter_AddRefs(domSel));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCOMPtr<nsIDOMNode> focusNode;
-  rv = domSel->GetFocusNode(getter_AddRefs(focusNode));
+  nsCOMPtr<nsIDOMNode> focusDOMNode;
+  rv = domSel->GetFocusNode(getter_AddRefs(focusDOMNode));
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRInt32 focusOffset;
   rv = domSel->GetFocusOffset(&focusOffset);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // No caret if this DOM node is inside of focused node but the selection's
   // focus point is not inside of this DOM node.
   if (isInsideOfFocusedNode) {
-    nsCOMPtr<nsIDOMNode> resultDOMNode =
+    nsCOMPtr<nsINode> focusNode(do_QueryInterface(focusDOMNode));
+    nsINode *resultNode =
       nsCoreUtils::GetDOMNodeFromDOMPoint(focusNode, focusOffset);
 
-    nsCOMPtr<nsINode> resultNode(do_QueryInterface(resultDOMNode));
     if (resultNode != thisNode &&
         !nsCoreUtils::IsAncestorOf(thisNode, resultNode))
       return NS_OK;
   }
 
-  DOMPointToHypertextOffset(focusNode, focusOffset, aCaretOffset);
+  DOMPointToHypertextOffset(focusDOMNode, focusOffset, aCaretOffset);
   return NS_OK;
 }
 
 PRInt32 nsHyperTextAccessible::GetCaretLineNumber()
 {
   // Provide the line number for the caret, relative to the
   // currently focused node. Use a 1-based index
   nsCOMPtr<nsISelection> domSel;
@@ -2125,16 +2100,42 @@ nsresult nsHyperTextAccessible::Rendered
   PRUint32 ourRenderedStart = iter.GetSkippedOffset();
   PRInt32 ourContentStart = iter.GetOriginalOffset();
 
   *aContentOffset = iter.ConvertSkippedToOriginal(aRenderedOffset + ourRenderedStart) - ourContentStart;
 
   return NS_OK;
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// nsHyperTextAccessible protected
+
+nsAccessible *
+nsHyperTextAccessible::GetAccessibleAtOffset(PRInt32 aOffset, PRInt32 *aAccIdx,
+                                             PRInt32 *aStartOffset,
+                                             PRInt32 *aEndOffset)
+{
+  PRInt32 startOffset = 0, endOffset = 0;
+  PRInt32 childCount = GetChildCount();
+  for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) {
+    nsAccessible *child = mChildren[childIdx];
+    endOffset += nsAccUtils::TextLength(child);
+    if (endOffset > aOffset) {
+      *aStartOffset = startOffset;
+      *aEndOffset = endOffset;
+      *aAccIdx = childIdx;
+      return child;
+    }
+
+    startOffset = endOffset;
+  }
+
+  return nsnull;
+}
+
 nsresult
 nsHyperTextAccessible::GetDOMPointByFrameOffset(nsIFrame *aFrame,
                                                 PRInt32 aOffset,
                                                 nsIAccessible *aAccessible,
                                                 nsIDOMNode **aNode,
                                                 PRInt32 *aNodeOffset)
 {
   NS_ENSURE_ARG(aAccessible);
--- a/accessible/src/html/nsHyperTextAccessible.h
+++ b/accessible/src/html/nsHyperTextAccessible.h
@@ -214,18 +214,18 @@ protected:
     * @param  aEndAcc       [out, optional] return the end accessible for this
     *                       substring
     * @return               the start frame for this substring
     */
   nsIFrame* GetPosAndText(PRInt32& aStartOffset, PRInt32& aEndOffset,
                           nsAString *aText = nsnull,
                           nsIFrame **aEndFrame = nsnull,
                           nsIntRect *aBoundsRect = nsnull,
-                          nsIAccessible **aStartAcc = nsnull,
-                          nsIAccessible **aEndAcc = nsnull);
+                          nsAccessible **aStartAcc = nsnull,
+                          nsAccessible **aEndAcc = nsnull);
 
   nsIntRect GetBoundsForString(nsIFrame *aFrame, PRUint32 aStartRenderedOffset, PRUint32 aEndRenderedOffset);
 
   // Selection helpers
 
     /**
    * Get the relevant selection interfaces and ranges for the current hyper
    * text.
@@ -247,16 +247,28 @@ protected:
 
   /**
    * Provide the line number for the caret, relative to the
    * current DOM node.
    * @return 1-based index for the line number with the caret
    */
   PRInt32 GetCaretLineNumber();
 
+  /**
+   * Return an accessible at the given hypertext offset.
+   *
+   * @param  aOffset       [out] the given hypertext offset
+   * @param  aAccIdx       [out] child index of returned accessible
+   * @param  aStartOffset  [out] start hypertext offset of returned accessible
+   * @param  aEndOffset    [out] end hypertext offset of returned accessible
+   */
+  nsAccessible *GetAccessibleAtOffset(PRInt32 aOffset, PRInt32 *aAccIdx,
+                                      PRInt32 *aStartOffset,
+                                      PRInt32 *aEndOffset);
+
   // Helpers
   nsresult GetDOMPointByFrameOffset(nsIFrame *aFrame, PRInt32 aOffset,
                                     nsIAccessible *aAccessible,
                                     nsIDOMNode **aNode, PRInt32 *aNodeOffset);
 
   
   /**
    * Return hyper text offset for the specified bound of the given DOM range.
--- a/accessible/src/msaa/nsAccessNodeWrap.cpp
+++ b/accessible/src/msaa/nsAccessNodeWrap.cpp
@@ -408,17 +408,17 @@ ISimpleDOMNode* nsAccessNodeWrap::MakeAc
     doc = do_QueryInterface(node);
     content = do_QueryInterface(node);
   }
 
   if (!doc)
     return NULL;
 
   ISimpleDOMNode *iNode = NULL;
-  nsRefPtr<nsAccessible> acc =
+  nsAccessible *acc =
     GetAccService()->GetAccessibleInWeakShell(node, mWeakShell);
   if (acc) {
     IAccessible *msaaAccessible = nsnull;
     acc->GetNativeInterface((void**)&msaaAccessible); // addrefs
     msaaAccessible->QueryInterface(IID_ISimpleDOMNode, (void**)&iNode); // addrefs
     msaaAccessible->Release(); // Release IAccessible
   }
   else {
--- a/accessible/src/xul/nsXULComboboxAccessible.cpp
+++ b/accessible/src/xul/nsXULComboboxAccessible.cpp
@@ -140,17 +140,17 @@ nsXULComboboxAccessible::GetDescription(
   nsCOMPtr<nsIDOMXULMenuListElement> menuListElm(do_QueryInterface(mDOMNode));
   if (!menuListElm)
     return NS_ERROR_FAILURE;
 
   nsCOMPtr<nsIDOMXULSelectControlItemElement> focusedOptionItem;
   menuListElm->GetSelectedItem(getter_AddRefs(focusedOptionItem));
   nsCOMPtr<nsIDOMNode> focusedOptionNode(do_QueryInterface(focusedOptionItem));
   if (focusedOptionNode) {
-    nsRefPtr<nsAccessible> focusedOption =
+    nsAccessible *focusedOption =
       GetAccService()->GetAccessibleInWeakShell(focusedOptionNode, mWeakShell);
     NS_ENSURE_TRUE(focusedOption, NS_ERROR_FAILURE);
 
     return focusedOption->GetDescription(aDescription);
   }
 
   return NS_OK;
 }
--- a/accessible/src/xul/nsXULListboxAccessible.cpp
+++ b/accessible/src/xul/nsXULListboxAccessible.cpp
@@ -359,21 +359,21 @@ nsXULListboxAccessible::GetCellAt(PRInt3
     do_QueryInterface(mDOMNode);
 
   nsCOMPtr<nsIDOMXULSelectControlItemElement> item;
   control->GetItemAtIndex(aRow, getter_AddRefs(item));
   NS_ENSURE_TRUE(item, NS_ERROR_INVALID_ARG);
 
   nsCOMPtr<nsIDOMNode> itemNode(do_QueryInterface(item));
 
-  nsRefPtr<nsAccessible> accessibleRow =
+  nsAccessible *row =
     GetAccService()->GetAccessibleInWeakShell(itemNode, mWeakShell);
-  NS_ENSURE_STATE(accessibleRow);
+  NS_ENSURE_STATE(row);
 
-  nsresult rv = accessibleRow->GetChildAt(aColumn, aAccessibleCell);
+  nsresult rv = row->GetChildAt(aColumn, aAccessibleCell);
   NS_ENSURE_SUCCESS(rv, NS_ERROR_INVALID_ARG);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULListboxAccessible::GetCellIndexAt(PRInt32 aRow, PRInt32 aColumn,
                                        PRInt32 *aIndex)
@@ -625,17 +625,17 @@ nsXULListboxAccessible::GetSelectedCells
   PRUint32 selectedItemsCount = 0;
   rv = selectedItems->GetLength(&selectedItemsCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRUint32 index = 0;
   for (; index < selectedItemsCount; index++) {
     nsCOMPtr<nsIDOMNode> itemNode;
     selectedItems->Item(index, getter_AddRefs(itemNode));
-    nsRefPtr<nsAccessible> item =
+    nsAccessible *item =
       GetAccService()->GetAccessibleInWeakShell(itemNode, mWeakShell);
 
     if (item) {
       PRInt32 cellCount = item->GetChildCount();
       for (PRInt32 cellIdx = 0; cellIdx < cellCount; cellIdx++) {
         nsAccessible *cell = mChildren[cellIdx];
         if (nsAccUtils::Role(cell) == nsIAccessibleRole::ROLE_CELL)
           selCells->AppendElement(static_cast<nsIAccessible*>(cell), PR_FALSE);
@@ -869,17 +869,17 @@ nsXULListitemAccessible::
     if (NS_SUCCEEDED(res) && typeString.Equals(NS_LITERAL_STRING("checkbox")))
       mIsCheckbox = PR_TRUE;
   }
 }
 
 /** Inherit the ISupports impl from nsAccessible, we handle nsIAccessibleSelectable */
 NS_IMPL_ISUPPORTS_INHERITED0(nsXULListitemAccessible, nsAccessible)
 
-already_AddRefed<nsAccessible>
+nsAccessible *
 nsXULListitemAccessible::GetListAccessible()
 {
   if (IsDefunct())
     return nsnull;
   
   nsCOMPtr<nsIDOMXULSelectControlItemElement> listItem =
     do_QueryInterface(mDOMNode);
   if (!listItem)
@@ -918,20 +918,20 @@ nsXULListitemAccessible::GetNameInternal
     }
   }
   return GetXULName(aName);
 }
 
 nsresult
 nsXULListitemAccessible::GetRoleInternal(PRUint32 *aRole)
 {
-  nsRefPtr<nsAccessible> listAcc = GetListAccessible();
-  NS_ENSURE_STATE(listAcc);
+  nsAccessible *list = GetListAccessible();
+  NS_ENSURE_STATE(list);
 
-  if (nsAccUtils::Role(listAcc) == nsIAccessibleRole::ROLE_TABLE) {
+  if (nsAccUtils::Role(list) == nsIAccessibleRole::ROLE_TABLE) {
     *aRole = nsIAccessibleRole::ROLE_ROW;
     return NS_OK;
   }
 
   if (mIsCheckbox)
     *aRole = nsIAccessibleRole::ROLE_CHECKBUTTON;
   else if (nsAccUtils::Role(mParent) == nsIAccessibleRole::ROLE_COMBOBOX_LIST)
     *aRole = nsIAccessibleRole::ROLE_COMBOBOX_OPTION;
--- a/accessible/src/xul/nsXULListboxAccessible.h
+++ b/accessible/src/xul/nsXULListboxAccessible.h
@@ -132,17 +132,17 @@ public:
   virtual void GetPositionAndSizeInternal(PRInt32 *aPosInSet,
                                           PRInt32 *aSetSize);
   virtual PRBool GetAllowsAnonChildAccessibles();
 
 protected:
   /**
    * Return listbox accessible for the listitem.
    */
-  already_AddRefed<nsAccessible> GetListAccessible();
+  nsAccessible *GetListAccessible();
 
 private:
   PRBool mIsCheckbox;
 };
 
 /**
  * Class represents xul:listcell.
  */
--- a/accessible/src/xul/nsXULMenuAccessible.cpp
+++ b/accessible/src/xul/nsXULMenuAccessible.cpp
@@ -133,32 +133,32 @@ NS_IMETHODIMP nsXULSelectableAccessible:
     do_QueryInterface(mSelectControl);
   if (xulMultiSelect) {
     PRInt32 length = 0;
     xulMultiSelect->GetSelectedCount(&length);
     for (PRInt32 index = 0; index < length; index++) {
       nsCOMPtr<nsIDOMXULSelectControlItemElement> selectedItem;
       xulMultiSelect->GetSelectedItem(index, getter_AddRefs(selectedItem));
       nsCOMPtr<nsIDOMNode> selectedNode(do_QueryInterface(selectedItem));
-      nsRefPtr<nsAccessible> selectedAcc =
+      nsAccessible *selectedAcc =
         GetAccService()->GetAccessibleInWeakShell(selectedNode, mWeakShell);
       if (selectedAcc)
         selectedAccessibles->AppendElement(static_cast<nsIAccessible*>(selectedAcc),
                                            PR_FALSE);
     }
   }
   else {  // Single select?
     nsCOMPtr<nsIDOMXULSelectControlItemElement> selectedItem;
     mSelectControl->GetSelectedItem(getter_AddRefs(selectedItem));
     nsCOMPtr<nsIDOMNode> selectedNode(do_QueryInterface(selectedItem));
     if(selectedNode) {
-      nsRefPtr<nsAccessible> selectedAcc =
+      nsAccessible *selectedAcc =
         GetAccService()->GetAccessibleInWeakShell(selectedNode, mWeakShell);
       if (selectedAcc)
-        selectedAccessibles->AppendElement(static_cast<nsIAccessible*>(selectedAcc.get()),
+        selectedAccessibles->AppendElement(static_cast<nsIAccessible*>(selectedAcc),
                                            PR_FALSE);
     }
   }
 
   PRUint32 uLength = 0;
   selectedAccessibles->GetLength(&uLength);
   if (uLength != 0) { // length of nsIArray containing selected options
     NS_ADDREF(*aChildren = selectedAccessibles);
@@ -182,22 +182,22 @@ NS_IMETHODIMP nsXULSelectableAccessible:
     xulMultiSelect->GetSelectedItem(aIndex, getter_AddRefs(selectedItem));
 
   if (aIndex == 0)
     mSelectControl->GetSelectedItem(getter_AddRefs(selectedItem));
 
   if (!selectedItem)
     return NS_ERROR_FAILURE;
 
-  nsRefPtr<nsAccessible> selectedAcc =
+  nsAccessible *selectedAcc =
     GetAccService()->GetAccessibleInWeakShell(selectedItem, mWeakShell);
   if (!selectedAcc)
     return NS_ERROR_FAILURE;
 
-  CallQueryInterface(selectedAcc, aAccessible);
+  NS_ADDREF(*aAccessible = selectedAcc);
   return NS_OK;
 }
 
 NS_IMETHODIMP nsXULSelectableAccessible::GetSelectionCount(PRInt32 *aSelectionCount)
 {
   *aSelectionCount = 0;
   if (!mSelectControl) {
     return NS_ERROR_FAILURE;
--- a/accessible/src/xul/nsXULTreeGridAccessible.cpp
+++ b/accessible/src/xul/nsXULTreeGridAccessible.cpp
@@ -1037,21 +1037,21 @@ nsXULTreeGridCellAccessible::GetColumnHe
   nsresult rv = NS_OK;
   nsCOMPtr<nsIMutableArray> headerCells =
     do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIDOMElement> columnElm;
   mColumn->GetElement(getter_AddRefs(columnElm));
 
-  nsRefPtr<nsAccessible> headerCell =
+  nsAccessible *headerCell =
     GetAccService()->GetAccessibleInWeakShell(columnElm, mWeakShell);
 
   if (headerCell)
-    headerCells->AppendElement(static_cast<nsIAccessible*>(headerCell.get()),
+    headerCells->AppendElement(static_cast<nsIAccessible*>(headerCell),
                                PR_FALSE);
 
   NS_ADDREF(*aHeaderCells = headerCells);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULTreeGridCellAccessible::GetRowHeaderCells(nsIArray **aHeaderCells)
--- a/accessible/tests/mochitest/attributes/test_text.html
+++ b/accessible/tests/mochitest/attributes/test_text.html
@@ -157,34 +157,46 @@
       testTextAttrs(ID, 16, attrs, defAttrs, 16, 33);
 
       tempElem = tempElem.parentNode;
       gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
       attrs = {"color": gComputedStyle.color};
       testTextAttrs(ID, 34, attrs, defAttrs, 33, 46);
 
       //////////////////////////////////////////////////////////////////////////
-      // area5
+      // area5: "Green!*!RedNormal"
       ID = "area5";
       defAttrs = buildDefaultTextAttrs(ID, "12pt");
       testDefaultTextAttrs(ID, defAttrs);
 
+      // Green
       tempElem = getNode(ID).firstChild.nextSibling;
       gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
       attrs = {"color": gComputedStyle.color};
       testTextAttrs(ID, 0, attrs, defAttrs, 0, 5);
 
+      // br
       attrs = {};
-      testTextAttrs(ID, 7, attrs, defAttrs, 5, 8);
+      testTextAttrs(ID, 5, attrs, defAttrs, 5, 6);
+
+      // img, embedded accessible, no attributes
+      attrs = {};
+      testTextAttrs(ID, 6, attrs, {}, 6, 7);
 
+      // br
+      attrs = {};
+      testTextAttrs(ID, 7, attrs, defAttrs, 7, 8);
+
+      // Red
       tempElem = tempElem.nextSibling.nextSibling.nextSibling.nextSibling;
       gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
       attrs = {"color": gComputedStyle.color};
       testTextAttrs(ID, 9, attrs, defAttrs, 8, 11);
 
+      // Normal
       attrs = {};
       testTextAttrs(ID, 11, attrs, defAttrs, 11, 18);
 
       //////////////////////////////////////////////////////////////////////////
       // area6 (CSS vertical-align property, bug 445938)
       ID = "area6";
       defAttrs = buildDefaultTextAttrs(ID, "12pt");
       testDefaultTextAttrs(ID, defAttrs);
@@ -415,16 +427,42 @@
       testTextAttrs(ID, 0, attrs, defAttrs, 0, 0);
 
       ID = "area14";
       defAttrs = buildDefaultTextAttrs(ID, kInputFontSize);
       attrs = { };
       testTextAttrs(ID, 0, attrs, defAttrs, 0, 0);
 
       //////////////////////////////////////////////////////////////////////////
+      // area15, embed char tests, "*plain*plain**bold*bold*"
+      ID = "area15";
+      defAttrs = buildDefaultTextAttrs(ID, "12pt");
+
+      // p
+      testTextAttrs(ID, 0, { }, { }, 0, 1);
+      // plain
+      testTextAttrs(ID, 1, { }, defAttrs, 1, 6);
+      // p
+      testTextAttrs(ID, 6, { }, { }, 6, 7);
+      // plain
+      testTextAttrs(ID, 7, { }, defAttrs, 7, 12);
+      // p and img
+      testTextAttrs(ID, 12, { }, { }, 12, 14);
+      // bold
+      attrs = { "font-weight": kBoldFontWeight };
+      testTextAttrs(ID, 14, attrs, defAttrs, 14, 18);
+      // p
+      testTextAttrs(ID, 18, { }, { }, 18, 19);
+      // bold
+      attrs = { "font-weight": kBoldFontWeight };
+      testTextAttrs(ID, 19, attrs, defAttrs, 19, 23);
+      // p
+      testTextAttrs(ID, 23, { }, { }, 23, 24);
+
+      //////////////////////////////////////////////////////////////////////////
       // test spelling text attributes
       testSpellTextAttrs(); // Will call SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 </head>
@@ -454,19 +492,20 @@
     <span style="color: green">
       Green
     </span><span style="color: green">
       Green too
       <span style="color: red">with red children</span>
       Green again
     </span>
   </p>
+  <!-- Green!*!RedNormal-->
   <p id="area5">
     <span style="color: green">Green</span>
-    <img src="moz.png" alt="image"/>
+    <img src="../moz.png" alt="image"/>
     <span style="color: red">Red</span>Normal
   </p>
   <p id="area6">
     This <sup>sentence</sup> has the word 
     <span style="vertical-align:super;">sentence</span> in 
     <sub>superscript</sub> and 
     <span style="vertical-align:sub;">subscript</span>
   </p>
@@ -510,10 +549,13 @@
     <span style="font-weight: 700;">bold</span>bolder
     <span style="font-weight: bold;">bold</span>bolder
     <span style="font-weight: 900;">bold</span>bolder
   </p>
 
   <p id="area12">hello</p>
   <p id="area13"></p>
   <input id="area14">
+
+  <!-- *plain*plain**bold*bold*-->
+  <div id="area15"><p>embed</p>plain<p>embed</p>plain<p>embed</p><img src="../moz.png" alt="image"/><b>bold</b><p>embed</p><b>bold</b><p>embed</p></div>
 </body>
 </html>
--- a/accessible/tests/mochitest/events/Makefile.in
+++ b/accessible/tests/mochitest/events/Makefile.in
@@ -56,15 +56,16 @@ include $(topsrcdir)/config/rules.mk
 		test_dragndrop.html \
 		test_flush.html \
 		test_focus.html \
 		test_focus.xul \
 		test_focus_name.html \
 		test_focusdoc.html \
 		test_mutation.html \
 		test_scroll.xul \
+		test_statechange.html \
 		test_text.html \
 		test_tree.xul \
 		test_valuechange.html \
 		$(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/a11y/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/events/test_statechange.html
@@ -0,0 +1,102 @@
+<html>
+
+<head>
+  <title>Accessible state change event 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/common.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/a11y/accessible/events.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/a11y/accessible/states.js"></script>
+
+  <script type="application/javascript">
+    ////////////////////////////////////////////////////////////////////////////
+    // Invokers
+
+    function makeEditableDoc(aDocNode, aIsEnabled)
+    {
+      this.DOMNode = aDocNode;
+
+      this.eventSeq = [
+        new invokerChecker(EVENT_STATE_CHANGE, getAccessible(this.DOMNode))
+      ];
+
+      this.invoke = function editabledoc_invoke() {
+        // Note: this should fire an EVENT_STATE_CHANGE
+        this.DOMNode.designMode = 'on';
+      };
+
+      this.check = function editabledoc_check(aEvent) {
+
+        testStates(aDocNode, 0, EXT_STATE_EDITABLE);
+
+        var event = null;
+        try {
+          var event = aEvent.QueryInterface(nsIAccessibleStateChangeEvent);
+        } catch (e) {
+          ok(false, "State change event was expected");
+        }
+
+        if (!event) { return; }
+
+        ok(event.isExtraState(), "Extra state change was expected");
+        is(event.state, EXT_STATE_EDITABLE, "Wrong state of statechange event");
+        ok(event.isEnabled(), "Expected editable state to be enabled");
+      }
+
+      this.getID = function editabledoc_getID() {
+        return prettyName(aDocNode) + " editable state changed";
+      };
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
+    // Do tests
+
+    var gQueue = null;
+
+    // var gA11yEventDumpID = "eventdump"; // debug stuff
+
+    function doTests()
+    {
+      gQueue = new eventQueue();
+
+      // Test delayed editable state change
+      var doc = document.getElementById("iframe").contentDocument;
+      gQueue.push(new makeEditableDoc(doc));
+
+      gQueue.invoke(); // Will call SimpleTest.finish();
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addA11yLoadEvent(doTests);
+  </script>
+</head>
+
+<body>
+
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=564471"
+     title="Make state change events async">
+    Mozilla Bug 564471
+  </a>
+
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test">
+  </pre>
+
+  <div id="testContainer">
+    <iframe id="iframe"></iframe>
+  </div>
+  <div id="eventdump"></div>
+</body>
+</html>
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -417,18 +417,16 @@ pref("privacy.cpd.siteSettings",        
 // 4 - Today
 pref("privacy.sanitize.timeSpan", 1);
 pref("privacy.sanitize.sanitizeOnShutdown", false);
 
 pref("privacy.sanitize.migrateFx3Prefs",    false);
 
 pref("network.proxy.share_proxy_settings",  false); // use the same proxy settings for all protocols
 
-pref("network.cookie.cookieBehavior", 0); // 0-Accept, 1-dontAcceptForeign, 2-dontUse
-
 // l12n and i18n
 pref("intl.accept_languages", "chrome://global/locale/intl.properties");
 pref("intl.charsetmenu.browser.static", "chrome://global/locale/intl.properties");
 pref("intl.charsetmenu.browser.more1",  "chrome://global/locale/intl.properties");
 pref("intl.charsetmenu.browser.more2",  "chrome://global/locale/intl.properties");
 pref("intl.charsetmenu.browser.more3",  "chrome://global/locale/intl.properties");
 pref("intl.charsetmenu.browser.more4",  "chrome://global/locale/intl.properties");
 pref("intl.charsetmenu.browser.more5",  "chrome://global/locale/intl.properties");
@@ -905,10 +903,11 @@ pref("dom.ipc.plugins.enabled", false);
 pref("browser.taskbar.previews.enable", true);
 pref("browser.taskbar.previews.max", 20);
 pref("browser.taskbar.previews.cachetime", 20);
 pref("browser.taskbar.lists.enabled", true);
 pref("browser.taskbar.lists.frequent.enabled", true);
 pref("browser.taskbar.lists.recent.enabled", false);
 pref("browser.taskbar.lists.maxListItemCount", 7);
 pref("browser.taskbar.lists.tasks.enabled", true);
+pref("browser.taskbar.lists.refreshInSeconds", 30);
 #endif
 #endif
--- a/browser/base/content/aboutDialog.xul
+++ b/browser/base/content/aboutDialog.xul
@@ -82,17 +82,17 @@
   <deck id="modes" flex="1">
     <vbox flex="1" id="clientBox">
 #expand <label id="version" value="&aboutVersion; __MOZ_APP_VERSION__"/>
       <label id="distribution"/>
       <label id="distributionId"/>
       <description id="copyright">
         <label
         class="text-link" href="about:license"
-        >&licenseLinkText;</label>&licenseLinkSuffix;&logoTrademark;
+        >&licenseLinkText;</label>&licenseLinkSuffix;&trademarkInfo;
       </description>
       <textbox id="userAgent" multiline="true" readonly="true" flex="1"/>
     </vbox>
     <vbox flex="1" id="creditsBox">
       <iframe id="creditsIframe" flex="1"/>
     </vbox>    
   </deck>
   <separator class="groove" id="groove"/>
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -2723,19 +2723,21 @@ function FillInHTMLTooltip(tipElement)
       retVal = true;
     }
   });
 
   return retVal;
 }
 
 var browserDragAndDrop = {
+  canDropLink: function (aEvent) Services.droppedLinkHandler.canDropLink(aEvent, true),
+
   dragOver: function (aEvent, statusString)
   {
-    if (Services.droppedLinkHandler.canDropLink(aEvent, true)) {
+    if (this.canDropLink(aEvent)) {
       aEvent.preventDefault();
 
       if (statusString) {
         var statusTextFld = document.getElementById("statusbar-display");
         statusTextFld.label = gNavigatorBundle.getString(statusString);
       }
     }
   },
@@ -2867,18 +2869,16 @@ var newWindowButtonObserver = {
     if (url) {
       // allow third-party services to fixup this URL
       openNewWindowWith(url, null, postData.value, true);
     }
   }
 }
 
 var DownloadsButtonDNDObserver = {
-  /////////////////////////////////////////////////////////////////////////////
-  // nsDragAndDrop
   onDragOver: function (aEvent)
   {
     var statusTextFld = document.getElementById("statusbar-display");
     statusTextFld.label = gNavigatorBundle.getString("dropondownloadsbutton");
     var types = aEvent.dataTransfer.types;
     if (types.contains("text/x-moz-url") ||
         types.contains("text/uri-list") ||
         types.contains("text/plain"))
@@ -6080,45 +6080,45 @@ var gPluginHandler = {
                    "PFSWindow", "chrome,centerscreen,resizable=yes",
                    {plugins: missingPluginsArray, browser: gBrowser.selectedBrowser});
       }
     }
 
     let notifications = {
       PluginBlocklisted : {
                             barID   : "blocked-plugins",
-                            iconURL : "chrome://mozapps/skin/plugins/pluginBlocked-16.png",
+                            iconURL : "chrome://mozapps/skin/plugins/notifyPluginBlocked.png",
                             message : gNavigatorBundle.getString("blockedpluginsMessage.title"),
                             buttons : [{
                                          label     : gNavigatorBundle.getString("blockedpluginsMessage.infoButton.label"),
                                          accessKey : gNavigatorBundle.getString("blockedpluginsMessage.infoButton.accesskey"),
                                          popup     : null,
                                          callback  : showBlocklistInfo
                                        },
                                        {
                                          label     : gNavigatorBundle.getString("blockedpluginsMessage.searchButton.label"),
                                          accessKey : gNavigatorBundle.getString("blockedpluginsMessage.searchButton.accesskey"),
                                          popup     : null,
                                          callback  : showOutdatedPluginsInfo
                                       }],
                           },
       PluginOutdated    : {
                             barID   : "outdated-plugins",
-                            iconURL : "chrome://mozapps/skin/plugins/pluginOutdated-16.png",
+                            iconURL : "chrome://mozapps/skin/plugins/notifyPluginOutdated.png",
                             message : gNavigatorBundle.getString("outdatedpluginsMessage.title"),
                             buttons : [{
                                          label     : gNavigatorBundle.getString("outdatedpluginsMessage.updateButton.label"),
                                          accessKey : gNavigatorBundle.getString("outdatedpluginsMessage.updateButton.accesskey"),
                                          popup     : null,
                                          callback  : showOutdatedPluginsInfo
                                       }],
                           },
       PluginNotFound    : {
                             barID   : "missing-plugins",
-                            iconURL : "chrome://mozapps/skin/plugins/pluginGeneric-16.png",
+                            iconURL : "chrome://mozapps/skin/plugins/notifyPluginGeneric.png",
                             message : gNavigatorBundle.getString("missingpluginsMessage.title"),
                             buttons : [{
                                          label     : gNavigatorBundle.getString("missingpluginsMessage.button.label"),
                                          accessKey : gNavigatorBundle.getString("missingpluginsMessage.button.accesskey"),
                                          popup     : null,
                                          callback  : showPluginsMissing
                                       }],
                           }
@@ -6309,17 +6309,17 @@ var gPluginHandler = {
     function showNotificationBar(pluginDumpID, browserDumpID) {
       // If there's already an existing notification bar, don't do anything.
       let notification = notificationBox.getNotificationWithValue("plugin-crashed");
       if (notification)
         return;
 
       // Configure the notification bar
       let priority = notificationBox.PRIORITY_WARNING_MEDIUM;
-      let iconURL = "chrome://mozapps/skin/plugins/pluginGeneric-16.png";
+      let iconURL = "chrome://mozapps/skin/plugins/notifyPluginCrashed.png";
       let reloadLabel = gNavigatorBundle.getString("crashedpluginsMessage.reloadButton.label");
       let reloadKey   = gNavigatorBundle.getString("crashedpluginsMessage.reloadButton.accesskey");
       let submitLabel = gNavigatorBundle.getString("crashedpluginsMessage.submitButton.label");
       let submitKey   = gNavigatorBundle.getString("crashedpluginsMessage.submitButton.accesskey");
 
       let buttons = [{
         label: reloadLabel,
         accessKey: reloadKey,
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -97,20 +97,16 @@
 
 #ifdef MOZ_SAFE_BROWSING
 <script type="application/javascript" src="chrome://browser/content/safebrowsing/sb-loader.js"/>
 #endif
 <script type="application/javascript" src="chrome://global/content/contentAreaUtils.js"/>
 
 <script type="application/javascript" src="chrome://browser/content/places/editBookmarkOverlay.js"/>
 
-<!-- This is still used for dragDropSecurityCheck and transferUtils.  Since we
-     rely on the new Drag and Drop API these dependencies should be removed. -->
-<script type="application/javascript" src="chrome://global/content/nsDragAndDrop.js"/>
-
 # All sets except for popupsets (commands, keys, stringbundles and broadcasters) *must* go into the 
 # browser-sets.inc file for sharing with hiddenWindow.xul.
 #include browser-sets.inc
 
   <popupset id="mainPopupSet">
     <menupopup id="tabContextMenu"
                onpopupshowing="if (event.target == this) TabContextMenu.updateContextMenu(this);"
                onpopuphidden="if (event.target == this) TabContextMenu.contextTab = null;">
@@ -635,16 +631,17 @@
             tooltip="tabbrowser-tab-tooltip">
         <tab class="tabbrowser-tab" selected="true"/>
       </tabs>
 
       <toolbarbutton id="new-tab-button"
                      class="toolbarbutton-1 chromeclass-toolbar-additional"
                      label="&tabCmd.label;"
                      command="cmd_newNavigatorTab"
+                     onclick="checkForMiddleClick(this, event);"
                      tooltiptext="&newTabButton.tooltip;"
                      ondrop="newTabButtonObserver.onDrop(event)"
                      ondragover="newTabButtonObserver.onDragOver(event)"
                      ondragenter="newTabButtonObserver.onDragOver(event)"
                      ondragleave="newTabButtonObserver.onDragLeave(event)"
                      removable="true"/>
 
       <toolbarbutton id="alltabs-button"
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -82,17 +82,17 @@ function nsContextMenu(aXulMenu, aBrowse
   this.linkURI           = null;
   this.linkProtocol      = null;
   this.inFrame           = false;
   this.hasBGImage        = false;
   this.isTextSelected    = false;
   this.isContentSelected = false;
   this.shouldDisplay     = true;
   this.isDesignMode      = false;
-  this.possibleSpellChecking = false;
+  this.onEditableArea = false;
   this.ellipsis = "\u2026";
   try {
     this.ellipsis = gPrefService.getComplexValue("intl.ellipsis",
                                                  Ci.nsIPrefLocalizedString).data;
   } catch (e) { }
 
   // Initialize new menu.
   this.initMenu(aXulMenu, aBrowser);
@@ -362,17 +362,17 @@ nsContextMenu.prototype = {
     this.showItem("context-blockimage", this.onImage && hostLabel &&
       !gPrivateBrowsingUI.privateBrowsingEnabled);
   },
 
   initSpellingItems: function() {
     var canSpell = InlineSpellCheckerUI.canSpellCheck;
     var onMisspelling = InlineSpellCheckerUI.overMisspelling;
     this.showItem("spell-check-enabled", canSpell);
-    this.showItem("spell-separator", canSpell || this.possibleSpellChecking);
+    this.showItem("spell-separator", canSpell || this.onEditableArea);
     if (canSpell) {
       document.getElementById("spell-check-enabled")
               .setAttribute("checked", InlineSpellCheckerUI.enabled);
     }
 
     this.showItem("spell-add-to-dictionary", onMisspelling);
 
     // suggestion list
@@ -390,17 +390,17 @@ nsContextMenu.prototype = {
     // dictionary list
     this.showItem("spell-dictionaries", InlineSpellCheckerUI.enabled);
     if (canSpell) {
       var dictMenu = document.getElementById("spell-dictionaries-menu");
       var dictSep = document.getElementById("spell-language-separator");
       InlineSpellCheckerUI.addDictionaryListToMenu(dictMenu, dictSep);
       this.showItem("spell-add-dictionaries-main", false);
     }
-    else if (this.possibleSpellChecking) {
+    else if (this.onEditableArea) {
       // when there is no spellchecker but we might be able to spellcheck
       // add the add to dictionaries item. This will ensure that people
       // with no dictionaries will be able to download them
       this.showItem("spell-add-dictionaries-main", true);
     }
     else
       this.showItem("spell-add-dictionaries-main", false);
   },
@@ -498,17 +498,17 @@ nsContextMenu.prototype = {
     this.onLink            = false;
     this.linkURL           = "";
     this.linkURI           = null;
     this.linkProtocol      = "";
     this.onMathML          = false;
     this.inFrame           = false;
     this.hasBGImage        = false;
     this.bgImageURL        = "";
-    this.possibleSpellChecking = false;
+    this.onEditableArea = false;
 
     // Clear any old spellchecking items from the menu, this used to
     // be in the menu hiding code but wasn't getting called in all
     // situations. Here, we can ensure it gets cleaned up any time the
     // menu is shown. Note: must be before uninit because that clears the
     // internal vars
     InlineSpellCheckerUI.clearSuggestionsFromMenu();
     InlineSpellCheckerUI.clearDictionaryListFromMenu();
@@ -547,26 +547,26 @@ nsContextMenu.prototype = {
         this.onAudio = true;
         this.mediaURL = this.target.currentSrc || this.target.src;
       }
       else if (this.target instanceof HTMLInputElement ) {
         this.onTextInput = this.isTargetATextBox(this.target);
         // allow spellchecking UI on all writable text boxes except passwords
         if (this.onTextInput && ! this.target.readOnly &&
             this.target.type != "password") {
-          this.possibleSpellChecking = true;
+          this.onEditableArea = true;
           InlineSpellCheckerUI.init(this.target.QueryInterface(Ci.nsIDOMNSEditableElement).editor);
           InlineSpellCheckerUI.initFromEvent(aRangeParent, aRangeOffset);
         }
         this.onKeywordField = this.isTargetAKeywordField(this.target);
       }
       else if (this.target instanceof HTMLTextAreaElement) {
         this.onTextInput = true;
         if (!this.target.readOnly) {
-          this.possibleSpellChecking = true;
+          this.onEditableArea = true;
           InlineSpellCheckerUI.init(this.target.QueryInterface(Ci.nsIDOMNSEditableElement).editor);
           InlineSpellCheckerUI.initFromEvent(aRangeParent, aRangeOffset);
         }
       }
       else if (this.target instanceof HTMLHtmlElement) {
         var bodyElt = this.target.ownerDocument.body;
         if (bodyElt) {
           let computedURL;
@@ -657,49 +657,51 @@ nsContextMenu.prototype = {
       this.onMathML = true;
 
     // See if the user clicked in a frame.
     var docDefaultView = this.target.ownerDocument.defaultView;
     if (docDefaultView != docDefaultView.top)
       this.inFrame = true;
 
     // if the document is editable, show context menu like in text inputs
-    var win = this.target.ownerDocument.defaultView;
-    if (win) {
-      var isEditable = false;
-      try {
-        var editingSession = win.QueryInterface(Ci.nsIInterfaceRequestor)
-                                .getInterface(Ci.nsIWebNavigation)
-                                .QueryInterface(Ci.nsIInterfaceRequestor)
-                                .getInterface(Ci.nsIEditingSession);
-        if (editingSession.windowIsEditable(win) &&
-            this.getComputedStyle(this.target, "-moz-user-modify") == "read-write") {
-          isEditable = true;
+    if (!this.onEditableArea) {
+      var win = this.target.ownerDocument.defaultView;
+      if (win) {
+        var isEditable = false;
+        try {
+          var editingSession = win.QueryInterface(Ci.nsIInterfaceRequestor)
+                                  .getInterface(Ci.nsIWebNavigation)
+                                  .QueryInterface(Ci.nsIInterfaceRequestor)
+                                  .getInterface(Ci.nsIEditingSession);
+          if (editingSession.windowIsEditable(win) &&
+              this.getComputedStyle(this.target, "-moz-user-modify") == "read-write") {
+            isEditable = true;
+          }
         }
-      }
-      catch(ex) {
-        // If someone built with composer disabled, we can't get an editing session.
-      }
+        catch(ex) {
+          // If someone built with composer disabled, we can't get an editing session.
+        }
 
-      if (isEditable) {
-        this.onTextInput       = true;
-        this.onKeywordField    = false;
-        this.onImage           = false;
-        this.onLoadedImage     = false;
-        this.onCompletedImage  = false;
-        this.onMathML          = false;
-        this.inFrame           = false;
-        this.hasBGImage        = false;
-        this.isDesignMode      = true;
-        this.possibleSpellChecking = true;
-        InlineSpellCheckerUI.init(editingSession.getEditorForWindow(win));
-        var canSpell = InlineSpellCheckerUI.canSpellCheck;
-        InlineSpellCheckerUI.initFromEvent(aRangeParent, aRangeOffset);
-        this.showItem("spell-check-enabled", canSpell);
-        this.showItem("spell-separator", canSpell);
+        if (isEditable) {
+          this.onTextInput       = true;
+          this.onKeywordField    = false;
+          this.onImage           = false;
+          this.onLoadedImage     = false;
+          this.onCompletedImage  = false;
+          this.onMathML          = false;
+          this.inFrame           = false;
+          this.hasBGImage        = false;
+          this.isDesignMode      = true;
+          this.onEditableArea = true;
+          InlineSpellCheckerUI.init(editingSession.getEditorForWindow(win));
+          var canSpell = InlineSpellCheckerUI.canSpellCheck;
+          InlineSpellCheckerUI.initFromEvent(aRangeParent, aRangeOffset);
+          this.showItem("spell-check-enabled", canSpell);
+          this.showItem("spell-separator", canSpell);
+        }
       }
     }
   },
 
   // Returns the computed style attribute for the given element.
   getComputedStyle: function(aElem, aProp) {
     return aElem.ownerDocument
                 .defaultView
--- a/browser/base/content/pageinfo/pageInfo.js
+++ b/browser/base/content/pageinfo/pageInfo.js
@@ -163,23 +163,29 @@ const COL_IMAGE_BG      = 6;
 const COPYCOL_NONE = -1;
 const COPYCOL_META_CONTENT = 1;
 const COPYCOL_IMAGE = COL_IMAGE_ADDRESS;
 
 // one nsITreeView for each tree in the window
 var gMetaView = new pageInfoTreeView(COPYCOL_META_CONTENT);
 var gImageView = new pageInfoTreeView(COPYCOL_IMAGE);
 
+
+var atomSvc = Components.classes["@mozilla.org/atom-service;1"]
+                        .getService(Components.interfaces.nsIAtomService);
+gImageView._ltrAtom = atomSvc.getAtom("ltr");
+gImageView._brokenAtom = atomSvc.getAtom("broken");
+
 gImageView.getCellProperties = function(row, col, props) {
-  var aserv = Components.classes[ATOM_CONTRACTID]
-                        .getService(Components.interfaces.nsIAtomService);
-
   if (gImageView.data[row][COL_IMAGE_SIZE] == gStrings.unknown &&
       !/^https:/.test(gImageView.data[row][COL_IMAGE_ADDRESS]))
-    props.AppendElement(aserv.getAtom("broken"));
+    props.AppendElement(this._brokenAtom);
+
+  if (col.element.id == "image-address")
+    props.AppendElement(this._ltrAtom);
 };
 
 var gImageHash = { };
 
 // localized strings (will be filled in when the document is loaded)
 // this isn't all of them, these are just the ones that would otherwise have been loaded inside a loop
 var gStrings = { };
 var gBundle;
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -2147,38 +2147,44 @@
       <property name="contentPrincipal"
                 onget="return this.mCurrentBrowser.contentPrincipal;"
                 readonly="true"/>
 
       <property name="securityUI"
                 onget="return this.mCurrentBrowser.securityUI;"
                 readonly="true"/>
 
-      <method name="dragDropSecurityCheck">
-        <parameter name="aEvent"/>
-        <parameter name="aDragSession"/>
-        <parameter name="aUri"/>
-        <body>
-          <![CDATA[
-            nsDragAndDrop.dragDropSecurityCheck(aEvent, aDragSession, aUri);
-          ]]>
-        </body>
-      </method>
-
       <method name="_handleKeyEvent">
         <parameter name="aEvent"/>
         <body><![CDATA[
           if (!aEvent.isTrusted) {
             // Don't let untrusted events mess with tabs.
             return;
           }
 
           if (aEvent.altKey)
             return;
 
+          // We need to take care of FAYT-watching as long as the findbar
+          // isn't initialized.  The checks on aEvent are copied from
+          // _shouldFastFind (see findbar.xml).
+          if (!gFindBarInitialized &&
+              !(aEvent.ctrlKey || aEvent.metaKey) &&
+              !aEvent.getPreventDefault()) {
+            let charCode = aEvent.charCode;
+            if (charCode) {
+              let char = String.fromCharCode(charCode);
+              if (char == "'" || char == "/" ||
+                  Services.prefs.getBoolPref("accessibility.typeaheadfind")) {
+                gFindBar._onBrowserKeypress(aEvent);
+                return;
+              }
+            }
+          }
+
 #ifdef XP_MACOSX
           if (!aEvent.metaKey)
             return;
 
           var offset = 1;
           switch (aEvent.charCode) {
             case '}'.charCodeAt(0):
               offset = -1;
@@ -2419,16 +2425,17 @@
 # This is a hack to circumvent bug 472020, otherwise the tabs show up on the
 # right of the newtab button.
         <children includes="tab"/>
 # This is to ensure anything extensions put here will go before the newtab
 # button, necessary due to the previous hack.
         <children/>
         <xul:toolbarbutton class="tabs-newtab-button"
                            command="cmd_newNavigatorTab"
+                           onclick="checkForMiddleClick(this, event);"
                            tooltiptext="&newTabButton.tooltip;"/>
       </xul:arrowscrollbox>
     </content>
 
     <implementation implements="nsIDOMEventListener">
       <constructor>
         <![CDATA[
           this.mTabMinWidth = Services.prefs.getIntPref("browser.tabs.tabMinWidth");
@@ -2506,20 +2513,16 @@
 
       <field name="_tabDropIndicator">
         document.getAnonymousElementByAttribute(this, "anonid", "tab-drop-indicator");
       </field>
 
       <field name="_dragOverDelay">350</field>
       <field name="_dragTime">0</field>
 
-      <field name="_supportedLinkDropTypes"><![CDATA[
-        ["text/x-moz-url", "text/uri-list", "text/plain", "application/x-moz-file"]
-      ]]></field>
-
       <field name="_container" readonly="true"><![CDATA[
         this.parentNode && this.parentNode.localName == "toolbar" ? this.parentNode : this;
       ]]></field>
 
       <property name="visible"
                 onget="return !this._container.collapsed;">
         <setter><![CDATA[
           this._container.collapsed = !val;
@@ -2587,17 +2590,17 @@
       <method name="_fillTrailingGap">
         <body><![CDATA[
           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.mTabstrip;
-            if (tabStrip.scrollPosition + tabStrip.scrollClientSize >=
+            if (tabStrip.scrollPosition + tabStrip.scrollClientSize >
                 tabStrip.scrollSize)
               tabStrip.scrollByPixels(-1);
           } catch (e) {}
         ]]></body>
       </method>
 
       <method name="handleEvent">
         <parameter name="aEvent"/>
@@ -2703,21 +2706,19 @@
                                        sourceNode.boxObject.width))) {
                 return dt.effectAllowed = "none";
               }
 
               return dt.effectAllowed = "copyMove";
             }
           }
 
-          for (let i = 0; i < this._supportedLinkDropTypes.length; i++) {
-            if (types.contains(this._supportedLinkDropTypes[i])) {
-              // Here we need to to do this manually
-              return dt.effectAllowed = dt.dropEffect = "link";
-            }
+          if (browserDragAndDrop.canDropLink(event)) {
+            // Here we need to do this manually
+            return dt.effectAllowed = dt.dropEffect = "link";
           }
           return dt.effectAllowed = "none";
         ]]></body>
       </method>
 
       <method name="_continueScroll">
         <parameter name="event"/>
         <body><![CDATA[
@@ -2955,44 +2956,24 @@
 
           this.tabbrowser.swapBrowsersAndCloseOther(newTab, draggedTab);
 
           // We need to select the tab after we've done
           // swapBrowsersAndCloseOther, so that the updateCurrentBrowser
           // it triggers will correctly update our URL bar.
           this.tabbrowser.selectedTab = newTab;
         } else {
-          let url;
-          for (let i = 0; i < this._supportedLinkDropTypes.length; i++) {
-            let dataType = this._supportedLinkDropTypes[i];
-            // uri-list: for now, support dropping of the first URL
-            // only
-            let isURLList = dataType == "text/uri-list";
-            let urlData = isURLList ?
-                          dt.mozGetDataAt("URL", 0) : dt.mozGetDataAt(dataType, 0);
-            if (urlData) {
-              url = transferUtils.retrieveURLFromData(urlData, isURLList ? "text/plain" : dataType);
-              break;
-            }
-          }
-          NS_ASSERT(url, "In the drop event, at least one mime-type should match our supported types");
+          let url = browserDragAndDrop.drop(event, { });
 
           // 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))
             return;
 
-          // XXXmano: temporary fix until dragDropSecurityCheck make the
-          // drag-session an optional paramter
-          let dragService = Cc["@mozilla.org/widget/dragservice;1"].
-                            getService(Ci.nsIDragService);
-          let dragSession = dragService.getCurrentSession();
-          nsDragAndDrop.dragDropSecurityCheck(event, dragSession, url);
-
           let bgLoad = Services.prefs.getBoolPref("browser.tabs.loadInBackground");
 
           if (event.shiftKey)
             bgLoad = !bgLoad;
 
           let tab = this._getDragTargetTab(event);
           if (!tab || dropEffect == "copy") {
             // We're adding a new tab.
--- a/browser/base/content/test/Makefile.in
+++ b/browser/base/content/test/Makefile.in
@@ -65,27 +65,29 @@ include $(topsrcdir)/config/rules.mk
 		test_bug364677.html \
 		bug364677-data.xml \
 		bug364677-data.xml^headers^ \
 		test_offline_gzip.html \
 		gZipOfflineChild.html \
 		gZipOfflineChild.html^headers^ \
 		gZipOfflineChild.cacheManifest \
 		gZipOfflineChild.cacheManifest^headers^ \
+		test_bug452451.html \
 		$(NULL)
 
 # The following tests are disabled because they are unreliable:
 #   browser_bug423833.js is bug 428712
 #   browser_sanitize-download-history.js is bug 432425
 #
 # browser_sanitizeDialog_treeView.js is disabled until the tree view is added
 # back to the clear recent history dialog (santize.xul), if it ever is (bug
 # 480169)
 
 _BROWSER_FILES = \
+                 browser_typeAheadFind.js \
                  browser_NetworkPrioritizer.js \
                  browser_allTabsPanel.js \
                  browser_alltabslistener.js \
                  browser_bug304198.js \
                  browser_bug321000.js \
                  title_test.svg \
                  browser_bug329212.js \
                  browser_bug356571.js \
--- a/browser/base/content/test/browser_bug321000.js
+++ b/browser/base/content/test/browser_bug321000.js
@@ -58,72 +58,31 @@ var gTests = [
 ];
 
 // Test for bug 23485 and bug 321000.
 // Urlbar should strip newlines,
 // search bar should replace newlines with spaces.
 function test() {
   waitForExplicitFinish();
 
+  let cbHelper = Cc["@mozilla.org/widget/clipboardhelper;1"].
+                 getService(Ci.nsIClipboardHelper);
+
   // Put a multi-line string in the clipboard.
-  info("About to put a string in clipboard");
-  Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper)
-                                             .copyString(kTestString);
-
   // Setting the clipboard value is an async OS operation, so we need to poll
   // the clipboard for valid data before going on.
-  setTimeout(poll_clipboard, 100);
-}
-
-var runCount = 0;
-function poll_clipboard() {
-  // Poll for a maximum of 5s (each run happens after 100ms).
-  if (++runCount > 50) {
-    // Log the failure.
-    ok(false, "Timed out while polling clipboard for pasted data");
-    // Cleanup and interrupt the test.
-    finish_test();
-    return;
-  }
-
-  info("Polling clipboard cycle " + runCount);
-  var clip = Cc["@mozilla.org/widget/clipboard;1"].
-             getService(Ci.nsIClipboard);
-  var trans = Cc["@mozilla.org/widget/transferable;1"].
-              createInstance(Ci.nsITransferable);
-  trans.addDataFlavor("text/unicode");
-  var str = new Object();
-  try {
-    // This code could throw if the clipboard is not set yet.
-    clip.getData(trans, clip.kGlobalClipboard);
-    trans.getTransferData("text/unicode", str, {});
-    str = str.value.QueryInterface(Ci.nsISupportsString);
-  }
-  catch(ex) {}
-
-  if (kTestString == str) {
-    next_test();
-  }
-  else
-    setTimeout(poll_clipboard, 100);
+  waitForClipboard(kTestString, function() { cbHelper.copyString(kTestString); },
+                   next_test, finish);
 }
 
 function next_test() {
-  if (gTests.length) {
-    var currentTest = gTests.shift();
-    test_paste(currentTest);
-  }
-  else {
-    // No more tests to run.
-    // Clear the clipboard, emptyClipboard would not clear the native one, so
-    // we are setting it to an empty string.
-    Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper)
-                                               .copyString("");
+  if (gTests.length)
+    test_paste(gTests.shift());
+  else
     finish();
-  }
 }
 
 function test_paste(aCurrentTest) {
   var element = aCurrentTest.element;
 
   // Register input listener.
   var inputListener = {
     test: aCurrentTest,
--- a/browser/base/content/test/browser_bug556061.js
+++ b/browser/base/content/test/browser_bug556061.js
@@ -30,129 +30,96 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-let cbSvc = Cc["@mozilla.org/widget/clipboard;1"].
-            getService(Ci.nsIClipboard);
-
 let testURL = "http://example.org/browser/browser/base/content/test/dummy_page.html";
 let testActionURL = "moz-action:switchtab," + testURL;
 let testTab;
-let clipboardText = "";
-let currentClipboardText = null;
-let clipboardPolls = 0;
-
-// The clipboard can have a string value without it being the one we expect, so
-// we'll check the current value against the previous value to see if it changed.
-// We can do this because our expected clipboard value should be different each
-// time we wait.
-function waitForClipboard() {
-  // Poll for a maximum of 5s (each run happens after 100ms).
-  if (++clipboardPolls > 50) {
-    // Log the failure.
-    ok(false, "Timed out while polling clipboard for pasted data");
-    // Cleanup and interrupt the test.
-    cleanup();
-    return;
-  }
-
-  let xferable = Cc["@mozilla.org/widget/transferable;1"].
-                 createInstance(Ci.nsITransferable);
-  xferable.addDataFlavor("text/unicode");
-  cbSvc.getData(xferable, cbSvc.kGlobalClipboard);
-  try {
-    let data = {};
-    xferable.getTransferData("text/unicode", data, {});
-    currentClipboardText = data.value.QueryInterface(Ci.nsISupportsString).data;
-  } catch (e) {}
-
-  if (currentClipboardText == clipboardText) {
-    setTimeout(waitForClipboard, 100);
-  } else {
-    clipboardText = currentClipboardText;
-    runNextTest();
-  }
-}
 
 function runNextTest() {
-  // reset clipboard polling count
-  clipboardPolls = 0;
-  // run next test, just assume we won't call in here without more tests
-  tests.shift()();
+  if (tests.length) {
+    let t = tests.shift();
+    waitForClipboard(t.expected, t.setup, function() {
+      t.success();
+      runNextTest();
+    }, cleanup);
+  }
+  else {
+    cleanup();
+  }
 }
 
 function cleanup() {
   gBrowser.removeTab(testTab);
   finish();
 }
 
-// Tests in order. Some tests setup for the next actual test...
 let tests = [
-  function () {
-    // Set the urlbar to include the moz-action
-    gURLBar.value = testActionURL;
-    is(gURLBar.value, testActionURL, "gURLBar.value starts with correct value");
-
-    // Focus the urlbar so we can select it all & copy
-    gURLBar.focus();
-    gURLBar.select();
-    goDoCommand("cmd_copy");
-    waitForClipboard();
-  },
-  function () {
-    is(clipboardText, testURL, "Clipboard has the correct value");
-    // We shouldn't have changed the value of gURLBar
-    is(gURLBar.value, testActionURL, "gURLBar.value didn't change when copying");
-
-    // Set selectionStart/End manually and make sure it matches the substring
-    gURLBar.selectionStart = 0;
-    gURLBar.selectionEnd = 10;
-    goDoCommand("cmd_copy");
-    waitForClipboard();
-  },
-  function () {
-    is(clipboardText, testURL.substring(0, 10), "Clipboard has the correct value");
-    is(gURLBar.value, testActionURL, "gURLBar.value didn't change when copying");
+  {
+    expected: testURL,
+    setup: function() {
+      gURLBar.value = testActionURL;
+      is(gURLBar.value, testActionURL, "gURLBar.value starts with correct value");
 
-    // Setup for cut test...
-    // Select all
-    gURLBar.select();
-    goDoCommand("cmd_cut");
-    waitForClipboard();
+      // Focus the urlbar so we can select it all & copy
+      gURLBar.focus();
+      gURLBar.select();
+      goDoCommand("cmd_copy");
+    },
+    success: function() {
+      is(gURLBar.value, testActionURL, "gURLBar.value didn't change when copying");
+    }
   },
-  function () {
-    is(clipboardText, testURL, "Clipboard has the correct value");
-    is(gURLBar.value, "", "gURLBar.value is now empty");
-
-    // Reset urlbar value
-    gURLBar.value = testActionURL;
-    // Sanity check that we have the right value
-    is(gURLBar.value, testActionURL, "gURLBar.value starts with correct value");
+  {
+    expected: testURL.substring(0, 10),
+    setup: function() {
+      // Set selectionStart/End manually and make sure it matches the substring
+      gURLBar.selectionStart = 0;
+      gURLBar.selectionEnd = 10;
+      goDoCommand("cmd_copy");
+    },
+    success: function() {
+      is(gURLBar.value, testActionURL, "gURLBar.value didn't change when copying");
+    }
+  },
+  {
+    expected: testURL,
+    setup: function() {
+      // Setup for cut test...
+      // Select all
+      gURLBar.select();
+      goDoCommand("cmd_cut");
+    },
+    success: function() {
+      is(gURLBar.value, "", "gURLBar.value is now empty");
+    }
+  },
+  {
+    expected: testURL.substring(testURL.length - 10, testURL.length),
+    setup: function() {
+      // Reset urlbar value
+      gURLBar.value = testActionURL;
+      // Sanity check that we have the right value
+      is(gURLBar.value, testActionURL, "gURLBar.value starts with correct value");
 
-    // Now just select part of the value & cut that.
-    gURLBar.selectionStart = testURL.length - 10;
-    gURLBar.selectionEnd = testURL.length;
-
-    goDoCommand("cmd_cut");
-    waitForClipboard();
-  },
-  function () {
-    is(clipboardText, testURL.substring(testURL.length - 10, testURL.length),
-       "Clipboard has the correct value");
-    is(gURLBar.value, testURL.substring(0, testURL.length - 10), "gURLBar.value has the correct value");
-
-    // We're done, so just finish up
-    cleanup();
+      // Now just select part of the value & cut that.
+      gURLBar.selectionStart = testURL.length - 10;
+      gURLBar.selectionEnd = testURL.length;
+      goDoCommand("cmd_cut");
+    },
+    success: function() {
+      is(gURLBar.value, testURL.substring(0, testURL.length - 10), "gURLBar.value has the correct value");
+    }
   }
-]
+];
 
 function test() {
   waitForExplicitFinish();
   testTab = gBrowser.addTab();
   gBrowser.selectedTab = testTab;
 
   // Kick off the testing
   runNextTest();
--- a/browser/base/content/test/browser_drag.js
+++ b/browser/base/content/test/browser_drag.js
@@ -1,10 +1,12 @@
 function test()
 {
+  waitForExplicitFinish();
+
   // ---- Test dragging the proxy icon ---
   var value = content.location.href;
   var urlString = value + "\n" + content.document.title;
   var htmlString = "<a href=\"" + value + "\">" + value + "</a>";
   var expected = [ [
     { type  : "text/x-moz-url",
       data  : urlString },
     { type  : "text/uri-list",
@@ -19,9 +21,27 @@ function test()
   var oldstate = proxyicon.getAttribute("pageproxystate");
   proxyicon.setAttribute("pageproxystate", "valid");
   var dt = EventUtils.synthesizeDragStart(proxyicon, expected);
   is(dt, null, "drag on proxy icon");
   proxyicon.setAttribute("pageproxystate", oldstate);
   // Now, the identity information panel is opened by the proxy icon click.
   // We need to close it for next tests.
   EventUtils.synthesizeKey("VK_ESCAPE", {}, window);
+
+  // now test dragging onto a tab
+  var tab1 = gBrowser.addTab();
+  var browser1 = gBrowser.getBrowserForTab(tab1);
+
+  var tab2 = gBrowser.addTab();
+  var browser2 = gBrowser.getBrowserForTab(tab2);
+
+  gBrowser.selectedTab = tab1;
+
+  browser2.addEventListener("load", function () {
+    is(browser2.contentWindow.location, "http://mochi.test:8888/", "drop on tab");
+    gBrowser.removeCurrentTab();
+    gBrowser.removeCurrentTab();
+    finish();
+  }, true);
+
+  EventUtils.synthesizeDrop(tab2, [[{type: "text/uri-list", data: "http://mochi.test:8888/"}]], "copy", window);
 }
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_typeAheadFind.js
@@ -0,0 +1,60 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is typeaheadfind test code.
+ *
+ * The Initial Developer of the Original Code is
+ * the Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Gavin Sharp <gavin@gavinsharp.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+function test() {
+  waitForExplicitFinish();
+  ok(!gFindBarInitialized, "find bar is not yet initialized");
+
+  let tab = gBrowser.addTab();
+  gBrowser.selectedTab = tab;
+  tab.linkedBrowser.addEventListener("load", function(aEvent) {
+    tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
+
+    ok(true, "Load listener called");
+    waitForFocus(onFocus, content);
+  }, true);
+
+  content.location = "data:text/html,<h1>A Page</h1>";
+}
+
+function onFocus() {
+  EventUtils.synthesizeKey("/", {});
+  ok(gFindBarInitialized, "find bar is now initialized");
+  gFindBar.close();
+  gBrowser.removeCurrentTab();
+  finish();
+}
--- a/browser/base/content/test/subtst_contextmenu.html
+++ b/browser/base/content/test/subtst_contextmenu.html
@@ -13,11 +13,14 @@ Browser context menu subtest.
 <img id="test-image" src="ctxmenu-image.png">
 <canvas id="test-canvas" width="100" height="100" style="background-color: blue"></canvas>
 <video id="test-video-ok"  src="video.ogg" width="100" height="100" style="background-color: green"></video>
 <video id="test-video-bad" src="bogus.duh" width="100" height="100" style="background-color: orange"></video>
 <video id="test-video-bad2" width="100" height="100" style="background-color: yellow">
   <source src="bogus.duh" type="video/durrrr;">
 </video>
 <iframe id="test-iframe" width="98"  height="98" style="border: 1px solid black"></iframe>
+<textarea id="test-textarea">chssseesbbbie</textarea> <!-- a weird word which generates only one suggestion -->
+<div id="test-contenteditable" contenteditable="true">chssseefsbbbie</div> <!-- a more weird word which generates no suggestions -->
+<input id="test-input-spellcheck" type="text" spellcheck="true" autofocus value="prodkjfgigrty"> <!-- this one also generates one suggestion -->
 
 </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/test_bug452451.html
@@ -0,0 +1,97 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=452451
+-->
+<head>
+  <title>Test for Bug 452451</title>
+  <script type="application/javascript" src="/MochiKit/packed.js"></script>
+  <script type="application/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=452451">Mozilla Bug 452451</a>
+<p id="display"></p>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 452451 **/
+
+  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+  const prefs = Components.classes["@mozilla.org/preferences-service;1"]
+                          .getService(Components.interfaces.nsIPrefBranch);
+
+  ok(prefs.getBoolPref("javascript.options.relimit"),
+     "relimit should be enabled by default");
+
+  /**
+   * Following tests are inspired from:
+   * js/src/tests/js1_5/extensions/regress-330569.js
+   */
+
+  var s;
+  const expected = 'InternalError: regular expression too complex';
+
+  s = '<!DOCTYPE HTML PUBLIC>' +
+      '<html>\n' +
+      '<head>\n' +
+      '<meta http-equiv="content-type" content="text/html">\n' +
+      '<title></title>\n'+
+      '</head>\n' +
+      '<body>\n' +
+      '<!-- hello -->\n' +
+      '<script language="JavaScript">\n' +
+      'var s = document. body. innerHTML;\n' +
+      'var d = s. replace (/<!--(.*|\n)*-->/, "");\n' +
+      '<\/script>\n' +
+      '<\/body>\n' +
+      '<\/html>\n';
+
+  try {
+    /<!--(.*|\n)*-->/.exec(s);
+  }
+  catch(ex) {
+    actual = ex;
+  }
+
+  is(actual, expected, "reg exp too complex error should have been thrown");
+
+  function testre( re, n )
+  {
+    var txt = '';
+    for (var i= 0; i <= n; ++i) {
+      txt += ',';
+      re.test(txt);
+    }
+  }
+
+  try {
+    testre( /(?:,*)*x/, 22 );
+  }
+  catch(ex) {
+    actual = ex;
+  }
+
+  is(actual, expected, "reg exp too complex error should have been thrown");
+
+  try {
+    testre( /(?:,|,)*x/, 22 );
+  }
+  catch(ex) {
+    actual = ex;
+  }
+
+  is(actual, expected, "reg exp too complex error should have been thrown");
+
+  try {
+    testre( /(?:,|,|,|,|,)*x/, 10 );
+  }
+  catch(ex) {
+    actual = ex;
+  }
+
+  is(actual, expected, "reg exp too complex error should have been thrown");
+</script>
+</pre>
+</body>
+</html>
--- a/browser/base/content/test/test_contextmenu.html
+++ b/browser/base/content/test/test_contextmenu.html
@@ -44,24 +44,37 @@ function getVisibleMenuItems(aMenu) {
         if (item.hidden)
             continue;
 
         var key = item.accessKey;
         if (key)
             key = key.toLowerCase();
 
         if (item.nodeName == "menuitem") {
-            ok(item.id, "child menuitem #" + i + " has an ID");
+            var isSpellSuggestion = item.className == "spell-suggestion";
+            if (isSpellSuggestion) {
+              is(item.id, "", "child menuitem #" + i + " is a spelling suggestion");
+            } else {
+              ok(item.id, "child menuitem #" + i + " has an ID");
+            }
             ok(item.label.length, "menuitem " + item.id + " has a label");
-            ok(key, "menuitem " + item.id + " has an access key");
-            if (accessKeys[key])
-                ok(false, "menuitem " + item.id + " has same accesskey as " + accessKeys[key]);
-            else
-                accessKeys[key] = item.id;
-            items.push(item.id);
+            if (isSpellSuggestion) {
+              is(key, "", "Spell suggestions shouldn't have an access key");
+              items.push("*" + item.label);
+            } else if (item.id.indexOf("spell-check-dictionary-") != 0 &&
+                       item.id != "spell-no-suggestions") {
+              ok(key, "menuitem " + item.id + " has an access key");
+              if (accessKeys[key])
+                  ok(false, "menuitem " + item.id + " has same accesskey as " + accessKeys[key]);
+              else
+                  accessKeys[key] = item.id;
+            }
+            if (!isSpellSuggestion) {
+              items.push(item.id);
+            }
             items.push(!item.disabled);
         } else if (item.nodeName == "menuseparator") {
             ok(true, "--- seperator id is " + item.id);
             items.push("---");
             items.push(null);
         } else if (item.nodeName == "menu") {
             ok(item.id, "child menu #" + i + " has an ID");
             ok(key, "menu has an access key");
@@ -301,17 +314,88 @@ function runTest(testNum) {
                                "context-printframe",        true,
                                "---",                       null,
                                "context-viewframesource",   true,
                                "context-viewframeinfo",     true], null,
                           "---",                  null,
                           "context-viewsource",   true,
                           "context-viewinfo",     true]);
         closeContextMenu();
+        openContextMenuFor(textarea); // Invoke context menu for next test.
+        break;
 
+    case 12:
+        // Context menu for textarea
+        checkContextMenu(["*chubbiness",         true, // spelling suggestion
+                          "spell-add-to-dictionary", true,
+                          "---",                 null,
+                          "context-undo",        false,
+                          "---",                 null,
+                          "context-cut",         false,
+                          "context-copy",        false,
+                          "context-paste",       null, // ignore clipboard state
+                          "context-delete",      false,
+                          "---",                 null,
+                          "context-selectall",   true,
+                          "---",                 null,
+                          "spell-check-enabled", true,
+                          "spell-dictionaries",  true,
+                              ["spell-check-dictionary-en-US", true,
+                               "---",                          null,
+                               "spell-add-dictionaries",       true], null]);
+
+        closeContextMenu();
+        openContextMenuFor(contenteditable); // Invoke context menu for next test.
+        break;
+
+    case 13:
+        // Context menu for contenteditable
+        checkContextMenu(["spell-no-suggestions", false,
+                          "spell-add-to-dictionary", true,
+                          "---",                 null,
+                          "context-undo",        false,
+                          "---",                 null,
+                          "context-cut",         false,
+                          "context-copy",        false,
+                          "context-paste",       null, // ignore clipboard state
+                          "context-delete",      false,
+                          "---",                 null,
+                          "context-selectall",   true,
+                          "---",                 null,
+                          "spell-check-enabled", true,
+                          "spell-dictionaries",  true,
+                              ["spell-check-dictionary-en-US", true,
+                               "---",                          null,
+                               "spell-add-dictionaries",       true], null]);
+
+        closeContextMenu();
+        openContextMenuFor(inputspell); // Invoke context menu for next test.
+        break;
+
+    case 14:
+        // Context menu for spell-check input
+        checkContextMenu(["*prodigality",        true, // spelling suggestion
+                          "spell-add-to-dictionary", true,
+                          "---",                 null,
+                          "context-undo",        false,
+                          "---",                 null,
+                          "context-cut",         false,
+                          "context-copy",        false,
+                          "context-paste",       null, // ignore clipboard state
+                          "context-delete",      false,
+                          "---",                 null,
+                          "context-selectall",   true,
+                          "---",                 null,
+                          "spell-check-enabled", true,
+                          "spell-dictionaries",  true,
+                              ["spell-check-dictionary-en-US", true,
+                               "---",                          null,
+                               "spell-add-dictionaries",       true], null]);
+
+        closeContextMenu();
         subwindow.close();
         SimpleTest.finish();
         return;
 
     /*
      * Other things that would be nice to test:
      *  - selected text
      *  - spelling / misspelled word (in text input?)
@@ -326,17 +410,18 @@ function runTest(testNum) {
         return;
   }
 
 }
 
 
 var testNum = 1;
 var subwindow, chromeWin, contextMenu;
-var text, link, mailto, input, img, canvas, video, iframe;
+var text, link, mailto, input, img, canvas, video, iframe,
+    textarea, contenteditable, inputspell;
 
 function startTest() {
     netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
     chromeWin = subwindow
                     .QueryInterface(Ci.nsIInterfaceRequestor)
                     .getInterface(Ci.nsIWebNavigation)
                     .QueryInterface(Ci.nsIDocShellTreeItem)
                     .rootTreeItem
@@ -351,16 +436,19 @@ function startTest() {
     mailto = subwindow.document.getElementById("test-mailto");
     input  = subwindow.document.getElementById("test-input");
     img    = subwindow.document.getElementById("test-image");
     canvas = subwindow.document.getElementById("test-canvas");
     video_ok   = subwindow.document.getElementById("test-video-ok");
     video_bad  = subwindow.document.getElementById("test-video-bad");
     video_bad2 = subwindow.document.getElementById("test-video-bad2");
     iframe = subwindow.document.getElementById("test-iframe");
+    textarea = subwindow.document.getElementById("test-textarea");
+    contenteditable = subwindow.document.getElementById("test-contenteditable");
+    inputspell = subwindow.document.getElementById("test-input-spellcheck");
 
     contextMenu.addEventListener("popupshown", function() { runTest(++testNum); }, false);
     runTest(1);
 }
 
 // We open this in a separate window, because the Mochitests run inside a frame.
 // The frame causes an extra menu item, and prevents running the test
 // standalone (ie, clicking the test name in the Mochitest window) to see
--- a/browser/branding/nightly/locales/en-US/brand.dtd
+++ b/browser/branding/nightly/locales/en-US/brand.dtd
@@ -1,4 +1,4 @@
 <!ENTITY  brandShortName        "Minefield">
 <!ENTITY  brandFullName         "Minefield">            
 <!ENTITY  vendorShortName       "Mozilla">
-<!ENTITY  logoTrademark         " ">
+<!ENTITY  trademarkInfo         " ">
--- a/browser/branding/unofficial/locales/en-US/brand.dtd
+++ b/browser/branding/unofficial/locales/en-US/brand.dtd
@@ -1,7 +1,7 @@
 <!ENTITY  brandShortName        "Mozilla Developer Preview">
 <!ENTITY  brandFullName         "Mozilla Developer Preview">
 <!ENTITY  vendorShortName       "mozilla.org">
-<!ENTITY  logoTrademark         " ">
+<!ENTITY  trademarkInfo         " ">
 
 <!-- LOCALIZATION NOTE (releaseBaseURL): The about: page appends __MOZ_APP_VERSION__.html, e.g. 2.0.html -->
 <!ENTITY  releaseBaseURL        "http://www.mozilla.org/projects/devpreview/releases/">
--- a/browser/components/places/content/tree.xml
+++ b/browser/components/places/content/tree.xml
@@ -109,34 +109,31 @@
           this.load([query], options);
         ]]></body>
       </method>
 
       <method name="load">
         <parameter name="queries"/>
         <parameter name="options"/>
         <body><![CDATA[
-          // Cleanup old result if exists.
-          let oldResult = this.result;
-          if (oldResult) {
-            oldResult.removeObserver(this.view);
-            oldResult.root.containerOpen = false;
-          }
-
           let result = PlacesUtils.history
                                   .executeQueries(queries, queries.length,
                                                   options);
           let callback;
           if (this.flatList) {
             let onOpenFlatContainer = this.onOpenFlatContainer;
             if (onOpenFlatContainer)
               callback = new Function("aContainer", onOpenFlatContainer);
           }
 
           let treeView = new PlacesTreeView(this.flatList, callback);
+
+          // Observer removal is done within the view itself.  When the tree
+          // goes away, treeboxobject calls view.setTree(null), which then
+          // calls removeObserver.
           result.addObserver(treeView, false);
           this.view = treeView;
           if (!this._controller) {
             this._controller = new PlacesController(this);
             this.controllers.appendController(this._controller);
           }
           this._cachedInsertionPoint = undefined;
         ]]></body>
--- a/browser/components/places/content/treeView.js
+++ b/browser/components/places/content/treeView.js
@@ -146,38 +146,41 @@ PlacesTreeView.prototype = {
    *        A result node.  Do not pass an obsolete node, or any
    *        node which isn't supposed to be in the tree (e.g. separators in
    *        sorted trees).
    * @param [optional] aForceBuild
    *        @see _isPlainContainer.
    *        If true, the row will be computed even if the node still isn't set
    *        in our rows array.
    * @param [optional] aParentRow
-   *        The row of aNode's parent.
-   *        DO NOT compute this yourself for the purpose of calling this
-   *        function.  However, do pass it if you have it handy.
-   *        Ignored for the root node.
+   *        The row of aNode's parent. Ignored for the root node.
    * @param [optional] aNodeIndex
    *        The index of aNode in its parent.  Only used if aParentRow is
    *        set too.
    *
    * @throws if aNode is invisible.
+   * @note If aParentRow and aNodeIndex are passed and parent is a plain
+   * container, this method will just return a calculated row value, without
+   * making assumptions on existence of the node at that position.
    * @return aNode's row if it's in the rows list or if aForceBuild is set, -1
    *         otherwise.
    */
   _getRowForNode:
   function PTV__getRowForNode(aNode, aForceBuild, aParentRow, aNodeIndex) {
     if (aNode == this._rootNode)
       throw "The root node is never visible";
 
-    let parent = aNode.parent;
-    if (!parent || !parent.containerOpen)
-      throw "Invisible node passed to _getRowForNode";
+    let ancestors = PlacesUtils.nodeAncestors(aNode);
+    for (let ancestor in ancestors) {
+      if (!ancestor.containerOpen)
+        throw "Invisible node passed to _getRowForNode";
+    }
 
     // Non-plain containers are initially built with their contents.
+    let parent = aNode.parent;
     let parentIsPlain = this._isPlainContainer(parent);
     if (!parentIsPlain) {
       if (parent == this._rootNode)
         return this._rows.indexOf(aNode);
 
       return this._rows.indexOf(aNode, aParentRow);
     }
 
@@ -379,17 +382,17 @@ PlacesTreeView.prototype = {
         continue;
 
       let firstRow = Math.max(min.value, aFirstRow);
       let lastRow = Math.min(max.value, aLastRow);
       for (let i = firstRow; i <= lastRow; i++) {
         nodesInfo.push({
           node: this._rows[i],
           oldRow: i,
-          wasVisbile: i >= firstVisibleRow && i <= lastVisibleRow
+          wasVisible: i >= firstVisibleRow && i <= lastVisibleRow
         });
       }
     }
 
     return nodesInfo;
   },
 
   /**
@@ -675,17 +678,19 @@ PlacesTreeView.prototype = {
     if (aNode == this._rootNode)
       throw Cr.NS_ERROR_NOT_IMPLEMENTED;
 
     // Bail out for hidden separators.
     if (PlacesUtils.nodeIsSeparator(aNode) &&
         this._result.sortingMode != Ci.nsINavHistoryQueryOptions.SORT_BY_NONE)
       return;
 
-    let oldRow = this._getRowForNode(aNode, true);
+    let parentRow = aParentNode == this._rootNode ?
+                    undefined : this._getRowForNode(aParentNode, true);
+    let oldRow = this._getRowForNode(aNode, true, parentRow, aOldIndex);
     if (oldRow < 0)
       throw Cr.NS_ERROR_UNEXPECTED;
 
     // If the node was exclusively selected, the node next to it will be
     // selected.
     let selectNext = false;
     let selection = this.selection;
     if (selection.getRangeCount() == 1) {
@@ -707,17 +712,17 @@ PlacesTreeView.prototype = {
       this._tree.invalidateRow(parentRow);
     }
 
     // Restore selection if the node was exclusively selected.
     if (!selectNext)
       return;
 
     // Restore selection.
-    let rowToSelect = Math.min(oldRow,  this._rows.length - 1);
+    let rowToSelect = Math.min(oldRow, this._rows.length - 1);
     this.selection.rangedSelect(rowToSelect, rowToSelect, true);
   },
 
   nodeMoved:
   function PTV_nodeMoved(aNode, aOldParent, aOldIndex, aNewParent, aNewIndex) {
     NS_ASSERT(this._result, "Got a notification but have no result!");
     if (!this._tree || !this._result)
       return;
--- a/browser/components/places/tests/chrome/Makefile.in
+++ b/browser/components/places/tests/chrome/Makefile.in
@@ -44,12 +44,13 @@ include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _CHROME_TEST_FILES = \
 	test_treeview_date.xul \
 	test_bug485100-change-case-loses-tag.xul \
 	test_bug427633_no_newfolder_if_noip.xul \
 	test_0_multiple_left_pane.xul \
 	test_0_bug510634.xul \
+	test_bug549192.xul \
 	$(NULL)
 
 libs:: $(_CHROME_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/chrome/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/browser/components/places/tests/chrome/test_bug549192.xul
@@ -0,0 +1,98 @@
+<?xml version="1.0"?>
+
+<!--
+    Any copyright is dedicated to the Public Domain.
+    http://creativecommons.org/licenses/publicdomain/
+   -->
+
+<?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://browser/content/places/places.css"?>
+<?xml-stylesheet href="chrome://browser/skin/places/places.css"?>
+<?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?>
+
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        title="549192:  History view not updated after deleting entry"
+        onload="runTest();">
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/MochiKit/packed.js" />
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
+
+  <body xmlns="http://www.w3.org/1999/xhtml" />
+
+  <tree id="tree"
+        type="places"
+        flatList="true"
+        flex="1">
+    <treecols>
+      <treecol label="Title" id="title" anonid="title" primary="true" ordinal="1" flex="1"/>
+    </treecols>
+    <treechildren flex="1"/>
+  </tree>
+
+  <script type="application/javascript"><![CDATA[
+    /**
+     * Bug 549192
+     * https://bugzilla.mozilla.org/show_bug.cgi?id=549192
+     *
+     * Ensures that history views are updated after deleting entries.
+     */
+
+    SimpleTest.waitForExplicitFinish();
+
+    function runTest() {
+      const Cc = Components.classes;
+      const Ci = Components.interfaces;
+      Components.utils.import("resource://gre/modules/Services.jsm");
+
+      // Cleanup.
+      PlacesUtils.bhistory.removeAllPages();
+
+      // Add some visits.
+      let vtime = Date.now() * 1000;
+      const ttype = PlacesUtils.history.TRANSITION_TYPED;
+      PlacesUtils.history
+                 .addVisit(Services.io.newURI("http://example.tld/", null, null),
+                           vtime, null, ttype, false, 0);
+      PlacesUtils.history
+                 .addVisit(Services.io.newURI("http://example2.tld/", null, null),
+                           vtime++, null, ttype, false, 0);
+      PlacesUtils.history
+                 .addVisit(Services.io.newURI("http://exmample3.tld/", null, null),
+                           vtime++, null, ttype, false, 0);
+
+      // Make a history query.
+      let query = PlacesUtils.history.getNewQuery();
+      let opts = PlacesUtils.history.getNewQueryOptions();
+      let queryURI = PlacesUtils.history.queriesToQueryString([query], 1, opts);
+
+      // Setup the places tree contents.
+      var tree = document.getElementById("tree");
+      tree.place = queryURI;
+
+      // loop through the rows and check formatting
+      let treeView = tree.view;
+      let rc = treeView.rowCount;
+      ok(rc == 3, "Rows found.");
+      let selection = treeView.selection;
+      for (let i = 0; i < rc; i++) {
+        selection.select(0);
+        let node = tree.selectedNode;
+        tree.controller.remove("Removing page");
+        ok(treeView.treeIndexForNode(node) == Ci.nsINavHistoryResultTreeViewer.INDEX_INVISIBLE,
+           node.uri + " removed.");
+        ok(treeView.rowCount == rc - i - 1, "Rows count decreased");
+      }
+
+      // Cleanup.
+      PlacesUtils.bhistory.removeAllPages();
+
+      SimpleTest.finish();
+    }
+
+  ]]></script>
+</window>
--- a/browser/components/privatebrowsing/content/aboutPrivateBrowsing.xhtml
+++ b/browser/components/privatebrowsing/content/aboutPrivateBrowsing.xhtml
@@ -48,16 +48,22 @@
   <!ENTITY % privatebrowsingpageDTD SYSTEM "chrome://browser/locale/aboutPrivateBrowsing.dtd">
   %privatebrowsingpageDTD;
 ]>
 
 <html xmlns="http://www.w3.org/1999/xhtml">
   <head>
     <link rel="stylesheet" href="chrome://global/skin/netError.css" type="text/css" media="all"/>
     <link rel="stylesheet" href="chrome://browser/skin/aboutPrivateBrowsing.css" type="text/css" media="all"/>
+    <style type="text/css"><![CDATA[
+      body.normal .showPrivate,
+      body.private .showNormal {
+        display: none;
+      }
+    ]]></style>
     <script type="application/javascript;version=1.7"><![CDATA[
       const Cc = Components.classes;
       const Ci = Components.interfaces;
 
       var pb = Cc["@mozilla.org/privatebrowsing;1"].
                getService(Ci.nsIPrivateBrowsingService);
 
       if (!pb.privateBrowsingEnabled) {
@@ -91,29 +97,19 @@
         icon.setAttribute("rel", "icon");
         icon.setAttribute("type", "image/png");
         icon.setAttribute("href", url);
         var head = document.getElementsByTagName("head")[0];
         head.insertBefore(icon, head.firstChild);
       }
 
       document.addEventListener("DOMContentLoaded", function () {
-        let selector;
         if (!pb.privateBrowsingEnabled) {
           document.body.setAttribute("class", "normal");
-          selector = ".showPrivate";
         }
-        else {
-          selector = ".showNormal";
-        }
-
-        // Remove hidden elements to avoid bug 39098
-        let elements = document.body.querySelectorAll(selector);
-        for (let i = 0; i < elements.length; ++ i)
-          elements[i].parentNode.removeChild(elements[i]);
 
         // Set up the help link
         let moreInfoURL = Cc["@mozilla.org/toolkit/URLFormatterService;1"].
                           getService(Ci.nsIURLFormatter).
                           formatURLPref("app.support.baseURL");
         let moreInfoLink = document.getElementById("moreInfoLink");
         if (moreInfoLink)
           moreInfoLink.setAttribute("href", moreInfoURL + "private-browsing");
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_downloadmonitor.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_downloadmonitor.js
@@ -44,68 +44,86 @@ function test() {
            getService(Ci.nsIPrivateBrowsingService);
   let dm = Cc["@mozilla.org/download-manager;1"].
            getService(Ci.nsIDownloadManager);
   if (!gDownloadMgr)
     gDownloadMgr = dm;
   let panel = document.getElementById("download-monitor");
   waitForExplicitFinish();
 
+  let acceptDialog = 0;
+  let confirmCalls = 0;
+  function promptObserver(aSubject, aTopic, aData) {
+    let dialogWin = aSubject.QueryInterface(Ci.nsIDOMWindow);
+    confirmCalls++;
+    if (acceptDialog-- > 0)
+      dialogWin.document.documentElement.getButton("accept").click();
+  }
+
+  Services.obs.addObserver(promptObserver, "common-dialog-loaded", false);
+
   // Add a new download
-  addDownload(dm, {
+  let [file, persist] = addDownload(dm, {
     resultFileName: "pbtest-1",
     downloadName: "PB Test 1"
   });
 
   // Make sure that the download is being displayed in the monitor panel
   if (!DownloadMonitorPanel.inited())
     DownloadMonitorPanel.init();
   else
     DownloadMonitorPanel.updateStatus();
   ok(!panel.hidden, "The download panel should be successfully added initially");
 
   // Enter the private browsing mode
+  acceptDialog = 1;
   pb.privateBrowsingEnabled = true;
+  is(confirmCalls, 1, "One prompt was accepted");
+  ok(pb.privateBrowsingEnabled, "The private browsing transition was successful");
 
-  setTimeout(function () {
+  executeSoon(function () {
     ok(panel.hidden, "The download panel should be hidden when entering the private browsing mode");
 
     // Add a new download
-    let file = addDownload(dm, {
+    let [file2, persist2] = addDownload(dm, {
       resultFileName: "pbtest-2",
       downloadName: "PB Test 2"
-    }).targetFile;
+    });
 
     // Update the panel
     DownloadMonitorPanel.updateStatus();
 
     // Make sure that the panel is visible
     ok(!panel.hidden, "The download panel should show up when a new download is added");
 
     // Exit the private browsing mode
+    acceptDialog = 1;
     pb.privateBrowsingEnabled = false;
+    is(confirmCalls, 2, "One prompt was accepted");
+    ok(!pb.privateBrowsingEnabled, "The private browsing transition was successful");
 
-    setTimeout(function () {
+    executeSoon(function () {
       ok(panel.hidden, "The download panel should be hidden when leaving the private browsing mode");
 
       // cleanup
       let dls = dm.activeDownloads;
       while (dls.hasMoreElements()) {
         let dl = dls.getNext().QueryInterface(Ci.nsIDownload);
         dm.removeDownload(dl.id);
         let file = dl.targetFile;
         if (file.exists())
           file.remove(false);
       }
       if (file.exists())
         file.remove(false);
 
+      Services.obs.removeObserver(promptObserver, "common-dialog-loaded", false);
       finish();
-    }, 0);
-  }, 0);
+    });
+  });
 }
 
 /**
  * Adds a download to the DM, and starts it.
  * (Copied from toolkit/componentns/downloads/test/unit/head_download_manager.js)
  * @param aParams (optional): an optional object which contains the function
  *                            parameters:
  *                              resultFileName: leaf node for the target file
@@ -149,16 +167,16 @@ function addDownload(dm, aParams)
   // try catch block
   let test = dm.getDownload(dl.id);
 
   aParams.runBeforeStart.call(undefined, dl);
 
   persist.progressListener = dl.QueryInterface(Ci.nsIWebProgressListener);
   persist.saveURI(dl.source, null, null, null, null, dl.targetFile);
 
-  return dl;
+  return [dl.targetFile, persist];
 }
 
 function createURI(aObj) {
   let ios = Services.io;
   return (aObj instanceof Ci.nsIFile) ? ios.newFileURI(aObj) :
                                         ios.newURI(aObj, null, null);
 }
--- a/browser/components/privatebrowsing/test/browser/staller.sjs
+++ b/browser/components/privatebrowsing/test/browser/staller.sjs
@@ -50,10 +50,11 @@ function handleRequest(request, response
     // This write will throw if the connection has been closed by the browser.
     response.write("stalling...\n");
     timer = Components.classes["@mozilla.org/timer;1"]
                         .createInstance(nsITimer);
     timer.initWithCallback(stall, 500, nsITimer.TYPE_ONE_SHOT);
   }
 
   response.setHeader("Content-Type", "text/plain", false);
+  response.setHeader("Accept-Ranges", "none", false);
   stall();
 }
--- a/browser/components/search/content/engineManager.js
+++ b/browser/components/search/content/engineManager.js
@@ -460,39 +460,18 @@ EngineView.prototype = {
   invalidate: function () {
     this.tree.invalidate();
   },
 
   ensureRowIsVisible: function (index) {
     this.tree.ensureRowIsVisible(index);
   },
 
-  getSourceIndexFromDrag: function () {
-    var dragService = Cc["@mozilla.org/widget/dragservice;1"].
-                      getService().QueryInterface(Ci.nsIDragService);
-    var dragSession = dragService.getCurrentSession();
-    var transfer = Cc["@mozilla.org/widget/transferable;1"].
-                   createInstance(Ci.nsITransferable);
-
-    transfer.addDataFlavor(ENGINE_FLAVOR);
-    dragSession.getData(transfer, 0);
-
-    var dataObj = {};
-    var len = {};
-    var sourceIndex = -1;
-    try {
-      transfer.getAnyTransferData({}, dataObj, len);
-    } catch (ex) {}
-
-    if (dataObj.value) {
-      sourceIndex = dataObj.value.QueryInterface(Ci.nsISupportsString).data;
-      sourceIndex = parseInt(sourceIndex.substring(0, len.value));
-    }
-
-    return sourceIndex;
+  getSourceIndexFromDrag: function (dataTransfer) {
+    return parseInt(dataTransfer.getData(ENGINE_FLAVOR));
   },
 
   // nsITreeView
   get rowCount() {
     return this._engineStore.engines.length;
   },
 
   getImageSrc: function(index, column) {
@@ -508,25 +487,25 @@ EngineView.prototype = {
       return this._engineStore.engines[index].alias;
     return "";
   },
 
   setTree: function(tree) {
     this.tree = tree;
   },
 
-  canDrop: function(targetIndex, orientation) {
-    var sourceIndex = this.getSourceIndexFromDrag();
+  canDrop: function(targetIndex, orientation, dataTransfer) {
+    var sourceIndex = this.getSourceIndexFromDrag(dataTransfer);
     return (sourceIndex != -1 &&
             sourceIndex != targetIndex &&
             sourceIndex != (targetIndex + orientation));
   },
 
-  drop: function(dropIndex, orientation) {
-    var sourceIndex = this.getSourceIndexFromDrag();
+  drop: function(dropIndex, orientation, dataTransfer) {
+    var sourceIndex = this.getSourceIndexFromDrag(dataTransfer);
     var sourceEngine = this._engineStore.engines[sourceIndex];
 
     if (dropIndex > sourceIndex) {
       if (orientation == Ci.nsITreeView.DROP_BEFORE)
         dropIndex--;
     } else {
       if (orientation == Ci.nsITreeView.DROP_AFTER)
         dropIndex++;    
--- a/browser/components/wintaskbar/WindowsJumpLists.jsm
+++ b/browser/components/wintaskbar/WindowsJumpLists.jsm
@@ -47,19 +47,17 @@ const Ci = Components.interfaces;
 
 // Prefs
 const PREF_TASKBAR_BRANCH    = "browser.taskbar.lists.";
 const PREF_TASKBAR_ENABLED   = "enabled";
 const PREF_TASKBAR_ITEMCOUNT = "maxListItemCount";
 const PREF_TASKBAR_FREQUENT  = "frequent.enabled";
 const PREF_TASKBAR_RECENT    = "recent.enabled";
 const PREF_TASKBAR_TASKS     = "tasks.enabled";
-
-// The amount of time between updates for jump lists
-const TIMER_TASKBAR_REFRESH = 1000*60*2; // 2 min.
+const PREF_TASKBAR_REFRESH   = "refreshInSeconds";
 
 /**
  * Exports
  */
 
 let EXPORTED_SYMBOLS = [
   "WinTaskbarJumpList",
 ];
@@ -100,16 +98,20 @@ XPCOMUtils.defineLazyServiceGetter(this,
 XPCOMUtils.defineLazyServiceGetter(this, "_ioService",
                                    "@mozilla.org/network/io-service;1",
                                    "nsIIOService");
 
 XPCOMUtils.defineLazyServiceGetter(this, "_winShellService",
                                    "@mozilla.org/browser/shell-service;1",
                                    "nsIWindowsShellService");
 
+XPCOMUtils.defineLazyServiceGetter(this, "_privateBrowsingSvc",
+                                   "@mozilla.org/privatebrowsing;1",
+                                   "nsIPrivateBrowsingService");
+
 /**
  * Global functions
  */
 
 function _getString(name) {
   return _stringBundle.GetStringFromName(name);
 }
 
@@ -142,16 +144,36 @@ var tasksCfg = [
   {
     get title()       _getString("taskbar.tasks.newWindow.label"),
     get description() _getString("taskbar.tasks.newWindow.description"),
     args:             "-browser",
     iconIndex:        0, // Fx app icon
     open:             true,
     close:            false, // no point
   },
+
+  // Privacy mode
+  {
+    get title() {
+      if (_privateBrowsingSvc.privateBrowsingEnabled)
+        return _getString("taskbar.tasks.exitPrivacyMode.label");
+      else
+        return _getString("taskbar.tasks.enterPrivacyMode.label");
+    },
+    get description() {
+      if (_privateBrowsingSvc.privateBrowsingEnabled)
+        return _getString("taskbar.tasks.exitPrivacyMode.description");
+      else
+        return _getString("taskbar.tasks.enterPrivacyMode.description");
+    },
+    args:             "-private-toggle",
+    iconIndex:        0, // Fx app icon
+    open:             true,
+    close:            true,
+  },
 ];
 
 /////////////////////////////////////////////////////////////////////////////
 // Implementation
 
 var WinTaskbarJumpList =
 {
   _builder: null,
@@ -188,22 +210,16 @@ var WinTaskbarJumpList =
     this.update();
   },
 
   update: function WTBJL_update() {
     // are we disabled via prefs? don't do anything!
     if (!this._enabled)
       return;
 
-    // hide jump lists when we're enabled and in private browsing mode
-    if (this._inPrivateBrowsing) {
-      this._deleteActiveJumpList();
-      return;
-    }
-
     // do what we came here to do, update the taskbar jumplist
     this._buildList();
   },
 
   _shutdown: function WTBJL__shutdown() {
     this._shuttingDown = true;
     this.update();
     this._free();
@@ -223,26 +239,25 @@ var WinTaskbarJumpList =
       // don't leave the last list hanging on the taskbar.
       this._deleteActiveJumpList();
       return;
     }
 
     if (!this._startBuild())
       return;
 
-    if (this._showTasks && !this._buildTasks())
-      return;
+    if (this._showTasks)
+      this._buildTasks();
 
     // Space for frequent items takes priority over recent.
-    
-    if (this._showFrequent && !this._buildFrequent())
-      return;
+    if (this._showFrequent)
+      this._buildFrequent();
 
-    if (this._showRecent && !this._buildRecent())
-      return;
+    if (this._showRecent)
+      this._buildRecent();
 
     this._commitBuild();
   },
 
   /**
    * Taskbar api wrappers
    */ 
 
@@ -269,80 +284,77 @@ var WinTaskbarJumpList =
     this._tasks.forEach(function (task) {
       if ((this._shuttingDown && !task.close) || (!this._shuttingDown && !task.open))
         return;
       var item = this._getHandlerAppItem(task.title, task.description,
                                          task.args, task.iconIndex);
       items.appendElement(item, false);
     }, this);
     
-    if (items.length == 0)
-      return true;
-
-    return this._builder.addListToBuild(this._builder.JUMPLIST_CATEGORY_TASKS, items);
+    if (items.length > 0)
+      this._builder.addListToBuild(this._builder.JUMPLIST_CATEGORY_TASKS, items);
   },
 
   _buildCustom: function WTBJL__buildCustom(title, items) {
-    if (items.length == 0)
-      return true;
-    return this._builder.addListToBuild(this._builder.JUMPLIST_CATEGORY_CUSTOMLIST, items, title);
+    if (items.length > 0)
+      this._builder.addListToBuild(this._builder.JUMPLIST_CATEGORY_CUSTOMLIST, items, title);
   },
 
   _buildFrequent: function WTBJL__buildFrequent() {
     // Windows supports default frequent and recent lists,
     // but those depend on internal windows visit tracking
     // which we don't populate. So we build our own custom
     // frequent and recent lists using our nav history data.
 
     var items = Cc["@mozilla.org/array;1"].
                 createInstance(Ci.nsIMutableArray);
     var list = this._getNavFrequent(this._maxItemCount);
 
     if (!list || list.length == 0)
-      return true;
+      return;
 
     // track frequent items so that we don't add them to
     // the recent list.
     this._frequentHashList = [];
 
     list.forEach(function (entry) {
       let shortcut = this._getHandlerAppItem(entry.title, entry.title, entry.uri, 1);
       items.appendElement(shortcut, false);
       this._frequentHashList.push(entry.uri);
     }, this);
-    return this._buildCustom(_getString("taskbar.frequent.label"), items);
+    this._buildCustom(_getString("taskbar.frequent.label"), items);
   },
 
   _buildRecent: function WTBJL__buildRecent() {
     var items = Cc["@mozilla.org/array;1"].
                 createInstance(Ci.nsIMutableArray);
     var list = this._getNavRecent(this._maxItemCount*2);
     
     if (!list || list.length == 0)
-      return true;
+      return;
 
     let count = 0;
     for (let idx = 0; idx < list.length; idx++) {
       if (count >= this._maxItemCount)
         break;
       let entry = list[idx];
       // do not add items to recent that have already been added
       // to frequent.
       if (this._frequentHashList &&
           this._frequentHashList.indexOf(entry.uri) != -1)
         continue;
       let shortcut = this._getHandlerAppItem(entry.title, entry.title, entry.uri, 1);
       items.appendElement(shortcut, false);
       count++;
     }
-    return this._buildCustom(_getString("taskbar.recent.label"), items);
+    this._buildCustom(_getString("taskbar.recent.label"), items);
   },
 
   _deleteActiveJumpList: function WTBJL__deleteAJL() {
-    return this._builder.deleteActiveList();
+    this._builder.deleteActiveList();
   },
 
   /**
    * Jump list item creation helpers
    */
 
   _getHandlerAppItem: function WTBJL__getHandlerAppItem(name, description, args, icon) {
     var file = _directoryService.get("XCurProcD", Ci.nsILocalFile);
@@ -439,37 +451,32 @@ var WinTaskbarJumpList =
       return;
     var enum = items.enumerate();
     while (enum.hasMoreElements()) {
       let oldItem = enum.getNext().QueryInterface(Ci.nsIJumpListShortcut);
       if (oldItem) {
         try { // in case we get a bad uri
           let uriSpec = oldItem.app.getParameter(0);
           _navHistoryService.QueryInterface(Ci.nsIBrowserHistory).removePage(
-            _ioService.newURI(uriSpec));
+            _ioService.newURI(uriSpec, null, null));
         } catch (err) { }
       }
     }
   },
 
   /**
    * Prefs utilities
    */ 
 
   _refreshPrefs: function WTBJL__refreshPrefs() {
     this._enabled = _prefs.getBoolPref(PREF_TASKBAR_ENABLED);
     this._showFrequent = _prefs.getBoolPref(PREF_TASKBAR_FREQUENT);
     this._showRecent = _prefs.getBoolPref(PREF_TASKBAR_RECENT);
     this._showTasks = _prefs.getBoolPref(PREF_TASKBAR_TASKS);
     this._maxItemCount = _prefs.getIntPref(PREF_TASKBAR_ITEMCOUNT);
-
-    // retrieve the initial status of the Private Browsing mode.
-    this._inPrivateBrowsing = Cc["@mozilla.org/privatebrowsing;1"].
-                              getService(Ci.nsIPrivateBrowsingService).
-                              privateBrowsingEnabled;
   },
 
   /**
    * Init and shutdown utilities
    */ 
 
   _initTaskbar: function WTBJL__initTaskbar() {
     this._builder = _taskbarService.createJumpListBuilder();
@@ -477,28 +484,32 @@ var WinTaskbarJumpList =
       return false;
 
     return true;
   },
 
   _initObs: function WTBJL__initObs() {
     _observerService.addObserver(this, "private-browsing", false);
     _observerService.addObserver(this, "quit-application-granted", false);
+    _observerService.addObserver(this, "browser:purge-session-history", false);
     _prefs.addObserver("", this, false);
   },
  
   _freeObs: function WTBJL__freeObs() {
     _observerService.removeObserver(this, "private-browsing");
     _observerService.removeObserver(this, "quit-application-granted");
+    _observerService.removeObserver(this, "browser:purge-session-history");
     _prefs.removeObserver("", this);
   },
 
   _initTimer: function WTBJL__initTimer(aTimer) {
     this._timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
-    this._timer.initWithCallback(this, TIMER_TASKBAR_REFRESH, this._timer.TYPE_REPEATING_SLACK);
+    this._timer.initWithCallback(this,
+                                 _prefs.getIntPref(PREF_TASKBAR_REFRESH)*1000,
+                                 this._timer.TYPE_REPEATING_SLACK);
   },
 
   _free: function WTBJL__free() {
     this._freeObs();
     delete this._builder;
     delete this._timer;
   },
 
@@ -508,34 +519,28 @@ var WinTaskbarJumpList =
 
   notify: function WTBJL_notify(aTimer) {
     this.update();
   },
 
   observe: function WTBJL_observe(aSubject, aTopic, aData) {
     switch (aTopic) {
       case "nsPref:changed":
+        if (this._enabled == true && !_prefs.getBoolPref(PREF_TASKBAR_ENABLED))
+          this._deleteActiveJumpList();
         this._refreshPrefs();
         this.update();
       break;
 
       case "quit-application-granted":
         this._shutdown();
       break;
 
       case "browser:purge-session-history":
         this.update();
       break;
 
       case "private-browsing":
-        switch (aData) {
-          case "enter":
-            this._inPrivateBrowsing = true;
-            break;
-          case "exit":
-            this._inPrivateBrowsing = false;
-            break;
-        }
         this.update();
       break;
     }
   },
 };
--- a/browser/installer/Makefile.in
+++ b/browser/installer/Makefile.in
@@ -81,16 +81,20 @@ endif
 ifdef NSS_DISABLE_DBM
 DEFINES += -DNSS_DISABLE_DBM=1
 endif
 
 ifdef MOZ_UPDATER
 DEFINES += -DMOZ_UPDATER=1
 endif
 
+ifdef _MSC_VER
+DEFINES += -D_MSC_VER=$(_MSC_VER)
+endif
+
 # Don't ifdef MOZ_IPC this because mac ppc needs it too.
 include $(topsrcdir)/ipc/app/defs.mk
 DEFINES += -DMOZ_CHILD_PROCESS_NAME=$(MOZ_CHILD_PROCESS_NAME)
 
 ifdef MOZ_PKG_MANIFEST_P
 MOZ_PKG_MANIFEST = package-manifest
 
 $(MOZ_PKG_MANIFEST): $(MOZ_PKG_MANIFEST_P)
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -52,20 +52,30 @@
 #ifdef MOZ_IPC
 @BINPATH@/@MOZ_CHILD_PROCESS_NAME@
 #endif
 #endif
 #ifdef WINCE
 @BINPATH@/mozce_shunt.dll
 #elifdef XP_WIN32
 #ifndef MOZ_MEMORY
+#if _MSC_VER == 1400
 @BINPATH@/Microsoft.VC80.CRT.manifest
 @BINPATH@/msvcm80.dll
 @BINPATH@/msvcp80.dll
 @BINPATH@/msvcr80.dll
+#elif _MSC_VER == 1500
+@BINPATH@/Microsoft.VC90.CRT.manifest
+@BINPATH@/msvcm90.dll
+@BINPATH@/msvcp90.dll
+@BINPATH@/msvcr90.dll
+#elif _MSC_VER == 1600
+@BINPATH@/msvcp100.dll
+@BINPATH@/msvcr100.dll
+#endif
 #else
 @BINPATH@/mozcrt19.dll
 @BINPATH@/mozcpp19.dll
 #endif
 #endif
 
 [browser]
 ; [Base Browser Files]
@@ -308,16 +318,17 @@
 @BINPATH@/components/PlacesProtocolHandler.js
 @BINPATH@/components/nsDefaultCLH.js
 @BINPATH@/components/nsContentPrefService.js
 @BINPATH@/components/nsContentDispatchChooser.js
 @BINPATH@/components/nsHandlerService.js
 @BINPATH@/components/nsWebHandlerApp.js
 @BINPATH@/components/nsBadCertHandler.js
 @BINPATH@/components/nsFormAutoComplete.js
+@BINPATH@/components/nsFormHistory.js
 @BINPATH@/components/contentSecurityPolicy.js
 @BINPATH@/components/contentAreaDropListener.js
 #ifdef XP_MACOSX
 @BINPATH@/components/libalerts_s.dylib
 #endif
 #ifdef MOZ_ENABLE_DBUS
 @BINPATH@/components/@DLL_PREFIX@dbusservice@DLL_SUFFIX@
 #endif
--- a/browser/installer/removed-files.in
+++ b/browser/installer/removed-files.in
@@ -76,20 +76,25 @@ defaults/profile/extensions/{972ce4c6-7e
 defaults/profile/search.rdf
 extensions/talkback@mozilla.org/
 extensions/talkback@mozilla.org/chrome.manifest
 extensions/talkback@mozilla.org/components/@DLL_PREFIX@qfaservices@DLL_SUFFIX@
 extensions/talkback@mozilla.org/components/qfaservices.xpt
 extensions/talkback@mozilla.org/install.rdf
 extensions/{641d8d09-7dda-4850-8228-ac0ab65e2ac9}/
 extensions/{641d8d09-7dda-4850-8228-ac0ab65e2ac9}/install.rdf
+greprefs/all.js
+greprefs/security-prefs.js
+greprefs/xpinstall.js
 install.rdf
 modules/JSON.jsm
 mozilla-runtime@BIN_SUFFIX@
 old-homepage-default.properties
+res/arrow.gif
+res/arrowd.gif
 res/broken-image.gif
 res/broken-image.png
 res/charsetData.properties
 res/charsetalias.properties
 res/cmessage.txt
 res/fonts/fontEncoding.properties
 res/fonts/fontNameMap.properties
 res/fonts/mathfontCMEX10.properties
@@ -694,19 +699,16 @@ xpicleanup@BIN_SUFFIX@
   components/xpcom_xpti.xpt
   components/xpconnect.xpt
   components/xpinstall.xpt
   components/xulapp.xpt
   components/xuldoc.xpt
   components/xultmpl.xpt
   components/zipwriter.xpt
   extensions/inspector@mozilla.org/chrome/chromelist.txt
-  greprefs/all.js
-  greprefs/security-prefs.js
-  greprefs/xpinstall.js
   init.d/README
   libwidget.rsrc
   plugins/Default Plugin.plugin/Contents/Info.plist
   plugins/Default Plugin.plugin/Contents/MacOS/Default Plugin
   plugins/Default Plugin.plugin/Contents/PkgInfo
   plugins/Default Plugin.plugin/Contents/Resources/Default Plugin.rsrc
   plugins/Default Plugin.plugin/Contents/Resources/English.lproj/InfoPlist.strings
   plugins/DefaultPlugin.plugin/
--- a/browser/locales/en-US/chrome/browser/taskbar.properties
+++ b/browser/locales/en-US/chrome/browser/taskbar.properties
@@ -1,6 +1,10 @@
 taskbar.tasks.newTab.label=Open new tab
 taskbar.tasks.newTab.description=Open a new browser tab.
 taskbar.tasks.newWindow.label=Open new window
 taskbar.tasks.newWindow.description=Open a new browser window.
+taskbar.tasks.enterPrivacyMode.label=Enter private browsing
+taskbar.tasks.enterPrivacyMode.description=Start private browsing. The current session will be saved.
+taskbar.tasks.exitPrivacyMode.label=Quit private browsing
+taskbar.tasks.exitPrivacyMode.description=Quit private browsing and restore the previous session.
 taskbar.frequent.label=Frequent
 taskbar.recent.label=Recent
--- a/build/autoconf/nss.m4
+++ b/build/autoconf/nss.m4
@@ -4,17 +4,17 @@
 # Based upon gtk.m4 (also PD) by Owen Taylor
 
 dnl AM_PATH_NSS([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
 dnl Test for NSS, and define NSS_CFLAGS and NSS_LIBS
 AC_DEFUN(AM_PATH_NSS,
 [dnl
 
 AC_ARG_WITH(nss-prefix,
-	[  --with-nss-prefix=PFX  Prefix where NSS is installed],
+	[  --with-nss-prefix=PFX   Prefix where NSS is installed],
 	nss_config_prefix="$withval",
 	nss_config_prefix="")
 
 AC_ARG_WITH(nss-exec-prefix,
 	[  --with-nss-exec-prefix=PFX
                           Exec prefix where NSS is installed],
 	nss_config_exec_prefix="$withval",
 	nss_config_exec_prefix="")
--- a/build/mobile/devicemanager.py
+++ b/build/mobile/devicemanager.py
@@ -49,96 +49,35 @@ class FileError(Exception):
   " Signifies an error which occurs while doing a file operation."
 
   def __init__(self, msg = ''):
     self.msg = msg
 
   def __str__(self):
     return self.msg
 
-class myProc(Thread):
-  def __init__(self, hostip, hostport, cmd, new_line = True, sleeptime = 0):
-    self.cmdline = cmd
-    self.newline = new_line
-    self.sleep = sleeptime
-    self.host = hostip
-    self.port = hostport
-    Thread.__init__(self)
-
-  def run(self):
-    promptre =re.compile('.*\$\>.$')
-    data = ""
-    try:
-      s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-    except:
-      return None
-      
-    try:
-      s.connect((self.host, int(self.port)))
-    except:
-      s.close()
-      return None
-      
-    try:
-      s.recv(1024)
-    except:
-      s.close()
-      return None
-      
-    for cmd in self.cmdline:
-      if (cmd == 'quit'): break
-      if self.newline: cmd += '\r\n'
-      try:
-        s.send(cmd)
-      except:
-        s.close()
-        return None
-        
-      time.sleep(int(self.sleep))
-
-      found = False
-      while (found == False):
-        try:
-          temp = s.recv(1024)
-        except:
-          s.close()
-          return None
-          
-        lines = temp.split('\n')
-        for line in lines:
-          if (promptre.match(line)):
-            found = True
-          data += temp
-
-    try:
-      s.send('quit\r\n')
-    except:
-      s.close()
-      return None
-    try:
-      s.close()
-    except:
-      return None
-    return data
-
 class DeviceManager:
   host = ''
   port = 0
   debug = 3
   _redo = False
-  deviceRoot = '/tests'
+  deviceRoot = None
   tempRoot = os.getcwd()
+  base_prompt = '\$\>'
+  prompt_sep = '\x00'
+  prompt_regex = '.*' + base_prompt + prompt_sep
 
   def __init__(self, host, port = 27020):
     self.host = host
     self.port = port
     self._sock = None
+    self.getDeviceRoot()
 
   def sendCMD(self, cmdline, newline = True, sleep = 0):
-    promptre = re.compile('.*\$\>.$')
+    promptre = re.compile(self.prompt_regex + '$')
 
     # TODO: any commands that don't output anything and quit need to match this RE
     pushre = re.compile('^push .*$')
     data = ""
     noQuit = False
 
     if (self._sock == None):
       try:
@@ -164,29 +103,30 @@ class DeviceManager:
         return None
       
     for cmd in cmdline:
       if (cmd == 'quit'): break
       if newline: cmd += '\r\n'
       
       try:
         self._sock.send(cmd)
+        if (self.debug >= 4): print "send cmd: " + str(cmd)
       except:
         self._redo = True
         self._sock.close()
         self._sock = None
         return None
       
       if (pushre.match(cmd) or cmd == 'rebt'):
         noQuit = True
       elif noQuit == False:
         time.sleep(int(sleep))
         found = False
         while (found == False):
-          if (self.debug >= 3): print "recv'ing..."
+          if (self.debug >= 4): print "recv'ing..."
           
           try:
             temp = self._sock.recv(1024)
           except:
             self._redo = True
             self._sock.close()
             self._sock = None
             return None
@@ -206,64 +146,59 @@ class DeviceManager:
         self._sock = None
         return None
 
     return data
   
   
   # take a data blob and strip instances of the prompt '$>\x00'
   def stripPrompt(self, data):
-    promptre = re.compile('.*\$\>.*')
+    promptre = re.compile(self.prompt_regex + '.*')
     retVal = []
     lines = data.split('\n')
     for line in lines:
       try:
         while (promptre.match(line)):
-          pieces = line.split('\x00')
-          index = pieces.index("$>")
+          pieces = line.split(self.prompt_sep)
+          index = pieces.index('$>')
           pieces.pop(index)
-          line = '\x00'.join(pieces)
+          line = self.prompt_sep.join(pieces)
       except(ValueError):
         pass
       retVal.append(line)
 
     return '\n'.join(retVal)
   
 
   def pushFile(self, localname, destname):
-    if (self.debug >= 2):
-      print "in push file with: " + localname + ", and: " + destname
+    if (self.debug >= 2): print "in push file with: " + localname + ", and: " + destname
     if (self.validateFile(destname, localname) == True):
-      if (self.debug >= 2):
-        print "files are validated"
+      if (self.debug >= 2): print "files are validated"
       return ''
 
     if self.mkDirs(destname) == None:
       print "unable to make dirs: " + destname
       return None
 
-    if (self.debug >= 2):
-      print "sending: push " + destname
+    if (self.debug >= 2): print "sending: push " + destname
     
     # sleep 5 seconds / MB
     filesize = os.path.getsize(localname)
     sleepsize = 1024 * 1024
     sleepTime = (int(filesize / sleepsize) * 5) + 2
     f = open(localname, 'rb')
     data = f.read()
     f.close()
     retVal = self.sendCMD(['push ' + destname + '\r\n', data], newline = False, sleep = sleepTime)
     if (retVal == None):
-      if (self.debug >= 2):
-        print "Error in sendCMD, not validating push"
+      if (self.debug >= 2): print "Error in sendCMD, not validating push"
       return None
 
     if (self.validateFile(destname, localname) == False):
-      if (self.debug >= 2):
-        print "file did not copy as expected"
+      if (self.debug >= 2): print "file did not copy as expected"
       return None
 
     return retVal
   
   def mkDir(self, name):
     return self.sendCMD(['mkdr ' + name])
   
   
@@ -281,17 +216,16 @@ class DeviceManager:
     return ''
 
   # push localDir from host to remoteDir on the device
   def pushDir(self, localDir, remoteDir):
     if (self.debug >= 2): print "pushing directory: " + localDir + " to " + remoteDir
     for root, dirs, files in os.walk(localDir):
       parts = root.split(localDir)
       for file in files:
-        print "examining file: " + file
         remoteRoot = remoteDir + '/' + parts[1]
         remoteName = remoteRoot + '/' + file
         if (parts[1] == ""): remoteRoot = remoteDir
         if (self.pushFile(os.path.join(root, file), remoteName) == None):
           time.sleep(5)
           self.removeFile(remoteName)
           time.sleep(5)
           if (self.pushFile(os.path.join(root, file), remoteName) == None):
@@ -341,94 +275,107 @@ class DeviceManager:
   
   
   # does a recursive delete of directory on the device: rm -Rf remoteDir
   def removeDir(self, remoteDir):
     self.sendCMD(['rmdr ' + remoteDir], sleep = 5)
 
 
   def getProcessList(self):
-    data = self.sendCMD(['ps', 'quit'], sleep = 3)
+    data = self.sendCMD(['ps'], sleep = 3)
     if (data == None):
       return None
       
     retVal = self.stripPrompt(data)
     lines = retVal.split('\n')
     files = []
     for line in lines:
       if (line.strip() != ''):
-        pidproc = line.strip().split(' ')
+        pidproc = line.strip().split()
         if (len(pidproc) == 2):
           files += [[pidproc[0], pidproc[1]]]
-      
+        elif (len(pidproc) == 3):
+          #android returns <userID> <procID> <procName>
+          files += [[pidproc[1], pidproc[2], pidproc[0]]]     
     return files
 
-
   def getMemInfo(self):
     data = self.sendCMD(['mems', 'quit'])
     if (data == None):
       return None
     retVal = self.stripPrompt(data)
     # TODO: this is hardcoded for now
     fhandle = open("memlog.txt", 'a')
     fhandle.write("\n")
     fhandle.write(retVal)
     fhandle.close()
 
   def fireProcess(self, appname):
     if (self.debug >= 2): print "FIRE PROC: '" + appname + "'"
-    self.process = myProc(self.host, self.port, ['exec ' + appname, 'quit'])
-    self.process.start()  
+    
+    if (self.processExist(appname) != ''):
+      print "WARNING: process %s appears to be running already\n" % appname
+    
+    self.sendCMD(['exec ' + appname])
+
+    #NOTE: we sleep for 30 seconds to allow the application to startup
+    time.sleep(30)
+
+    self.process = self.processExist(appname)
+    if (self.debug >= 4): print "got pid: " + str(self.process) + " for process: " + str(appname)
 
   def launchProcess(self, cmd, outputFile = "process.txt", cwd = ''):
     if (outputFile == "process.txt"):
       outputFile = self.getDeviceRoot() + '/' + "process.txt"
-      
+
     cmdline = subprocess.list2cmdline(cmd)
     self.fireProcess(cmdline + " > " + outputFile)
     handle = outputFile
-        
+
     return handle
   
+  #hardcoded: sleep interval of 5 seconds, timeout of 10 minutes
   def communicate(self, process, timeout = 600):
+    interval = 5
     timed_out = True
     if (timeout > 0):
       total_time = 0
       while total_time < timeout:
-        time.sleep(1)
+        time.sleep(interval)
         if (not self.poll(process)):
           timed_out = False
           break
-        total_time += 1
+        total_time += interval
 
     if (timed_out == True):
       return None
 
     return [self.getFile(process, "temp.txt"), None]
 
 
   def poll(self, process):
     try:
-      if (not self.process.isAlive()):
+      if (self.processExist(process) == None):
         return None
       return 1
     except:
       return None
     return 1
   
 
 
   # iterates process list and returns pid if exists, otherwise ''
   def processExist(self, appname):
     pid = ''
   
-    pieces = appname.split('/')
-    app = pieces[-1]
+    pieces = appname.split(' ')
+    parts = pieces[0].split('/')
+    app = parts[-1]
     procre = re.compile('.*' + app + '.*')
-  
+
     procList = self.getProcessList()
     if (procList == None):
       return None
       
     for proc in procList:
       if (procre.match(proc[1])):
         pid = proc[0]
         break
@@ -437,30 +384,29 @@ class DeviceManager:
 
   def killProcess(self, appname):
     if (self.sendCMD(['kill ' + appname]) == None):
       return None
 
     return True
 
   def getTempDir(self):
-    promptre = re.compile('.*\$\>\x00.*')
     retVal = ''
     data = self.sendCMD(['tmpd', 'quit'])
     if (data == None):
       return None
     return self.stripPrompt(data).strip('\n')
 
   
   # copy file from device (remoteFile) to host (localFile)
   def getFile(self, remoteFile, localFile = ''):
     if localFile == '':
         localFile = os.path.join(self.tempRoot, "temp.txt")
   
-    promptre = re.compile('.*\$\>\x00.*')
+    promptre = re.compile(self.prompt_regex + '.*')
     data = self.sendCMD(['cat ' + remoteFile, 'quit'], sleep = 5)
     if (data == None):
       return None
     retVal = self.stripPrompt(data)
     fhandle = open(localFile, 'wb')
     fhandle.write(retVal)
     fhandle.close()
     return retVal
@@ -501,18 +447,17 @@ class DeviceManager:
   # return the md5 sum of a remote file
   def getRemoteHash(self, filename):
       data = self.sendCMD(['hash ' + filename, 'quit'], sleep = 1)
       if (data == None):
           return ''
       retVal = self.stripPrompt(data)
       if (retVal != None):
         retVal = retVal.strip('\n')
-      if (self.debug >= 3): 
-        print "remote hash: '" + retVal + "'"
+      if (self.debug >= 3): print "remote hash returned: '" + retVal + "'"
       return retVal
     
 
   # return the md5 sum of a file on the host
   def getLocalHash(self, filename):
       file = open(filename, 'rb')
       if (file == None):
           return None
@@ -525,46 +470,52 @@ class DeviceManager:
       while 1:
           data = file.read(1024)
           if not data:
               break
           mdsum.update(data)
 
       file.close()
       hexval = mdsum.hexdigest()
-      if (self.debug >= 3):
-        print "local hash: '" + hexval + "'"
+      if (self.debug >= 3): print "local hash returned: '" + hexval + "'"
       return hexval
 
   # Gets the device root for the testing area on the device
   # For all devices we will use / type slashes and depend on the device-agent
-  # to sort those out.
+  # to sort those out.  The agent will return us the device location where we
+  # should store things, we will then create our /tests structure relative to
+  # that returned path.
   # Structure on the device is as follows:
   # /tests
   #       /<fennec>|<firefox>  --> approot
   #       /profile
   #       /xpcshell
   #       /reftest
   #       /mochitest
   def getDeviceRoot(self):
     if (not self.deviceRoot):
-      if (self.dirExists('/tests')):
-        self.deviceRoot = '/tests'
-      else:
-        self.mkDir('/tests')
-        self.deviceRoot = '/tests'
+      data = self.sendCMD(['testroot'], sleep = 1)
+      if (data == None):
+        return '/tests'
+      self.deviceRoot = self.stripPrompt(data).strip('\n') + '/tests'
+
+    if (not self.dirExists(self.deviceRoot)):
+      self.mkDir(self.deviceRoot)
+
     return self.deviceRoot
 
   # Either we will have /tests/fennec or /tests/firefox but we will never have
   # both.  Return the one that exists
   def getAppRoot(self):
     if (self.dirExists(self.getDeviceRoot() + '/fennec')):
       return self.getDeviceRoot() + '/fennec'
+    elif (self.dirExists(self.getDeviceRoot() + '/firefox')):
+      return self.getDeviceRoot() + '/firefox'
     else:
-      return self.getDeviceRoot() + '/firefox'
+      return 'org.mozilla.fennec'
 
   # Gets the directory location on the device for a specific test type
   # Type is one of: xpcshell|reftest|mochitest
   def getTestRoot(self, type):
     if (re.search('xpcshell', type, re.I)):
       self.testRoot = self.getDeviceRoot() + '/xpcshell'
     elif (re.search('?(i)reftest', type)):
       self.testRoot = self.getDeviceRoot() + '/reftest'
@@ -587,18 +538,18 @@ class DeviceManager:
   def unpackFile(self, filename):
     dir = ''
     parts = filename.split('/')
     if (len(parts) > 1):
       if self.fileExists(filename):
         dir = '/'.join(parts[:-1])
     elif self.fileExists('/' + filename):
       dir = '/' + filename
-    elif self.fileExists('/tests/' + filename):
-      dir = '/tests/' + filename
+    elif self.fileExists(self.getDeviceRoot() + '/' + filename):
+      dir = self.getDeviceRoot() + '/' + filename
     else:
       return None
 
     return self.sendCMD(['cd ' + dir, 'unzp ' + filename])
 
 
   def reboot(self, wait = False):
     self.sendCMD(['rebt'])
@@ -625,8 +576,76 @@ class DeviceManager:
       for file in files:
         remoteRoot = remoteDir + '/' + parts[1]
         remoteRoot = remoteRoot.replace('/', '/')
         if (parts[1] == ""): remoteRoot = remoteDir
         remoteName = remoteRoot + '/' + file
         if (self.validateFile(remoteName, os.path.join(root, file)) <> True):
             return None
     return True
+
+  #TODO: make this simpler by doing a single directive at a time
+  # Returns information about the device:
+  # Directive indicates the information you want to get, your choices are:
+  # os - name of the os
+  # id - unique id of the device
+  # uptime - uptime of the device
+  # systime - system time of the device
+  # screen - screen resolution
+  # memory - memory stats
+  # process - list of running processes (same as ps)
+  # disk - total, free, available bytes on disk
+  # power - power status (charge, battery temp)
+  # all - all of them
+  def getInfo(self, directive):
+    data = None
+    if (directive in ('os','id','uptime','systime','screen','memory','process',
+                      'disk','power')):
+      data = self.sendCMD(['info ' + directive, 'quit'], sleep = 1)
+    else:
+      directive = None
+      data = self.sendCMD(['info', 'quit'], sleep = 1)
+
+    if (data is None):
+      return None
+      
+    data = self.stripPrompt(data)
+    result = {}
+        
+    if directive:
+      result[directive] = data.split('\n')
+      for i in range(len(result[directive])):
+        if (len(result[directive][i]) != 0):
+          result[directive][i] = result[directive][i].strip()
+
+      # Get rid of any empty attributes
+      result[directive].remove('')
+
+    else:
+      lines = data.split('\n')
+      result['id'] = lines[0]
+      result['os'] = lines[1]
+      result['systime'] = lines[2]
+      result['uptime'] = lines[3]
+      result['screen'] = lines[4]
+      result['memory'] = lines[5]
+      if (lines[6] == 'Power status'):
+        tmp = []
+        for i in range(4):
+          tmp.append(line[7 + i])
+        result['power'] = tmp
+      tmp = []
+
+      # Linenum is the line where the process list begins
+      linenum = 11
+      for j in range(len(lines) - linenum):
+        if (lines[j + linenum].strip() != ''):
+          procline = lines[j + linenum].split('\t')
+
+          if len(procline) == 2:
+            tmp.append([procline[0], procline[1]])
+          elif len(procline) == 3:
+            # Android has <userid> <procid> <procname>
+            # We put the userid to achieve a common format
+            tmp.append([procline[1], procline[2], procline[0]])
+      result['process'] = tmp
+    return result
+
--- a/config/Expression.py
+++ b/config/Expression.py
@@ -104,17 +104,21 @@ class Expression:
     Production: ( [0-9]+ | \w+)
     Note that the order is important, and the expression is kind-of
     ambiguous as \w includes 0-9. One could make it unambiguous by
     removing 0-9 from the first char of a string literal.
     """
     rv = None
     word_len = re.match('[0-9]*', self.content).end()
     if word_len:
-      rv = Expression.__ASTLeaf('int', int(self.content[:word_len]))
+      if self.content[0] == '0':
+        value = int(self.content[:word_len], 8)
+      else:
+        value = int(self.content[:word_len])
+      rv = Expression.__ASTLeaf('int', value)
     else:
       word_len = re.match('\w*', self.content).end()
       if word_len:
         rv = Expression.__ASTLeaf('string', self.content[:word_len])
       else:
         raise Expression.ParseError, self
     self.__strip(word_len)
     self.__ignore_whitespace()
--- a/config/Makefile.in
+++ b/config/Makefile.in
@@ -144,24 +144,26 @@ stl_compiler = gcc
 else
 ifdef _MSC_VER
 stl_compiler = msvc
 endif
 endif
 endif
 
 ifdef stl_compiler
-stl-wrappers-sentinel: $(srcdir)/make-stl-wrappers.py $(srcdir)/$(stl_compiler)-stl-wrapper.template.h $(srcdir)/stl-headers $(GLOBAL_DEPS)
+STL_WRAPPERS_SENTINEL = $(DIST)/stl_wrappers/sentinel
+
+$(STL_WRAPPERS_SENTINEL): $(srcdir)/make-stl-wrappers.py $(srcdir)/$(stl_compiler)-stl-wrapper.template.h $(srcdir)/stl-headers $(GLOBAL_DEPS)
 	$(PYTHON) $(srcdir)/make-stl-wrappers.py stl_wrappers $(stl_compiler) $(srcdir)/$(stl_compiler)-stl-wrapper.template.h $(srcdir)/stl-headers
 	$(PYTHON) $(srcdir)/nsinstall.py stl_wrappers $(DIST)
-	touch stl-wrappers-sentinel
+	touch $(STL_WRAPPERS_SENTINEL)
 
-export:: stl-wrappers-sentinel
+export:: $(STL_WRAPPERS_SENTINEL)
 
-GARBAGE += stl-wrappers-sentinel
+GARBAGE += $(STL_WRAPPERS_SENTINEL)
 GARBAGE_DIRS += stl_wrappers
 endif
 
 install::
 	$(SYSINSTALL) $(IFLAGS1) $(DEPTH)/mozilla-config.h $(DESTDIR)$(includedir)
 
 GARBAGE += \
 	$(FINAL_LINK_COMPS) $(FINAL_LINK_LIBS) $(FINAL_LINK_COMP_NAMES) buildid $(srcdir)/*.pyc
--- a/config/Preprocessor.py
+++ b/config/Preprocessor.py
@@ -165,26 +165,32 @@ class Preprocessor:
       args = [sys.stdin]
     includes.extend(args)
     for f in includes:
       self.do_include(f)
     pass
 
   def getCommandLineParser(self, unescapeDefines = False):
     escapedValue = re.compile('".*"$')
+    numberValue = re.compile('\d+$')
     def handleE(option, opt, value, parser):
       for k,v in os.environ.iteritems():
         self.context[k] = v
     def handleD(option, opt, value, parser):
       vals = value.split('=', 1)
       if len(vals) == 1:
         vals.append(1)
       elif unescapeDefines and escapedValue.match(vals[1]):
         # strip escaped string values
         vals[1] = vals[1][1:-1]
+      elif numberValue.match(vals[1]):
+        if vals[1][0] == '0':
+          vals[1] = int(vals[1], 8)
+        else:
+          vals[1] = int(vals[1])
       self.context[vals[0]] = vals[1]
     def handleU(option, opt, value, parser):
       del self.context[value]
     def handleF(option, opt, value, parser):
       self.do_filter(value)
     def handleLE(option, opt, value, parser):
       self.setLineEndings(value)
     def handleMarker(option, opt, value, parser):
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -591,16 +591,17 @@ MOZILLA_OFFICIAL = @MOZILLA_OFFICIAL@
 # Win32 options
 MOZ_BROWSE_INFO	= @MOZ_BROWSE_INFO@
 MOZ_TOOLS_DIR	= @MOZ_TOOLS_DIR@
 MOZ_QUANTIFY	= @MOZ_QUANTIFY@
 MSMANIFEST_TOOL = @MSMANIFEST_TOOL@
 WIN32_REDIST_DIR = @WIN32_REDIST_DIR@
 WIN32_CRT_SRC_DIR = @WIN32_CRT_SRC_DIR@
 MOZ_MEMORY_LDFLAGS = @MOZ_MEMORY_LDFLAGS@
+MOZ_CRT_CPU_ARCH = @MOZ_CRT_CPU_ARCH@
 
 # This is for custom CRT building
 ifdef MOZ_MEMORY
 ifdef WIN32_CRT_SRC_DIR
 DLLFLAGS = @DLLFLAGS@
 endif
 endif
 
--- a/config/tests/unit-Preprocessor.py
+++ b/config/tests/unit-Preprocessor.py
@@ -399,10 +399,54 @@ FAIL
   def test_lineEndings(self):
     f = NamedIO('lineEndings.in', '''first
 #literal second
 ''')
     self.pp.setLineEndings('cr')
     self.pp.do_include(f)
     self.assertEqual(self.pp.out.getvalue(), "first\rsecond\r")
 
+  def test_number_value_equals(self):
+    f = NamedIO("number_value_equals.in", """#define FOO 1000
+#if FOO == 1000
+number value is equal
+#else
+number value is not equal
+#endif
+""")
+    self.pp.do_include(f)
+    self.assertEqual(self.pp.out.getvalue(), "number value is equal\n")
+
+  def test_number_value_equals_defines(self):
+    f = NamedIO("number_value_equals_defines.in", """#if FOO == 1000
+number value is equal
+#else
+number value is not equal
+#endif
+""")
+    self.pp.handleCommandLine(["-DFOO=1000"])
+    self.pp.do_include(f)
+    self.assertEqual(self.pp.out.getvalue(), "number value is equal\n")
+
+  def test_octal_value_equals(self):
+    f = NamedIO("octal_value_equals.in", """#define FOO 0100
+#if FOO == 0100
+octal value is equal
+#else
+octal value is not equal
+#endif
+""")
+    self.pp.do_include(f)
+    self.assertEqual(self.pp.out.getvalue(), "octal value is equal\n")
+
+  def test_octal_value_equals_defines(self):
+    f = NamedIO("octal_value_equals_defines.in", """#if FOO == 0100
+octal value is equal
+#else
+octal value is not equal
+#endif
+""")
+    self.pp.handleCommandLine(["-DFOO=0100"])
+    self.pp.do_include(f)
+    self.assertEqual(self.pp.out.getvalue(), "octal value is equal\n")
+
 if __name__ == '__main__':
   unittest.main()
--- a/configure.in
+++ b/configure.in
@@ -105,17 +105,17 @@ dnl ====================================
 _SUBDIR_HOST_CFLAGS="$HOST_CFLAGS"
 _SUBDIR_HOST_CXXFLAGS="$HOST_CXXFLAGS"
 _SUBDIR_HOST_LDFLAGS="$HOST_LDFLAGS"
 _SUBDIR_CONFIG_ARGS="$ac_configure_args"
 
 dnl Set the version number of the libs included with mozilla
 dnl ========================================================
 MOZJPEG=62
-MOZPNG=10400
+MOZPNG=10401
 MOZZLIB=0x1230
 NSPR_VERSION=4
 NSS_VERSION=3
 
 dnl Set the minimum version of toolkit libs used by mozilla
 dnl ========================================================
 GLIB_VERSION=1.2.0
 LIBIDL_VERSION=0.6.3
@@ -210,22 +210,22 @@ case "$target" in
     if test -z "$CXX"; then CXX=g++-4.2; fi
     ;;
 esac
 fi
 
 COMPILE_ENVIRONMENT=1
 MOZ_ARG_DISABLE_BOOL(compile-environment,
 [  --disable-compile-environment
-                           Disable compiler/library checks.],
+                          Disable compiler/library checks.],
     COMPILE_ENVIRONMENT= )
 AC_SUBST(COMPILE_ENVIRONMENT)
 
 MOZ_ARG_WITH_STRING(l10n-base,
-[  --with-l10n-base=DIR     path to l10n repositories],
+[  --with-l10n-base=DIR    path to l10n repositories],
     L10NBASEDIR=$withval)
 if test ! -z "$L10NBASEDIR"; then
     if test "$L10NBASEDIR" = "yes" -o "$L10NBASEDIR" = "no"; then
         AC_MSG_ERROR([--with-l10n-base must specify a path])
     elif test -d "$L10NBASEDIR"; then
         L10NBASEDIR=`cd "$L10NBASEDIR" && pwd`
     else
         AC_MSG_ERROR([Invalid value --with-l10n-base, $L10NBASEDIR doesn't exist])
@@ -241,37 +241,37 @@ fi
 
 dnl ========================================================
 dnl = Android uses a very custom (hacky) toolchain; we need to do this
 dnl = here, so that the compiler checks can succeed
 dnl ========================================================
 
 MOZ_ARG_WITH_STRING(android-ndk,
 [  --with-android-ndk=DIR
-                           location where the Android NDK can be found],
+                          location where the Android NDK can be found],
     android_ndk=$withval)
 
 MOZ_ARG_WITH_STRING(android-toolchain,
 [  --with-android-toolchain=DIR
-                           location of the android toolchain, default NDK/build/prebuilt/HOST/arm-eabi-4.4.0],
+                          location of the android toolchain, default NDK/build/prebuilt/HOST/arm-eabi-4.4.0],
     android_toolchain=$withval)
 
 MOZ_ARG_WITH_STRING(android-platform,
 [  --with-android-platform=DIR
-                           location of NDK platform dir, default NDK/build/platforms/android-5/arch-arm],
+                          location of NDK platform dir, default NDK/build/platforms/android-5/arch-arm],
     android_platform=$withval)
 
 MOZ_ARG_WITH_STRING(android-sdk,
 [  --with-android-sdk=DIR
-                           location where the Android SDK can be found (base directory, e.g. .../android/platforms/android-6)],
+                          location where the Android SDK can be found (base directory, e.g. .../android/platforms/android-6)],
     android_sdk=$withval)
 
 MOZ_ARG_WITH_STRING(android-tools,
 [  --with-android-tools=DIR
-                           location where the Android Tools can be found (base directory, e.g. .../android/tools)],
+                          location where the Android Tools can be found (base directory, e.g. .../android/tools)],
     android_tools=$withval)
 
 if test "$target" = "arm-android-eabi" ; then
     if test -z "$android_ndk" ; then
         AC_MSG_ERROR([You must specify --with-android-ndk=/path/to/ndk when targeting Android.])
     fi
 
     if test -z "$android_sdk" ; then
@@ -354,22 +354,22 @@ AR_FLAGS='cr $@'
 if test "$COMPILE_ENVIRONMENT"; then
 
 dnl Do some special WinCE toolchain stuff
 case "$target" in
 *wince|*winmo)
 
     MOZ_ARG_WITH_STRING(wince-sdk,
     [  --with-wince-sdk=WINCE_SDK_DIR
-                        The path to the Windows CE SDK],
+                          The path to the Windows CE SDK],
     WINCE_SDK_DIR=$withval)
 
     MOZ_ARG_WITH_STRING(ogles-sdk,
     [  --with-ogles-sdk=OGLES_SDK_DIR
-                        The path to the OGLES SDK],
+                          The path to the OGLES SDK],
     OGLES_SDK_DIR=$withval)
 
     AC_DEFINE(WINCE)
     
     export WINCE=1
 
     echo -----------------------------------------------------------------------------
     echo Building Windows CE Shunt Library and Tool Chain
@@ -1099,17 +1099,17 @@ esac
 AC_SUBST(MACOSX_DEPLOYMENT_TARGET)
 
 dnl ========================================================
 dnl = Mac OS X SDK support
 dnl ========================================================
 MACOS_SDK_DIR=
 NEXT_ROOT=
 MOZ_ARG_WITH_STRING(macos-sdk,
-[  --with-macos-sdk=dir   Location of platform SDK to use (Mac OS X only)],
+[  --with-macos-sdk=dir    Location of platform SDK to use (Mac OS X only)],
     MACOS_SDK_DIR=$withval)
 
 dnl MACOS_SDK_DIR will be set to the SDK location whenever one is in use.
 dnl NEXT_ROOT will be set and exported only if it's needed.
 AC_SUBST(MACOS_SDK_DIR)
 AC_SUBST(NEXT_ROOT)
 
 if test "$MACOS_SDK_DIR"; then
@@ -1560,19 +1560,16 @@ if test "$GNU_CC"; then
     # FIXME: Let us build with strict aliasing. bug 414641.
     CFLAGS="$CFLAGS -fno-strict-aliasing"
     MKSHLIB='$(CXX) $(CXXFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-h,$@ -o $@'
     MKCSHLIB='$(CC) $(CFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-h,$@ -o $@'
     DSO_LDOPTS='-shared'
     if test "$GCC_USE_GNU_LD"; then
         # Don't allow undefined symbols in libraries
         DSO_LDOPTS="$DSO_LDOPTS -Wl,-z,defs"
-        LDFLAGS="$LDFLAGS -Wl,--gc-sections"
-        CFLAGS="$CFLAGS -ffunction-sections -fdata-sections"
-        CXXFLAGS="$CXXFLAGS -ffunction-sections -fdata-sections"
     fi
     WARNINGS_AS_ERRORS='-Werror'
     DSO_CFLAGS=''
     DSO_PIC_CFLAGS='-fPIC'
     ASFLAGS="$ASFLAGS -fPIC"
     _MOZ_RTTI_FLAGS_ON=${_COMPILER_PREFIX}-frtti
     _MOZ_RTTI_FLAGS_OFF=${_COMPILER_PREFIX}-fno-rtti
     _MOZ_EXCEPTIONS_FLAGS_ON='-fhandle-exceptions'
@@ -4561,17 +4558,19 @@ dnl check for LC_MESSAGES
 AC_CACHE_CHECK(for LC_MESSAGES,
 		ac_cv_i18n_lc_messages,
 		[AC_TRY_COMPILE([#include <locale.h>],
 				[int category = LC_MESSAGES;],
 				ac_cv_i18n_lc_messages=yes,
 				ac_cv_i18n_lc_messages=no)])
 if test "$ac_cv_i18n_lc_messages" = yes; then
    AC_DEFINE(HAVE_I18N_LC_MESSAGES)
-fi 	
+fi
+
+AC_HAVE_FUNCS(localeconv)
 
 fi # SKIP_COMPILER_CHECKS
 
 TARGET_XPCOM_ABI=
 if test -n "${CPU_ARCH}" -a -n "${TARGET_COMPILER_ABI}"; then
     TARGET_XPCOM_ABI="${CPU_ARCH}-${TARGET_COMPILER_ABI}"
 fi
 
@@ -4608,16 +4607,17 @@ fi
 
 dnl We can't run TRY_COMPILE tests on Windows, so hard-code some
 dnl features that Windows actually does support.
 
 if test -n "$SKIP_COMPILER_CHECKS"; then
    dnl Windows has malloc.h
    AC_DEFINE(MALLOC_H, [<malloc.h>])
    AC_DEFINE(HAVE_FORCEINLINE)
+   AC_DEFINE(HAVE_LOCALECONV)
 fi # SKIP_COMPILER_CHECKS
 
 dnl ========================================================
 dnl =
 dnl = Check for external package dependencies
 dnl =
 dnl ========================================================
 MOZ_ARG_HEADER(External Packages)
@@ -4646,17 +4646,17 @@ if test -n "$LIBXUL_SDK"; then
 else
     LIBXUL_DIST="$MOZ_BUILD_ROOT/dist"
 fi
 AC_SUBST(LIBXUL_DIST)
 
 SYSTEM_LIBXUL=
 
 MOZ_ARG_WITH_BOOL(system-libxul,
-[  --with-system-libxul   Use system installed libxul SDK],
+[  --with-system-libxul    Use system installed libxul SDK],
     SYSTEM_LIBXUL=1)
 
 if test -n "$SYSTEM_LIBXUL" && test -z "$MOZ_ENABLE_LIBXUL"; then
     AC_MSG_ERROR([--with-system-libxul needs --with-libxul-sdk])
 fi
 
 dnl ========================================================
 dnl = If NSPR was not detected in the system, 
@@ -4735,17 +4735,17 @@ AC_SUBST(MOZ_LIBEVENT_INCLUDES)
 AC_SUBST(MOZ_LIBEVENT_LIBS)
 
 dnl ========================================================
 dnl = If NSS was not detected in the system, 
 dnl = use the one in the source tree (mozilla/security/nss)
 dnl ========================================================
 
 MOZ_ARG_WITH_BOOL(system-nss,
-[  --with-system-nss      Use system installed NSS],
+[  --with-system-nss       Use system installed NSS],
     _USE_SYSTEM_NSS=1 )
 
 if test -n "$_USE_SYSTEM_NSS"; then
     AM_PATH_NSS(3.12.6, [MOZ_NATIVE_NSS=1], [MOZ_NATIVE_NSS=])
 fi
 
 if test -n "$MOZ_NATIVE_NSS"; then
    NSS_LIBS="$NSS_LIBS -lcrmf"
@@ -4930,44 +4930,47 @@ if test "${PNG_DIR}" -a -d "${PNG_DIR}" 
     PNG_LIBS="-L${PNG_DIR}/lib ${PNG_LIBS}"
 fi
 
 fi # SKIP_LIBRARY_CHECKS
 
 dnl system HunSpell Support
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(system-hunspell,
-[  --enable-system-hunspell  Use system hunspell (located with pkgconfig)],
+[  --enable-system-hunspell
+                          Use system hunspell (located with pkgconfig)],
     SYSTEM_HUNSPELL=1 )
 
 if test -n "$SYSTEM_HUNSPELL"; then
     PKG_CHECK_MODULES(MOZ_HUNSPELL, hunspell)
 fi
 
 AC_SUBST(SYSTEM_HUNSPELL)
 
 dnl ========================================================
 dnl Java SDK support
 dnl ========================================================
 JAVA_INCLUDE_PATH=
 MOZ_ARG_WITH_STRING(java-include-path,
-[  --with-java-include-path=dir   Location of Java SDK headers],
+[  --with-java-include-path=dir
+                          Location of Java SDK headers],
     JAVA_INCLUDE_PATH=$withval)
 
 JAVA_BIN_PATH=
 MOZ_ARG_WITH_STRING(java-bin-path,
-[  --with-java-bin-path=dir   Location of Java binaries (java, javac, jar)],
+[  --with-java-bin-path=dir
+                          Location of Java binaries (java, javac, jar)],
     JAVA_BIN_PATH=$withval)
 
 dnl ========================================================
 dnl Use ARM userspace kernel helpers; tell NSPR to enable
 dnl their usage and use them in spidermonkey.
 dnl ========================================================
 MOZ_ARG_WITH_BOOL(arm-kuser,
-[  --with-arm-kuser         Use kuser helpers (Linux/ARM only -- requires kernel 2.6.13 or later)],
+[  --with-arm-kuser        Use kuser helpers (Linux/ARM only -- requires kernel 2.6.13 or later)],
     USE_ARM_KUSER=1,
     USE_ARM_KUSER=)
 if test -n "$USE_ARM_KUSER"; then
    AC_DEFINE(USE_ARM_KUSER)
 fi
 
 dnl ========================================================
 dnl =
@@ -5012,16 +5015,17 @@ MOZ_RDF=1
 MOZ_REFLOW_PERF=
 MOZ_SAFE_BROWSING=
 MOZ_FASTSTART=
 MOZ_HELP_VIEWER=
 MOZ_SPELLCHECK=1
 MOZ_SPLASHSCREEN=
 MOZ_STORAGE=1
 MOZ_SVG=1
+MOZ_THUMB2=
 MOZ_TIMELINE=
 MOZ_TOOLKIT_SEARCH=1
 MOZ_UI_LOCALE=en-US
 MOZ_UNIVERSALCHARDET=1
 MOZ_URL_CLASSIFIER=
 MOZ_USE_NATIVE_UCONV=
 MOZ_VIEW_SOURCE=1
 MOZ_XSLT_STANDALONE=
@@ -5323,17 +5327,18 @@ dnl ====================================
 dnl = startup-notification support module
 dnl ========================================================
 
 if test "$MOZ_ENABLE_GTK2"
 then
     MOZ_ENABLE_STARTUP_NOTIFICATION=
 
     MOZ_ARG_ENABLE_BOOL(startup-notification,
-    [  --enable-startup-notification       Enable startup-notification support (default: disabled) ],
+    [  --enable-startup-notification
+                          Enable startup-notification support (default: disabled) ],
         MOZ_ENABLE_STARTUP_NOTIFICATION=force,
         MOZ_ENABLE_STARTUP_NOTIFICATION=)
     if test "$MOZ_ENABLE_STARTUP_NOTIFICATION"
     then
         PKG_CHECK_MODULES(MOZ_STARTUP_NOTIFICATION,
                           libstartup-notification-1.0 >= $STARTUP_NOTIFICATION_VERSION,
         [MOZ_ENABLE_STARTUP_NOTIFICATION=1], [
             if test "$MOZ_ENABLE_STARTUP_NOTIFICATION" = "force"
@@ -5419,17 +5424,18 @@ MOZ_ARG_ENABLE_STRING(ui-locale,
                           Select the user interface locale (default: en-US)],
     MOZ_UI_LOCALE=$enableval )
 AC_SUBST(MOZ_UI_LOCALE)
 
 dnl ========================================================
 dnl = Trademarked Branding 
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(official-branding,
-[  --enable-official-branding Enable Official mozilla.org Branding
+[  --enable-official-branding
+                          Enable Official mozilla.org Branding
                           Do not distribute builds with
                           --enable-official-branding unless you have
                           permission to use trademarks per
                           http://www.mozilla.org/foundation/trademarks/ .],
 [
   if test -z "$MOZ_OFFICIAL_BRANDING_DIRECTORY"; then
     AC_MSG_ERROR([You must specify MOZ_OFFICIAL_BRANDING_DIRECTORY to use --enable-official-branding.])
   else
@@ -5439,17 +5445,17 @@ MOZ_ARG_ENABLE_BOOL(official-branding,
 ], MOZ_OFFICIAL_BRANDING=)
 
 AC_SUBST(MOZ_OFFICIAL_BRANDING)
 if test -n "$MOZ_OFFICIAL_BRANDING"; then
   AC_DEFINE(MOZ_OFFICIAL_BRANDING)
 fi
 
 MOZ_ARG_WITH_STRING(branding,
-[  --with-branding=dir    Use branding from the specified directory.],
+[  --with-branding=dir     Use branding from the specified directory.],
     MOZ_BRANDING_DIRECTORY=$withval)
 
 REAL_BRANDING_DIRECTORY="${MOZ_BRANDING_DIRECTORY}"
 if test -z "$REAL_BRANDING_DIRECTORY"; then
   REAL_BRANDING_DIRECTORY=${MOZ_BUILD_APP}/branding/nightly
 fi
 
 if test -f "${_topsrcdir}/$REAL_BRANDING_DIRECTORY/configure.sh"; then
@@ -5457,33 +5463,34 @@ if test -f "${_topsrcdir}/$REAL_BRANDING
 fi
 
 AC_SUBST(MOZ_BRANDING_DIRECTORY)
 
 dnl ========================================================
 dnl = Distribution ID
 dnl ========================================================
 MOZ_ARG_WITH_STRING(distribution-id,
-[  --with-distribution-id=ID  Set distribution-specific id (default=org.mozilla)],
+[  --with-distribution-id=ID
+                          Set distribution-specific id (default=org.mozilla)],
 [ val=`echo $withval`
     MOZ_DISTRIBUTION_ID="$val"])
 
 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_ARG_DISABLE_BOOL(pango,
-[  --disable-pango Disable usage of Pango ],
+[  --disable-pango         Disable usage of Pango ],
     MOZ_PANGO=,
     MOZ_PANGO=1)
 
 dnl ========================================================
 dnl = Pango
 dnl ========================================================
 if test "$MOZ_ENABLE_GTK2"
 then
@@ -5626,17 +5633,17 @@ dnl ====================================
 dnl = libnotify support
 dnl ========================================================
 
 if test "$MOZ_ENABLE_GTK2"
 then
     MOZ_ENABLE_LIBNOTIFY=1
 
     MOZ_ARG_DISABLE_BOOL(libnotify,
-    [  --disable-libnotify       Disable libnotify support ],
+    [  --disable-libnotify     Disable libnotify support ],
     MOZ_ENABLE_LIBNOTIFY=,
     MOZ_ENABLE_LIBNOTIFY=1)
 
     if test "$MOZ_ENABLE_LIBNOTIFY"
     then
         AC_DEFINE(MOZ_ENABLE_LIBNOTIFY)
     fi
 fi
@@ -5712,17 +5719,17 @@ dnl ====================================
 dnl = dbus support
 dnl ========================================================
 
 if test "$MOZ_ENABLE_GTK2" || test "$MOZ_ENABLE_QT"
 then
     MOZ_ENABLE_DBUS=1
 
     MOZ_ARG_DISABLE_BOOL(dbus,
-    [  --disable-dbus       Disable dbus support ],
+    [  --disable-dbus          Disable dbus support ],
         MOZ_ENABLE_DBUS=,
         MOZ_ENABLE_DBUS=1)
 
     if test "$MOZ_ENABLE_DBUS"
     then
         PKG_CHECK_MODULES(MOZ_DBUS, dbus-1 >= $DBUS_VERSION)
         PKG_CHECK_MODULES(MOZ_DBUS_GLIB, dbus-glib-1 >= $DBUS_VERSION)
         AC_DEFINE(MOZ_ENABLE_DBUS)
@@ -5798,17 +5805,17 @@ MOZ_ARG_DISABLE_BOOL(plugins,
 [  --disable-plugins       Disable plugins support],
     MOZ_PLUGINS=,
     MOZ_PLUGINS=1)
 
 dnl ========================================================
 dnl = Disable building dbm
 dnl ========================================================
 MOZ_ARG_DISABLE_BOOL(dbm,
-[  --disable-dbm       Disable building dbm],
+[  --disable-dbm           Disable building dbm],
     NSS_DISABLE_DBM=1,
     NSS_DISABLE_DBM=)
 
 dnl bi-directional support always on
 IBMBIDI=1
 AC_DEFINE(IBMBIDI)
 
 dnl ========================================================
@@ -5849,17 +5856,17 @@ dnl ====================================
 if test "$MOZ_JSLOADER"; then
     AC_DEFINE(MOZ_JSLOADER)
 fi
 
 dnl ========================================================
 dnl Disable printing
 dnl ========================================================
 MOZ_ARG_DISABLE_BOOL(printing,
-[  --disable-printing  Disable printing support],
+[  --disable-printing      Disable printing support],
     NS_PRINTING=,
     NS_PRINTING=1 )
 
 if test "$MOZ_WIDGET_TOOLKIT" = "qt"; then
     AC_MSG_WARN([Printing does not work with Qt at this time. Omitting printing support.])
     NS_PRINTING=
 fi
 
@@ -5895,17 +5902,18 @@ MOZ_ARG_ENABLE_BOOL(plaintext-editor-onl
     MOZ_PLAINTEXT_EDITOR_ONLY= )
 dnl Note the #define is MOZILLA, not MOZ, for compat with the Mac build.
 AC_SUBST(MOZ_PLAINTEXT_EDITOR_ONLY)
 
 dnl ========================================================
 dnl = Disable Fast Load
 dnl ========================================================
 MOZ_ARG_DISABLE_BOOL(xpcom-fastload,
-[  --disable-xpcom-fastload           Disable XPCOM fastload support],
+[  --disable-xpcom-fastload
+                          Disable XPCOM fastload support],
     MOZ_NO_FAST_LOAD=1,
     MOZ_NO_FAST_LOAD=)
 
 AC_SUBST(MOZ_NO_FAST_LOAD)
 
 if test -n "$MOZ_NO_FAST_LOAD"; then
     AC_DEFINE(MOZ_NO_FAST_LOAD)
 fi
@@ -6064,30 +6072,48 @@ case "${target}" in
 esac
 
 MOZ_ARG_ENABLE_BOOL(javaxpcom,
 [  --enable-javaxpcom
                           Enable Java-XPCOM bridge],
     MOZ_JAVAXPCOM=1,
     MOZ_JAVAXPCOM= )
 
+case "$host_os" in
+  cygwin*|msvc*|mks*)
+    if test -n "$JAVA_HOME"; then
+      JAVA_HOME=`cygpath -u \`cygpath -m -s "$JAVA_HOME"\``
+    fi
+    ;;
+  *mingw*)
+    if test -n "$JAVA_HOME"; then
+      JAVA_HOME=`cd "$JAVA_HOME" && pwd`
+    fi
+    ;;
+esac
+
+if test -n "${JAVA_BIN_PATH}"; then
+  dnl Look for javac and jar in the specified path.
+  JAVA_PATH="$JAVA_BIN_PATH"
+else
+  dnl No path specified, so look for javac and jar in $JAVA_HOME & $PATH.
+  JAVA_PATH="$JAVA_HOME/bin:$PATH"
+fi
+
+MOZ_PATH_PROG(JAVA, java, :, [$JAVA_PATH])
+MOZ_PATH_PROG(JAVAC, javac, :, [$JAVA_PATH])
+MOZ_PATH_PROG(JAR, jar, :, [$JAVA_PATH])
+
+if test -n "${JAVA_BIN_PATH}" || test "$OS_TARGET" = Android; then
+  if test -z "$JAVA" || test "$JAVA" = ":" || test -z "$JAVAC" || test "$JAVAC" = ":" || test -z "$JAR" || test "$JAR" = ":"; then
+    AC_MSG_ERROR([The programs java, javac and jar were not found.  Set \$JAVA_HOME to your java sdk directory or use --with-java-bin-path={java-bin-dir}])
+  fi
+fi
+
 if test -n "${MOZ_JAVAXPCOM}"; then
-  case "$host_os" in
-    cygwin*|msvc*|mks*)
-      if test -n "$JAVA_HOME"; then
-        JAVA_HOME=`cygpath -u \`cygpath -m -s "$JAVA_HOME"\``
-      fi
-      ;;
-    *mingw*)
-      if test -n "$JAVA_HOME"; then
-        JAVA_HOME=`cd "$JAVA_HOME" && pwd`
-      fi
-      ;;
-  esac
-
   if test -n "${JAVA_INCLUDE_PATH}"; then
     dnl Make sure jni.h exists in the given include path.
     if test ! -f "$JAVA_INCLUDE_PATH/jni.h"; then
       AC_MSG_ERROR([jni.h was not found in given include path $JAVA_INCLUDE_PATH.])
     fi
   else
     case "$target_os" in
       darwin*)
@@ -6098,31 +6124,16 @@ if test -n "${MOZ_JAVAXPCOM}"; then
         dnl Try $JAVA_HOME
         JAVA_INCLUDE_PATH="$JAVA_HOME/include"
         ;;
     esac
     if test ! -f "$JAVA_INCLUDE_PATH/jni.h"; then
       AC_MSG_ERROR([The header jni.h was not found.  Set \$JAVA_HOME to your java sdk directory, use --with-java-bin-path={java-bin-dir}, or reconfigure with --disable-javaxpcom.])
     fi
   fi
-
-  if test -n "${JAVA_BIN_PATH}"; then
-    dnl Look for javac and jar in the specified path.
-    JAVA_PATH="$JAVA_BIN_PATH"
-  else
-    dnl No path specified, so look for javac and jar in $JAVA_HOME & $PATH.
-    JAVA_PATH="$JAVA_HOME/bin:$PATH"
-  fi
-
-  MOZ_PATH_PROG(JAVA, java, :, [$JAVA_PATH])
-  MOZ_PATH_PROG(JAVAC, javac, :, [$JAVA_PATH])
-  MOZ_PATH_PROG(JAR, jar, :, [$JAVA_PATH])
-  if test -z "$JAVA" || test "$JAVA" = ":" || test -z "$JAVAC" || test "$JAVAC" = ":" || test -z "$JAR" || test "$JAR" = ":"; then
-    AC_MSG_ERROR([The programs java, javac and jar were not found.  Set \$JAVA_HOME to your java sdk directory, use --with-java-bin-path={java-bin-dir}, or reconfigure with --disable-javaxpcom.])
-  fi
 fi
 
 dnl ========================================================
 dnl = Breakpad crash reporting (on by default on supported platforms)
 dnl ========================================================
 
 case $target in
 i?86-*-mingw*)
@@ -6135,17 +6146,17 @@ i?86-*-linux*|x86_64-*-linux*|arm-*-linu
   MOZ_CRASHREPORTER=1
   ;;
 *solaris*)
   MOZ_CRASHREPORTER=1
   ;;
 esac
 
 MOZ_ARG_DISABLE_BOOL(crashreporter,
-[  --disable-crashreporter          Disable breakpad crash reporting],
+[  --disable-crashreporter Disable breakpad crash reporting],
     MOZ_CRASHREPORTER=,
     MOZ_CRASHREPORTER=1)
 
 if test -n "$MOZ_CRASHREPORTER"; then
    AC_DEFINE(MOZ_CRASHREPORTER)
 
   if (test "$OS_ARCH" = "Linux" || test "$OS_ARCH" = "SunOS") && \
     test -z "$SKIP_LIBRARY_CHECKS"; then
@@ -6153,17 +6164,18 @@ if test -n "$MOZ_CRASHREPORTER"; then
     AC_SUBST(MOZ_GTHREAD_CFLAGS)
     AC_SUBST(MOZ_GTHREAD_LIBS)
 
     AC_CHECK_HEADERS([curl/curl.h], [], [AC_MSG_ERROR([Couldn't find curl/curl.h which is required for the crash reporter.  Use --disable-crashreporter to disable the crash reporter.])])
   fi
 fi
 
 MOZ_ARG_WITH_STRING(crashreporter-enable-percent,
-[  --with-crashreporter-enable-percent=NN  Enable sending crash reports by default on NN% of users. (default=100)],
+[  --with-crashreporter-enable-percent=NN
+                          Enable sending crash reports by default on NN% of users. (default=100)],
 [ val=`echo $withval | sed 's/[^0-9]//g'`
     MOZ_CRASHREPORTER_ENABLE_PERCENT="$val"])
 
 if test -z "$MOZ_CRASHREPORTER_ENABLE_PERCENT"; then
    MOZ_CRASHREPORTER_ENABLE_PERCENT=100
 fi
 AC_DEFINE_UNQUOTED(MOZ_CRASHREPORTER_ENABLE_PERCENT, $MOZ_CRASHREPORTER_ENABLE_PERCENT)
 
@@ -6356,44 +6368,44 @@ MOZ_ARG_DISABLE_BOOL(mathml,
 if test "$MOZ_MATHML"; then
   AC_DEFINE(MOZ_MATHML)
 fi
 
 dnl ========================================================
 dnl SVG
 dnl ========================================================
 MOZ_ARG_DISABLE_BOOL(svg,
-[  --disable-svg            Disable SVG support],
+[  --disable-svg           Disable SVG support],
     MOZ_SVG=,
     MOZ_SVG=1 )
 if test -n "$MOZ_SVG"; then
   AC_DEFINE(MOZ_SVG)
 fi
 
 dnl ========================================================
 dnl SMIL
 dnl ========================================================
 MOZ_SMIL=1
 MOZ_ARG_DISABLE_BOOL(smil,
-[  --disable-smil           Disable SMIL animation support],
+[  --disable-smil          Disable SMIL animation support],
     MOZ_SMIL=,
     MOZ_SMIL=1 )
 # Automatically disable SMIL if SVG is disabled
 if test -z "$MOZ_SVG"; then
   MOZ_SMIL=
 fi
 if test -n "$MOZ_SMIL"; then
   AC_DEFINE(MOZ_SMIL)
 fi
 
 dnl ========================================================
 dnl Build Freetype in the tree
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(tree-freetype,
-[  --enable-tree-freetype         Enable Tree FreeType],
+[  --enable-tree-freetype  Enable Tree FreeType],
     MOZ_TREE_FREETYPE=1,
     MOZ_TREE_FREETYPE= )
 if test -n "$MOZ_TREE_FREETYPE"; then
    AC_DEFINE(MOZ_TREE_FREETYPE)
    AC_SUBST(MOZ_TREE_FREETYPE)
    MOZ_ENABLE_CAIRO_FT=1       
    FT_FONT_FEATURE="#define CAIRO_HAS_FT_FONT 1"
    FT2_CFLAGS='-I$(topsrcdir)/modules/freetype2/include'
@@ -6458,28 +6470,28 @@ MOZ_ARG_DISABLE_BOOL(updater,
 [  --disable-updater       Disable building of updater],
     MOZ_UPDATER=,
     MOZ_UPDATER=1 )
 AC_SUBST(MOZ_UPDATER)
 
 # app update channel is 'default' when not supplied.
 MOZ_ARG_ENABLE_STRING([update-channel],
 [  --enable-update-channel=CHANNEL
-                           Select application update channel (default=default)],
+                          Select application update channel (default=default)],
     MOZ_UPDATE_CHANNEL=`echo $enableval | tr A-Z a-z`)
 
 if test -z "$MOZ_UPDATE_CHANNEL"; then
     MOZ_UPDATE_CHANNEL=default
 fi
 AC_DEFINE_UNQUOTED(MOZ_UPDATE_CHANNEL, $MOZ_UPDATE_CHANNEL)
 
 # tools/update-packaging is not checked out by default.
 MOZ_ARG_ENABLE_BOOL(update-packaging,
 [  --enable-update-packaging
-                           Enable tools/update-packaging],
+                          Enable tools/update-packaging],
     MOZ_UPDATE_PACKAGING=1,
     MOZ_UPDATE_PACKAGING= )
 AC_SUBST(MOZ_UPDATE_PACKAGING)
 
 dnl ========================================================
 dnl ActiveX
 dnl ========================================================
 
@@ -6538,17 +6550,17 @@ MOZ_ARG_DISABLE_BOOL(tests,
     ENABLE_TESTS=,
     ENABLE_TESTS=1 )
 
 dnl ========================================================
 dnl parental controls (for Windows Vista)
 dnl ========================================================
 MOZ_ARG_DISABLE_BOOL(parental-controls,
 [  --disable-parental-controls
-                           Do not build parental controls],
+                          Do not build parental controls],
    MOZ_DISABLE_PARENTAL_CONTROLS=1,
    MOZ_DISABLE_PARENTAL_CONTROLS=)
 if test -n "$MOZ_DISABLE_PARENTAL_CONTROLS"; then
     AC_DEFINE(MOZ_DISABLE_PARENTAL_CONTROLS)
 fi
 
 AC_SUBST(MOZ_DISABLE_PARENTAL_CONTROLS)
 
@@ -6558,17 +6570,17 @@ dnl = Module specific options
 dnl =
 dnl ========================================================
 MOZ_ARG_HEADER(Individual module options)
 
 dnl ========================================================
 dnl = Disable feed handling components
 dnl ========================================================
 MOZ_ARG_DISABLE_BOOL(feeds,
-[  --disable-feeds        Disable feed handling and processing components],
+[  --disable-feeds         Disable feed handling and processing components],
     MOZ_FEEDS=,
     MOZ_FEEDS=1 )
 if test -n "$MOZ_FEEDS"; then
     AC_DEFINE(MOZ_FEEDS)
 else
     if test "$MOZ_BUILD_APP" = "browser"; then
         AC_MSG_ERROR([Cannot build Firefox with --disable-feeds.])
     fi
@@ -6704,67 +6716,67 @@ if test -n "$MOZ_HELP_VIEWER"; then
      dnl Do this if defined in confvars.sh
      AC_DEFINE(MOZ_HELP_VIEWER)
 fi
 
 dnl ========================================================
 dnl = Enable safe browsing (anti-phishing)
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(safe-browsing,
-[  --enable-safe-browsing        Enable safe browsing (anti-phishing) implementation],
+[  --enable-safe-browsing  Enable safe browsing (anti-phishing) implementation],
     MOZ_SAFE_BROWSING=1,
     MOZ_SAFE_BROWSING= )
 if test -n "$MOZ_SAFE_BROWSING"; then
     AC_DEFINE(MOZ_SAFE_BROWSING)
 fi
 AC_SUBST(MOZ_SAFE_BROWSING)
 
 dnl ========================================================
 dnl = Enable faststart component
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(faststart,
-[  --enable-faststart            Enable the faststart component],
+[  --enable-faststart      Enable the faststart component],
     MOZ_FASTSTART=1,
     MOZ_FASTSTART= )
 if test -n "$MOZ_FASTSTART"; then
     AC_DEFINE(MOZ_FASTSTART)
 fi
 AC_SUBST(MOZ_FASTSTART)
 
 dnl ========================================================
 dnl = Enable url-classifier
 dnl ========================================================
 dnl Implicitly enabled by default if building with safe-browsing
 if test -n "$MOZ_SAFE_BROWSING"; then
     MOZ_URL_CLASSIFIER=1
 fi
 MOZ_ARG_ENABLE_BOOL(url-classifier,
-[  --enable-url-classifier        Enable url classifier module],
+[  --enable-url-classifier Enable url classifier module],
     MOZ_URL_CLASSIFIER=1,
     MOZ_URL_CLASSIFIER= )
 if test -n "$MOZ_URL_CLASSIFIER"; then
     AC_DEFINE(MOZ_URL_CLASSIFIER)
 fi
 AC_SUBST(MOZ_URL_CLASSIFIER)
 
 dnl ========================================================
 dnl = Disable zipwriter
 dnl ========================================================
 MOZ_ARG_DISABLE_BOOL(zipwriter,
-[  --disable-zipwriter             Disable zipwriter component],
+[  --disable-zipwriter     Disable zipwriter component],
     MOZ_ZIPWRITER=,
     MOZ_ZIPWRITER=1 )
 AC_SUBST(MOZ_ZIPWRITER)
 
 dnl ========================================================
 dnl = Disable libconic
 dnl ========================================================
 MOZ_ENABLE_LIBCONIC=1
 MOZ_ARG_DISABLE_BOOL(libconic,
-[  --disable-libconic              Disable libconic],
+[  --disable-libconic      Disable libconic],
     MOZ_ENABLE_LIBCONIC=,
     MOZ_ENABLE_LIBCONIC=1 )
 
 if test -n "$MOZ_ENABLE_LIBCONIC"; then
     PKG_CHECK_MODULES(LIBCONIC, conic,
                       MOZ_ENABLE_LIBCONIC=1,
                       MOZ_ENABLE_LIBCONIC=)
 fi
@@ -6779,17 +6791,17 @@ AC_SUBST(LIBCONIC_LIBS)
 dnl ========================================================
 dnl = Maemo checks
 dnl ========================================================
 
 MAEMO_SDK_TARGET_VER=-1
 
 MOZ_ARG_WITH_STRING(maemo-version,
 [  --with-maemo-version=MAEMO_SDK_TARGET_VER
-                        Maemo SDK Version],
+                          Maemo SDK Version],
   MAEMO_SDK_TARGET_VER=$withval)
 
 case "$MAEMO_SDK_TARGET_VER" in
 5)
     MOZ_PLATFORM_MAEMO=5
     ;;
 
 6)
@@ -6843,36 +6855,65 @@ if test $MOZ_PLATFORM_MAEMO; then
       MOZ_PLATFORM_MAEMO_LIBS="$MOZ_PLATFORM_MAEMO_LIBS $LIBHILDONFM_LIBS"
       MOZ_PLATFORM_MAEMO_CFLAGS="$MOZ_PLATFORM_MAEMO_CFLAGS $LIBHILDONFM_CFLAGS"
       if test -z "$_LIB_FOUND"; then
          AC_MSG_ERROR([Hildon FM-2 is required when building for Maemo])
       fi
 
    fi
 
+   if test "$MOZ_PLATFORM_MAEMO" -gt 5; then
+     MOZ_THUMB2=1
+   fi
+
    PKG_CHECK_MODULES(LIBLOCATION,liblocation, _LIB_FOUND=1, _LIB_FOUND=)
    MOZ_PLATFORM_MAEMO_LIBS="$MOZ_PLATFORM_MAEMO_LIBS $LIBLOCATION_LIBS"
    MOZ_PLATFORM_MAEMO_CFLAGS="$MOZ_PLATFORM_MAEMO_CFLAGS $LIBLOCATION_CFLAGS"
    if test "$_LIB_FOUND"; then
       MOZ_MAEMO_LIBLOCATION=1
       AC_DEFINE(MOZ_MAEMO_LIBLOCATION)
    else
       AC_MSG_WARN([Cannot liblocation-dev. Disabling Maemo geolocation.])
    fi
    AC_SUBST(MOZ_MAEMO_LIBLOCATION)
 
    AC_SUBST(MOZ_PLATFORM_MAEMO_LIBS)
    AC_SUBST(MOZ_PLATFORM_MAEMO_CFLAGS)
 fi
 
 dnl ========================================================
+dnl = Enable building the Thumb2 instruction set
+dnl ========================================================
+MOZ_ARG_ENABLE_BOOL(thumb2,
+ [  --enable-thumb2         Enable Thumb2 instruction set],
+    MOZ_THUMB2=1,
+    MOZ_THUMB2=)
+
+if test -n "$MOZ_THUMB2"; then
+  case "$target_cpu" in
+    arm*)
+      if test "$GNU_CC"; then
+        CFLAGS="$CFLAGS -march=armv7-a -mthumb -Wa, -march=armv7-a -Wa, -mthumb"
+        CXXFLAGS="$CXXFLAGS -march=armv7-a -mthumb -Wa, -march=armv7-a -Wa, -mthumb"
+        ASFLAGS="$ASFLAGS -march=armv7-a -mthumb"
+      else
+        AC_MSG_ERROR([--enable-thumb2 is not supported for non-GNU toolchains])
+      fi
+    ;;
+    *)
+      AC_MSG_ERROR([--enable-thumb2 is not supported for non-ARM CPU architectures])
+    ;;
+  esac
+fi
+
+dnl ========================================================
 dnl = faststripe theme
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(faststripe,
-[  --enable-faststripe  Use faststripe theme],
+[  --enable-faststripe     Use faststripe theme],
     MOZ_THEME_FASTSTRIPE=1,
     MOZ_THEME_FASTSTRIPE= )
 AC_SUBST(MOZ_THEME_FASTSTRIPE)
 
 dnl ========================================================
 dnl =
 dnl = Feature options that require extra sources to be pulled
 dnl =
@@ -6924,16 +6965,24 @@ MOZ_ARG_ENABLE_STRING(debug,
         _MOZ_DEBUG_FLAGS_SET=1
     fi
   else
     MOZ_DEBUG=
   fi ],
   MOZ_DEBUG=)
 
 MOZ_DEBUG_ENABLE_DEFS="-DDEBUG -D_DEBUG"
+MOZ_ARG_WITH_STRING(debug-label,
+[  --with-debug-label=LABELS
+                          Define DEBUG_<value> for each comma-separated
+                          value given.],
+[ for option in `echo $withval | sed 's/,/ /g'`; do
+    MOZ_DEBUG_ENABLE_DEFS="$MOZ_DEBUG_ENABLE_DEFS -DDEBUG_${option}"
+done])
+
  case "${target_os}" in
     beos*)
         MOZ_DEBUG_ENABLE_DEFS="$MOZ_DEBUG_ENABLE_DEFS -DDEBUG_${USER}"
         ;;
     msvc*|mks*|cygwin*|mingw*|os2*|wince*|winmo*)
         MOZ_DEBUG_ENABLE_DEFS="$MOZ_DEBUG_ENABLE_DEFS -DDEBUG_`echo ${USERNAME} | sed -e 's| |_|g'`"
         ;;
     *) 
@@ -6958,17 +7007,18 @@ if test -n "$MOZ_DEBUG"; then
     fi
     CFLAGS=$_SAVE_CFLAGS
 fi
 
 dnl ========================================================
 dnl enable mobile optimizations
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(mobile-optimize,
-[  --enable-mobile-optimize   Enable mobile optimizations],
+[  --enable-mobile-optimize
+                          Enable mobile optimizations],
     MOZ_GFX_OPTIMIZE_MOBILE=1)
 
 AC_SUBST(MOZ_GFX_OPTIMIZE_MOBILE)
 
 if test "$MOZ_GFX_OPTIMIZE_MOBILE"; then
     AC_DEFINE(MOZ_GFX_OPTIMIZE_MOBILE)
 fi
 
@@ -7024,18 +7074,18 @@ MOZ_ARG_ENABLE_STRING(debugger-info-modu
     AC_MSG_WARN([--enable-debugger-info-modules is deprecated, use --enable-debug-symbols instead])
     MOZ_DEBUG_SYMBOLS=1
   fi ])
 
 dnl ========================================================
 dnl = Enable generation of debug symbols
 dnl ========================================================
 MOZ_ARG_ENABLE_STRING(debug-symbols,
-[  --enable-debug-symbols[=DBG]    Enable debugging symbols
-                                   (using compiler flags DBG)],
+[  --enable-debug-symbols[=DBG]
+                          Enable debugging symbols (using compiler flags DBG)],
 [ if test "$enableval" != "no"; then
       MOZ_DEBUG_SYMBOLS=1
       if test -n "$enableval" -a "$enableval" != "yes"; then
           if test -z "$_MOZ_DEBUG_FLAGS_SET"; then
               MOZ_DEBUG_FLAGS=`echo $enableval | sed -e 's|\\\ | |g'`
           else
               AC_MSG_ERROR([--enable-debug-symbols flags cannot be used with --enable-debug flags])
           fi
@@ -7046,17 +7096,18 @@ if test -n "$MOZ_DEBUG" -o -n "$MOZ_DEBU
     AC_DEFINE(MOZ_DEBUG_SYMBOLS)
     export MOZ_DEBUG_SYMBOLS
 fi
 
 dnl ========================================================
 dnl = Disable any treating of compile warnings as errors
 dnl ========================================================
 MOZ_ARG_DISABLE_BOOL(warnings-as-errors,
-[  --disable-warnings-as-errors       Disable treating of warnings as errors],
+[  --disable-warnings-as-errors
+                          Disable treating of warnings as errors],
     MOZ_DISABLE_WARNINGS_AS_ERRORS=1,
     MOZ_DISABLE_WARNINGS_AS_ERRORS= )
 if test "$MOZ_DISABLE_WARNINGS_AS_ERRORS"; then
    WARNINGS_AS_ERRORS=''
 fi
 
 dnl ========================================================
 dnl = Disable runtime logging checks
@@ -7139,77 +7190,86 @@ if test "$MOZ_MEMORY"; then
 
   AC_DEFINE(MOZ_MEMORY)
   if test "x$MOZ_DEBUG" = "x1"; then
     AC_DEFINE(MOZ_MEMORY_DEBUG)
   fi
   dnl The generic feature tests that determine how to compute ncpus are long and
   dnl complicated.  Therefore, simply define special cpp variables for the
   dnl platforms we have special knowledge of.
-  case "${target_os}" in
-  darwin*)
+  case "${target}" in
+  *-darwin*)
     AC_DEFINE(MOZ_MEMORY_DARWIN)
     ;;
-  *freebsd*)
+  *-*freebsd*)
     AC_DEFINE(MOZ_MEMORY_BSD)
     ;;
-  *linux*)
+  *-*linux*)
     AC_DEFINE(MOZ_MEMORY_LINUX)
     ;;
-  netbsd*)
+  *-netbsd*)
     AC_DEFINE(MOZ_MEMORY_BSD)
     ;;
-  solaris*)
+  *-solaris*)
     AC_DEFINE(MOZ_MEMORY_SOLARIS)
     ;;
-  msvc*|mks*|cygwin*|mingw*)
+  *-msvc*|*-mks*|*-cygwin*|*-mingw*)
     AC_DEFINE(MOZ_MEMORY_WINDOWS)
     dnl This is sort of awful. Will revisit if we add support for more versions
     if test "$CC_VERSION" != "14.00.50727.762" -a "$CC_VERSION" != "15.00.30729.01"; then
         AC_MSG_ERROR([Building jemalloc requires exactly Visual C++ 2005 SP1 or 2008 SP1 currently.])
     fi
     if test -z "$WIN32_CRT_SRC_DIR"; then
       if test -z "$VCINSTALLDIR" -o ! -d "$VCINSTALLDIR"; then
         AC_MSG_ERROR([When building jemalloc, set WIN32_CRT_SRC_DIR to the path to the Visual C++ CRT source (usually VCINSTALLDIR\crt\src, but VCINSTALLDIR is not set, so I can't autodetect it for you).])
       else
         WIN32_CRT_SRC_DIR="$VCINSTALLDIR\crt\src"
       fi
     fi
     dnl cpu check
     case "${target_cpu}" in
     i*86)
-      _WIN32_CRT_CPU=intel
+      MOZ_CRT_CPU_ARCH=intel
+      ;;
+    x86_64)
+      MOZ_CRT_CPU_ARCH=amd64
       ;;
     *)
       AC_MSG_ERROR([--enable-jemalloc not supported on ${target}])
       ;;
     esac
 
+    AC_SUBST(MOZ_CRT_CPU_ARCH)
+
     if test ! -d "$WIN32_CRT_SRC_DIR"; then
       AC_MSG_ERROR([Invalid Win32 CRT source directory: ${WIN32_CRT_SRC_DIR}])
     fi
     WIN32_CRT_SRC_DIR=`cd "$WIN32_CRT_SRC_DIR" && pwd -W`
     _objdir_win=`pwd -W`
-    WIN32_CUSTOM_CRT_DIR="$_objdir_win/memory/jemalloc/crtsrc/build/$_WIN32_CRT_CPU"
+    WIN32_CUSTOM_CRT_DIR="$_objdir_win/memory/jemalloc/crtsrc/build/$MOZ_CRT_CPU_ARCH"
     MOZ_MEMORY_LDFLAGS="-MANIFEST:NO -LIBPATH:\"$WIN32_CUSTOM_CRT_DIR\" -NODEFAULTLIB:msvcrt -NODEFAULTLIB:msvcrtd -NODEFAULTLIB:msvcprt -NODEFAULTLIB:msvcprtd -DEFAULTLIB:mozcrt19 -DEFAULTLIB:mozcpp19"
     dnl Also pass this to NSPR/NSS
     DLLFLAGS="$DLLFLAGS $MOZ_MEMORY_LDFLAGS"
     export DLLFLAGS
     ;;
-  *wince)
+  *-*wince)
     AC_DEFINE(MOZ_MEMORY_WINCE)
     AC_DEFINE(MOZ_MEMORY_WINDOWS)
     if test -z "$WINCE_WINDOWS_MOBILE"; then
       AC_DEFINE(MOZ_MEMORY_WINCE6)
     fi
     ;;
-  *winmo)
+  *-*winmo)
     AC_DEFINE(MOZ_MEMORY_WINCE)
     AC_DEFINE(MOZ_MEMORY_WINDOWS)
     ;;
+  *-android*)
+    AC_DEFINE(MOZ_MEMORY_LINUX)
+    AC_DEFINE(MOZ_MEMORY_ANDROID)
+    ;;
   *)
     AC_MSG_ERROR([--enable-jemalloc not supported on ${target}])
     ;;
   esac
 
   if test "$OS_ARCH" != "Darwin"; then
     dnl NB: this must be kept in sync with jemalloc.h
     AC_DEFINE(HAVE_JEMALLOC_VALLOC)
@@ -7228,18 +7288,18 @@ dnl = Use malloc wrapper lib
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(wrap-malloc,
 [  --enable-wrap-malloc    Wrap malloc calls (gnu linker only)],
     _WRAP_MALLOC=1,
     _WRAP_MALLOC= )
 
 if test -n "$_WRAP_MALLOC"; then
     if test "$GNU_CC"; then
-    WRAP_MALLOC_CFLAGS="${LDFLAGS} -Wl,--wrap -Wl,malloc -Wl,--wrap -Wl,free -Wl,--wrap -Wl,realloc -Wl,--wrap -Wl,__builtin_new -Wl,--wrap -Wl,__builtin_vec_new -Wl,--wrap -Wl,__builtin_delete -Wl,--wrap -Wl,__builtin_vec_delete -Wl,--wrap -Wl,PR_Free -Wl,--wrap -Wl,PR_Malloc -Wl,--wrap -Wl,PR_Calloc -Wl,--wrap -Wl,PR_Realloc"
-    MKSHLIB='$(CXX) $(DSO_LDOPTS) $(WRAP_MALLOC_CFLAGS) -o $@'
+    WRAP_MALLOC_CFLAGS="${LDFLAGS} -Wl,--wrap -Wl,malloc -Wl,--wrap -Wl,calloc -Wl,--wrap -Wl,valloc -Wl,--wrap -Wl,free -Wl,--wrap -Wl,realloc -Wl,--wrap -Wl,memalign -Wl,--wrap -Wl,__builtin_new -Wl,--wrap -Wl,__builtin_vec_new -Wl,--wrap -Wl,__builtin_delete -Wl,--wrap -Wl,__builtin_vec_delete -Wl,--wrap -Wl,PR_Free -Wl,--wrap -Wl,PR_Malloc -Wl,--wrap -Wl,PR_Calloc -Wl,--wrap -Wl,PR_Realloc -Wl,--wrap -Wl,strdup -Wl,--wrap -Wl,strndup"
+    MKSHLIB='$(CXX) $(DSO_LDOPTS) $(WRAP_MALLOC_CFLAGS) $(WRAP_MALLOC_LIB) -o $@'
     fi
 fi
 
 dnl ========================================================
 dnl = Location of malloc wrapper lib
 dnl ========================================================
 MOZ_ARG_WITH_STRING(wrap-malloc,
 [  --with-wrap-malloc=DIR  Location of malloc wrapper library],
@@ -7255,17 +7315,17 @@ MOZ_ARG_ENABLE_BOOL(tracevis,
 if test -n "$MOZ_TRACEVIS"; then
     AC_DEFINE(MOZ_TRACEVIS)
 fi
 
 dnl ========================================================
 dnl = Use GCTimer
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(gctimer,
-[  --enable-gctimer       Enable GC timer (default=no)],
+[  --enable-gctimer        Enable GC timer (default=no)],
     MOZ_GCTIMER=1,
     MOZ_GCTIMER= )
 if test -n "$MOZ_GCTIMER"; then
     AC_DEFINE(MOZ_GCTIMER)
 fi
 
 dnl ========================================================
 dnl = Use Valgrind
@@ -7324,30 +7384,30 @@ MOZ_ARG_ENABLE_BOOL(vtune,
 if test -n "$MOZ_VTUNE"; then
     AC_DEFINE(MOZ_VTUNE)
 fi
 
 dnl ========================================================
 dnl Zealous JavaScript GC
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(gczeal,
-[  --enable-gczeal          Enable zealous JavaScript GCing],
+[  --enable-gczeal         Enable zealous JavaScript GCing],
     JS_GC_ZEAL=1,
     JS_GC_ZEAL= )
 if test -n "$JS_GC_ZEAL"; then
     AC_DEFINE(JS_GC_ZEAL)
 fi
 
 dnl ========================================================
 dnl = Enable static checking using gcc-dehydra
 dnl ========================================================
 
 MOZ_ARG_WITH_STRING(static-checking,
 [  --with-static-checking=path/to/gcc_dehydra.so
-                            Enable static checking of code using GCC-dehydra],
+                          Enable static checking of code using GCC-dehydra],
     DEHYDRA_PATH=$withval,
     DEHYDRA_PATH= )
 
 if test -n "$DEHYDRA_PATH"; then
     if test ! -f "$DEHYDRA_PATH"; then
         AC_MSG_ERROR([The dehydra plugin is not at the specified path.])
     fi
     AC_DEFINE(NS_STATIC_CHECKING)
@@ -7399,17 +7459,17 @@ if test -n "$MOZ_TIMELINE"; then
 fi
 
 dnl ========================================================
 dnl = Enable NS_FUNCTION_TIMER, which provides Function 
 dnl = timing for identifying code bottlenecks 
 dnl = NS_FUNCTION_TIMER is off by default.
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(functiontimer,
-[  --enable-functiontimer       Enable NS_FUNCTION_TIMER ],
+[  --enable-functiontimer  Enable NS_FUNCTION_TIMER ],
     NS_FUNCTION_TIMER=1,
     NS_FUNCTION_TIMER= )
 if test -n "$NS_FUNCTION_TIMER"; then
     AC_DEFINE(NS_FUNCTION_TIMER)
 fi
 
 dnl ========================================================
 dnl Turn on reflow counting
@@ -7436,17 +7496,17 @@ if test -n "$_ENABLE_CODESIGHS"; then
         AC_MSG_ERROR([Codesighs directory $srcdir/tools/codesighs required.])
     fi
 fi
 
 dnl ========================================================
 dnl = Support for Quantify (Windows)
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(quantify,
-[  --enable-quantify      Enable Quantify support (Windows only) ],
+[  --enable-quantify       Enable Quantify support (Windows only) ],
     MOZ_QUANTIFY=1,
     MOZ_QUANTIFY= )
 
 dnl ========================================================
 dnl = Support for demangling undefined symbols
 dnl ========================================================
 if test -z "$SKIP_LIBRARY_CHECKS"; then
     AC_LANG_SAVE
@@ -7622,17 +7682,17 @@ dnl Profile guided optimization
 dnl ========================================================
 dnl Test for profiling options
 dnl Under gcc 3.3, use -fprofile-arcs/-fbranch-probabilities
 dnl Under gcc 3.4+, use -fprofile-generate/-fprofile-use
 
 dnl Provide a switch to disable PGO even when called via profiledbuild.
 MOZ_ARG_DISABLE_BOOL(profile-guided-optimization,
 [  --disable-profile-guided-optimization
-                           Don't build with PGO even if called via make profiledbuild],
+                          Don't build with PGO even if called via make profiledbuild],
 MOZ_PROFILE_GUIDED_OPTIMIZE_DISABLE=1,
 MOZ_PROFILE_GUIDED_OPTIMIZE_DISABLE=)
 
 AC_SUBST(MOZ_PROFILE_GUIDED_OPTIMIZE_DISABLE)
 
 _SAVE_CFLAGS="$CFLAGS"
 CFLAGS="$CFLAGS -fprofile-generate -fprofile-correction"
 
@@ -8082,17 +8142,17 @@ AC_SUBST(HOST_LIBIDL_LIBS)
 
 dnl ========================================================
 dnl Check for cairo
 dnl ========================================================
 MOZ_CAIRO_CFLAGS='-I$(LIBXUL_DIST)/include/cairo'
 
 MOZ_TREE_CAIRO=1
 MOZ_ARG_ENABLE_BOOL(system-cairo,
-[ --enable-system-cairo Use system cairo (located with pkgconfig)],
+[  --enable-system-cairo   Use system cairo (located with pkgconfig)],
 MOZ_TREE_CAIRO=,
 MOZ_TREE_CAIRO=1 )
 
 # Check for headers defining standard int types.
 AC_CHECK_HEADERS(stdint.h inttypes.h sys/int_types.h)
 
 if test "$MOZ_TREE_CAIRO"; then
     AC_DEFINE(MOZ_TREE_CAIRO)
@@ -8269,17 +8329,18 @@ fi
 AC_SUBST(MOZ_XUL)
 
 dnl ========================================================
 dnl disable profile locking
 dnl   do no use this in applications that can have more than
 dnl   one process accessing the profile directory.
 dnl ========================================================
 MOZ_ARG_DISABLE_BOOL(profilelocking,
-[  --disable-profilelocking           Disable profile locking],
+[  --disable-profilelocking
+                          Disable profile locking],
     MOZ_PROFILELOCKING=,
     MOZ_PROFILELOCKING=1 )
 if test "$MOZ_PROFILELOCKING"; then
   AC_DEFINE(MOZ_PROFILELOCKING)
 fi
 
 dnl ========================================================
 dnl disable rdf services
@@ -8337,17 +8398,17 @@ AC_SUBST(NECKO_DISK_CACHE)
 if test "$NECKO_DISK_CACHE"; then
     AC_DEFINE(NECKO_DISK_CACHE)
 fi
 
 dnl
 dnl option to disable necko's wifi scanner
 dnl
 MOZ_ARG_DISABLE_BOOL(necko-wifi,
-[  --disable-necko-wifi   Disable necko wifi scanner],
+[  --disable-necko-wifi    Disable necko wifi scanner],
     NECKO_WIFI=,
     NECKO_WIFI=1
 )
 
 if test "$OS_ARCH" = "OS2"; then
   dnl OS/2 implementation of Necko-WiFi support will be added in bug 506566
   NECKO_WIFI=
 fi
@@ -8965,16 +9026,19 @@ if test -z "$MOZ_NATIVE_NSPR"; then
        ac_configure_args="$ac_configure_args --enable-debug --disable-optimize"
     fi
     if test -n "$HAVE_64BIT_OS"; then
         ac_configure_args="$ac_configure_args --enable-64bit"
     fi
     if test -n "$USE_ARM_KUSER"; then
         ac_configure_args="$ac_configure_args --with-arm-kuser"
     fi
+    if test -n "$MOZ_THUMB2"; then
+        ac_configure_args="$ac_configure_args --enable-thumb2"
+    fi
     AC_OUTPUT_SUBDIRS(nsprpub)
     ac_configure_args="$_SUBDIR_CONFIG_ARGS"
 fi
 
 if test -z "$MOZ_NATIVE_NSPR"; then
     # Hack to deal with the fact that we use NSPR_CFLAGS everywhere
     AC_MSG_WARN([Recreating autoconf.mk with updated nspr-config output])
     if test "$OS_ARCH" != "WINNT" && test "$OS_ARCH" != "WINCE"; then
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -1346,22 +1346,16 @@ public:
   static PRUint32 FilterDropEffect(PRUint32 aAction, PRUint32 aEffectAllowed);
 
   /**
    * Return true if aURI is a local file URI (i.e. file://).
    */
   static PRBool URIIsLocalFile(nsIURI *aURI);
 
   /**
-   * If aContent is an HTML element with a DOM level 0 'name', then
-   * return the name. Otherwise return null.
-   */
-  static nsIAtom* IsNamedItem(Element* aElement);
-
-  /**
    * Get the application manifest URI for this document.  The manifest URI
    * is specified in the manifest= attribute of the root element of the
    * document.
    *
    * @param aDocument The document that lists the manifest.
    * @param aURI The manifest URI.
    */
   static void GetOfflineAppManifest(nsIDocument *aDocument, nsIURI **aURI);
--- a/content/base/public/nsIContent.h
+++ b/content/base/public/nsIContent.h
@@ -66,18 +66,18 @@ enum nsLinkState {
   eLinkState_Unknown    = 0,
   eLinkState_Unvisited  = 1,
   eLinkState_Visited    = 2,
   eLinkState_NotLink    = 3
 };
 
 // IID for the nsIContent interface
 #define NS_ICONTENT_IID       \
-{ 0x9e3b1a15, 0x72d5, 0x4e4f, \
-  { 0x8f, 0x4b, 0x75, 0xde, 0x07, 0x9c, 0x16, 0xdc } }
+{ 0x1450010b, 0xcdca, 0x451c, \
+  { 0xba, 0xdc, 0x07, 0x90, 0x89, 0x7b, 0xce, 0xb8 } }
 
 /**
  * A node of content in a document's content model. This interface
  * is supported by all content objects.
  */
 class nsIContent : public nsINode {
 public:
 #ifdef MOZILLA_INTERNAL_API
@@ -773,17 +773,22 @@ public:
   // PRInt32.  We should really use PRUint32 instead.
   virtual PRInt32 IntrinsicState() const;
 
   /**
    * Get the ID of this content node (the atom corresponding to the
    * value of the null-namespace attribute whose name is given by
    * GetIDAttributeName().  This may be null if there is no ID.
    */
-  virtual nsIAtom* GetID() const = 0;
+  nsIAtom* GetID() const {
+    if (HasFlag(NODE_HAS_ID)) {
+      return DoGetID();
+    }
+    return nsnull;
+  }
 
   /**
    * Get the class list of this content node (this corresponds to the
    * value of the null-namespace attribute whose name is given by
    * GetClassAttributeName()).  This may be null if there are no
    * classes, but that's not guaranteed.
    */
   const nsAttrValue* GetClasses() const {
@@ -910,16 +915,23 @@ public:
                               nsAString& aNamespaceURI) const;
 
   nsIAtom* LookupPrefix(const nsAString& aNamespaceURI);
 
   PRBool IsEqual(nsIContent *aOther);
 
   virtual PRBool IsEqualNode(nsINode* aOther);
 
+protected:
+  /**
+   * Hook for implementing GetID.  This is guaranteed to only be
+   * called if the NODE_HAS_ID flag is set.
+   */
+  virtual nsIAtom* DoGetID() const = 0;
+
 private:
   /**
    * Hook for implementing GetClasses.  This is guaranteed to only be
    * called if the NODE_MAY_HAVE_CLASS flag is set.
    */
   virtual const nsAttrValue* DoGetClasses() const = 0;
 
   /**
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -57,27 +57,27 @@
 #include "nsIStreamListener.h"
 #include "nsIObserver.h"
 #include "nsGkAtoms.h"
 #include "nsAutoPtr.h"
 #include "nsPIDOMWindow.h"
 #ifdef MOZ_SMIL
 #include "nsSMILAnimationController.h"
 #endif // MOZ_SMIL
+#include "nsIScriptGlobalObject.h"
 
 class nsIContent;
 class nsPresContext;
 class nsIPresShell;
 class nsIDocShell;
 class nsStyleSet;
 class nsIStyleSheet;
 class nsIStyleRule;
 class nsCSSStyleSheet;
 class nsIViewManager;
-class nsIScriptGlobalObject;
 class nsIDOMEvent;
 class nsIDOMEventTarget;
 class nsIDeviceContext;
 class nsIParser;
 class nsIDOMNode;
 class nsIDOMElement;
 class nsIDOMDocumentFragment;
 class nsILineBreaker;
@@ -111,18 +111,18 @@ class Loader;
 
 namespace dom {
 class Link;
 class Element;
 } // namespace dom
 } // namespace mozilla
 
 #define NS_IDOCUMENT_IID      \
-{ 0xeb847679, 0x3b48, 0x411c, \
-  { 0xa9, 0xb8, 0x8a, 0xdc, 0xdb, 0xc6, 0x47, 0xb8 } }
+{ 0x3ee6a14b, 0x83b5, 0x4629, \
+  { 0x96, 0x9b, 0xe9, 0x84, 0x7c, 0x57, 0x24, 0x3c } }
 
 // Flag for AddStyleSheet().
 #define NS_STYLESHEET_FROM_CATALOG                (1 << 0)
 
 // Document states
 
 // RTL locale: specific to the XUL localedir attribute
 #define NS_DOCUMENT_STATE_RTL_LOCALE              (1 << 0)
@@ -624,18 +624,23 @@ public:
    * Get/set the object from which the context for the event/script handling can
    * be got. Normally GetScriptHandlingObject() returns the same object as
    * GetScriptGlobalObject(), but if the document is loaded as data,
    * non-null may be returned, even if GetScriptGlobalObject() returns null.
    * aHasHadScriptHandlingObject is set PR_TRUE if document has had the object
    * for event/script handling. Do not process any events/script if the method
    * returns null, but aHasHadScriptHandlingObject is true.
    */
-  virtual nsIScriptGlobalObject*
-    GetScriptHandlingObject(PRBool& aHasHadScriptHandlingObject) const = 0;
+  nsIScriptGlobalObject*
+    GetScriptHandlingObject(PRBool& aHasHadScriptHandlingObject) const
+  {
+    aHasHadScriptHandlingObject = mHasHadScriptHandlingObject;
+    return mScriptGlobalObject ? mScriptGlobalObject.get() :
+                                 GetScriptHandlingObjectInternal();
+  }
   virtual void SetScriptHandlingObject(nsIScriptGlobalObject* aScriptObject) = 0;
 
   /**
    * Get the object that is used as the scope for all of the content
    * wrappers whose owner document is this document. Unlike the script global
    * object, this will only return null when the global object for this
    * document is truly gone. Use this object when you're trying to find a
    * content wrapper in XPConnect.
@@ -660,16 +665,27 @@ public:
     return mRemovedFromDocShell ? GetInnerWindowInternal() : mWindow;
   }
 
   /**
    * Get the script loader for this document
    */ 
   virtual nsScriptLoader* ScriptLoader() = 0;
 
+  /**
+   * Add/Remove an element to the document's id and name hashes
+   */
+  virtual void AddToIdTable(mozilla::dom::Element* aElement, nsIAtom* aId) = 0;
+  virtual void RemoveFromIdTable(mozilla::dom::Element* aElement,
+                                 nsIAtom* aId) = 0;
+  virtual void AddToNameTable(mozilla::dom::Element* aElement,
+                              nsIAtom* aName) = 0;
+  virtual void RemoveFromNameTable(mozilla::dom::Element* aElement,
+                                   nsIAtom* aName) = 0;
+
   //----------------------------------------------------------------------
 
   // Document notification API's
 
   /**
    * Add a new observer of document change notifications. Whenever
    * content is changed, appended, inserted or removed the observers are
    * informed.  An observer that is already observing the document must
@@ -792,16 +808,20 @@ public:
   virtual void GetXMLDeclaration(nsAString& aVersion,
                                  nsAString& aEncoding,
                                  nsAString& Standalone) = 0;
 
   PRBool IsHTML() const
   {
     return mIsRegularHTML;
   }
+  PRBool IsXUL() const
+  {
+    return mIsXUL;
+  }
 
   virtual PRBool IsScriptEnabled() = 0;
 
   virtual nsresult AddXMLEventsContent(nsIContent * aXMLEventsElement) = 0;
 
   /**
    * Create an element with the specified name, prefix and namespace ID.
    * If aDocumentDefaultType is true we create an element of the default type
@@ -1359,18 +1379,17 @@ public:
   virtual void SetChangeScrollPosWhenScrollingToRef(PRBool aValue) = 0;
 
   /**
    * This method is similar to GetElementById() from nsIDOMDocument but it
    * returns a mozilla::dom::Element instead of a nsIDOMElement.
    * It prevents converting nsIDOMElement to mozill:dom::Element which is
    * already converted from mozilla::dom::Element.
    */
-  virtual mozilla::dom::Element* GetElementById(const nsAString& aElementId,
-                                                nsresult* aResult) = 0;
+  virtual mozilla::dom::Element* GetElementById(const nsAString& aElementId) = 0;
 
 protected:
   ~nsIDocument()
   {
     // XXX The cleanup of mNodeInfoManager (calling DropDocumentReference and
     //     releasing it) happens in the nsDocument destructor. We'd prefer to
     //     do it here but nsNodeInfoManager is a concrete class that we don't
     //     want to expose to users of the nsIDocument API outside of Gecko.
@@ -1379,16 +1398,19 @@ protected:
   nsPropertyTable* GetExtraPropertyTable(PRUint16 aCategory);
 
   // Never ever call this. Only call GetWindow!
   virtual nsPIDOMWindow *GetWindowInternal() = 0;
 
   // Never ever call this. Only call GetInnerWindow!
   virtual nsPIDOMWindow *GetInnerWindowInternal() = 0;
 
+  // Never ever call this. Only call GetScriptHandlingObject!
+  virtual nsIScriptGlobalObject* GetScriptHandlingObjectInternal() const = 0;
+
   /**
    * These methods should be called before and after dispatching
    * a mutation event.
    * To make this easy and painless, use the mozAutoSubtreeModified helper class.
    */
   virtual void WillDispatchMutationEvent(nsINode* aTarget) = 0;
   virtual void MutationEventDispatched(nsINode* aTarget) = 0;
   friend class mozAutoSubtreeModified;
@@ -1449,16 +1471,17 @@ protected:
   // basically be true only for documents that exist in newly-opened windows or
   // documents created to satisfy a GetDocument() on a window when there's no
   // document in it.
   PRPackedBool mIsInitialDocumentInWindow;
 
   PRPackedBool mShellIsHidden;
 
   PRPackedBool mIsRegularHTML;
+  PRPackedBool mIsXUL;
 
   // True if we're loaded as data and therefor has any dangerous stuff, such
   // as scripts and plugins, disabled.
   PRPackedBool mLoadedAsData;
 
   // If true, whoever is creating the document has gotten it to the
   // point where it's safe to start layout on it.
   PRPackedBool mMayStartLayout;
@@ -1483,16 +1506,24 @@ protected:
   PRPackedBool mAllowDNSPrefetch;
   
   // True when this document is a static clone of a normal document
   PRPackedBool mIsStaticDocument;
 
   // True while this document is being cloned to a static document.
   PRPackedBool mCreatingStaticClone;
 
+  // True if document has ever had script handling object.
+  PRPackedBool mHasHadScriptHandlingObject;
+
+  // The document's script global object, the object from which the
+  // document can get its script context and scope. This is the
+  // *inner* window object.
+  nsCOMPtr<nsIScriptGlobalObject> mScriptGlobalObject;
+
   // If mIsStaticDocument is true, mOriginalDocument points to the original
   // document.
   nsCOMPtr<nsIDocument> mOriginalDocument;
 
   // The bidi options for this document.  What this bitfield means is
   // defined in nsBidiUtils.h
   PRUint32 mBidiOptions;
 
--- a/content/base/public/nsIDocumentEncoder.idl
+++ b/content/base/public/nsIDocumentEncoder.idl
@@ -56,17 +56,17 @@ interface nsIDocumentEncoderNodeFixup : 
    * @param [OUT] aSerializeCloneKids True if the document encoder should
    * apply recursive serialization to the children of the fixed up node
    * instead of the children of the original node.
    * @return The resulting fixed up node.
    */
   nsIDOMNode fixupNode(in nsIDOMNode aNode, out boolean aSerializeCloneKids);
 };
 
-[scriptable, uuid(f85c5a20-258d-11db-a98b-0800200c9a66)]
+[scriptable, uuid(794a81f6-bde6-4f76-9f5e-0ea0911a2d9f)]
 interface nsIDocumentEncoder : nsISupports
 {
   // Output methods flag bits. There are a frightening number of these,
   // because everyone wants something a little bit different
    
 
   /** 
    * Output only the selection (as opposed to the whole document).
@@ -209,18 +209,32 @@ interface nsIDocumentEncoder : nsISuppor
   const unsigned long OutputPersistNBSP = (1 << 17);
 
   /**
    * Normally when serializing the whole document using the HTML or 
    * XHTML serializer, the encoding declaration is rewritten to match.
    * This flag suppresses that behavior.
    */
   const unsigned long OutputDontRewriteEncodingDeclaration = (1 << 18);
+ 
+  /**
+   * When using the HTML or XHTML serializer, skip elements that are not
+   * visible when this flag is set.  Elements are not visible when they
+   * have CSS style display:none or visibility:collapse, for example.
+   */
+  const unsigned long SkipInvisibleContent = (1 << 19);
   
   /**
+   * Output for delsp=yes (RFC 3676). This is used with OutputFormatFlowed
+   * when converting to text for mail sending.
+   * PlainText output only.
+   */
+  const unsigned long OutputFormatDelSp  = (1 << 20);
+ 
+  /**
    * Initialize with a pointer to the document and the mime type.
    * @param aDocument Document to encode.
    * @param aMimeType MimeType to use. May also be set by SetMimeType.
    * @param aFlags Flags to use while encoding. May also be set by SetFlags.
    */
   void init(in nsIDOMDocument aDocument,
             in AString aMimeType,
             in unsigned long aFlags);
--- a/content/base/public/nsINode.h
+++ b/content/base/public/nsINode.h
@@ -112,19 +112,20 @@ enum {
   // in the document and therefore should get bindings attached.
   NODE_FORCE_XBL_BINDINGS =      0x00000040U,
 
   // Whether a binding manager may have a pointer to this
   NODE_MAY_BE_IN_BINDING_MNGR =  0x00000080U,
 
   NODE_IS_EDITABLE =             0x00000100U,
 
-  // Optimizations to quickly check whether element may have ID, class or style
-  // attributes. Not all element implementations may use these!
-  NODE_MAY_HAVE_ID =             0x00000200U,
+  // Set to true if the element has a non-empty id attribute. This can in rare
+  // cases lie for nsXMLElement, such as when the node has been moved between
+  // documents with different id mappings.
+  NODE_HAS_ID =                  0x00000200U,
   // For all Element nodes, NODE_MAY_HAVE_CLASS is guaranteed to be set if the
   // node in fact has a class, but may be set even if it doesn't.
   NODE_MAY_HAVE_CLASS =          0x00000400U,
   NODE_MAY_HAVE_STYLE =          0x00000800U,
 
   NODE_IS_INSERTION_PARENT =     0x00001000U,
 
   // Node has an :empty or :-moz-only-whitespace selector
@@ -165,19 +166,25 @@ enum {
 
   // At least one descendant in the flattened tree has NODE_NEEDS_FRAME set.
   // This should be set on every node on the flattened tree path between the
   // node(s) with NODE_NEEDS_FRAME and the root content.
   NODE_DESCENDANTS_NEED_FRAMES = 0x00100000U,
 
   // Set if the node is an element.
   NODE_IS_ELEMENT              = 0x00200000U,
+  
+  // Set if the node has the accesskey attribute set.
+  NODE_HAS_ACCESSKEY           = 0x00400000U,
+
+  // Set if the node has the accesskey attribute set.
+  NODE_HAS_NAME                = 0x00800000U,
 
   // Four bits for the script-type ID
-  NODE_SCRIPT_TYPE_OFFSET =               22,
+  NODE_SCRIPT_TYPE_OFFSET =               24,
 
   NODE_SCRIPT_TYPE_SIZE =                  4,
 
   // Remaining bits are node type specific.
   NODE_TYPE_SPECIFIC_BITS_OFFSET =
     NODE_SCRIPT_TYPE_OFFSET + NODE_SCRIPT_TYPE_SIZE
 };
 
@@ -917,25 +924,16 @@ public:
    * node is not in an editor, the result comes from the nsFrameSelection that
    * is related to aPresShell, so the result might not be the ancestor of this
    * node. Be aware that if this node and the computed selection limiter are
    * not in same subtree, this returns the root content of the closeset subtree.
    */
   nsIContent* GetSelectionRootContent(nsIPresShell* aPresShell);
 
   virtual nsINodeList* GetChildNodesList();
-  nsIContent* GetSibling(PRInt32 aOffset)
-  {
-    nsINode *parent = GetNodeParent();
-    if (!parent) {
-      return nsnull;
-    }
-
-    return parent->GetChildAt(parent->IndexOf(this) + aOffset);
-  }
   nsIContent* GetFirstChild() const { return mFirstChild; }
   nsIContent* GetLastChild() const
   {
     PRUint32 count;
     nsIContent* const* children = GetChildArray(&count);
 
     return count > 0 ? children[count - 1] : nsnull;
   }
--- a/content/base/src/contentSecurityPolicy.js
+++ b/content/base/src/contentSecurityPolicy.js
@@ -241,44 +241,41 @@ ContentSecurityPolicy.prototype = {
   /**
    * Generates and sends a violation report to the specified report URIs.
    */
   sendReports:
   function(blockedUri, violatedDirective) {
     var uriString = this._policy.getReportURIs();
     var uris = uriString.split(/\s+/);
     if (uris.length > 0) {
-      // Generate report to send composed of:
-      // <csp-report>
-      //   <request>GET /index.html HTTP/1.1</request>
-      //   <request-headers>Host: example.com
-      //            User-Agent: ...
-      //            ...
-      //   </request-headers>
-      //   <blocked-uri>...</blocked-uri>
-      //   <violated-directive>...</violated-directive>
-      // </csp-report>
-      //   
+      // Generate report to send composed of
+      // {
+      //   csp-report: {
+      //     request: "GET /index.html HTTP/1.1",
+      //     request-headers: "Host: example.com
+      //                       User-Agent: ...
+      //                       ...",
+      //     blocked-uri: "...",
+      //     violated-directive: "..."
+      //   }
+      // }
       var strHeaders = "";
       for (let i in this._requestHeaders) {
         strHeaders += this._requestHeaders[i] + "\n";
       }
-
-      var report = "<csp-report>\n" +
-        " <request>" + this._request + "</request>\n" +
-        "   <request-headers><![CDATA[\n" +
-        strHeaders +
-        "   ]]></request-headers>\n" +
-        "   <blocked-uri>" + 
-        (blockedUri instanceof Ci.nsIURI ? blockedUri.asciiSpec : blockedUri) + 
-        "</blocked-uri>\n" +
-        "   <violated-directive>" + violatedDirective + "</violated-directive>\n" +
-        "</csp-report>\n";
-
-      CSPdebug("Constructed violation report:\n" + report);
+      var report = {
+        'csp-report': {
+          'request': this._request,
+          'request-headers': strHeaders,
+          'blocked-uri': (blockedUri instanceof Ci.nsIURI ?
+                          blockedUri.asciiSpec : blockedUri),
+          'violated-directive': violatedDirective
+        }
+      }
+      CSPdebug("Constructed violation report:\n" + JSON.stringify(report));
 
       // For each URI in the report list, send out a report.
       for (let i in uris) {
         if (uris[i] === "")
           continue;
 
         var failure = function(aEvt) {  
           if (req.readyState == 4 && req.status != 200) {
@@ -296,17 +293,17 @@ ContentSecurityPolicy.prototype = {
           //req.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE;
  
           // make request anonymous
           // This prevents sending cookies with the request,
           // in case the policy URI is injected, it can't be
           // abused for CSRF.
           req.channel.loadFlags |= Ci.nsIChannel.LOAD_ANONYMOUS;
 
-          req.send(report);
+          req.send(JSON.stringify(report));
           CSPdebug("Sent violation report to " + uris[i]);
         } catch(e) {
           // it's possible that the URI was invalid, just log a
           // warning and skip over that.
           CSPWarning("Tried to send report to invalid URI: \"" + uris[i] + "\"");
         }
       }
     }
--- a/content/base/src/nsAttrValue.cpp
+++ b/content/base/src/nsAttrValue.cpp
@@ -1137,47 +1137,54 @@ nsAttrValue::SetColorValue(nscolor aColo
   cont->mStringBits = reinterpret_cast<PtrBits>(buf) | eStringBase;
 }
 
 PRBool
 nsAttrValue::ParseColor(const nsAString& aString, nsIDocument* aDocument)
 {
   ResetIfSet();
 
+  // FIXME (partially, at least): HTML5's algorithm says we shouldn't do
+  // the whitespace compression, trimming, or the test for emptiness.
+  // (I'm a little skeptical that we shouldn't do the whitespace
+  // trimming; WebKit also does it.)
   nsAutoString colorStr(aString);
   colorStr.CompressWhitespace(PR_TRUE, PR_TRUE);
   if (colorStr.IsEmpty()) {
     return PR_FALSE;
   }
 
   nscolor color;
   // No color names begin with a '#'; in standards mode, all acceptable
   // numeric colors do.
   if (colorStr.First() == '#') {
-    colorStr.Cut(0, 1);
-    if (NS_HexToRGB(colorStr, &color)) {
+    nsDependentString withoutHash(colorStr.get() + 1, colorStr.Length() - 1);
+    if (NS_HexToRGB(withoutHash, &color)) {
       SetColorValue(color, aString);
       return PR_TRUE;
     }
   } else {
     if (NS_ColorNameToRGB(colorStr, &color)) {
       SetColorValue(color, aString);
       return PR_TRUE;
     }
   }
 
-  if (aDocument->GetCompatibilityMode() != eCompatibility_NavQuirks) {
-    return PR_FALSE;
+  // FIXME (maybe): HTML5 says we should handle system colors.  This
+  // means we probably need another storage type, since we'd need to
+  // handle dynamic changes.  However, I think this is a bad idea:
+  // http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2010-May/026449.html
+
+  // Use NS_LooseHexToRGB as a fallback if nothing above worked.
+  if (NS_LooseHexToRGB(colorStr, &color)) {
+    SetColorValue(color, aString);
+    return PR_TRUE;
   }
 
-  // In compatibility mode, try LooseHexToRGB as a fallback for either
-  // of the above two possibilities.
-  NS_LooseHexToRGB(colorStr, &color);
-  SetColorValue(color, aString);
-  return PR_TRUE;
+  return PR_FALSE;
 }
 
 PRBool nsAttrValue::ParseFloatValue(const nsAString& aString)
 {
   ResetIfSet();
 
   PRInt32 ec;
   float val = PromiseFlatString(aString).ToFloat(&ec);
--- a/content/base/src/nsAttrValue.h
+++ b/content/base/src/nsAttrValue.h
@@ -269,17 +269,18 @@ public:
    * http://dev.w3.org/html5/spec/common-dom-interfaces.html#limited-to-only-non-negative-numbers-greater-than-zero
    *
    * @param aString       the string to parse
    * @return              whether the value was valid
    */
   PRBool ParsePositiveIntValue(const nsAString& aString);
 
   /**
-   * Parse a string into a color.
+   * Parse a string into a color.  This implements what HTML5 calls the
+   * "rules for parsing a legacy color value".
    *
    * @param aString the string to parse
    * @param aDocument the document (to find out whether we're in quirks mode)
    * @return whether the value could be parsed
    */
   PRBool ParseColor(const nsAString& aString, nsIDocument* aDocument);
 
   /**
--- a/content/base/src/nsContentAreaDragDrop.cpp
+++ b/content/base/src/nsContentAreaDragDrop.cpp
@@ -40,73 +40,101 @@
 
 // Local Includes
 #include "nsContentAreaDragDrop.h"
 
 // Helper Classes
 #include "nsString.h"
 
 // Interfaces needed to be included
-#include "nsIVariant.h"
+#include "nsCopySupport.h"
 #include "nsIDOMNSUIEvent.h"
 #include "nsIDOMUIEvent.h"
 #include "nsISelection.h"
 #include "nsIDOMNode.h"
 #include "nsIDOMNodeList.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMNSEvent.h"
 #include "nsIDOMDragEvent.h"
 #include "nsIDOMAbstractView.h"
 #include "nsPIDOMWindow.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMDocumentRange.h"
 #include "nsIDOMRange.h"
-#include "nsIDocumentEncoder.h"
 #include "nsIFormControl.h"
-#include "nsISelectionPrivate.h"
 #include "nsIDOMHTMLAreaElement.h"
 #include "nsIDOMHTMLAnchorElement.h"
 #include "nsITransferable.h"
 #include "nsComponentManagerUtils.h"
 #include "nsXPCOM.h"
 #include "nsISupportsPrimitives.h"
 #include "nsServiceManagerUtils.h"
 #include "nsNetUtil.h"
 #include "nsIFile.h"
 #include "nsIWebNavigation.h"
 #include "nsIDocShell.h"
 #include "nsIContent.h"
 #include "nsIImageLoadingContent.h"
-#include "nsINameSpaceManager.h"
 #include "nsUnicharUtils.h"
 #include "nsIURL.h"
 #include "nsIDocument.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIPrincipal.h"
 #include "nsIDocShellTreeItem.h"
-#include "nsIFrame.h"
 #include "nsRange.h"
 #include "nsIWebBrowserPersist.h"
 #include "nsEscape.h"
 #include "nsContentUtils.h"
 #include "nsIMIMEService.h"
 #include "imgIContainer.h"
 #include "imgIRequest.h"
-#include "nsContentCID.h"
 #include "nsDOMDataTransfer.h"
-#include "nsISelectionController.h"
-#include "nsFrameSelection.h"
-#include "nsWidgetsCID.h"
-
-static NS_DEFINE_CID(kHTMLConverterCID,        NS_HTMLFORMATCONVERTER_CID);
 
 // private clipboard data flavors for html copy, used by editor when pasting
 #define kHTMLContext   "text/_moz_htmlcontext"
 #define kHTMLInfo      "text/_moz_htmlinfo"
 
+nsresult NS_NewDomSelection(nsISelection **aDomSelection);
+
+// if inNode is null, use the selection from the window
+static nsresult
+GetTransferableForNodeOrSelection(nsIDOMWindow*     aWindow,
+                                  nsIContent*       aNode,
+                                  nsITransferable** aTransferable)
+{
+  NS_ENSURE_ARG_POINTER(aWindow);
+
+  nsCOMPtr<nsIDOMDocument> domDoc;
+  aWindow->GetDocument(getter_AddRefs(domDoc));
+  NS_ENSURE_TRUE(domDoc, NS_ERROR_FAILURE);
+  nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
+
+  nsresult rv;
+  nsCOMPtr<nsISelection> selection;
+  nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aNode);
+  if (node) {
+    // Make a temporary selection with this node in a single range.
+    rv = NS_NewDomSelection(getter_AddRefs(selection));
+    NS_ENSURE_SUCCESS(rv, rv);
+    nsCOMPtr<nsIDOMRange> range;
+    rv = NS_NewRange(getter_AddRefs(range));
+    NS_ENSURE_SUCCESS(rv, rv);
+    rv = range->SelectNode(node);
+    NS_ENSURE_SUCCESS(rv, rv);
+    rv = selection->AddRange(range);
+    NS_ENSURE_SUCCESS(rv, rv);
+  } else {
+    aWindow->GetSelection(getter_AddRefs(selection));
+  }
+
+  rv = nsCopySupport::GetTransferableForSelection(selection, doc,
+                                                  aTransferable);
+  NS_ENSURE_SUCCESS(rv, rv);
+  return rv;
+}
 
 class NS_STACK_CLASS DragDataProducer
 {
 public:
   DragDataProducer(nsIDOMWindow* aWindow,
                    nsIContent* aTarget,
                    nsIContent* aSelectionTargetNode,
                    PRBool aIsAltKeyPressed);
@@ -129,23 +157,16 @@ private:
   static already_AddRefed<nsIContent> FindParentLinkNode(nsIContent* inNode);
   static void GetAnchorURL(nsIContent* inNode, nsAString& outURL);
   static void GetNodeString(nsIContent* inNode, nsAString & outNodeString);
   static void CreateLinkText(const nsAString& inURL, const nsAString & inText,
                               nsAString& outLinkText);
   static void GetSelectedLink(nsISelection* inSelection,
                               nsIContent **outLinkNode);
 
-  // if inNode is null, use the selection from the window
-  static nsresult SerializeNodeOrSelection(nsIDOMWindow* inWindow,
-                                           nsIContent* inNode,
-                                           nsAString& outResultString,
-                                           nsAString& outHTMLContext,
-                                           nsAString& outHTMLInfo);
-
   nsCOMPtr<nsIDOMWindow> mWindow;
   nsCOMPtr<nsIContent> mTarget;
   nsCOMPtr<nsIContent> mSelectionTargetNode;
   PRPackedBool mIsAltKeyPressed;
 
   nsString mUrlString;
   nsString mImageSourceString;
   nsString mImageDestFileName;
@@ -412,16 +433,17 @@ DragDataProducer::Produce(nsDOMDataTrans
 {
   NS_PRECONDITION(aCanDrag && aDragSelection && aDataTransfer && aDragNode,
                   "null pointer passed to Produce");
   NS_ASSERTION(mWindow, "window not set");
   NS_ASSERTION(mSelectionTargetNode, "selection target node should have been set");
 
   *aDragNode = nsnull;
 
+  nsresult rv;
   nsIContent* dragNode = nsnull;
 
   // find the selection to see what we could be dragging and if
   // what we're dragging is in what is selected.
   nsCOMPtr<nsISelection> selection;
   mWindow->GetSelection(getter_AddRefs(selection));
   if (!selection) {
     return NS_OK;
@@ -658,49 +680,56 @@ DragDataProducer::Produce(nsDOMDataTrans
   }
 
   if (nodeToSerialize || *aDragSelection) {
     // if we have selected text, use it in preference to the node
     if (*aDragSelection) {
       nodeToSerialize = nsnull;
     }
 
-    SerializeNodeOrSelection(mWindow, nodeToSerialize,
-                             mHtmlString, mContextString, mInfoString);
-
-    nsCOMPtr<nsIFormatConverter> htmlConverter =
-      do_CreateInstance(kHTMLConverterCID);
-    NS_ENSURE_TRUE(htmlConverter, NS_ERROR_FAILURE);
-
-    nsCOMPtr<nsISupportsString> html =
-      do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID);
-    NS_ENSURE_TRUE(html, NS_ERROR_FAILURE);
-    html->SetData(mHtmlString);
-
-    nsCOMPtr<nsISupportsString> text;
-    PRUint32 textLen;
-    htmlConverter->Convert(kHTMLMime, html, mHtmlString.Length() * 2,
-                           kUnicodeMime, getter_AddRefs(text), &textLen);
-    NS_ENSURE_TRUE(text, NS_ERROR_FAILURE);
-    text->GetData(mTitleString);
+    mHtmlString.Truncate();
+    mContextString.Truncate();
+    mInfoString.Truncate();
+    mTitleString.Truncate();
+    nsCOMPtr<nsITransferable> transferable;
+    rv = ::GetTransferableForNodeOrSelection(mWindow, nodeToSerialize,
+                                             getter_AddRefs(transferable));
+    NS_ENSURE_SUCCESS(rv, rv);
+    nsCOMPtr<nsISupportsString> data;
+    PRUint32 dataSize;
+    rv = transferable->GetTransferData(kHTMLMime, getter_AddRefs(data), &dataSize);
+    if (NS_SUCCEEDED(rv)) {
+      data->GetData(mHtmlString);
+    }
+    rv = transferable->GetTransferData(kHTMLContext, getter_AddRefs(data), &dataSize);
+    if (NS_SUCCEEDED(rv)) {
+      data->GetData(mContextString);
+    }
+    rv = transferable->GetTransferData(kHTMLInfo, getter_AddRefs(data), &dataSize);
+    if (NS_SUCCEEDED(rv)) {
+      data->GetData(mInfoString);
+    }
+    rv = transferable->GetTransferData(kUnicodeMime, getter_AddRefs(data), &dataSize);
+    NS_ENSURE_SUCCESS(rv, rv); // require plain text at a minimum
+    data->GetData(mTitleString);
   }
 
   // default text value is the URL
   if (mTitleString.IsEmpty()) {
     mTitleString = mUrlString;
   }
 
   // if we haven't constructed a html version, make one now
   if (mHtmlString.IsEmpty() && !mUrlString.IsEmpty())
     CreateLinkText(mUrlString, mTitleString, mHtmlString);
 
   // if there is no drag node, which will be the case for a selection, just
   // use the selection target node.
-  nsresult rv = AddStringsToDataTransfer(
-           dragNode ? dragNode : mSelectionTargetNode.get(), aDataTransfer);
+  rv = AddStringsToDataTransfer(
+         dragNode ? dragNode : mSelectionTargetNode.get(), aDataTransfer);
   NS_ENSURE_SUCCESS(rv, rv);
 
   NS_IF_ADDREF(*aDragNode = dragNode);
   return NS_OK;
 }
 
 void
 DragDataProducer::AddString(nsDOMDataTransfer* aDataTransfer,
@@ -977,57 +1006,8 @@ DragDataProducer::GetSelectedLink(nsISel
 
     if (link == link2) {
       NS_IF_ADDREF(*outLinkNode = link);
     }
   }
 
   return;
 }
-
-// static
-nsresult
-DragDataProducer::SerializeNodeOrSelection(nsIDOMWindow* inWindow,
-                                           nsIContent* inNode,
-                                           nsAString& outResultString,
-                                           nsAString& outContext,
-                                           nsAString& outInfo)
-{
-  NS_ENSURE_ARG_POINTER(inWindow);
-
-  nsresult rv;
-  nsCOMPtr<nsIDocumentEncoder> encoder =
-    do_CreateInstance(NS_HTMLCOPY_ENCODER_CONTRACTID);
-  NS_ENSURE_TRUE(encoder, NS_ERROR_FAILURE);
-
-  nsCOMPtr<nsIDOMDocument> domDoc;
-  inWindow->GetDocument(getter_AddRefs(domDoc));
-  NS_ENSURE_TRUE(domDoc, NS_ERROR_FAILURE);
-
-  PRUint32 flags = nsIDocumentEncoder::OutputAbsoluteLinks |
-                   nsIDocumentEncoder::OutputEncodeHTMLEntities |
-                   nsIDocumentEncoder::OutputRaw;
-  nsCOMPtr<nsIDOMRange> range;
-  nsCOMPtr<nsISelection> selection;
-  nsCOMPtr<nsIDOMNode> node = do_QueryInterface(inNode);
-  if (node) {
-    // make a range around this node
-    rv = NS_NewRange(getter_AddRefs(range));
-    NS_ENSURE_SUCCESS(rv, rv);
-    rv = range->SelectNode(node);
-    NS_ENSURE_SUCCESS(rv, rv);
-  } else {
-    inWindow->GetSelection(getter_AddRefs(selection));
-    flags |= nsIDocumentEncoder::OutputSelectionOnly;
-  }
-
-  rv = encoder->Init(domDoc, NS_LITERAL_STRING(kHTMLMime), flags);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (range) {
-    encoder->SetRange(range);
-  } else if (selection) {
-    encoder->SetSelection(selection);
-  }
-
-  return encoder->EncodeToStringWithContext(outContext, outInfo,
-                                            outResultString);
-}
--- a/content/base/src/nsContentIterator.cpp
+++ b/content/base/src/nsContentIterator.cpp
@@ -41,16 +41,17 @@
 #include "nsIContentIterator.h"
 #include "nsRange.h"
 #include "nsIContent.h"
 #include "nsIDOMText.h"
 #include "nsCOMPtr.h"
 #include "nsTArray.h"
 #include "nsContentUtils.h"
 #include "nsINode.h"
+#include "nsCycleCollectionParticipant.h"
 
 // couple of utility static functs
 
 ///////////////////////////////////////////////////////////////////////////
 // ContentHasChildren: returns true if the node has children
 //
 static inline PRBool
 NodeHasChildren(nsINode *aNode)
@@ -113,17 +114,18 @@ NodeIsInTraversalRange(nsINode *aNode, P
 
 
 /*
  *  A simple iterator class for traversing the content in "close tag" order
  */
 class nsContentIterator : public nsIContentIterator //, public nsIEnumerator
 {
 public:
-  NS_DECL_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_CLASS(nsContentIterator)
 
   nsContentIterator();
   virtual ~nsContentIterator();
 
   // nsIContentIterator interface methods ------------------------------
 
   virtual nsresult Init(nsINode* aRoot);
 
@@ -247,18 +249,30 @@ nsresult NS_NewPreContentIterator(nsICon
   return NS_OK;
 }
 
 
 /******************************************************
  * XPCOM cruft
  ******************************************************/
  
-NS_IMPL_ISUPPORTS1(nsContentIterator, nsIContentIterator)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(nsContentIterator)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(nsContentIterator)
 
+NS_INTERFACE_MAP_BEGIN(nsContentIterator)
+  NS_INTERFACE_MAP_ENTRY(nsIContentIterator)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContentIterator)
+  NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsContentIterator)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_CYCLE_COLLECTION_4(nsContentIterator,
+                           mCurNode,
+                           mFirst,
+                           mLast,
+                           mCommonParent)
 
 /******************************************************
  * constructor/destructor
  ******************************************************/
 
 nsContentIterator::nsContentIterator() :
   // don't need to explicitly initialize |nsCOMPtr|s, they will automatically be NULL
   mCachedIndex(0), mIsDone(PR_FALSE), mPre(PR_FALSE)
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -4891,45 +4891,16 @@ nsContentUtils::EqualsIgnoreASCIICase(co
 
 /* static */
 void
 nsAutoGCRoot::Shutdown()
 {
   NS_IF_RELEASE(sJSRuntimeService);
 }
 
-nsIAtom*
-nsContentUtils::IsNamedItem(Element* aElement)
-{
-  // Only the content types reflected in Level 0 with a NAME
-  // attribute are registered. Images, layers and forms always get
-  // reflected up to the document. Applets and embeds only go
-  // to the closest container (which could be a form).
-  nsGenericHTMLElement* elm = nsGenericHTMLElement::FromContent(aElement);
-  if (!elm) {
-    return nsnull;
-  }
-
-  nsIAtom* tag = elm->Tag();
-  if (tag != nsGkAtoms::img    &&
-      tag != nsGkAtoms::form   &&
-      tag != nsGkAtoms::applet &&
-      tag != nsGkAtoms::embed  &&
-      tag != nsGkAtoms::object) {
-    return nsnull;
-  }
-
-  const nsAttrValue* val = elm->GetParsedAttr(nsGkAtoms::name);
-  if (val && val->Type() == nsAttrValue::eAtom) {
-    return val->GetAtomValue();
-  }
-
-  return nsnull;
-}
-
 /* static */
 nsIInterfaceRequestor*
 nsContentUtils::GetSameOriginChecker()
 {
   if (!sSameOriginChecker) {
     sSameOriginChecker = new nsSameOriginChecker();
     NS_IF_ADDREF(sSameOriginChecker);
   }
--- a/content/base/src/nsCopySupport.cpp
+++ b/content/base/src/nsCopySupport.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):
  *   Kathleen Brade <brade@netscape.com>
  *   David Gardiner <david.gardiner@unisa.edu.au>
+ *   Mats Palmgren <matpal@gmail.com>
  *
  * 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
@@ -129,17 +130,19 @@ SelectionCopyHelper(nsISelection *aSel, 
   // is. if it is a selection into input/textarea element or in a html content
   // with pre-wrap style : text/plain. Otherwise text/html.
   // see nsHTMLCopyEncoder::SetSelection
   mimeType.AssignLiteral(kUnicodeMime);
   
   // we want preformatted for the case where the selection is inside input/textarea
   // and we don't want pretty printing for others cases, to not have additionnal
   // line breaks which are then converted into spaces by the htmlConverter (see bug #524975)
-  PRUint32 flags = nsIDocumentEncoder::OutputPreformatted | nsIDocumentEncoder::OutputRaw;
+  PRUint32 flags = nsIDocumentEncoder::OutputPreformatted
+                   | nsIDocumentEncoder::OutputRaw
+                   | nsIDocumentEncoder::SkipInvisibleContent;
 
   nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(aDoc);
   NS_ASSERTION(domDoc, "Need a document");
 
   rv = docEncoder->Init(domDoc, mimeType, flags);
   if (NS_FAILED(rv)) 
     return rv;
 
@@ -170,17 +173,17 @@ SelectionCopyHelper(nsISelection *aSel, 
     PRUint32 ConvertedLen;
     rv = htmlConverter->Convert(kHTMLMime, plainHTML, textBuffer.Length() * 2, kUnicodeMime, getter_AddRefs(ConvertedData), &ConvertedLen);
     NS_ENSURE_SUCCESS(rv, rv);
 
     ConvertedData->GetData(plaintextBuffer);
 
     mimeType.AssignLiteral(kHTMLMime);
 
-    flags = 0;
+    flags = nsIDocumentEncoder::SkipInvisibleContent;
 
     rv = docEncoder->Init(domDoc, mimeType, flags);
     NS_ENSURE_SUCCESS(rv, rv);
 
     rv = docEncoder->SetSelection(aSel);
     NS_ENSURE_SUCCESS(rv, rv);
 
     // encode the selection as html with contextual info
@@ -415,17 +418,17 @@ nsCopySupport::GetContents(const nsACStr
   nsCOMPtr<nsIDocumentEncoder> docEncoder;
 
   nsCAutoString encoderContractID(NS_DOC_ENCODER_CONTRACTID_BASE);
   encoderContractID.Append(aMimeType);
     
   docEncoder = do_CreateInstance(encoderContractID.get());
   NS_ENSURE_TRUE(docEncoder, NS_ERROR_FAILURE);
 
-  PRUint32 flags = aFlags;
+  PRUint32 flags = aFlags | nsIDocumentEncoder::SkipInvisibleContent;
   
   if (aMimeType.Equals("text/plain"))
     flags |= nsIDocumentEncoder::OutputPreformatted;
 
   NS_ConvertASCIItoUTF16 unicodeMimeType(aMimeType);
 
   nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(aDoc);
   NS_ASSERTION(domDoc, "Need a document");
--- a/content/base/src/nsDOMAttribute.cpp
+++ b/content/base/src/nsDOMAttribute.cpp
@@ -68,23 +68,36 @@ nsDOMAttribute::nsDOMAttribute(nsDOMAttr
                                const nsAString   &aValue)
   : nsIAttribute(aAttrMap, aNodeInfo), mValue(aValue), mChild(nsnull)
 {
   NS_ABORT_IF_FALSE(mNodeInfo, "We must get a nodeinfo here!");
 
 
   // We don't add a reference to our content. It will tell us
   // to drop our reference when it goes away.
+
+  EnsureChildState();
+
+  nsIContent* content = GetContentInternal();
+  if (content) {
+    content->AddMutationObserver(this);
+  }
 }
 
 nsDOMAttribute::~nsDOMAttribute()
 {
   if (mChild) {
     static_cast<nsTextNode*>(mChild)->UnbindFromAttribute();
     NS_RELEASE(mChild);
+    mFirstChild = nsnull;
+  }
+
+  nsIContent* content = GetContentInternal();
+  if (content) {
+    content->RemoveMutationObserver(this);
   }
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMAttribute)
 
 NS_IMPL_CYCLE_COLLECTION_ROOT_BEGIN(nsDOMAttribute)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
 NS_IMPL_CYCLE_COLLECTION_ROOT_END
@@ -100,28 +113,29 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsDOMAttribute)
   NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMAttribute)
   if (tmp->mChild) {
     static_cast<nsTextNode*>(tmp->mChild)->UnbindFromAttribute();
     NS_RELEASE(tmp->mChild);
+    tmp->mFirstChild = nsnull;
   }
   NS_IMPL_CYCLE_COLLECTION_UNLINK_LISTENERMANAGER
   NS_IMPL_CYCLE_COLLECTION_UNLINK_USERDATA
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 DOMCI_DATA(Attr, nsDOMAttribute)
 
 // QueryInterface implementation for nsDOMAttribute
 NS_INTERFACE_TABLE_HEAD(nsDOMAttribute)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
-  NS_NODE_INTERFACE_TABLE5(nsDOMAttribute, nsIDOMAttr, nsIAttribute, nsIDOMNode,
-                           nsIDOM3Attr, nsPIDOMEventTarget)
+  NS_NODE_INTERFACE_TABLE6(nsDOMAttribute, nsIDOMAttr, nsIAttribute, nsIDOMNode,
+                           nsIDOM3Attr, nsPIDOMEventTarget, nsIMutationObserver)
   NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsDOMAttribute)
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsISupportsWeakReference,
                                  new nsNodeSupportsWeakRefTearoff(this))
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMEventTarget,
                                  nsDOMEventRTTearoff::Create(this))
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOM3EventTarget,
                                  nsDOMEventRTTearoff::Create(this))
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMNSEventTarget,
@@ -139,16 +153,21 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE_FULL(ns
 void
 nsDOMAttribute::SetMap(nsDOMAttributeMap *aMap)
 {
   if (mAttrMap && !aMap && sInitialized) {
     // We're breaking a relationship with content and not getting a new one,
     // need to locally cache value. GetValue() does that.
     GetValue(mValue);
   }
+
+  nsIContent* content = GetContentInternal();
+  if (content) {
+    content->RemoveMutationObserver(this);
+  }
   
   mAttrMap = aMap;
 }
 
 nsIContent*
 nsDOMAttribute::GetContent() const
 {
   return GetContentInternal();
@@ -301,21 +320,17 @@ NS_IMETHODIMP
 nsDOMAttribute::GetChildNodes(nsIDOMNodeList** aChildNodes)
 {
   return nsINode::GetChildNodes(aChildNodes);
 }
 
 NS_IMETHODIMP
 nsDOMAttribute::HasChildNodes(PRBool* aHasChildNodes)
 {
-  PRBool hasChild;
-  nsresult rv = EnsureChildState(PR_FALSE, hasChild);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  *aHasChildNodes = hasChild;
+  *aHasChildNodes = mFirstChild != nsnull;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMAttribute::HasAttributes(PRBool* aHasAttributes)
 {
   NS_ENSURE_ARG_POINTER(aHasAttributes);
@@ -325,22 +340,18 @@ nsDOMAttribute::HasAttributes(PRBool* aH
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMAttribute::GetFirstChild(nsIDOMNode** aFirstChild)
 {
   *aFirstChild = nsnull;
 
-  PRBool hasChild;
-  nsresult rv = EnsureChildState(PR_TRUE, hasChild);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (mChild) {
-    CallQueryInterface(mChild, aFirstChild);
+  if (mFirstChild) {
+    CallQueryInterface(mFirstChild, aFirstChild);
   }
   
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMAttribute::GetLastChild(nsIDOMNode** aLastChild)
 {
@@ -579,48 +590,40 @@ PRBool
 nsDOMAttribute::IsNodeOfType(PRUint32 aFlags) const
 {
     return !(aFlags & ~eATTRIBUTE);
 }
 
 PRUint32
 nsDOMAttribute::GetChildCount() const
 {
-  return GetChildCount(PR_FALSE);
+  return mFirstChild ? 1 : 0;
 }
 
 nsIContent *
 nsDOMAttribute::GetChildAt(PRUint32 aIndex) const
 {
-  // Don't need to check result of EnsureChildState since mChild will be null.
-  PRBool hasChild;
-  EnsureChildState(PR_TRUE, hasChild);
-
-  return aIndex == 0 && hasChild ? mChild : nsnull;
+  return aIndex == 0 ? mFirstChild : nsnull;
 }
 
 nsIContent * const *
 nsDOMAttribute::GetChildArray(PRUint32* aChildCount) const
 {
-  *aChildCount = GetChildCount(PR_TRUE);
-  return &mChild;
+  *aChildCount = GetChildCount();
+  return &mFirstChild;
 }
 
 PRInt32
 nsDOMAttribute::IndexOf(nsINode* aPossibleChild) const
 {
-  // No need to call EnsureChildState here. If we don't already have a child
-  // then aPossibleChild can't possibly be our child.
-  if (!aPossibleChild || aPossibleChild != mChild) {
+  if (!aPossibleChild || aPossibleChild != mFirstChild) {
     return -1;
   }
 
-  PRBool hasChild;
-  EnsureChildState(PR_FALSE, hasChild);
-  return hasChild ? 0 : -1;
+  return 0;
 }
 
 nsresult
 nsDOMAttribute::InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
                               PRBool aNotify)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
@@ -654,18 +657,16 @@ nsDOMAttribute::RemoveChildAt(PRUint32 a
     mutation.mRelatedNode =
       do_QueryInterface(static_cast<nsIAttribute*>(this));
     subtree.UpdateTarget(GetOwnerDoc(), this);
     nsEventDispatcher::Dispatch(mChild, nsnull, &mutation);
   }
   if (guard.Mutated(0) && mChild != child) {
     return NS_OK;
   }
-  NS_RELEASE(mChild);
-  static_cast<nsTextNode*>(child.get())->UnbindFromAttribute();
 
   nsString nullString;
   SetDOMStringToNull(nullString);
   SetValue(nullString);
   return NS_OK;
 }
 
 nsresult
@@ -719,44 +720,62 @@ nsDOMAttribute::RemoveEventListenerByIID
 nsresult
 nsDOMAttribute::GetSystemEventGroup(nsIDOMEventGroup** aGroup)
 {
   nsIEventListenerManager* elm = GetListenerManager(PR_TRUE);
   NS_ENSURE_STATE(elm);
   return elm->GetSystemEventGroupLM(aGroup);
 }
 
-nsresult
-nsDOMAttribute::EnsureChildState(PRBool aSetText, PRBool &aHasChild) const
+void
+nsDOMAttribute::EnsureChildState()
 {
-  aHasChild = PR_FALSE;
-
-  nsDOMAttribute* mutableThis = const_cast<nsDOMAttribute*>(this);
+  NS_PRECONDITION(!mChild, "Someone screwed up");
 
   nsAutoString value;
-  mutableThis->GetValue(value);
+  GetValue(value);
+
+  if (!value.IsEmpty()) {
+    NS_NewTextNode(&mChild, mNodeInfo->NodeInfoManager());
+
+    static_cast<nsTextNode*>(mChild)->BindToAttribute(this);
+    mFirstChild = mChild;
 
-  if (!mChild && !value.IsEmpty()) {
-    nsresult rv = NS_NewTextNode(&mutableThis->mChild,
-                                 mNodeInfo->NodeInfoManager());
-    NS_ENSURE_SUCCESS(rv, rv);
+    mChild->SetText(value, PR_FALSE);
+  }
+}
 
-    static_cast<nsTextNode*>(mChild)->BindToAttribute(mutableThis);
+void
+nsDOMAttribute::AttributeChanged(nsIDocument* aDocument,
+                                 nsIContent* aContent,
+                                 PRInt32 aNameSpaceID,
+                                 nsIAtom* aAttribute,
+                                 PRInt32 aModType)
+{
+  nsIContent* content = GetContentInternal();
+  if (aContent != content) {
+    return;
   }
 
-  aHasChild = !value.IsEmpty();
-
-  if (aSetText && aHasChild) {
-    // aNotify should probably be PR_TRUE sometimes, but it's unlikely that
-    // anyone cares. And we aren't updating the node when the attribute changes
-    // anyway so any notifications are way late.
-    mChild->SetText(value, PR_FALSE);
+  if (aNameSpaceID != mNodeInfo->NamespaceID()) {
+    return;
   }
 
-  return NS_OK;
+  nsCOMPtr<nsIAtom> nameAtom = GetNameAtom(content);
+  if (nameAtom != aAttribute) {
+    return;
+  }
+
+  // Just blow away our mChild and recreate it if needed
+  if (mChild) {
+    static_cast<nsTextNode*>(mChild)->UnbindFromAttribute();
+    NS_RELEASE(mChild);
+    mFirstChild = nsnull;
+  }
+  EnsureChildState();
 }
 
 void
 nsDOMAttribute::Initialize()
 {
   sInitialized = PR_TRUE;
 }
 
--- a/content/base/src/nsDOMAttribute.h
+++ b/content/base/src/nsDOMAttribute.h
@@ -48,22 +48,24 @@
 #include "nsIDOMNodeList.h"
 #include "nsString.h"
 #include "nsCOMPtr.h"
 #include "nsINodeInfo.h"
 #include "nsIDOM3Attr.h"
 #include "nsDOMAttributeMap.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsContentUtils.h"
+#include "nsStubMutationObserver.h"
 
 // Attribute helper class used to wrap up an attribute with a dom
 // object that implements nsIDOMAttr, nsIDOM3Attr, nsIDOMNode, nsIDOM3Node
 class nsDOMAttribute : public nsIAttribute,
                        public nsIDOMAttr,
-                       public nsIDOM3Attr
+                       public nsIDOM3Attr,
+                       public nsStubMutationObserver
 {
 public:
   nsDOMAttribute(nsDOMAttributeMap* aAttrMap, nsINodeInfo *aNodeInfo,
                  const nsAString& aValue);
   virtual ~nsDOMAttribute();
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
@@ -113,36 +115,30 @@ public:
   virtual nsresult SetTextContent(const nsAString& aTextContent);
 
   static void Initialize();
   static void Shutdown();
 
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsDOMAttribute,
                                                          nsIAttribute)
 
+  NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
+
 protected:
   virtual mozilla::dom::Element* GetNameSpaceElement()
   {
     return GetContentInternal()->AsElement();
   }
 
   static PRBool sInitialized;
 
 private:
   already_AddRefed<nsIAtom> GetNameAtom(nsIContent* aContent);
 
-  nsresult EnsureChildState(PRBool aSetText, PRBool &aHasChild) const;
-
-  PRUint32 GetChildCount(PRBool aSetText) const
-  {
-    PRBool hasChild;
-    EnsureChildState(aSetText, hasChild);
-
-    return hasChild ? 1 : 0;
-  }
+  void EnsureChildState();
 
   nsString mValue;
   // XXX For now, there's only a single child - a text element
   // representing the value.  This is strong ref, but we use a raw
   // pointer so we can implement GetChildArray().
   nsIContent* mChild;
 
   nsIContent *GetContentInternal() const
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -188,16 +188,18 @@ static NS_DEFINE_CID(kDOMEventGroupCID, 
 #ifdef MOZ_SMIL
 #include "nsSMILAnimationController.h"
 #include "imgIContainer.h"
 #include "nsSVGUtils.h"
 #endif // MOZ_SMIL
 
 // FOR CSP (autogenerated by xpidl)
 #include "nsIContentSecurityPolicy.h"
+#include "nsHTMLStyleSheet.h"
+#include "nsHTMLCSSStyleSheet.h"
 
 #include "mozilla/dom/Link.h"
 using namespace mozilla::dom;
 
 
 /* Keeps track of whether or not CSP is enabled */
 static PRBool gCSPEnabled = PR_TRUE;
 
@@ -1447,17 +1449,17 @@ nsDocument::~nsDocument()
   if (mSubDocuments) {
     PL_DHashTableDestroy(mSubDocuments);
 
     mSubDocuments = nsnull;
   }
 
   // Destroy link map now so we don't waste time removing
   // links one by one
-  DestroyLinkMap();
+  DestroyElementMaps();
 
   nsAutoScriptBlocker scriptBlocker;
 
   PRInt32 indx; // must be signed
   PRUint32 count = mChildren.ChildCount();
   for (indx = PRInt32(count) - 1; indx >= 0; --indx) {
     mChildren.ChildAt(indx)->UnbindFromTree();
     mChildren.RemoveChildAt(indx);
@@ -1876,34 +1878,32 @@ nsDocument::ResetToURI(nsIURI *aURI, nsI
 #ifdef PR_LOGGING
   if (gDocumentLeakPRLog && PR_LOG_TEST(gDocumentLeakPRLog, PR_LOG_DEBUG)) {
     nsCAutoString spec;
     aURI->GetSpec(spec);
     PR_LogPrint("DOCUMENT %p ResetToURI %s", this, spec.get());
   }
 #endif
 
-  mIdentifierMap.Clear();
-
   SetPrincipal(nsnull);
   mSecurityInfo = nsnull;
 
   mDocumentLoadGroup = nsnull;
 
   // Delete references to sub-documents and kill the subdocument map,
   // if any. It holds strong references
   if (mSubDocuments) {
     PL_DHashTableDestroy(mSubDocuments);
 
     mSubDocuments = nsnull;
   }
 
   // Destroy link map now so we don't waste time removing
   // links one by one
-  DestroyLinkMap();
+  DestroyElementMaps();
 
   PRUint32 count = mChildren.ChildCount();
   { // Scope for update
     MOZ_AUTO_DOC_UPDATE(this, UPDATE_CONTENT_MODEL, PR_TRUE);    
     for (PRInt32 i = PRInt32(count) - 1; i >= 0; i--) {
       nsCOMPtr<nsIContent> content = mChildren.ChildAt(i);
 
       if (nsINode::GetFirstChild() == content) {
@@ -2327,189 +2327,70 @@ nsDocument::GetLastModified(nsAString& a
     // (or even the current time), fall back to what NS4.x returned.
     aLastModified.Assign(NS_LITERAL_STRING("01/01/1970 00:00:00"));
   }
 
   return NS_OK;
 }
 
 void
-nsDocument::UpdateNameTableEntry(Element *aElement)
+nsDocument::AddToNameTable(Element *aElement, nsIAtom* aName)
 {
   if (!mIsRegularHTML)
     return;
 
-  nsIAtom* name = nsContentUtils::IsNamedItem(aElement);
-  if (!name)
-    return;
-
-  nsIdentifierMapEntry *entry = mIdentifierMap.GetEntry(name);
-  if (!entry) {
-    // We're not tracking the elements with this name
-    return;
-  }
-
-  entry->AddNameElement(aElement);
+  nsIdentifierMapEntry *entry = mIdentifierMap.GetEntry(aName);
+
+  // entry is null if we're not tracking the elements with this name
+
+  if (entry) {
+    entry->AddNameElement(aElement);
+  }
 }
 
 void
-nsDocument::RemoveFromNameTable(Element *aElement)
-{
-  if (!mIsRegularHTML)
+nsDocument::RemoveFromNameTable(Element *aElement, nsIAtom* aName)
+{
+  // Speed up document teardown
+  if (!mIsRegularHTML || mIdentifierMap.Count() == 0)
     return;
 
-  nsIAtom* name = nsContentUtils::IsNamedItem(aElement);
-  if (!name)
+  nsIdentifierMapEntry *entry = mIdentifierMap.GetEntry(aName);
+  if (!entry) // Should never be false unless we had OOM when adding the entry
     return;
 
-  nsIdentifierMapEntry *entry = mIdentifierMap.GetEntry(name);
-  if (!entry) {
-    // We're not tracking the elements with this name
-    return;
-  }
-
   entry->RemoveNameElement(aElement);
 }
 
 void
-nsDocument::UpdateIdTableEntry(Element *aElement)
-{
-  nsIAtom* id = aElement->GetID();
-  if (!id)
-    return;
-
-  nsIdentifierMapEntry *entry = mIdentifierMap.PutEntry(id);
+nsDocument::AddToIdTable(Element *aElement, nsIAtom* aId)
+{
+  nsIdentifierMapEntry *entry = mIdentifierMap.PutEntry(aId);
 
   if (entry) { /* True except on OOM */
     entry->AddIdElement(aElement);
   }
 }
 
 void
-nsDocument::RemoveFromIdTable(Element *aElement)
-{
-  nsIAtom* id = aElement->GetID();
-  if (!id)
+nsDocument::RemoveFromIdTable(Element *aElement, nsIAtom* aId)
+{
+  NS_ASSERTION(aId, "huhwhatnow?");
+
+  // Speed up document teardown
+  if (mIdentifierMap.Count() == 0) {
     return;
-
-  nsIdentifierMapEntry *entry = mIdentifierMap.GetEntry(id);
-  if (!entry) /* Should be false unless we had OOM when adding the entry */
+  }
+
+  nsIdentifierMapEntry *entry = mIdentifierMap.GetEntry(aId);
+  if (!entry) // Can be null for XML elements with changing ids.
     return;
 
   if (entry->RemoveIdElement(aElement)) {
-    mIdentifierMap.RemoveEntry(id);
-  }
-}
-
-void
-nsDocument::UnregisterNamedItems(nsIContent *aContent)
-{
-  if (!aContent->IsElement()) {
-    // non-element nodes are not named items nor can they have children.
-    return;
-  }
-
-  RemoveFromNameTable(aContent->AsElement());
-  RemoveFromIdTable(aContent->AsElement());
-
-  for (nsINode::ChildIterator iter(aContent); !iter.IsDone(); iter.Next()) {
-    UnregisterNamedItems(iter);
-  }
-}
-
-void
-nsDocument::RegisterNamedItems(nsIContent *aContent)
-{
-  if (!aContent->IsElement()) {
-    // non-element nodes are not named items nor can they have children.
-    return;
-  }
-
-  UpdateNameTableEntry(aContent->AsElement());
-  UpdateIdTableEntry(aContent->AsElement());
-
-  for (nsINode::ChildIterator iter(aContent); !iter.IsDone(); iter.Next()) {
-    RegisterNamedItems(iter);
-  }
-}
-
-void
-nsDocument::ContentAppended(nsIDocument* aDocument,
-                            nsIContent* aContainer,
-                            nsIContent* aFirstNewContent,
-                            PRInt32 aNewIndexInContainer)
-{
-  NS_ASSERTION(aDocument == this, "unexpected doc");
-
-  for (nsINode::ChildIterator iter(aContainer, aNewIndexInContainer);
-       !iter.IsDone();
-       iter.Next()) {
-    RegisterNamedItems(iter);
-  }
-}
-
-void
-nsDocument::ContentInserted(nsIDocument* aDocument,
-                            nsIContent* aContainer,
-                            nsIContent* aContent,
-                            PRInt32 aIndexInContainer)
-{
-  NS_ASSERTION(aDocument == this, "unexpected doc");
-
-  NS_ABORT_IF_FALSE(aContent, "Null content!");
-
-  RegisterNamedItems(aContent);
-}
-
-void
-nsDocument::ContentRemoved(nsIDocument* aDocument,
-                           nsIContent* aContainer,
-                           nsIContent* aChild,
-                           PRInt32 aIndexInContainer)
-{
-  NS_ASSERTION(aDocument == this, "unexpected doc");
-
-  NS_ABORT_IF_FALSE(aChild, "Null content!");
-
-  UnregisterNamedItems(aChild);
-}
-
-void
-nsDocument::AttributeWillChange(nsIDocument* aDocument,
-                                nsIContent* aContent, PRInt32 aNameSpaceID,
-                                nsIAtom* aAttribute, PRInt32 aModType)
-{
-  NS_ABORT_IF_FALSE(aContent && aContent->IsElement(), "Null content!");
-  NS_PRECONDITION(aAttribute, "Must have an attribute that's changing!");
-
-  if (aNameSpaceID != kNameSpaceID_None)
-    return;
-  if (aAttribute == nsGkAtoms::name) {
-    RemoveFromNameTable(aContent->AsElement());
-  } else if (aAttribute == aContent->GetIDAttributeName()) {
-    RemoveFromIdTable(aContent->AsElement());
-  }
-}
-
-void
-nsDocument::AttributeChanged(nsIDocument* aDocument,
-                             nsIContent* aContent, PRInt32 aNameSpaceID,
-                             nsIAtom* aAttribute, PRInt32 aModType)
-{
-  NS_ASSERTION(aDocument == this, "unexpected doc");
-
-  NS_ABORT_IF_FALSE(aContent && aContent->IsElement(), "Null content!");
-  NS_PRECONDITION(aAttribute, "Must have an attribute that's changing!");
-
-  if (aNameSpaceID != kNameSpaceID_None)
-    return;
-  if (aAttribute == nsGkAtoms::name) {
-    UpdateNameTableEntry(aContent->AsElement());
-  } else if (aAttribute == aContent->GetIDAttributeName()) {
-    UpdateIdTableEntry(aContent->AsElement());
+    mIdentifierMap.RemoveEntry(aId);
   }
 }
 
 nsIPrincipal*
 nsDocument::GetPrincipal()
 {
   return NodePrincipal();
 }
@@ -3318,17 +3199,17 @@ nsDocument::RemoveChildAt(PRUint32 aInde
   NS_ASSERTION(aMutationEvent, "Someone tried to inhibit mutations on document child removal.");
   nsCOMPtr<nsIContent> oldKid = GetChildAt(aIndex);
   if (!oldKid) {
     return NS_OK;
   }
 
   if (oldKid->IsElement()) {
     // Destroy the link map up front before we mess with the child list.
-    DestroyLinkMap();
+    DestroyElementMaps();
   }
 
   nsresult rv =
     doRemoveChildAt(aIndex, aNotify, oldKid, mChildren, aMutationEvent);
   mCachedRootElement = nsnull;
   return rv;
 }
 
@@ -3677,22 +3558,20 @@ nsDocument::SetScriptGlobalObject(nsIScr
 
   // Remember the pointer to our window (or lack there of), to avoid
   // having to QI every time it's asked for.
   nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(mScriptGlobalObject);
   mWindow = window;
 }
 
 nsIScriptGlobalObject*
-nsDocument::GetScriptHandlingObject(PRBool& aHasHadScriptHandlingObject) const
-{
-  aHasHadScriptHandlingObject = mHasHadScriptHandlingObject;
-  if (mScriptGlobalObject) {
-    return mScriptGlobalObject;
-  }
+nsDocument::GetScriptHandlingObjectInternal() const
+{
+  NS_ASSERTION(!mScriptGlobalObject,
+               "Do not call this when mScriptGlobalObject is set!");
 
   nsCOMPtr<nsIScriptGlobalObject> scriptHandlingObject =
     do_QueryReferent(mScriptObject);
   nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(scriptHandlingObject);
   if (win) {
     NS_ASSERTION(win->IsInnerWindow(), "Should have inner window here!");
     nsPIDOMWindow* outer = win->GetOuterWindow();
     if (!outer || outer->GetCurrentInnerWindow() != win) {
@@ -3854,118 +3733,70 @@ nsDocument::CheckGetElementByIdArg(const
         EmptyString(), 0, 0,
         nsIScriptError::warningFlag,
         "DOM");
     return PR_FALSE;
   }
   return PR_TRUE;
 }
 
-nsIdentifierMapEntry*
-nsDocument::GetElementByIdInternal(nsIAtom* aID)
-{
-  // We don't have to flush before we do the initial hashtable lookup, since if
-  // the id is already in the hashtable it couldn't have been removed without
-  // us being notified (all removals notify immediately, as far as I can tell).
-  // So do the lookup first.
-  nsIdentifierMapEntry *entry = mIdentifierMap.PutEntry(aID);
-  NS_ENSURE_TRUE(entry, nsnull);
-
-  if (entry->GetIdElement())
-    return entry;
-
-  // Now we have to flush.  It could be that we know nothing about this ID yet
-  // but more content has been added to the document since.  Note that we have
-  // to flush notifications, so that the entry will get updated properly.
-
-  // Make sure to stash away the current generation so we can check whether
-  // the table changes when we flush.
-  PRUint32 generation = mIdentifierMap.GetGeneration();
-  
-  FlushPendingNotifications(Flush_ContentAndNotify);
-
-  if (generation != mIdentifierMap.GetGeneration()) {
-    // Table changed, so the entry pointer is no longer valid; look up the
-    // entry again, adding if necessary (the adding may be necessary in case
-    // the flush actually deleted entries).
-    entry = mIdentifierMap.PutEntry(aID);
-  }
-  
-  return entry;
-}
-
 Element*
-nsDocument::GetElementById(const nsAString& aElementId, nsresult *aResult)
+nsDocument::GetElementById(const nsAString& aElementId)
 {
   nsCOMPtr<nsIAtom> idAtom(do_GetAtom(aElementId));
   if (!idAtom) {
-    *aResult = NS_ERROR_OUT_OF_MEMORY;
-
+    // This can only fail due to OOM when the atom doesn't exist, in which
+    // case there can't be an entry for it.
     return nsnull;
   }
 
   if (!CheckGetElementByIdArg(idAtom)) {
-    *aResult = NS_OK;
-
     return nsnull;
   }
 
-  nsIdentifierMapEntry *entry = GetElementByIdInternal(idAtom);
-  if (!entry) {
-    *aResult = NS_ERROR_OUT_OF_MEMORY;
-
-    return nsnull;
-  }
-
-  *aResult = NS_OK;
-
-  return entry->GetIdElement();
+  nsIdentifierMapEntry *entry = mIdentifierMap.PutEntry(idAtom);
+  return entry ? entry->GetIdElement() : nsnull;
 }
 
 NS_IMETHODIMP
 nsDocument::GetElementById(const nsAString& aId, nsIDOMElement** aReturn)
 {
-  nsresult rv;
-  Element *content = GetElementById(aId, &rv);
+  Element *content = GetElementById(aId);
   if (content) {
-    rv = CallQueryInterface(content, aReturn);
-  }
-  else {
-    *aReturn = nsnull;
-  }
-
-  return rv;
+    return CallQueryInterface(content, aReturn);
+  }
+
+  *aReturn = nsnull;
+
+  return NS_OK;
 }
 
 Element*
 nsDocument::AddIDTargetObserver(nsIAtom* aID, IDTargetObserver aObserver,
                                 void* aData)
 {
   if (!CheckGetElementByIdArg(aID))
     return nsnull;
 
-  nsIdentifierMapEntry *entry = GetElementByIdInternal(aID);
+  nsIdentifierMapEntry *entry = mIdentifierMap.PutEntry(aID);
   NS_ENSURE_TRUE(entry, nsnull);
 
   entry->AddContentChangeCallback(aObserver, aData);
   return entry->GetIdElement();
 }
 
 void
 nsDocument::RemoveIDTargetObserver(nsIAtom* aID,
                                    IDTargetObserver aObserver, void* aData)
 {
   if (!CheckGetElementByIdArg(aID))
     return;
 
   nsIdentifierMapEntry *entry = mIdentifierMap.GetEntry(aID);
   if (!entry) {
-    // We don't need to do the stuff that GetElementByIdInternal does;
-    // if there's no entry already in mIdentifierMap, then there's no
-    // callback to remove.
     return;
   }
 
   entry->RemoveContentChangeCallback(aObserver, aData);
 }
 
 void
 nsDocument::DispatchContentLoadedEvents()
@@ -7375,22 +7206,23 @@ nsDocument::ForgetLink(Link* aLink)
   nsPtrHashKey<Link>* entry = mStyledLinks.GetEntry(aLink);
   NS_ASSERTION(entry || mStyledLinksCleared,
                "Document knows nothing about this Link!");
 #endif
   (void)mStyledLinks.RemoveEntry(aLink);
 }
 
 void
-nsDocument::DestroyLinkMap()
+nsDocument::DestroyElementMaps()
 {
 #ifdef DEBUG
   mStyledLinksCleared = true;
 #endif
   mStyledLinks.Clear();
+  mIdentifierMap.Clear();
 }
 
 static
 PLDHashOperator
 EnumerateStyledLinks(nsPtrHashKey<Link>* aEntry, void* aArray)
 {
   nsTArray<Link*>* array = static_cast<nsTArray<Link*>*>(aArray);
   (void)array->AppendElement(aEntry->GetKey());
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -90,23 +90,17 @@
 #include "nsTObserverArray.h"
 #include "nsStubMutationObserver.h"
 #include "nsIChannel.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsContentList.h"
 #include "nsGkAtoms.h"
 #include "nsIApplicationCache.h"
 #include "nsIApplicationCacheContainer.h"
-
-// Put these here so all document impls get them automatically
-#include "nsHTMLStyleSheet.h"
-#include "nsHTMLCSSStyleSheet.h"
-
 #include "nsStyleSet.h"
-#include "nsXMLEventsManager.h"
 #include "pldhash.h"
 #include "nsAttrAndChildArray.h"
 #include "nsDOMAttributeMap.h"
 #include "nsContentUtils.h"
 #include "nsThreadUtils.h"
 #include "nsIDocumentViewer.h"
 #include "nsIDOMXPathNSResolver.h"
 #include "nsIInterfaceRequestor.h"
@@ -130,16 +124,19 @@ class nsIOutputStream;
 class nsDocument;
 class nsIDTD;
 class nsIRadioVisitor;
 class nsIFormControl;
 struct nsRadioGroupStruct;
 class nsOnloadBlocker;
 class nsUnblockOnloadEvent;
 class nsChildContentList;
+class nsXMLEventsManager;
+class nsHTMLStyleSheet;
+class nsHTMLCSSStyleSheet;
 
 /**
  * Right now our identifier map entries contain information for 'name'
  * and 'id' mappings of a given string. This is so that
  * nsHTMLDocument::ResolveName only has to do one hash lookup instead
  * of two. It's not clear whether this still matters for performance.
  * 
  * We also store the document.all result list here. This is mainly so that
@@ -639,28 +636,37 @@ public:
   /**
    * Set the object from which a document can get a script context.
    * This is the context within which all scripts (during document
    * creation and during event handling) will run.
    */
   virtual nsIScriptGlobalObject* GetScriptGlobalObject() const;
   virtual void SetScriptGlobalObject(nsIScriptGlobalObject* aGlobalObject);
 
-  virtual nsIScriptGlobalObject*
-    GetScriptHandlingObject(PRBool& aHasHadScriptHandlingObject) const;
   virtual void SetScriptHandlingObject(nsIScriptGlobalObject* aScriptObject);
 
   virtual nsIScriptGlobalObject* GetScopeObject();
 
   /**
    * Get the script loader for this document
    */
   virtual nsScriptLoader* ScriptLoader();
 
   /**
+   * Add/Remove an element to the document's id and name hashes
+   */
+  virtual void AddToIdTable(mozilla::dom::Element* aElement, nsIAtom* aId);
+  virtual void RemoveFromIdTable(mozilla::dom::Element* aElement,
+                                 nsIAtom* aId);
+  virtual void AddToNameTable(mozilla::dom::Element* aElement,
+                              nsIAtom* aName);
+  virtual void RemoveFromNameTable(mozilla::dom::Element* aElement,
+                                   nsIAtom* aName);
+
+  /**
    * Add a new observer of document change notifications. Whenever
    * content is changed, appended, inserted or removed the observers are
    * informed.
    */
   virtual void AddObserver(nsIDocumentObserver* aObserver);
 
   /**
    * Remove an observer of document change notifications. This will
@@ -807,23 +813,16 @@ public:
   NS_DECL_NSIDOMEVENTTARGET
 
   // nsIDOM3EventTarget
   NS_DECL_NSIDOM3EVENTTARGET
 
   // nsIDOMNSEventTarget
   NS_DECL_NSIDOMNSEVENTTARGET
 
-  // nsIMutationObserver
-  NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
-  NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
-  NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
-  NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
-  NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTEWILLCHANGE
-
   // nsIScriptObjectPrincipal
   virtual nsIPrincipal* GetPrincipal();
 
   // nsIApplicationCacheContainer
   NS_DECL_NSIAPPLICATIONCACHECONTAINER
 
   virtual nsresult Init();
   
@@ -937,27 +936,20 @@ public:
   virtual void SetChangeScrollPosWhenScrollingToRef(PRBool aValue);
 
   already_AddRefed<nsContentList>
     GetElementsByTagName(const nsAString& aTagName);
   already_AddRefed<nsContentList>
     GetElementsByTagNameNS(const nsAString& aNamespaceURI,
                            const nsAString& aLocalName);
 
-  virtual mozilla::dom::Element *GetElementById(const nsAString& aElementId,
-                                                nsresult *aResult);
+  virtual mozilla::dom::Element *GetElementById(const nsAString& aElementId);
 
 protected:
   friend class nsNodeUtils;
-  void RegisterNamedItems(nsIContent *aContent);
-  void UnregisterNamedItems(nsIContent *aContent);
-  void UpdateNameTableEntry(Element *aElement);
-  void UpdateIdTableEntry(Element *aElement);
-  void RemoveFromNameTable(Element *aElement);
-  void RemoveFromIdTable(Element *aElement);
 
   /**
    * Check that aId is not empty and log a message to the console
    * service if it is.
    * @returns PR_TRUE if aId looks correct, PR_FALSE otherwise.
    */
   static PRBool CheckGetElementByIdArg(const nsIAtom* aId);
   nsIdentifierMapEntry* GetElementByIdInternal(nsIAtom* aID);
@@ -966,18 +958,18 @@ protected:
 
   void RetrieveRelevantHeaders(nsIChannel *aChannel);
 
   static PRBool TryChannelCharset(nsIChannel *aChannel,
                                   PRInt32& aCharsetSource,
                                   nsACString& aCharset);
 
   // Call this before the document does something that will unbind all content.
-  // That will stop us from resolving URIs for all links as they are removed.
-  void DestroyLinkMap();
+  // That will stop us from doing a lot of work as each element is removed.
+  void DestroyElementMaps();
 
   // Refreshes the hrefs of all the links in the document.
   void RefreshLinkHrefs();
 
   nsIContent* GetFirstBaseNodeWithHref();
   nsresult SetFirstBaseNodeWithHref(nsIContent *node);
 
   // Get the first <title> element with the given IsNodeOfType type, or
@@ -1006,16 +998,17 @@ protected:
   }
 
   void DispatchPageTransition(nsPIDOMEventTarget* aDispatchTarget,
                               const nsAString& aType,
                               PRBool aPersisted);
 
   virtual nsPIDOMWindow *GetWindowInternal();
   virtual nsPIDOMWindow *GetInnerWindowInternal();
+  virtual nsIScriptGlobalObject* GetScriptHandlingObjectInternal() const;
 
 #define NS_DOCUMENT_NOTIFY_OBSERVERS(func_, params_)                  \
   NS_OBSERVER_ARRAY_NOTIFY_OBSERVERS(mObservers, nsIDocumentObserver, \
                                      func_, params_);
   
 #ifdef DEBUG
   void VerifyRootContentState();
 #endif
@@ -1045,21 +1038,16 @@ protected:
   nsWeakPtr mWeakSink;
 
   nsCOMArray<nsIStyleSheet> mStyleSheets;
   nsCOMArray<nsIStyleSheet> mCatalogSheets;
 
   // Array of observers
   nsTObserverArray<nsIDocumentObserver*> mObservers;
 
-  // The document's script global object, the object from which the
-  // document can get its script context and scope. This is the
-  // *inner* window object.
-  nsCOMPtr<nsIScriptGlobalObject> mScriptGlobalObject;
-
   // If document is created for example using
   // document.implementation.createDocument(...), mScriptObject points to
   // the script global object of the original document.
   nsWeakPtr mScriptObject;
 
   // Weak reference to the scope object (aka the script global object)
   // that, unlike mScriptGlobalObject, is never unset once set. This
   // is a weak reference to avoid leaks due to circular references.
@@ -1080,18 +1068,16 @@ protected:
   nsTHashtable<nsIdentifierMapEntry> mIdentifierMap;
 
   nsClassHashtable<nsStringHashKey, nsRadioGroupStruct> mRadioGroups;
 
   // True if the document has been detached from its content viewer.
   PRPackedBool mIsGoingAway:1;
   // True if the document is being destroyed.
   PRPackedBool mInDestructor:1;
-  // True if document has ever had script handling object.
-  PRPackedBool mHasHadScriptHandlingObject:1;
 
   // True if this document has ever had an HTML or SVG <title> element
   // bound to it
   PRPackedBool mMayHaveTitleElement:1;
 
   PRPackedBool mHasWarnedAboutBoxObjects:1;
 
   PRPackedBool mDelayFrameLoaderInitialization:1;
--- a/content/base/src/nsDocumentEncoder.cpp
+++ b/content/base/src/nsDocumentEncoder.cpp
@@ -16,16 +16,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):
  *   Pierre Phaneuf <pp@ludusdesign.com>
+ *   Mats Palmgren <matpal@gmail.com>
  *
  * 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
@@ -45,17 +46,16 @@
 
 #include "nscore.h"
 #include "nsIFactory.h"
 #include "nsISupports.h"
 #include "nsIComponentManager.h" 
 #include "nsIServiceManager.h"
 #include "nsIDocument.h"
 #include "nsIHTMLDocument.h"
-#include "nsISelection.h"
 #include "nsCOMPtr.h"
 #include "nsIContentSerializer.h"
 #include "nsIUnicodeEncoder.h"
 #include "nsIOutputStream.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMText.h"
 #include "nsIDOMCDATASection.h"
 #include "nsIDOMComment.h"
@@ -64,21 +64,23 @@
 #include "nsIDOMNodeList.h"
 #include "nsIRange.h"
 #include "nsIDOMRange.h"
 #include "nsIDOMDocument.h"
 #include "nsICharsetConverterManager.h"
 #include "nsGkAtoms.h"
 #include "nsIContent.h"
 #include "nsIEnumerator.h"
-#include "nsISelectionPrivate.h"
 #include "nsIParserService.h"
 #include "nsIScriptContext.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIScriptSecurityManager.h"
+#include "nsISelection.h"
+#include "nsISelectionPrivate.h"
+#include "nsITransferable.h" // for kUnicodeMime
 #include "nsContentUtils.h"
 #include "nsUnicharUtils.h"
 #include "nsReadableUtils.h"
 #include "nsTArray.h"
 #include "nsIFrame.h"
 
 nsresult NS_NewDomSelection(nsISelection **aDomSelection);
 
@@ -114,16 +116,39 @@ protected:
                                PRInt32 aDepth);
   nsresult SerializeRangeContextStart(const nsTArray<nsINode*>& aAncestorArray,
                                       nsAString& aString);
   nsresult SerializeRangeContextEnd(const nsTArray<nsINode*>& aAncestorArray,
                                     nsAString& aString);
 
   nsresult FlushText(nsAString& aString, PRBool aForce);
 
+  PRBool IsVisibleNode(nsINode* aNode)
+  {
+    NS_PRECONDITION(aNode, "");
+
+    if (mFlags & SkipInvisibleContent) {
+      nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
+      if (content) {
+        nsIFrame* frame = content->GetPrimaryFrame();
+        if (!frame) {
+          if (aNode->IsNodeOfType(nsINode::eTEXT)) {
+            // We have already checked that our parent is visible.
+            return PR_TRUE;
+          }
+          return PR_FALSE;
+        }
+        PRBool isVisible = frame->GetStyleVisibility()->IsVisible();
+        if (!isVisible && aNode->IsNodeOfType(nsINode::eTEXT))
+          return PR_FALSE;
+      }
+    }
+    return PR_TRUE;
+  }
+
   static PRBool IsTag(nsIContent* aContent, nsIAtom* aAtom);
   
   virtual PRBool IncludeInContext(nsINode *aNode);
 
   nsCOMPtr<nsIDocument>          mDocument;
   nsCOMPtr<nsISelection>         mSelection;
   nsCOMPtr<nsIRange>             mRange;
   nsCOMPtr<nsINode>              mNode;
@@ -264,18 +289,19 @@ nsDocumentEncoder::IncludeInContext(nsIN
 
 nsresult
 nsDocumentEncoder::SerializeNodeStart(nsINode* aNode,
                                       PRInt32 aStartOffset,
                                       PRInt32 aEndOffset,
                                       nsAString& aStr,
                                       nsINode* aOriginalNode)
 {
-  PRUint16 type;
-
+  if (!IsVisibleNode(aNode))
+    return NS_OK;
+  
   nsINode* node = nsnull;
   nsCOMPtr<nsINode> fixedNodeKungfuDeathGrip;
 
   // Caller didn't do fixup, so we'll do it ourselves
   if (!aOriginalNode) {
     aOriginalNode = aNode;
     if (mNodeFixup) { 
       PRBool dummy;
@@ -287,16 +313,17 @@ nsDocumentEncoder::SerializeNodeStart(ns
     }
   }
 
   // Either there was no fixed-up node,
   // or the caller did fixup themselves and aNode is already fixed
   if (!node)
     node = aNode;
 
+  PRUint16 type;
   node->GetNodeType(&type);
   switch (type) {
     case nsIDOMNode::ELEMENT_NODE:
     {
       nsIContent* originalElement =
         aOriginalNode && aOriginalNode->IsElement() ?
           static_cast<nsIContent*>(aOriginalNode) : nsnull;
       mSerializer->AppendElementStart(static_cast<nsIContent*>(node),
@@ -336,27 +363,33 @@ nsDocumentEncoder::SerializeNodeStart(ns
 
   return NS_OK;
 }
 
 nsresult
 nsDocumentEncoder::SerializeNodeEnd(nsINode* aNode,
                                     nsAString& aStr)
 {
+  if (!IsVisibleNode(aNode))
+    return NS_OK;
+
   if (aNode->IsElement()) {
     mSerializer->AppendElementEnd(static_cast<nsIContent*>(aNode), aStr);
   }
   return NS_OK;
 }
 
 nsresult
 nsDocumentEncoder::SerializeToStringRecursive(nsINode* aNode,
                                               nsAString& aStr,
                                               PRBool aDontSerializeRoot)
 {
+  if (!IsVisibleNode(aNode))
+    return NS_OK;
+
   nsresult rv = NS_OK;
   PRBool serializeClonedChildren = PR_FALSE;
   nsINode* maybeFixedNode = nsnull;
 
   // Keep the node from FixupNode alive.
   nsCOMPtr<nsINode> fixedNodeKungfuDeathGrip;
   if (mNodeFixup) {
     nsCOMPtr<nsIDOMNode> domNodeIn = do_QueryInterface(aNode);
@@ -364,17 +397,17 @@ nsDocumentEncoder::SerializeToStringRecu
     mNodeFixup->FixupNode(domNodeIn, &serializeClonedChildren, getter_AddRefs(domNodeOut));
     fixedNodeKungfuDeathGrip = do_QueryInterface(domNodeOut);
     maybeFixedNode = fixedNodeKungfuDeathGrip;
   }
 
   if (!maybeFixedNode)
     maybeFixedNode = aNode;
 
-  if (mIsCopying) {
+  if (mFlags & SkipInvisibleContent) {
     if (aNode->IsNodeOfType(nsINode::eCONTENT)) {
       nsIFrame* frame = static_cast<nsIContent*>(aNode)->GetPrimaryFrame();
       if (frame) {
         PRBool isSelectable;
         frame->IsSelectable(&isSelectable, nsnull);
         if (!isSelectable){
           aDontSerializeRoot = PR_TRUE;
         }
@@ -651,29 +684,34 @@ nsresult
 nsDocumentEncoder::SerializeRangeNodes(nsIRange* aRange,
                                        nsINode* aNode,
                                        nsAString& aString,
                                        PRInt32 aDepth)
 {
   nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
   NS_ENSURE_TRUE(content, NS_ERROR_FAILURE);
 
-  nsresult rv=NS_OK;
-  
+  if (!IsVisibleNode(aNode))
+    return NS_OK;
+
+  nsresult rv = NS_OK;
+
   // get start and end nodes for this recursion level
   nsCOMPtr<nsIContent> startNode, endNode;
-  PRInt32 start = mStartRootIndex - aDepth;
-  if (start >= 0 && (PRUint32)start <= mStartNodes.Length())
-    startNode = mStartNodes[start];
+  {
+    PRInt32 start = mStartRootIndex - aDepth;
+    if (start >= 0 && (PRUint32)start <= mStartNodes.Length())
+      startNode = mStartNodes[start];
 
-  PRInt32 end = mEndRootIndex - aDepth;
-  if (end >= 0 && (PRUint32)end <= mEndNodes.Length())
-    endNode = mEndNodes[end];
+    PRInt32 end = mEndRootIndex - aDepth;
+    if (end >= 0 && (PRUint32)end <= mEndNodes.Length())
+      endNode = mEndNodes[end];
+  }
 
-  if ((startNode != content) && (endNode != content))
+  if (startNode != content && endNode != content)
   {
     // node is completely contained in range.  Serialize the whole subtree
     // rooted by this node.
     rv = SerializeToStringRecursive(aNode, aString, PR_FALSE);
     NS_ENSURE_SUCCESS(rv, rv);
   }
   else
   {
@@ -853,16 +891,26 @@ nsDocumentEncoder::SerializeRangeToStrin
   
   nsresult rv = NS_OK;
 
   rv = SerializeRangeContextStart(mCommonAncestors, aOutputString);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if ((startParent == endParent) && IsTextNode(startParent))
   {
+    if (mFlags & SkipInvisibleContent) {
+      // Check that the parent is visible if we don't a frame.
+      // IsVisibleNode() will do it when there's a frame.
+      nsCOMPtr<nsIContent> content = do_QueryInterface(startParent);
+      if (content && !content->GetPrimaryFrame()) {
+        nsIContent* parent = content->GetParent();
+        if (!parent || !IsVisibleNode(parent))
+          return NS_OK;
+      }
+    }
     rv = SerializeNodeStart(startParent, startOffset, endOffset, aOutputString);
     NS_ENSURE_SUCCESS(rv, rv);
   }
   else
   {
     rv = SerializeRangeNodes(aRange, mCommonParent, aOutputString, 0);
     NS_ENSURE_SUCCESS(rv, rv);
   }
@@ -1075,31 +1123,31 @@ nsHTMLCopyEncoder::nsHTMLCopyEncoder()
 }
 
 nsHTMLCopyEncoder::~nsHTMLCopyEncoder()
 {
 }
 
 NS_IMETHODIMP
 nsHTMLCopyEncoder::Init(nsIDOMDocument* aDocument,
-                        const nsAString& aMimetype,
+                        const nsAString& aMimeType,
                         PRUint32 aFlags)
 {
   if (!aDocument)
     return NS_ERROR_INVALID_ARG;
 
   mIsTextWidget = PR_FALSE;
   Initialize();
 
   mIsCopying = PR_TRUE;
   mDocument = do_QueryInterface(aDocument);
   NS_ENSURE_TRUE(mDocument, NS_ERROR_FAILURE);
 
   mMimeType.AssignLiteral("text/html");
-  
+
   // Make all links absolute when copying
   // (see related bugs #57296, #41924, #58646, #32768)
   mFlags = aFlags | OutputAbsoluteLinks;
 
   if (!mDocument->IsScriptEnabled())
     mFlags |= OutputNoScriptContent;
 
   return NS_OK;
--- a/content/base/src/nsDocumentFragment.cpp
+++ b/content/base/src/nsDocumentFragment.cpp
@@ -149,16 +149,19 @@ public:
   }
   virtual const nsAttrName* GetAttrNameAt(PRUint32 aIndex) const
   {
     return nsnull;
   }
 
   virtual PRBool IsNodeOfType(PRUint32 aFlags) const;
 
+  virtual nsIAtom* DoGetID() const;
+  virtual nsIAtom *GetIDAttributeName() const;
+
 protected:
   nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 };
 
 nsresult
 NS_NewDocumentFragment(nsIDOMDocumentFragment** aInstancePtrResult,
                        nsNodeInfoManager *aNodeInfoManager)
 {
@@ -190,16 +193,28 @@ nsDocumentFragment::~nsDocumentFragment(
 }
 
 PRBool
 nsDocumentFragment::IsNodeOfType(PRUint32 aFlags) const
 {
   return !(aFlags & ~(eCONTENT | eDOCUMENT_FRAGMENT));
 }
 
+nsIAtom*
+nsDocumentFragment::DoGetID() const
+{
+  return nsnull;  
+}
+
+nsIAtom*
+nsDocumentFragment::GetIDAttributeName() const
+{
+  return nsnull;
+}
+
 DOMCI_DATA(DocumentFragment, nsDocumentFragment)
 
 // QueryInterface implementation for nsDocumentFragment
 NS_INTERFACE_TABLE_HEAD(nsDocumentFragment)
   NS_NODE_INTERFACE_TABLE2(nsDocumentFragment, nsIDOMNode,
                            nsIDOMDocumentFragment)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DocumentFragment)
 NS_INTERFACE_MAP_END_INHERITING(nsGenericElement)
--- a/content/base/src/nsFormData.h
+++ b/content/base/src/nsFormData.h
@@ -34,17 +34,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsFormData_h__
 #define nsFormData_h__
 
 #include "nsIDOMFormData.h"
 #include "nsIXMLHttpRequest.h"
-#include "nsIFormSubmission.h"
+#include "nsFormSubmission.h"
 #include "nsTArray.h"
 
 class nsFormData : public nsIDOMFormData,
                    public nsIXHRSendable,
                    public nsFormSubmission
 {
 public:
   nsFormData();
--- a/content/base/src/nsFrameLoader.cpp
+++ b/content/base/src/nsFrameLoader.cpp
@@ -84,16 +84,17 @@
 
 #include "nsGkAtoms.h"
 #include "nsINameSpaceManager.h"
 
 #include "nsThreadUtils.h"
 #include "nsIContentViewer.h"
 #include "nsIDOMChromeWindow.h"
 #include "nsInProcessTabChildGlobal.h"
+#include "mozilla/AutoRestore.h"
 
 class nsAsyncDocShellDestroyer : public nsRunnable
 {
 public:
   nsAsyncDocShellDestroyer(nsIDocShell* aDocShell)
     : mDocShell(aDocShell)
   {
   }
@@ -509,35 +510,60 @@ AllDescendantsOfType(nsIDocShellTreeItem
     if (kidType != aType || !AllDescendantsOfType(kid, aType)) {
       return PR_FALSE;
     }
   }
 
   return PR_TRUE;
 }
 
-bool
+/**
+ * A class that automatically sets mInShow to false when it goes
+ * out of scope.
+ */
+class NS_STACK_CLASS AutoResetInShow {
+  private:
+    nsFrameLoader* mFrameLoader;
+    MOZILLA_DECL_USE_GUARD_OBJECT_NOTIFIER
+  public:
+    AutoResetInShow(nsFrameLoader* aFrameLoader MOZILLA_GUARD_OBJECT_NOTIFIER_PARAM)
+      : mFrameLoader(aFrameLoader)
+    {
+      MOZILLA_GUARD_OBJECT_NOTIFIER_INIT;
+    }
+    ~AutoResetInShow() { mFrameLoader->mInShow = PR_FALSE; }
+};
+
+
+PRBool
 nsFrameLoader::Show(PRInt32 marginWidth, PRInt32 marginHeight,
                     PRInt32 scrollbarPrefX, PRInt32 scrollbarPrefY,
                     nsIFrameFrame* frame)
 {
+  if (mInShow) {
+    return PR_FALSE;
+  }
+  // Reset mInShow if we exit early.
+  AutoResetInShow resetInShow(this);
+  mInShow = PR_TRUE;
+
   nsContentType contentType;
 
   nsresult rv = EnsureDocShell();
   if (NS_FAILED(rv)) {
-    return false;
+    return PR_FALSE;
   }
 
   if (!mDocShell)
-    return false;
+    return PR_FALSE;
 
   nsCOMPtr<nsIPresShell> presShell;
   mDocShell->GetPresShell(getter_AddRefs(presShell));
   if (presShell)
-    return true;
+    return PR_TRUE;
 
   mDocShell->SetMarginWidth(marginWidth);
   mDocShell->SetMarginHeight(marginHeight);
 
   nsCOMPtr<nsIScrollable> sc = do_QueryInterface(mDocShell);
   if (sc) {
     sc->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_X,
                                        scrollbarPrefX);
@@ -558,17 +584,17 @@ nsFrameLoader::Show(PRInt32 marginWidth,
   else {
     nsCOMPtr<nsIDocShellTreeItem> sameTypeParent;
     treeItem->GetSameTypeParent(getter_AddRefs(sameTypeParent));
     contentType = sameTypeParent ? eContentTypeContentFrame : eContentTypeContent;
   }
 
   nsIView* view = frame->CreateViewAndWidget(contentType);
   if (!view)
-    return false;
+    return PR_FALSE;
 
   nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(mDocShell);
   NS_ASSERTION(baseWindow, "Found a nsIDocShell that isn't a nsIBaseWindow.");
   baseWindow->InitWindow(nsnull, view->GetWidget(), 0, 0, 10, 10);
   // This is kinda whacky, this "Create()" call doesn't really
   // create anything, one starts to wonder why this was named
   // "Create"...
   baseWindow->Create();
@@ -589,22 +615,36 @@ nsFrameLoader::Show(PRInt32 marginWidth,
 
       if (designMode.EqualsLiteral("on")) {
         doc->SetDesignMode(NS_LITERAL_STRING("off"));
         doc->SetDesignMode(NS_LITERAL_STRING("on"));
       }
     }
   }
 
-  return true;
+  mInShow = PR_FALSE;
+  if (mHideCalled) {
+    mHideCalled = PR_FALSE;
+    Hide();
+    return PR_FALSE;
+  }
+  return PR_TRUE;
 }
 
 void
 nsFrameLoader::Hide()
 {
+  if (mHideCalled) {
+    return;
+  }
+  if (mInShow) {
+    mHideCalled = PR_TRUE;
+    return;
+  }
+
   if (!mDocShell)
     return;
 
   nsCOMPtr<nsIContentViewer> contentViewer;
   mDocShell->GetContentViewer(getter_AddRefs(contentViewer));
   if (contentViewer)
     contentViewer->SetSticky(PR_FALSE);
 
@@ -618,16 +658,17 @@ nsFrameLoader::Hide()
 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?");
+  NS_ENSURE_STATE(!mInShow && !aOther->mInShow);
 
   nsIContent* ourContent = mOwnerContent;
   nsIContent* otherContent = aOther->mOwnerContent;
 
   if (!ourContent || !otherContent) {
     // Can't handle this
     return NS_ERROR_NOT_IMPLEMENTED;
   }
--- a/content/base/src/nsFrameLoader.h
+++ b/content/base/src/nsFrameLoader.h
@@ -49,27 +49,32 @@
 #include "nsIFrameLoader.h"
 #include "nsIURI.h"
 #include "nsFrameMessageManager.h"
 
 class nsIContent;
 class nsIURI;
 class nsIFrameFrame;
 class nsIInProcessContentFrameMessageManager;
+class AutoResetInShow;
 
 class nsFrameLoader : public nsIFrameLoader
 {
+  friend class AutoResetInShow;
+
 protected:
   nsFrameLoader(nsIContent *aOwner) :
     mOwnerContent(aOwner),
     mDepthTooGreat(PR_FALSE),
     mIsTopLevelContent(PR_FALSE),
     mDestroyCalled(PR_FALSE),
     mNeedsAsyncDestroy(PR_FALSE),
-    mInSwap(PR_FALSE)
+    mInSwap(PR_FALSE),
+    mInShow(PR_FALSE),
+    mHideCalled(PR_FALSE)
   {}
 
 public:
   ~nsFrameLoader() {
     mNeedsAsyncDestroy = PR_TRUE;
     nsFrameLoader::Destroy();
   }
 
@@ -84,19 +89,19 @@ public:
   nsIDocShell* GetExistingDocShell() { return mDocShell; }
   nsPIDOMEventTarget* GetTabChildGlobalAsEventTarget();
   nsresult CreateStaticClone(nsIFrameLoader* aDest);
 
   /**
    * Called from the layout frame associated with this frame loader;
    * this notifies us to hook up with the widget and view.
    */
-  bool Show(PRInt32 marginWidth, PRInt32 marginHeight,
-            PRInt32 scrollbarPrefX, PRInt32 scrollbarPrefY,
-            nsIFrameFrame* frame);
+  PRBool Show(PRInt32 marginWidth, PRInt32 marginHeight,
+              PRInt32 scrollbarPrefX, PRInt32 scrollbarPrefY,
+              nsIFrameFrame* frame);
 
   /**
    * Called from the layout frame associated with this frame loader, when
    * the frame is being torn down; this notifies us that out widget and view
    * are going away and we should unhook from them.
    */
   void Hide();
 
@@ -125,11 +130,13 @@ public:
   nsRefPtr<nsFrameMessageManager> mMessageManager;
   nsCOMPtr<nsIInProcessContentFrameMessageManager> mChildMessageManager;
 private:
   PRPackedBool mDepthTooGreat : 1;
   PRPackedBool mIsTopLevelContent : 1;
   PRPackedBool mDestroyCalled : 1;
   PRPackedBool mNeedsAsyncDestroy : 1;
   PRPackedBool mInSwap : 1;
+  PRPackedBool mInShow : 1;
+  PRPackedBool mHideCalled : 1;
 };
 
 #endif
--- a/content/base/src/nsGenericDOMDataNode.cpp
+++ b/content/base/src/nsGenericDOMDataNode.cpp
@@ -560,17 +560,17 @@ nsGenericDOMDataNode::UnbindFromTree(PRB
   UnsetFlags(NS_CREATE_FRAME_IF_NON_WHITESPACE |
              NS_REFRAME_IF_WHITESPACE);
   
   nsIDocument *document = GetCurrentDoc();
   if (document) {
     // Notify XBL- & nsIAnonymousContentCreator-generated
     // anonymous content that the document is changing.
     // This is needed to update the insertion point.
-    document->BindingManager()->ChangeDocumentFor(this, document, nsnull);
+    document->BindingManager()->RemovedFromDocument(this, document);
   }
 
   mParentPtrBits = aNullParent ? 0 : mParentPtrBits & ~PARENT_BIT_INDOCUMENT;
 
   nsDataSlots *slots = GetExistingDataSlots();
   if (slots) {
     slots->mBindingParent = nsnull;
   }
@@ -1103,17 +1103,17 @@ already_AddRefed<nsIAtom>
 nsGenericDOMDataNode::GetCurrentValueAtom()
 {
   nsAutoString val;
   GetData(val);
   return NS_NewAtom(val);
 }
 
 nsIAtom*
-nsGenericDOMDataNode::GetID() const
+nsGenericDOMDataNode::DoGetID() const
 {
   return nsnull;
 }
 
 const nsAttrValue*
 nsGenericDOMDataNode::DoGetClasses() const
 {
   NS_NOTREACHED("Shouldn't ever be called");
--- a/content/base/src/nsGenericDOMDataNode.h
+++ b/content/base/src/nsGenericDOMDataNode.h
@@ -243,17 +243,17 @@ public:
 #endif
 
   virtual nsIContent *GetBindingParent() const;
   virtual PRBool IsNodeOfType(PRUint32 aFlags) const;
 
   virtual already_AddRefed<nsIURI> GetBaseURI() const;
   virtual PRBool IsLink(nsIURI** aURI) const;
 
-  virtual nsIAtom* GetID() const;
+  virtual nsIAtom* DoGetID() const;
   virtual const nsAttrValue* DoGetClasses() const;
   NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker);
   virtual nsICSSStyleRule* GetInlineStyleRule();
   NS_IMETHOD SetInlineStyleRule(nsICSSStyleRule* aStyleRule, PRBool aNotify);
   NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const;
   virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
                                               PRInt32 aModType) const;
   virtual nsIAtom *GetClassAttributeName() const;
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -509,27 +509,27 @@ nsINode::GetLastChild(nsIDOMNode** aNode
   return NS_OK;
 }
 
 nsresult
 nsINode::GetPreviousSibling(nsIDOMNode** aPrevSibling)
 {
   *aPrevSibling = nsnull;
 
-  nsIContent *sibling = GetSibling(-1);
+  nsIContent *sibling = GetPreviousSibling();
 
   return sibling ? CallQueryInterface(sibling, aPrevSibling) : NS_OK;
 }
 
 nsresult
 nsINode::GetNextSibling(nsIDOMNode** aNextSibling)
 {
   *aNextSibling = nsnull;
 
-  nsIContent *sibling = GetSibling(1);
+  nsIContent *sibling = GetNextSibling();
 
   return sibling ? CallQueryInterface(sibling, aNextSibling) : NS_OK;
 }
 
 nsresult
 nsINode::GetOwnerDocument(nsIDOMDocument** aOwnerDocument)
 {
   *aOwnerDocument = nsnull;
@@ -2964,17 +2964,17 @@ nsGenericElement::UnbindFromTree(PRBool 
   nsIDocument *document =
     HasFlag(NODE_FORCE_XBL_BINDINGS) ? GetOwnerDoc() : GetCurrentDoc();
 
   mParentPtrBits = aNullParent ? 0 : mParentPtrBits & ~PARENT_BIT_INDOCUMENT;
 
   if (document) {
     // Notify XBL- & nsIAnonymousContentCreator-generated
     // anonymous content that the document is changing.
-    document->BindingManager()->ChangeDocumentFor(this, document, nsnull);
+    document->BindingManager()->RemovedFromDocument(this, document);
 
     document->ClearBoxObjectFor(this);
   }
 
   // Ensure that CSS transitions don't continue on an element at a
   // different place in the tree (even if reinserted before next
   // animation refresh).
   // FIXME (Bug 522599): Need a test for this.
@@ -3244,48 +3244,16 @@ nsGenericElement::DispatchDOMEvent(nsEve
                                    nsPresContext* aPresContext,
                                    nsEventStatus* aEventStatus)
 {
   return nsEventDispatcher::DispatchDOMEvent(static_cast<nsIContent*>(this),
                                              aEvent, aDOMEvent,
                                              aPresContext, aEventStatus);
 }
 
-nsIAtom*
-nsGenericElement::GetID() const
-{
-  if (!HasFlag(NODE_MAY_HAVE_ID)) {
-    return nsnull;
-  }
-
-  nsIAtom* IDName = GetIDAttributeName();
-  if (IDName) {
-    const nsAttrValue* attrVal = mAttrsAndChildren.GetAttr(IDName);
-    if (attrVal){
-      if (attrVal->Type() == nsAttrValue::eAtom) {
-        return attrVal->GetAtomValue();
-      }
-      if(attrVal->IsEmptyString()){
-        return nsnull;
-      }
-      // Check if the ID has been stored as a string.
-      // This would occur if the ID attribute name changed after 
-      // the ID was parsed. 
-      if (attrVal->Type() == nsAttrValue::eString) {
-        nsAutoString idVal(attrVal->GetStringValue());
-
-        // Create an atom from the value and set it into the attribute list. 
-        const_cast<nsAttrValue*>(attrVal)->ParseAtom(idVal);
-        return attrVal->GetAtomValue();
-      }
-    }
-  }
-  return nsnull;
-}
-
 const nsAttrValue*
 nsGenericElement::DoGetClasses() const
 {
   NS_NOTREACHED("Shouldn't ever be called");
   return nsnull;
 }
 
 NS_IMETHODIMP
@@ -3367,22 +3335,16 @@ nsGenericElement::IsAttributeMapped(cons
 nsChangeHint
 nsGenericElement::GetAttributeChangeHint(const nsIAtom* aAttribute,
                                          PRInt32 aModType) const
 {
   return nsChangeHint(0);
 }
 
 nsIAtom *
-nsGenericElement::GetIDAttributeName() const
-{
-  return mNodeInfo->GetIDAttributeAtom();
-}
-
-nsIAtom *
 nsGenericElement::GetClassAttributeName() const
 {
   return nsnull;
 }
 
 PRBool
 nsGenericElement::FindAttributeDependence(const nsIAtom* aAttribute,
                                           const MappedAttributeEntry* const aMaps[],
@@ -3799,17 +3761,17 @@ nsGenericElement::GetPrimaryFrame(mozFlu
   return GetPrimaryFrame();
 }
 
 void
 nsGenericElement::DestroyContent()
 {
   nsIDocument *document = GetOwnerDoc();
   if (document) {
-    document->BindingManager()->ChangeDocumentFor(this, document, nsnull);
+    document->BindingManager()->RemovedFromDocument(this, document);
     document->ClearBoxObjectFor(this);
   }
 
   // XXX We really should let cycle collection do this, but that currently still
   //     leaks (see https://bugzilla.mozilla.org/show_bug.cgi?id=406684).
   nsContentUtils::ReleaseWrapper(this, this);
 
   PRUint32 i, count = mAttrsAndChildren.ChildCount();
@@ -4360,19 +4322,18 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
       if (tmp->IsXUL())
         NS_IF_RELEASE(slots->mControllers);
       slots->mChildrenList = nsnull;
     }
   }
 
   {
     nsIDocument *doc;
-    if (!tmp->GetNodeParent() && (doc = tmp->GetOwnerDoc()) &&
-        tmp->HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
-      doc->BindingManager()->ChangeDocumentFor(tmp, doc, nsnull);
+    if (!tmp->GetNodeParent() && (doc = tmp->GetOwnerDoc())) {
+      doc->BindingManager()->RemovedFromDocument(tmp, doc);
     }
   }
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsGenericElement)
   NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
@@ -4728,25 +4689,16 @@ nsGenericElement::SetAttrAndNotify(PRInt
 }
 
 PRBool
 nsGenericElement::ParseAttribute(PRInt32 aNamespaceID,
                                  nsIAtom* aAttribute,
                                  const nsAString& aValue,
                                  nsAttrValue& aResult)
 {
-  if (aNamespaceID == kNameSpaceID_None &&
-      aAttribute == GetIDAttributeName() && !aValue.IsEmpty()) {
-    SetFlags(NODE_MAY_HAVE_ID);
-    // Store id as an atom.  id="" means that the element has no id,
-    // not that it has an emptystring as the id.
-    aResult.ParseAtom(aValue);
-    return PR_TRUE;
-  }
-
   return PR_FALSE;
 }
 
 PRBool
 nsGenericElement::SetMappedAttribute(nsIDocument* aDocument,
                                      nsIAtom* aName,
                                      nsAttrValue& aValue,
                                      nsresult* aRetval)
--- a/content/base/src/nsGenericElement.h
+++ b/content/base/src/nsGenericElement.h
@@ -374,17 +374,16 @@ public:
 
   // nsIContent interface methods
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               PRBool aCompileEventHandlers);
   virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
                               PRBool aNullParent = PR_TRUE);
   virtual already_AddRefed<nsINodeList> GetChildren(PRInt32 aChildType);
-  virtual nsIAtom *GetIDAttributeName() const;
   virtual nsIAtom *GetClassAttributeName() const;
   virtual already_AddRefed<nsINodeInfo> GetExistingAttrNameFromQName(const nsAString& aStr) const;
   nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
                    const nsAString& aValue, PRBool aNotify)
   {
     return SetAttr(aNameSpaceID, aName, nsnull, aValue, aNotify);
   }
   virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, nsIAtom* aPrefix,
@@ -446,17 +445,16 @@ public:
   {
     List(out, aIndent, EmptyCString());
   }
   virtual void DumpContent(FILE* out, PRInt32 aIndent, PRBool aDumpAll) const;
   void List(FILE* out, PRInt32 aIndent, const nsCString& aPrefix) const;
   void ListAttributes(FILE* out) const;
 #endif
 
-  virtual nsIAtom* GetID() const;
   virtual const nsAttrValue* DoGetClasses() const;
   NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker);
   virtual nsICSSStyleRule* GetInlineStyleRule();
   NS_IMETHOD SetInlineStyleRule(nsICSSStyleRule* aStyleRule, PRBool aNotify);
   NS_IMETHOD_(PRBool)
     IsAttributeMapped(const nsIAtom* aAttribute) const;
   virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
                                               PRInt32 aModType) const;
@@ -989,25 +987,39 @@ protected:
   void UnregisterFreezableElement() {
     nsIDocument* doc = GetOwnerDoc();
     if (doc) {
       doc->UnregisterFreezableElement(this);
     }
   }
 
   /**
-   * GetContentsAsText will take all the textnodes that are children
-   * of |this| and concatenate the text in them into aText.  It
-   * completely ignores any non-text-node children of |this|; in
-   * particular it does not descend into any children of |this| that
-   * happen to be container elements.
-   *
-   * @param aText the resulting text [OUT]
+   * Add/remove this element to the documents id cache
    */
-  void GetContentsAsText(nsAString& aText);
+  void AddToIdTable(nsIAtom* aId) {
+    NS_ASSERTION(HasFlag(NODE_HAS_ID), "Node lacking NODE_HAS_ID flag");
+    nsIDocument* doc = GetCurrentDoc();
+    if (doc && (!IsInAnonymousSubtree() || doc->IsXUL())) {
+      doc->AddToIdTable(this, aId);
+    }
+  }
+  void RemoveFromIdTable() {
+    if (HasFlag(NODE_HAS_ID)) {
+      nsIDocument* doc = GetCurrentDoc();
+      if (doc) {
+        nsIAtom* id = DoGetID();
+        // id can be null during mutation events evilness. Also, XUL elements
+        // loose their proto attributes during cc-unlink, so this can happen
+        // during cc-unlink too.
+        if (id) {
+          doc->RemoveFromIdTable(this, DoGetID());
+        }
+      }
+    }
+  }
 
   /**
    * Functions to carry out event default actions for links of all types
    * (HTML links, XLinks, SVG "XLinks", etc.)
    */
 
   /**
    * Check that we meet the conditions to handle a link event
--- a/content/base/src/nsNodeUtils.cpp
+++ b/content/base/src/nsNodeUtils.cpp
@@ -264,18 +264,32 @@ nsNodeUtils::LastRelease(nsINode* aNode)
 #endif
 
     nsContentUtils::RemoveListenerManager(aNode);
     aNode->UnsetFlags(NODE_HAS_LISTENERMANAGER);
   }
 
   if (aNode->IsElement()) {
     nsIDocument* ownerDoc = aNode->GetOwnerDoc();
+    Element* elem = aNode->AsElement();
     if (ownerDoc) {
-      ownerDoc->ClearBoxObjectFor(aNode->AsElement());
+      ownerDoc->ClearBoxObjectFor(elem);
+    }
+    
+    NS_ASSERTION(aNode->HasFlag(NODE_FORCE_XBL_BINDINGS) ||
+                 !ownerDoc ||
+                 !ownerDoc->BindingManager() ||
+                 !ownerDoc->BindingManager()->GetBinding(elem),
+                 "Non-forced node has binding on destruction");
+
+    // if NODE_FORCE_XBL_BINDINGS is set, the node might still have a binding
+    // attached
+    if (aNode->HasFlag(NODE_FORCE_XBL_BINDINGS) &&
+        ownerDoc && ownerDoc->BindingManager()) {
+      ownerDoc->BindingManager()->RemovedFromDocument(elem, ownerDoc);
     }
   }
 
   nsContentUtils::ReleaseWrapper(aNode, aNode);
 
   delete aNode;
 }
 
@@ -559,23 +573,16 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNod
     // aNode's children.
     PRUint32 i, length = aNode->GetChildCount();
     for (i = 0; i < length; ++i) {
       nsCOMPtr<nsINode> child;
       rv = CloneAndAdopt(aNode->GetChildAt(i), aClone, PR_TRUE, nodeInfoManager,
                          aCx, aOldScope, aNewScope, aNodesWithProperties,
                          clone, getter_AddRefs(child));
       NS_ENSURE_SUCCESS(rv, rv);
-      if (isDeepDocumentClone) {
-        NS_ASSERTION(child->IsNodeOfType(nsINode::eCONTENT),
-                     "A clone of a child of a node is not nsIContent?");
-
-        nsIContent* content = static_cast<nsIContent*>(child.get());
-        static_cast<nsDocument*>(clone.get())->RegisterNamedItems(content);
-      }
     }
   }
 
   // XXX setting document on some nodes not in a document so XBL will bind
<