Merge mozilla-central into electrolysis.
authorBenjamin Smedberg <benjamin@smedbergs.us>
Wed, 11 Nov 2009 12:35:42 -0500
changeset 36071 4badd9a1932fd39a7d56d16e7db0b8d4aec52fdb
parent 36070 8014289bdafb440881cea3852241d678cef963d4 (current diff)
parent 34772 b00b441c641f8df8a5b50aa3f4b83a4348cf9b5a (diff)
child 36072 ac1ad8585c51cac384f511ca6cf6593134c259b9
push idunknown
push userunknown
push dateunknown
milestone1.9.3a1pre
Merge mozilla-central into electrolysis.
accessible/tests/mochitest/test_elm_filectrl.html
accessible/tests/mochitest/test_elm_select.html
accessible/tests/mochitest/test_elm_tree.xul
accessible/tests/mochitest/test_elm_txtcntnr.html
browser/components/dirprovider/nsBrowserDirectoryProvider.cpp
config/nsinstall_win.c
configure.in
content/base/public/nsIDOMFileRequest.idl
content/base/src/Makefile.in
content/base/src/nsDOMFileRequest.cpp
content/base/src/nsDOMFileRequest.h
content/base/src/nsGkAtomList.h
gfx/public/nsRegion.h
modules/plugin/base/src/nsNPAPIPluginInstance.cpp
modules/plugin/base/src/nsNPAPIPluginInstance.h
modules/plugin/base/src/nsPluginHost.cpp
modules/plugin/test/mochitest/Makefile.in
modules/plugin/test/testplugin/nptest.cpp
netwerk/protocol/http/src/nsHttpHandler.cpp
widget/src/gtk2/nsWindow.cpp
widget/src/windows/nsWindow.cpp
--- a/Makefile.in
+++ b/Makefile.in
@@ -191,16 +191,17 @@ ifdef MOZ_CRASHREPORTER
 	$(PYTHON) $(topsrcdir)/toolkit/crashreporter/tools/symbolstore.py \
 	  $(MAKE_SYM_STORE_ARGS)                                          \
 	  $(foreach dir,$(SYM_STORE_SOURCE_DIRS),-s $(dir))               \
 	  $(DUMP_SYMS_BIN)                                                \
 	  $(DIST)/crashreporter-symbols                                   \
 	  $(MAKE_SYM_STORE_PATH) >                                        \
 	  $(DIST)/crashreporter-symbols/$(SYMBOL_INDEX_NAME)
 	echo packing symbols
+	$(NSINSTALL) -D $(DIST)/$(PKG_PATH)
 	cd $(DIST)/crashreporter-symbols && \
           zip -r9D "../$(PKG_PATH)$(SYMBOL_ARCHIVE_BASENAME).zip" .
 endif # MOZ_CRASHREPORTER
 
 uploadsymbols:
 ifdef MOZ_CRASHREPORTER
 	$(SHELL) $(topsrcdir)/toolkit/crashreporter/tools/upload_symbols.sh "$(DIST)/$(PKG_PATH)$(SYMBOL_ARCHIVE_BASENAME).zip"
 endif
--- a/accessible/src/base/nsAccUtils.cpp
+++ b/accessible/src/base/nsAccUtils.cpp
@@ -897,23 +897,25 @@ nsAccUtils::TextLength(nsIAccessible *aA
   return text.Length();
 }
 
 PRBool
 nsAccUtils::MustPrune(nsIAccessible *aAccessible)
 { 
   PRUint32 role = nsAccUtils::Role(aAccessible);
 
+  // We don't prune buttons any more however AT don't expect children inside of
+  // button in general, we allow menu buttons to have children to make them
+  // accessible.
   return role == nsIAccessibleRole::ROLE_MENUITEM || 
     role == nsIAccessibleRole::ROLE_COMBOBOX_OPTION ||
     role == nsIAccessibleRole::ROLE_OPTION ||
     role == nsIAccessibleRole::ROLE_ENTRY ||
     role == nsIAccessibleRole::ROLE_FLAT_EQUATION ||
     role == nsIAccessibleRole::ROLE_PASSWORD_TEXT ||
-    role == nsIAccessibleRole::ROLE_PUSHBUTTON ||
     role == nsIAccessibleRole::ROLE_TOGGLE_BUTTON ||
     role == nsIAccessibleRole::ROLE_GRAPHIC ||
     role == nsIAccessibleRole::ROLE_SLIDER ||
     role == nsIAccessibleRole::ROLE_PROGRESSBAR ||
     role == nsIAccessibleRole::ROLE_SEPARATOR;
 }
 
 PRBool
--- a/accessible/src/base/nsAccUtils.h
+++ b/accessible/src/base/nsAccUtils.h
@@ -275,16 +275,29 @@ public:
     PRUint32 state = 0;
     if (aAcc)
       aAcc->GetState(&state, nsnull);
 
     return state;
   }
 
   /**
+   * Return the extended state for the given accessible.
+   */
+  static PRUint32 ExtendedState(nsIAccessible *aAcc)
+  {
+    PRUint32 state = 0;
+    PRUint32 extstate = 0;
+    if (aAcc)
+      aAcc->GetState(&state, &extstate);
+
+    return extstate;
+  }
+
+  /**
    * Get the ARIA attribute characteristics for a given ARIA attribute.
    * 
    * @param aAtom  ARIA attribute
    * @return       A bitflag representing the attribute characteristics
    *               (see nsARIAMap.h for possible bit masks, prefixed "ARIA_")
    */
   static PRUint8 GetAttributeCharacteristics(nsIAtom* aAtom);
 
--- a/accessible/src/base/nsAccessibilityAtomList.h
+++ b/accessible/src/base/nsAccessibilityAtomList.h
@@ -56,16 +56,19 @@
 
 
   // Alphabetical list of generic atoms
 ACCESSIBILITY_ATOM(button, "button")
 ACCESSIBILITY_ATOM(col, "col")
 ACCESSIBILITY_ATOM(_empty, "")
 ACCESSIBILITY_ATOM(_false, "false")
 ACCESSIBILITY_ATOM(image, "image")
+ACCESSIBILITY_ATOM(menu, "menu")
+ACCESSIBILITY_ATOM(menuButton, "menu-button")
+ACCESSIBILITY_ATOM(menugenerated, "menugenerated")
 ACCESSIBILITY_ATOM(password, "password")
 ACCESSIBILITY_ATOM(reset, "reset")
 ACCESSIBILITY_ATOM(row, "row")
 ACCESSIBILITY_ATOM(submit, "submit")
 ACCESSIBILITY_ATOM(_true, "true")
 ACCESSIBILITY_ATOM(_undefined, "undefined")
 
   // Header info
@@ -120,22 +123,22 @@ ACCESSIBILITY_ATOM(legend, "legend")
 ACCESSIBILITY_ATOM(li, "li")
 ACCESSIBILITY_ATOM(link, "link")
 ACCESSIBILITY_ATOM(listcols, "listcols") // XUL
 ACCESSIBILITY_ATOM(listcol, "listcol") // XUL
 ACCESSIBILITY_ATOM(listhead, "listhead") // XUL
 ACCESSIBILITY_ATOM(listheader, "listheader") // XUL
 ACCESSIBILITY_ATOM(map, "map")
 ACCESSIBILITY_ATOM(math, "math")
-ACCESSIBILITY_ATOM(menu, "menu")    // XUL
 ACCESSIBILITY_ATOM(menupopup, "menupopup")     // XUL
 ACCESSIBILITY_ATOM(object, "object")
 ACCESSIBILITY_ATOM(ol, "ol")
 ACCESSIBILITY_ATOM(optgroup, "optgroup")
 ACCESSIBILITY_ATOM(option, "option")
+ACCESSIBILITY_ATOM(panel, "panel") // XUL
 ACCESSIBILITY_ATOM(q, "q")
 ACCESSIBILITY_ATOM(select, "select")
 ACCESSIBILITY_ATOM(select1, "select1") // XForms
 ACCESSIBILITY_ATOM(svg, "svg")
 ACCESSIBILITY_ATOM(table, "table")
 ACCESSIBILITY_ATOM(tabpanels, "tabpanels") // XUL
 ACCESSIBILITY_ATOM(tbody, "tbody")
 ACCESSIBILITY_ATOM(td, "td")
@@ -159,16 +162,17 @@ ACCESSIBILITY_ATOM(alt, "alt")
 ACCESSIBILITY_ATOM(anonid, "anonid") // Used for ID's in XBL
 ACCESSIBILITY_ATOM(contenteditable, "contenteditable")
 ACCESSIBILITY_ATOM(control, "control")
 ACCESSIBILITY_ATOM(disabled, "disabled")
 ACCESSIBILITY_ATOM(_class, "class")
 ACCESSIBILITY_ATOM(cycles, "cycles") // used for XUL cycler attribute
 ACCESSIBILITY_ATOM(curpos, "curpos") // XUL
 ACCESSIBILITY_ATOM(data, "data")
+ACCESSIBILITY_ATOM(_default, "default") // XUL button
 ACCESSIBILITY_ATOM(draggable, "draggable")
 ACCESSIBILITY_ATOM(droppable, "droppable")   // XUL combo box
 ACCESSIBILITY_ATOM(editable, "editable")
 ACCESSIBILITY_ATOM(_for, "for")
 ACCESSIBILITY_ATOM(headers, "headers")   // HTML table
 ACCESSIBILITY_ATOM(hidden, "hidden")   // XUL tree columns
 ACCESSIBILITY_ATOM(href, "href") // XUL, XLink
 ACCESSIBILITY_ATOM(increment, "increment") // XUL
--- a/accessible/src/base/nsCoreUtils.cpp
+++ b/accessible/src/base/nsCoreUtils.cpp
@@ -1102,8 +1102,50 @@ PRBool
 nsCoreUtils::IsColumnHidden(nsITreeColumn *aColumn)
 {
   nsCOMPtr<nsIDOMElement> element;
   aColumn->GetElement(getter_AddRefs(element));
   nsCOMPtr<nsIContent> content = do_QueryInterface(element);
   return content->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::hidden,
                               nsAccessibilityAtoms::_true, eCaseMatters);
 }
+
+void
+nsCoreUtils::GeneratePopupTree(nsIDOMNode *aNode, PRBool aIsAnon)
+{
+  // Set menugenerated="true" on the menupopup node to generate the sub-menu
+  // items if they have not been generated.
+
+  nsCOMPtr<nsIDOMNodeList> list;
+  if (aIsAnon) {
+    nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
+    nsIDocument* document = content->GetCurrentDoc();
+    if (document)
+      document->GetXBLChildNodesFor(content, getter_AddRefs(list));
+
+  } else {
+    aNode->GetChildNodes(getter_AddRefs(list));
+  }
+
+  PRUint32 length = 0;
+  if (!list || NS_FAILED(list->GetLength(&length)))
+    return;
+
+  for (PRUint32 idx = 0; idx < length; idx++) {
+    nsCOMPtr<nsIDOMNode> childNode;
+    list->Item(idx, getter_AddRefs(childNode));
+    nsCOMPtr<nsIContent> child(do_QueryInterface(childNode));
+
+    PRBool isPopup = child->NodeInfo()->Equals(nsAccessibilityAtoms::menupopup,
+                                               kNameSpaceID_XUL) ||
+                     child->NodeInfo()->Equals(nsAccessibilityAtoms::panel,
+                                               kNameSpaceID_XUL);
+    if (isPopup && !child->AttrValueIs(kNameSpaceID_None,
+                                       nsAccessibilityAtoms::menugenerated,
+                                       nsAccessibilityAtoms::_true,
+                                       eCaseMatters)) {
+
+      child->SetAttr(kNameSpaceID_None, nsAccessibilityAtoms::menugenerated,
+                     NS_LITERAL_STRING("true"), PR_TRUE);
+      return;
+    }
+  }
+}
--- a/accessible/src/base/nsCoreUtils.h
+++ b/accessible/src/base/nsCoreUtils.h
@@ -441,12 +441,21 @@ public:
   /**
    * Return true if the given node is table header element.
    */
   static PRBool IsHTMLTableHeader(nsIContent *aContent)
   {
     return aContent->NodeInfo()->Equals(nsAccessibilityAtoms::th) ||
       aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::scope);
   }
+
+  /**
+   * Generates frames for popup subtree.
+   *
+   * @param aNode    [in] DOM node containing the menupopup element as a child
+   * @param aIsAnon  [in] specifies whether popup should be searched inside of
+   *                  anonymous or explicit content
+   */
+  static void GeneratePopupTree(nsIDOMNode *aNode, PRBool aIsAnon = PR_FALSE);
 };
 
 #endif
 
--- a/accessible/src/base/nsRootAccessible.cpp
+++ b/accessible/src/base/nsRootAccessible.cpp
@@ -396,21 +396,22 @@ void nsRootAccessible::TryFireEarlyLoadE
   NS_ASSERTION(rootContentTreeItem, "No root content tree item");
   if (rootContentTreeItem == treeItem) {
     // No frames or iframes, so we can fire the doc load finished event early
     FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_INTERNAL_LOAD,
                                aDocNode);
   }
 }
 
-PRBool nsRootAccessible::FireAccessibleFocusEvent(nsIAccessible *aAccessible,
-                                                  nsIDOMNode *aNode,
-                                                  nsIDOMEvent *aFocusEvent,
-                                                  PRBool aForceEvent,
-                                                  PRBool aIsAsynch)
+PRBool
+nsRootAccessible::FireAccessibleFocusEvent(nsIAccessible *aAccessible,
+                                           nsIDOMNode *aNode,
+                                           nsIDOMEvent *aFocusEvent,
+                                           PRBool aForceEvent,
+                                           PRBool aIsAsynch)
 {
   if (mCaretAccessible) {
     nsCOMPtr<nsIDOMNSEvent> nsevent(do_QueryInterface(aFocusEvent));
     if (nsevent) {
       // Use the originally focused node where the selection lives.
       // For example, use the anonymous HTML:input instead of the containing
       // XUL:textbox. In this case, sometimes it is a later focus event
       // which points to the actual anonymous child with focus, so to be safe 
@@ -526,20 +527,26 @@ PRBool nsRootAccessible::FireAccessibleF
   NS_IF_ADDREF(gLastFocusedNode);
 
   gLastFocusedFrameType = (focusFrame && focusFrame->GetStyleVisibility()->IsVisible()) ? focusFrame->GetType() : 0;
 
   nsCOMPtr<nsIAccessibleDocument> docAccessible = do_QueryInterface(finalFocusAccessible);
   if (docAccessible) {
     // Doc is gaining focus, but actual focus may be on an element within document
     nsCOMPtr<nsIDOMNode> realFocusedNode = GetCurrentFocus();
-    if (realFocusedNode != aNode || realFocusedNode == mDOMNode) {
+    if ((realFocusedNode != aNode || realFocusedNode == mDOMNode) &&
+        !(nsAccUtils::ExtendedState(finalFocusAccessible) &
+                    nsIAccessibleStates::EXT_STATE_EDITABLE)) {
       // Suppress document focus, because real DOM focus will be fired next,
-      // and that's what we care about
+      // except in the case of editable documents because we can't rely on a
+      // followup focus event for an element in an editable document.
       // Make sure we never fire focus for the nsRootAccessible (mDOMNode)
+
+      // XXX todo dig deeper on editor focus inconsistency in bug 526313
+
       return PR_FALSE;
     }
   }
 
   FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_FOCUS,
                              finalFocusNode, nsAccEvent::eRemoveDupes,
                              aIsAsynch);
 
--- a/accessible/src/base/nsTextEquivUtils.cpp
+++ b/accessible/src/base/nsTextEquivUtils.cpp
@@ -558,17 +558,17 @@ PRUint32 nsTextEquivUtils::gRoleToNameRu
   eNoRule,           // ROLE_FOOTER
   eFromSubtreeIfRec, // ROLE_PARAGRAPH
   eNoRule,           // ROLE_RULER
   eNoRule,           // ROLE_AUTOCOMPLETE
   eNoRule,           // ROLE_EDITBAR
   eFromValue,        // ROLE_ENTRY
   eNoRule,           // ROLE_CAPTION
   eNoRule,           // ROLE_DOCUMENT_FRAME
-  eNoRule,           // ROLE_HEADING
+  eFromSubtreeIfRec, // ROLE_HEADING
   eNoRule,           // ROLE_PAGE
   eFromSubtreeIfRec, // ROLE_SECTION
   eNoRule,           // ROLE_REDUNDANT_OBJECT
   eNoRule,           // ROLE_FORM
   eNoRule,           // ROLE_IME
   eNoRule,           // ROLE_APP_ROOT
   eFromSubtree,      // ROLE_PARENT_MENUITEM
   eNoRule,           // ROLE_CALENDAR
--- a/accessible/src/html/nsHTMLTableAccessible.cpp
+++ b/accessible/src/html/nsHTMLTableAccessible.cpp
@@ -398,16 +398,18 @@ nsHTMLTableHeaderCellAccessible::GetRole
     case 1:
       *aRole = nsIAccessibleRole::ROLE_ROWHEADER;
       return NS_OK;
   }
 
   // Assume it's columnheader if there are headers in siblings, oterwise
   // rowheader.
   nsIContent* parent = content->GetParent();
+  NS_ENSURE_STATE(parent);
+
   PRInt32 indexInParent = parent->IndexOf(content);
 
   for (PRInt32 idx = indexInParent - 1; idx >= 0; idx--) {
     nsIContent* sibling = parent->GetChildAt(idx);
     if (sibling && sibling->IsNodeOfType(nsINode::eELEMENT)) {
       if (nsCoreUtils::IsHTMLTableHeader(sibling))
         *aRole = nsIAccessibleRole::ROLE_COLUMNHEADER;
       else
--- a/accessible/src/html/nsHyperTextAccessible.cpp
+++ b/accessible/src/html/nsHyperTextAccessible.cpp
@@ -2027,16 +2027,21 @@ nsHyperTextAccessible::ScrollSubstringTo
         nsIntRect frameRect = parentFrame->GetScreenRectExternal();
         PRInt32 devOffsetX = coords.x - frameRect.x;
         PRInt32 devOffsetY = coords.y - frameRect.y;
 
         nsPoint offsetPoint(presContext->DevPixelsToAppUnits(devOffsetX),
                             presContext->DevPixelsToAppUnits(devOffsetY));
 
         nsSize size(parentFrame->GetSize());
+
+        // avoid divide by zero
+        size.width = size.width ? size.width : 1;
+        size.height = size.height ? size.height : 1;
+
         PRInt16 hPercent = offsetPoint.x * 100 / size.width;
         PRInt16 vPercent = offsetPoint.y * 100 / size.height;
 
         rv = nsCoreUtils::ScrollSubstringTo(GetFrame(), startNode, startOffset,
                                             endNode, endOffset,
                                             vPercent, hPercent);
         NS_ENSURE_SUCCESS(rv, rv);
 
--- a/accessible/src/xul/nsXULColorPickerAccessible.cpp
+++ b/accessible/src/xul/nsXULColorPickerAccessible.cpp
@@ -31,52 +31,68 @@
  * 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 ***** */
 
-// NOTE: alphabetically ordered
 #include "nsXULColorPickerAccessible.h"
+
+#include "nsAccessibleTreeWalker.h"
+
 #include "nsIDOMElement.h"
 
 
-/**
-  * XUL Color Picker Tile
-  */
+////////////////////////////////////////////////////////////////////////////////
+// nsXULColorPickerTileAccessible
+////////////////////////////////////////////////////////////////////////////////
 
-/**
-  * Default Constructor
-  */
-nsXULColorPickerTileAccessible::nsXULColorPickerTileAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
-nsFormControlAccessible(aNode, aShell)
-{ 
+nsXULColorPickerTileAccessible::
+  nsXULColorPickerTileAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell) :
+  nsAccessibleWrap(aNode, aShell)
+{
 }
 
-/**
-  * We are a pushbutton
-  */
+////////////////////////////////////////////////////////////////////////////////
+// nsXULColorPickerTileAccessible: nsIAccessible
+
+NS_IMETHODIMP
+nsXULColorPickerTileAccessible::GetValue(nsAString& aValue)
+{
+  aValue.Truncate();
+
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
+  content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::color, aValue);
+
+  return NS_OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// nsXULColorPickerTileAccessible: nsAccessible
+
 nsresult
 nsXULColorPickerTileAccessible::GetRoleInternal(PRUint32 *aRole)
 {
   *aRole = nsIAccessibleRole::ROLE_PUSHBUTTON;
   return NS_OK;
 }
 
-/**
-  * Possible states: focused, focusable, selected
-  */
 nsresult
 nsXULColorPickerTileAccessible::GetStateInternal(PRUint32 *aState,
                                                  PRUint32 *aExtraState)
 {
+  // Possible states: focused, focusable, selected.
+
   // get focus and disable status from base class
-  nsresult rv = nsFormControlAccessible::GetStateInternal(aState, aExtraState);
+  nsresult rv = nsAccessibleWrap::GetStateInternal(aState, aExtraState);
   NS_ENSURE_A11Y_SUCCESS(rv, rv);
 
   *aState |= nsIAccessibleStates::STATE_FOCUSABLE;
 
   // Focused?
   nsCOMPtr<nsIDOMElement> element(do_QueryInterface(mDOMNode));
   NS_ASSERTION(element, "No XUL Element for colorpicker");
   PRBool isFocused = PR_FALSE;
@@ -87,54 +103,103 @@ nsXULColorPickerTileAccessible::GetState
   PRBool isSelected = PR_FALSE;
   element->HasAttribute(NS_LITERAL_STRING("selected"), &isSelected);
   if (isFocused)
     *aState |= nsIAccessibleStates::STATE_SELECTED;
 
   return NS_OK;
 }
 
-NS_IMETHODIMP nsXULColorPickerTileAccessible::GetValue(nsAString& _retval)
-{
-  if (!mDOMNode)
-    return NS_ERROR_FAILURE;
 
-  nsCOMPtr<nsIDOMElement> element(do_QueryInterface(mDOMNode));
-  NS_ASSERTION(element, "No XUL Element for colorpicker");
-  return element->GetAttribute(NS_LITERAL_STRING("color"), _retval);
-}
-
-/**
-  * XUL Color Picker
-  */
+////////////////////////////////////////////////////////////////////////////////
+// nsXULColorPickerAccessible
+////////////////////////////////////////////////////////////////////////////////
 
 /**
   * Default Constructor
   */
 nsXULColorPickerAccessible::nsXULColorPickerAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
 nsXULColorPickerTileAccessible(aNode, aShell)
 { 
 }
 
-/**
-  * Possible states: focused, focusable, unavailable(disabled)
-  */
+////////////////////////////////////////////////////////////////////////////////
+// nsXULColorPickerAccessible: nsAccessNode
+
+nsresult
+nsXULColorPickerAccessible::Init()
+{
+  nsresult rv = nsXULColorPickerTileAccessible::Init();
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsCoreUtils::GeneratePopupTree(mDOMNode, PR_TRUE);
+  return NS_OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// nsXULColorPickerAccessible: nsAccessible
+
 nsresult
 nsXULColorPickerAccessible::GetStateInternal(PRUint32 *aState,
                                              PRUint32 *aExtraState)
 {
+  // Possible states: focused, focusable, unavailable(disabled).
+
   // get focus and disable status from base class
-  nsresult rv = nsFormControlAccessible::GetStateInternal(aState, aExtraState);
+  nsresult rv = nsAccessibleWrap::GetStateInternal(aState, aExtraState);
   NS_ENSURE_A11Y_SUCCESS(rv, rv);
 
   *aState |= nsIAccessibleStates::STATE_FOCUSABLE |
              nsIAccessibleStates::STATE_HASPOPUP;
 
   return NS_OK;
 }
 
 nsresult
 nsXULColorPickerAccessible::GetRoleInternal(PRUint32 *aRole)
 {
   *aRole = nsIAccessibleRole::ROLE_BUTTONDROPDOWNGRID;
   return NS_OK;
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// nsXULColorPickerAccessible: protected nsAccessible
+
+void
+nsXULColorPickerAccessible::CacheChildren()
+{
+  if (IsDefunct()) {
+    mAccChildCount = eChildCountUninitialized;
+    return;   // This outer doc node has been shut down
+  }
+
+  if (mAccChildCount != eChildCountUninitialized)
+    return;
+
+  mAccChildCount = 0;  // Avoid reentry
+
+  nsCOMPtr<nsIAccessible> menupopupAccessible;
+  nsAccessibleTreeWalker walker(mWeakShell, mDOMNode, PR_TRUE);
+  walker.GetFirstChild();
+
+  while (walker.mState.accessible) {
+    PRUint32 role = nsAccUtils::Role(walker.mState.accessible);
+
+    if (role == nsIAccessibleRole::ROLE_ALERT) {
+      // Get an accessbile for menupopup or panel elements.
+      menupopupAccessible = walker.mState.accessible;
+      break;
+    }
+
+    walker.GetNextSibling();
+  }
+
+  if (!menupopupAccessible)
+    return;
+
+  SetFirstChild(menupopupAccessible);
+
+  nsRefPtr<nsAccessible> menupopupAcc =
+    nsAccUtils::QueryObject<nsAccessible>(menupopupAccessible);
+  menupopupAcc->SetParent(this);
+
+  mAccChildCount++;
+}
--- a/accessible/src/xul/nsXULColorPickerAccessible.h
+++ b/accessible/src/xul/nsXULColorPickerAccessible.h
@@ -35,34 +35,49 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef _nsXULColorPickerAccessible_H_
 #define _nsXULColorPickerAccessible_H_
 
 // NOTE: alphabetically ordered
-#include "nsFormControlAccessible.h"
+#include "nsAccessibleWrap.h"
 
-class nsXULColorPickerTileAccessible : public nsFormControlAccessible
+/**
+ * Used for color button in colorpicker palette.
+ */
+class nsXULColorPickerTileAccessible : public nsAccessibleWrap
 {
 public:
   nsXULColorPickerTileAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
 
   // nsIAccessible
   NS_IMETHOD GetValue(nsAString& _retval);
 
   // nsAccessible
   virtual nsresult GetRoleInternal(PRUint32 *aRole);
   virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
 };
 
+
+/**
+ * Used for colorpicker button (xul:colorpicker@type="button").
+ */
 class nsXULColorPickerAccessible : public nsXULColorPickerTileAccessible
 {
 public:
   nsXULColorPickerAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
 
+  // nsAccessNode
+  virtual nsresult Init();
+
   // nsAccessible
   virtual nsresult GetRoleInternal(PRUint32 *aRole);
   virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
+
+protected:
+
+  // nsAccessible
+  virtual void CacheChildren();
 };
 
 #endif  
--- a/accessible/src/xul/nsXULComboboxAccessible.cpp
+++ b/accessible/src/xul/nsXULComboboxAccessible.cpp
@@ -53,17 +53,17 @@ nsXULComboboxAccessible::
   nsAccessibleWrap(aDOMNode, aShell)
 {
 }
 
 nsresult
 nsXULComboboxAccessible::Init()
 {
   nsresult rv = nsAccessibleWrap::Init();
-  nsXULMenupopupAccessible::GenerateMenu(mDOMNode);
+  nsCoreUtils::GeneratePopupTree(mDOMNode);
   return rv;
 }
 
 nsresult
 nsXULComboboxAccessible::GetRoleInternal(PRUint32 *aRole)
 {
   nsCOMPtr<nsIContent> content = do_QueryInterface(mDOMNode);
   if (!content) {
--- a/accessible/src/xul/nsXULFormControlAccessible.cpp
+++ b/accessible/src/xul/nsXULFormControlAccessible.cpp
@@ -51,78 +51,92 @@
 #include "nsIDOMXULSelectCntrlItemEl.h"
 #include "nsIDOMXULTextboxElement.h"
 #include "nsIEditor.h"
 #include "nsIFrame.h"
 #include "nsINameSpaceManager.h"
 #include "nsITextControlFrame.h"
 #include "nsIPresShell.h"
 
-/**
-  * XUL Button: can contain arbitrary HTML content
-  */
+////////////////////////////////////////////////////////////////////////////////
+// nsXULButtonAccessible
+////////////////////////////////////////////////////////////////////////////////
 
-/**
-  * Default Constructor
-  */
-
-// Don't inherit from nsFormControlAccessible - it doesn't allow children and a button can have a dropmarker child
-nsXULButtonAccessible::nsXULButtonAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
-nsAccessibleWrap(aNode, aShell)
-{ 
+nsXULButtonAccessible::
+  nsXULButtonAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell) :
+  nsAccessibleWrap(aNode, aShell)
+{
 }
 
-/**
-  * Only one actions available
-  */
-NS_IMETHODIMP nsXULButtonAccessible::GetNumActions(PRUint8 *_retval)
+////////////////////////////////////////////////////////////////////////////////
+// nsXULButtonAccessible: nsISupports
+
+NS_IMPL_ISUPPORTS_INHERITED0(nsXULButtonAccessible, nsAccessible)
+
+////////////////////////////////////////////////////////////////////////////////
+// nsXULButtonAccessible: nsIAccessible
+
+NS_IMETHODIMP
+nsXULButtonAccessible::GetNumActions(PRUint8 *aCount)
 {
-  *_retval = 1;
+  NS_ENSURE_ARG_POINTER(aCount);
+
+  *aCount = 1;
   return NS_OK;
 }
 
-/**
-  * Return the name of our only action
-  */
-NS_IMETHODIMP nsXULButtonAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
+NS_IMETHODIMP
+nsXULButtonAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
 {
   if (aIndex == eAction_Click) {
     aName.AssignLiteral("press"); 
     return NS_OK;
   }
   return NS_ERROR_INVALID_ARG;
 }
 
-/**
-  * Tell the button to do its action
-  */
-NS_IMETHODIMP nsXULButtonAccessible::DoAction(PRUint8 index)
+NS_IMETHODIMP
+nsXULButtonAccessible::DoAction(PRUint8 aIndex)
 {
-  if (index == 0) {
+  if (aIndex == 0)
     return DoCommand();
-  }
+
   return NS_ERROR_INVALID_ARG;
 }
 
-/**
-  * We are a pushbutton
-  */
+////////////////////////////////////////////////////////////////////////////////
+// nsXULButtonAccessible: nsAccessNode
+
+nsresult
+nsXULButtonAccessible::Init()
+{
+  nsresult rv = nsAccessibleWrap::Init();
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  if (ContainsMenu())
+    nsCoreUtils::GeneratePopupTree(mDOMNode);
+
+  return NS_OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// nsXULButtonAccessible: nsAccessible
+
 nsresult
 nsXULButtonAccessible::GetRoleInternal(PRUint32 *aRole)
 {
   *aRole = nsIAccessibleRole::ROLE_PUSHBUTTON;
   return NS_OK;
 }
 
-/**
-  * Possible states: focused, focusable, unavailable(disabled)
-  */
 nsresult
 nsXULButtonAccessible::GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState)
 {
+  // Possible states: focused, focusable, unavailable(disabled).
+
   // get focus and disable status from base class
   nsresult rv = nsAccessible::GetStateInternal(aState, aExtraState);
   NS_ENSURE_A11Y_SUCCESS(rv, rv);
 
   PRBool disabled = PR_FALSE;
   nsCOMPtr<nsIDOMXULControlElement> xulFormElement(do_QueryInterface(mDOMNode));
   if (xulFormElement) {
     xulFormElement->GetDisabled(&disabled);
@@ -147,73 +161,128 @@ nsXULButtonAccessible::GetStateInternal(
         xulButtonElement->GetCheckState(&checkState);
         if (checkState == nsIDOMXULButtonElement::CHECKSTATE_MIXED) { 
           *aState |= nsIAccessibleStates::STATE_MIXED;
         }
       }
     }
   }
 
-  nsCOMPtr<nsIDOMElement> element(do_QueryInterface(mDOMNode));
-  if (element) {
-    PRBool isDefault = PR_FALSE;
-    element->HasAttribute(NS_LITERAL_STRING("default"), &isDefault) ;
-    if (isDefault)
-      *aState |= nsIAccessibleStates::STATE_DEFAULT;
+  if (ContainsMenu())
+    *aState |= nsIAccessibleStates::STATE_HASPOPUP;
 
-    nsAutoString type;
-    element->GetAttribute(NS_LITERAL_STRING("type"), type);
-    if (type.EqualsLiteral("menu") || type.EqualsLiteral("menu-button")) {
-      *aState |= nsIAccessibleStates::STATE_HASPOPUP;
-    }
-  }
+  nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
+  if (content->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::_default))
+    *aState |= nsIAccessibleStates::STATE_DEFAULT;
 
   return NS_OK;
 }
 
-void nsXULButtonAccessible::CacheChildren()
+////////////////////////////////////////////////////////////////////////////////
+// nsXULButtonAccessible: nsAccessible protected
+
+void
+nsXULButtonAccessible::CacheChildren()
 {
-  // An XUL button accessible may have 1 child dropmarker accessible
+  // In general XUL button has not accessible children. Nevertheless menu
+  // buttons can have button (@type="menu-button") and popup accessibles
+  // (@type="menu-button" or @type="menu").
+
   if (!mWeakShell) {
     mAccChildCount = eChildCountUninitialized;
     return;   // This outer doc node has been shut down
   }
   if (mAccChildCount == eChildCountUninitialized) {
     mAccChildCount = 0;  // Avoid reentry
+
     SetFirstChild(nsnull);
-    PRBool allowsAnonChildren = GetAllowsAnonChildAccessibles();
-    nsAccessibleTreeWalker walker(mWeakShell, mDOMNode, allowsAnonChildren);
+
+    // XXX: no children until the button is menu button. Probably it's not
+    // totally correct but in general AT wants to have leaf buttons.
+    nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
+
+    PRBool isMenu = content->AttrValueIs(kNameSpaceID_None,
+                                         nsAccessibilityAtoms::type,
+                                         nsAccessibilityAtoms::menu,
+                                         eCaseMatters);
+
+    PRBool isMenuButton = isMenu ?
+      PR_FALSE :
+      content->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::type,
+                           nsAccessibilityAtoms::menuButton, eCaseMatters);
+
+    if (!isMenu && !isMenuButton)
+      return;
+
+    nsCOMPtr<nsIAccessible> buttonAccessible;
+    nsCOMPtr<nsIAccessible> menupopupAccessible;
+
+    nsAccessibleTreeWalker walker(mWeakShell, mDOMNode, PR_TRUE);
     walker.GetFirstChild();
-    nsCOMPtr<nsIAccessible> dropMarkerAccessible;
+
     while (walker.mState.accessible) {
-      dropMarkerAccessible = walker.mState.accessible;
+      PRUint32 role = nsAccUtils::Role(walker.mState.accessible);
+
+      if (role == nsIAccessibleRole::ROLE_MENUPOPUP) {
+        // Get an accessbile for menupopup or panel elements.
+        menupopupAccessible = walker.mState.accessible;
+
+      } else if (isMenuButton && role == nsIAccessibleRole::ROLE_PUSHBUTTON) {
+        // Button type="menu-button" contains a real button. Get an accessible
+        // for it. Ignore dropmarker button what is placed as a last child.
+        buttonAccessible = walker.mState.accessible;
+        break;
+      }
+
       walker.GetNextSibling();
     }
 
-    // If the anonymous tree walker can find accessible children, 
-    // and the last one is a push button, then use it as the only accessible 
-    // child -- because this is the scenario where we have a dropmarker child
+    if (!menupopupAccessible)
+      return;
+
+    SetFirstChild(menupopupAccessible);
+
+    nsRefPtr<nsAccessible> menupopupAcc =
+      nsAccUtils::QueryObject<nsAccessible>(menupopupAccessible);
+    menupopupAcc->SetParent(this);
+
+    mAccChildCount++;
 
-    if (dropMarkerAccessible) {
-      if (nsAccUtils::RoleInternal(dropMarkerAccessible) ==
-          nsIAccessibleRole::ROLE_PUSHBUTTON) {
-        SetFirstChild(dropMarkerAccessible);
-        nsRefPtr<nsAccessible> childAcc =
-          nsAccUtils::QueryAccessible(dropMarkerAccessible);
-        childAcc->SetNextSibling(nsnull);
-        childAcc->SetParent(this);
-        mAccChildCount = 1;
-      }
+    if (buttonAccessible) {
+      if (menupopupAcc)
+        menupopupAcc->SetNextSibling(buttonAccessible);
+      else
+        SetFirstChild(buttonAccessible);
+
+      nsRefPtr<nsAccessible> buttonAcc =
+        nsAccUtils::QueryObject<nsAccessible>(buttonAccessible);
+      buttonAcc->SetParent(this);
+
+      mAccChildCount++;
     }
   }
 }
 
-/**
-  * XUL Dropmarker: can contain arbitrary HTML content
-  */
+////////////////////////////////////////////////////////////////////////////////
+// nsXULButtonAccessible protected
+
+PRBool
+nsXULButtonAccessible::ContainsMenu()
+{
+  static nsIContent::AttrValuesArray strings[] =
+    {&nsAccessibilityAtoms::menu, &nsAccessibilityAtoms::menuButton, nsnull};
+
+  nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
+  return content->FindAttrValueIn(kNameSpaceID_None, nsAccessibilityAtoms::type,
+                                  strings, eCaseMatters) >= 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// nsXULDropmarkerAccessible
+////////////////////////////////////////////////////////////////////////////////
 
 /**
   * Default Constructor
   */
 nsXULDropmarkerAccessible::nsXULDropmarkerAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
 nsFormControlAccessible(aNode, aShell)
 { 
 }
--- a/accessible/src/xul/nsXULFormControlAccessible.h
+++ b/accessible/src/xul/nsXULFormControlAccessible.h
@@ -41,36 +41,56 @@
 #define _nsXULFormControlAccessible_H_
 
 // NOTE: alphabetically ordered
 #include "nsAccessibleWrap.h"
 #include "nsFormControlAccessible.h"
 #include "nsXULMenuAccessible.h"
 #include "nsHyperTextAccessibleWrap.h"
 
+/**
+ * Used for XUL button.
+ *
+ * @note  Don't inherit from nsFormControlAccessible - it doesn't allow children
+ *         and a button can have a dropmarker child.
+ */
 class nsXULButtonAccessible : public nsAccessibleWrap
-// Don't inherit from nsFormControlAccessible - it doesn't allow children and a button can have a dropmarker child
 {
 public:
   enum { eAction_Click = 0 };
   nsXULButtonAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
 
+  // nsISupports
+  NS_DECL_ISUPPORTS_INHERITED
+
   // nsIAccessible
   NS_IMETHOD GetNumActions(PRUint8 *_retval);
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
   NS_IMETHOD DoAction(PRUint8 index);
 
+  // nsAccessNode
+  virtual nsresult Init();
+
   // nsAccessible
   virtual nsresult GetRoleInternal(PRUint32 *aRole);
   virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
 
 protected:
+
+  // nsAccessible
   void CacheChildren();
+
+  // nsXULButtonAccessible
+  PRBool ContainsMenu();
 };
 
+
+/**
+ * Used for XUL checkbox.
+ */
 class nsXULCheckboxAccessible : public nsFormControlAccessible
 {
 public:
   enum { eAction_Click = 0 };
   nsXULCheckboxAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
 
   // nsIAccessible
   NS_IMETHOD GetNumActions(PRUint8 *_retval);
--- a/accessible/src/xul/nsXULMenuAccessible.cpp
+++ b/accessible/src/xul/nsXULMenuAccessible.cpp
@@ -268,17 +268,17 @@ nsXULMenuitemAccessible::nsXULMenuitemAc
 nsAccessibleWrap(aDOMNode, aShell)
 { 
 }
 
 nsresult
 nsXULMenuitemAccessible::Init()
 {
   nsresult rv = nsAccessibleWrap::Init();
-  nsXULMenupopupAccessible::GenerateMenu(mDOMNode);
+  nsCoreUtils::GeneratePopupTree(mDOMNode);
   return rv;
 }
 
 nsresult
 nsXULMenuitemAccessible::GetStateInternal(PRUint32 *aState,
                                           PRUint32 *aExtraState)
 {
   nsresult rv = nsAccessible::GetStateInternal(aState, aExtraState);
@@ -637,56 +637,16 @@ nsXULMenupopupAccessible::GetStateIntern
 
   if (*aState & nsIAccessibleStates::STATE_INVISIBLE)
     *aState |= (nsIAccessibleStates::STATE_OFFSCREEN |
                 nsIAccessibleStates::STATE_COLLAPSED);
 
   return NS_OK;
 }
 
-already_AddRefed<nsIDOMNode>
-nsXULMenupopupAccessible::FindInNodeList(nsIDOMNodeList *aNodeList, 
-                                         nsIAtom *aAtom, PRUint32 aNameSpaceID)
-{
-  PRUint32 numChildren;
-  if (!aNodeList || NS_FAILED(aNodeList->GetLength(&numChildren))) {
-    return nsnull;
-  }
-  nsCOMPtr<nsIDOMNode> childNode;
-  for (PRUint32 childIndex = 0; childIndex < numChildren; childIndex++) {
-    aNodeList->Item(childIndex, getter_AddRefs(childNode));
-    nsCOMPtr<nsIContent> content = do_QueryInterface(childNode);
-    if (content && content->NodeInfo()->Equals(aAtom, kNameSpaceID_XUL)) {
-      nsIDOMNode *matchNode = childNode;
-      NS_ADDREF(matchNode);
-      return matchNode;
-    }
-  }
-  return nsnull;
-}
-
-void nsXULMenupopupAccessible::GenerateMenu(nsIDOMNode *aNode)
-{
-  // Set menugenerated="true" on the menupopup node to generate the
-  // sub-menu items if they have not been generated
-  nsCOMPtr<nsIDOMNodeList> nodeList;
-  aNode->GetChildNodes(getter_AddRefs(nodeList));
-
-  nsCOMPtr<nsIDOMNode> menuPopup = FindInNodeList(nodeList, nsAccessibilityAtoms::menupopup,
-                                                  kNameSpaceID_XUL);
-  nsCOMPtr<nsIDOMElement> popupElement(do_QueryInterface(menuPopup));
-  if (popupElement) {
-    nsAutoString attr;
-    popupElement->GetAttribute(NS_LITERAL_STRING("menugenerated"), attr);
-    if (!attr.EqualsLiteral("true")) {
-      popupElement->SetAttribute(NS_LITERAL_STRING("menugenerated"), NS_LITERAL_STRING("true"));
-    }
-  }
-}
-
 nsresult
 nsXULMenupopupAccessible::GetNameInternal(nsAString& aName)
 {
   nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
   while (content && aName.IsEmpty()) {
     content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::label, aName);
     content = content->GetParent();
   }
@@ -699,25 +659,33 @@ nsXULMenupopupAccessible::GetRoleInterna
 {
   nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
   if (!content) {
     return NS_ERROR_FAILURE;
   }
   nsCOMPtr<nsIAccessible> parent;
   GetParent(getter_AddRefs(parent));
   if (parent) {
-    // Some widgets like the search bar have several popups, owned by buttons
     PRUint32 role = nsAccUtils::Role(parent);
     if (role == nsIAccessibleRole::ROLE_COMBOBOX ||
-        role == nsIAccessibleRole::ROLE_PUSHBUTTON ||
         role == nsIAccessibleRole::ROLE_AUTOCOMPLETE) {
       *aRole = nsIAccessibleRole::ROLE_COMBOBOX_LIST;
       return NS_OK;
+
+    } else if (role == nsIAccessibleRole::ROLE_PUSHBUTTON) {
+      // Some widgets like the search bar have several popups, owned by buttons.
+      nsCOMPtr<nsIAccessible> grandParent;
+      parent->GetParent(getter_AddRefs(grandParent));
+      if (role == nsIAccessibleRole::ROLE_AUTOCOMPLETE) {
+        *aRole = nsIAccessibleRole::ROLE_COMBOBOX_LIST;
+        return NS_OK;
+      }
     }
   }
+
   *aRole = nsIAccessibleRole::ROLE_MENUPOPUP;
   return NS_OK;
 }
 
 // ------------------------ Menu Bar -----------------------------
 
 nsXULMenubarAccessible::nsXULMenubarAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell): 
   nsAccessibleWrap(aDOMNode, aShell)
--- a/accessible/src/xul/nsXULMenuAccessible.h
+++ b/accessible/src/xul/nsXULMenuAccessible.h
@@ -108,30 +108,29 @@ public:
   NS_IMETHOD GetNumActions(PRUint8 *_retval);
 
   // nsAccessible
   virtual nsresult GetNameInternal(nsAString& aName);
   virtual nsresult GetRoleInternal(PRUint32 *aRole);
   virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
 };
 
+
+/**
+ * Used for XUL menupopup and panel.
+ */
 class nsXULMenupopupAccessible : public nsXULSelectableAccessible
 {
 public:
   nsXULMenupopupAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell);
 
   // nsAccessible
   virtual nsresult GetNameInternal(nsAString& aName);
   virtual nsresult GetRoleInternal(PRUint32 *aRole);
   virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
-
-  // nsXULMenupopupAccessible
-  static already_AddRefed<nsIDOMNode> FindInNodeList(nsIDOMNodeList *aNodeList,
-                                                     nsIAtom *aAtom, PRUint32 aNameSpaceID);
-  static void GenerateMenu(nsIDOMNode *aNode);
 };
 
 class nsXULMenubarAccessible : public nsAccessibleWrap
 {
 public:
   nsXULMenubarAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell);
 
   // nsAccessible
--- a/accessible/tests/mochitest/Makefile.in
+++ b/accessible/tests/mochitest/Makefile.in
@@ -37,16 +37,18 @@
 # ***** END LICENSE BLOCK *****
 
 DEPTH		= ../../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = accessible
 
+DIRS	= tree
+
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _TEST_FILES =\
 		letters.gif \
 		moz.png \
 		$(topsrcdir)/content/media/test/bug461281.ogg \
 		longdesc_src.html \
@@ -83,30 +85,27 @@ include $(topsrcdir)/config/rules.mk
 		test_aria_roles.xul \
 		test_aria_token_attrs.html \
 		test_attrs_elm_tree.xul \
 		test_bug420863.html \
 	$(warning   test_childAtPoint.html temporarily disabled) \
 	$(warning	test_childAtPoint.xul temporarily disabled) \
 		test_cssattrs.html \
 		test_descr.html \
-		test_elm_filectrl.html \
 		test_elm_listbox.xul \
 	$(warning   test_elm_media.html temporarily disabled) \
 		test_elm_plugin.html \
-		test_elm_select.html \
-		test_elm_tree.xul \
-		test_elm_txtcntnr.html \
 		test_events_caretmove.html \
 		test_events_coalescence.html \
 		test_events_doc.html \
 		test_events_draganddrop.html \
 		test_events_flush.html \
 		test_events_focus.html \
 		test_events_focus.xul \
+		test_events_focusdoc.html \
 		test_events_mutation.html \
 		test_events_scroll.xul \
 		test_events_tree.xul \
 		test_events_valuechange.html \
 		test_groupattrs.xul \
 		test_groupattrs.html \
 		test_invalidate_accessnode.html \
 		test_invalidate_elmli.html \
--- a/accessible/tests/mochitest/role.js
+++ b/accessible/tests/mochitest/role.js
@@ -1,14 +1,16 @@
 ////////////////////////////////////////////////////////////////////////////////
 // Role constants
 
 const ROLE_ALERT = nsIAccessibleRole.ROLE_ALERT;
 const ROLE_APPLICATION = nsIAccessibleRole.ROLE_APPLICATION;
 const ROLE_APP_ROOT = nsIAccessibleRole.ROLE_APP_ROOT;
+const ROLE_AUTOCOMPLETE = nsIAccessibleRole.ROLE_AUTOCOMPLETE;
+const ROLE_BUTTONDROPDOWNGRID = nsIAccessibleRole.ROLE_BUTTONDROPDOWNGRID;
 const ROLE_CAPTION = nsIAccessibleRole.ROLE_CAPTION;
 const ROLE_CELL = nsIAccessibleRole.ROLE_CELL;
 const ROLE_CHROME_WINDOW = nsIAccessibleRole.ROLE_CHROME_WINDOW;
 const ROLE_COMBOBOX = nsIAccessibleRole.ROLE_COMBOBOX;
 const ROLE_COMBOBOX_LIST = nsIAccessibleRole.ROLE_COMBOBOX_LIST;
 const ROLE_COMBOBOX_OPTION = nsIAccessibleRole.ROLE_COMBOBOX_OPTION;
 const ROLE_COLUMNHEADER = nsIAccessibleRole.ROLE_COLUMNHEADER;
 const ROLE_DOCUMENT = nsIAccessibleRole.ROLE_DOCUMENT;
@@ -22,21 +24,24 @@ const ROLE_GROUPING = nsIAccessibleRole.
 const ROLE_HEADING = nsIAccessibleRole.ROLE_HEADING;
 const ROLE_IMAGE_MAP = nsIAccessibleRole.ROLE_IMAGE_MAP;
 const ROLE_INTERNAL_FRAME = nsIAccessibleRole.ROLE_INTERNAL_FRAME;
 const ROLE_LABEL = nsIAccessibleRole.ROLE_LABEL;
 const ROLE_LINK = nsIAccessibleRole.ROLE_LINK;
 const ROLE_LIST = nsIAccessibleRole.ROLE_LIST;
 const ROLE_LISTBOX = nsIAccessibleRole.ROLE_LISTBOX;
 const ROLE_LISTITEM = nsIAccessibleRole.ROLE_LISTITEM;
+const ROLE_MENUITEM = nsIAccessibleRole.ROLE_MENUITEM;
+const ROLE_MENUPOPUP = nsIAccessibleRole.ROLE_MENUPOPUP;
 const ROLE_NOTHING = nsIAccessibleRole.ROLE_NOTHING;
 const ROLE_OPTION = nsIAccessibleRole.ROLE_OPTION;
 const ROLE_OUTLINE = nsIAccessibleRole.ROLE_OUTLINE;
 const ROLE_OUTLINEITEM = nsIAccessibleRole.ROLE_OUTLINEITEM;
 const ROLE_PARAGRAPH = nsIAccessibleRole.ROLE_PARAGRAPH;
+const ROLE_PARENT_MENUITEM = nsIAccessibleRole.ROLE_PARENT_MENUITEM;
 const ROLE_PASSWORD_TEXT = nsIAccessibleRole.ROLE_PASSWORD_TEXT;
 const ROLE_PROGRESSBAR = nsIAccessibleRole.ROLE_PROGRESSBAR;
 const ROLE_PUSHBUTTON = nsIAccessibleRole.ROLE_PUSHBUTTON;
 const ROLE_ROW = nsIAccessibleRole.ROLE_ROW;
 const ROLE_ROWHEADER = nsIAccessibleRole.ROLE_ROWHEADER;
 const ROLE_SECTION = nsIAccessibleRole.ROLE_SECTION;
 const ROLE_SLIDER = nsIAccessibleRole.ROLE_SLIDER;
 const ROLE_STATICTEXT = nsIAccessibleRole.ROLE_STATICTEXT;
--- a/accessible/tests/mochitest/test_descr.html
+++ b/accessible/tests/mochitest/test_descr.html
@@ -30,16 +30,19 @@
       // No description from @title attribute because it is used to generate
       // name.
       testDescr("img2", "");
 
       // Description from @title attribute, name is generated from @alt
       // attribute.
       testDescr("img3", "description");
 
+      // Description from content of h2.
+      testDescr("p", "heading");
+
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 
 </head>
@@ -56,10 +59,12 @@
   <pre id="test">
   </pre>
 
   <p id="description">aria description</p>
   <img id="img1" aria-describedby="description" />
   <img id="img2" title="title" />
   <img id="img3" alt="name" title="description" />
 
+  <h2 id="heading">heading</h2>
+  <p id="p" aria-describedby="heading" role="button">click me</p>
 </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/test_events_focusdoc.html
@@ -0,0 +1,102 @@
+<html>
+
+<head>
+  <title>Accessible document focus 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">
+
+    /**
+     * Focus invoker.
+     */
+    function takeFocus(aAcc)
+    {
+      this.DOMNode = aAcc; // xxx rename this expected property in events.js
+
+      this.invoke = function takeFocus_invoke()
+      {
+        this.DOMNode.takeFocus();
+      };
+
+      this.check = function takeFocus_check()
+      {
+        testStates(this.DOMNode, STATE_FOCUSABLE | STATE_FOCUSED);
+      };
+
+      this.getID = function takeFocus_getID() { return aAcc.name + " focus"; };
+    }
+
+
+    /**
+     * Do tests.
+     */
+    var gQueue = null;
+
+    //var gA11yEventDumpID = "eventdump";
+
+    function doTests()
+    {
+      // setup
+      var frameDoc = document.getElementById("iframe").contentDocument;
+      frameDoc.designMode = "on";
+      var frameDocAcc = getAccessible(frameDoc, [nsIAccessibleDocument]);
+      var buttonAcc = getAccessible("b1");
+
+      // Test focus events.
+      gQueue = new eventQueue(nsIAccessibleEvent.EVENT_FOCUS);
+
+      // try to give focus to contentEditable frame twice to cover bug 512059
+      gQueue.push(new takeFocus(buttonAcc));
+      gQueue.push(new takeFocus(frameDocAcc));
+      gQueue.push(new takeFocus(buttonAcc));
+      gQueue.push(new takeFocus(frameDocAcc));
+
+      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=512058"
+    title="Can't set focus to designMode document via accessibility APIs">
+   Mozilla Bug 512058
+  </a>
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=512059"
+     title="Accessibility focus event never fired for designMode document after the first focus">
+    Mozilla Bug 512059
+  </a>
+
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test">
+  </pre>
+
+  <div id="eventdump"></div>
+
+  <div id="testContainer">
+  <button id="b1">a button</button>
+  <iframe id="iframe" src="about:blank"></iframe>
+  <button id="b2">a button</button>
+  </div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/tree/Makefile.in
@@ -0,0 +1,61 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is
+# Mozilla Corporation.
+# Portions created by the Initial Developer are Copyright (C) 2009
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Alexander Surkov <surkov.alexander@gmail.com> (original author)
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either of the GNU General Public License Version 2 or later (the "GPL"),
+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH		= ../../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+relativesrcdir  = accessible/tree
+
+include $(DEPTH)/config/autoconf.mk
+include $(topsrcdir)/config/rules.mk
+
+_TEST_FILES =\
+		test_button.xul \
+		test_colorpicker.xul \
+		test_combobox.xul \
+		test_filectrl.html \
+		test_media.html \
+		test_menu.xul \
+		test_select.html \
+		test_tree.xul \
+		test_txtctrl.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/tree/test_button.xul
@@ -0,0 +1,198 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
+                 type="text/css"?>
+
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        title="Accessible XUL button hierarchy tests">
+
+  <script type="application/javascript" 
+          src="chrome://mochikit/content/MochiKit/packed.js" />
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/a11y/accessible/common.js" />
+  <script type="application/javascript"
+          src="chrome://mochikit/content/a11y/accessible/role.js" />
+
+  <script type="application/javascript">
+  <![CDATA[
+    ////////////////////////////////////////////////////////////////////////////
+    // Test
+
+    function doTest()
+    {
+      //////////////////////////////////////////////////////////////////////////
+      // button1
+
+      var accTree = {
+        role: ROLE_PUSHBUTTON,
+        name: "hello",
+        children: [ ]
+      };
+      testAccessibleTree("button1", accTree);
+
+      //////////////////////////////////////////////////////////////////////////
+      // button2
+
+      accTree = {
+        role: ROLE_PUSHBUTTON,
+        name: "hello",
+        children: [
+          {
+            role: ROLE_MENUPOPUP,
+            children: [
+              {
+                role: ROLE_MENUITEM
+              },
+              {
+                role: ROLE_MENUITEM
+              }
+            ]
+          }
+        ]
+      };
+      testAccessibleTree("button2", accTree);
+
+      //////////////////////////////////////////////////////////////////////////
+      // button3
+
+      accTree = {
+        role: ROLE_PUSHBUTTON,
+        name: "hello",
+        children: [
+          {
+            role: ROLE_MENUPOPUP,
+            children: [
+              {
+                role: ROLE_MENUITEM
+              },
+              {
+                role: ROLE_MENUITEM
+              }
+            ]
+          },
+          {
+            role: ROLE_PUSHBUTTON,
+            children: [
+            ]
+          }
+        ]
+      };
+      testAccessibleTree("button3", accTree);
+
+      //////////////////////////////////////////////////////////////////////////
+      // button4
+
+      var accTree = {
+        role: ROLE_PUSHBUTTON,
+        name: "hello",
+        children: [ ]
+      };
+      testAccessibleTree("button4", accTree);
+
+      //////////////////////////////////////////////////////////////////////////
+      // button5
+
+      accTree = {
+        role: ROLE_PUSHBUTTON,
+        name: "hello",
+        children: [
+          {
+            role: ROLE_MENUPOPUP,
+            children: [
+              {
+                role: ROLE_MENUITEM
+              },
+              {
+                role: ROLE_MENUITEM
+              }
+            ]
+          }
+        ]
+      };
+      testAccessibleTree("button5", accTree);
+
+      //////////////////////////////////////////////////////////////////////////
+      // button6
+
+      accTree = {
+        role: ROLE_PUSHBUTTON,
+        name: "hello",
+        children: [
+          {
+            role: ROLE_MENUPOPUP,
+            children: [
+              {
+                role: ROLE_MENUITEM
+              },
+              {
+                role: ROLE_MENUITEM
+              }
+            ]
+          },
+          {
+            role: ROLE_PUSHBUTTON,
+            children: [
+            ]
+          }
+        ]
+      };
+      testAccessibleTree("button6", accTree);
+
+      SimpleTest.finish()
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addA11yLoadEvent(doTest);
+  ]]>
+  </script>
+
+  <hbox flex="1" style="overflow: auto;">
+    <body xmlns="http://www.w3.org/1999/xhtml">
+      <a target="_blank"
+         href="https://bugzilla.mozilla.org/show_bug.cgi?id=249292"
+         title="Ensure accessible children for toolbarbutton types 'menu' and 'menu-button'">
+        Mozilla Bug 249292
+      </a><br/>
+      <p id="display"></p>
+      <div id="content" style="display: none">
+      </div>
+      <pre id="test">
+      </pre>
+    </body>
+
+    <vbox flex="1">
+      <button id="button1" label="hello"/>
+      <button id="button2" type="menu" label="hello">
+        <menupopup>
+          <menuitem label="menuitem"/>
+          <menuitem label="menuitem"/>
+        </menupopup>
+      </button>
+      <button id="button3" type="menu-button" label="hello">
+        <menupopup>
+          <menuitem label="menuitem"/>
+          <menuitem label="menuitem"/>
+        </menupopup>
+      </button>
+
+      <toolbarbutton id="button4" label="hello"/>
+      <toolbarbutton id="button5" type="menu" label="hello">
+        <menupopup>
+          <menuitem label="menuitem"/>
+          <menuitem label="menuitem"/>
+        </menupopup>
+      </toolbarbutton>
+      <toolbarbutton id="button6" type="menu-button" label="hello">
+        <menupopup>
+          <menuitem label="menuitem"/>
+          <menuitem label="menuitem"/>
+        </menupopup>
+      </toolbarbutton>
+    </vbox>
+  </hbox>
+
+</window>
+
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/tree/test_colorpicker.xul
@@ -0,0 +1,75 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
+                 type="text/css"?>
+
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        title="Accessible XUL button hierarchy tests">
+
+  <script type="application/javascript" 
+          src="chrome://mochikit/content/MochiKit/packed.js" />
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/a11y/accessible/common.js" />
+  <script type="application/javascript"
+          src="chrome://mochikit/content/a11y/accessible/role.js" />
+
+  <script type="application/javascript">
+  <![CDATA[
+    ////////////////////////////////////////////////////////////////////////////
+    // Test
+
+    function doTest()
+    {
+      //////////////////////////////////////////////////////////////////////////
+      // button1
+
+      var accTree = {
+        role: ROLE_BUTTONDROPDOWNGRID,
+        children: [
+          {
+            role: ROLE_ALERT,
+            children: [ ]
+          }
+        ]
+      };
+
+      var colorButtons = accTree.children[0].children;
+      for (var idx = 0; idx < 70; idx++) {
+        var obj = { role: ROLE_PUSHBUTTON };
+        colorButtons.push(obj);
+      }
+
+      testAccessibleTree("colorpicker", accTree);
+
+      SimpleTest.finish()
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addA11yLoadEvent(doTest);
+  ]]>
+  </script>
+
+  <hbox flex="1" style="overflow: auto;">
+    <body xmlns="http://www.w3.org/1999/xhtml">
+      <a target="_blank"
+         href="https://bugzilla.mozilla.org/show_bug.cgi?id=249292"
+         title="Ensure accessible children for toolbarbutton types 'menu' and 'menu-button'">
+        Mozilla Bug 249292
+      </a><br/>
+      <p id="display"></p>
+      <div id="content" style="display: none">
+      </div>
+      <pre id="test">
+      </pre>
+    </body>
+
+    <vbox flex="1">
+      <colorpicker id="colorpicker" type="button"/>
+    </vbox>
+  </hbox>
+
+</window>
+
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/tree/test_combobox.xul
@@ -0,0 +1,138 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
+                 type="text/css"?>
+
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        title="Accessible XUL menulist and textbox @autocomplete hierarchy tests">
+
+  <script type="application/javascript" 
+          src="chrome://mochikit/content/MochiKit/packed.js" />
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/a11y/accessible/common.js" />
+  <script type="application/javascript"
+          src="chrome://mochikit/content/a11y/accessible/role.js" />
+
+  <script type="application/javascript">
+  <![CDATA[
+    ////////////////////////////////////////////////////////////////////////////
+    // Test
+
+    function doTest()
+    {
+      //////////////////////////////////////////////////////////////////////////
+      // menulist
+
+      var accTree = {
+        role: ROLE_COMBOBOX,
+        children: [
+          {
+            role: ROLE_COMBOBOX_LIST,
+            children: [
+              {
+                role: ROLE_COMBOBOX_OPTION
+              },
+              {
+                role: ROLE_COMBOBOX_OPTION
+              }
+            ]
+          }
+        ]
+      };
+      testAccessibleTree("menulist", accTree);
+
+      //////////////////////////////////////////////////////////////////////////
+      // textbox@type=autocomplete #1 (history)
+
+      accTree = {
+        role: ROLE_AUTOCOMPLETE,
+        children: [
+          {
+            role: ROLE_ENTRY,
+            children: [
+              {
+                role: ROLE_TEXT_LEAF
+              }
+            ]
+          },
+          {
+            role: ROLE_COMBOBOX_LIST, // context menu popup
+            children: [ ]
+          }
+        ]
+      };
+      testAccessibleTree("autocomplete", accTree);
+
+      //////////////////////////////////////////////////////////////////////////
+      // textbox@type=autocomplete #2 (child menupoup)
+
+      accTree = {
+        role: ROLE_AUTOCOMPLETE,
+        children: [
+          {
+            role: ROLE_COMBOBOX_LIST, // autocomplete menu popup
+            children: [
+              {
+                role: ROLE_COMBOBOX_OPTION
+              }
+            ]
+          },
+          {
+            role: ROLE_ENTRY,
+            children: [ ]
+          },
+          {
+            role: ROLE_COMBOBOX_LIST, // context menu popup
+            children: [ ]
+          }
+        ]
+      };
+      testAccessibleTree("autocomplete2", accTree);
+
+      SimpleTest.finish()
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addA11yLoadEvent(doTest);
+  ]]>
+  </script>
+
+  <hbox flex="1" style="overflow: auto;">
+    <body xmlns="http://www.w3.org/1999/xhtml">
+      <a target="_blank"
+         href="https://bugzilla.mozilla.org/show_bug.cgi?id=249292"
+         title="Ensure accessible children for toolbarbutton types 'menu' and 'menu-button'">
+        Mozilla Bug 249292
+      </a><br/>
+      <p id="display"></p>
+      <div id="content" style="display: none">
+      </div>
+      <pre id="test">
+      </pre>
+    </body>
+
+    <vbox flex="1">
+      <menulist id="menulist">
+        <menupopup>
+          <menuitem label="item"/>
+          <menuitem label="item"/>
+        </menupopup>
+      </menulist>
+
+      <textbox id="autocomplete" type="autocomplete"
+               autocompletesearch="history"
+               value="http://localhost:8888/redirect-a11y.html"/>
+
+      <textbox id="autocomplete2" type="autocomplete">
+        <menupopup>
+          <menuitem label="item1"/>
+        </menupopup>
+      </textbox>
+    </vbox>
+  </hbox>
+
+</window>
+
rename from accessible/tests/mochitest/test_elm_filectrl.html
rename to accessible/tests/mochitest/tree/test_filectrl.html
copy from accessible/tests/mochitest/test_elm_media.html
copy to accessible/tests/mochitest/tree/test_media.html
--- a/accessible/tests/mochitest/test_elm_media.html
+++ b/accessible/tests/mochitest/tree/test_media.html
@@ -10,137 +10,50 @@ https://bugzilla.mozilla.org/show_bug.cg
   <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/actions.js"></script>
-  <script type="application/javascript"
           src="chrome://mochikit/content/a11y/accessible/role.js"></script>
   <script type="application/javascript"
           src="chrome://mochikit/content/a11y/accessible/states.js"></script>
 
   <script type="application/javascript">
 
-    // gA11yEventDumpID = "eventDump";
-
-    function focusChecker(aAcc)
-    {
-      this.type = EVENT_FOCUS;
-      this.target = aAcc;
-      this.getID = function focusChecker_getID()
-      {
-        return "focus handling";
-      }
-      this.check = function focusChecker_check(aEvent)
-      {
-        testStates(this.target, STATE_FOCUSED);
-      }
-    }
-
-    function nameChecker(aAcc, aName)
-    {
-      this.type = EVENT_NAME_CHANGE;
-      this.target = aAcc;
-      this.getID = function nameChecker_getID()
-      {
-        return "name change handling";
-      },
-      this.check = function nameChecker_check(aEvent)
-      {
-        is(aEvent.accessible.name, aName,
-           "Wrong name of " + prettyName(aEvent.accessible) + " on focus");
-      }
-    }
-
     function doTest()
     {
       //////////////////////////////////////////////////////////////////////////
       // test the accessible tree
 
       var accTree = {
         role: ROLE_GROUPING,
         children: [
           { // start/stop button
-            role: ROLE_PUSHBUTTON,
-            name: "Play",
-            states: {
-              states: STATE_FOCUSABLE
-            }
+            role: ROLE_PUSHBUTTON
           },
           { // buffer bar
             role: ROLE_PROGRESSBAR
           },
           { // progress bar
             role: ROLE_PROGRESSBAR
           },
           { // slider of progress bar
-            role: ROLE_SLIDER,
-            name: "0:00 of 0:01 elapsed",
-            states: {
-              states: STATE_FOCUSABLE
-            }
-          },
-          { // duration label, role="presentation"
-            role: ROLE_NOTHING
+            role: ROLE_SLIDER
           },
           { // mute button
-            role: ROLE_PUSHBUTTON,
-            name: "Mute",
-            states: {
-              states: STATE_FOCUSABLE
-            }
+            role: ROLE_PUSHBUTTON
           }
         ]
       };
       testAccessibleTree("audio", accTree);
 
-      //////////////////////////////////////////////////////////////////////////
-      // test actions of audio controls
-
-      var audioElm = getAccessible("audio");
-      var playBtn = audioElm.firstChild;
-      var scrubber = playBtn.nextSibling.nextSibling.nextSibling;
-      var muteBtn = audioElm.lastChild;
-
-      var actions = [
-        {
-          ID: muteBtn,
-          actionName: "press",
-          events: CLICK_EVENTS,
-          eventSeq: [
-            new focusChecker(muteBtn),
-            new nameChecker(muteBtn, "Unmute"),
-          ]
-        },
-        {
-          ID: scrubber,
-          actionName: "activate",
-          events: null,
-          eventSeq: [
-            new focusChecker(scrubber)
-          ]
-        },
-        {
-          ID: playBtn,
-          actionName: "press",
-          events: CLICK_EVENTS,
-          eventSeq: [
-            new focusChecker(playBtn),
-            new nameChecker(playBtn, "Pause"),
-          ]
-        }
-      ];
-
-      testActions(actions); // Will call SimpleTest.finish();
+      SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 </head>
 <body>
 
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/tree/test_menu.xul
@@ -0,0 +1,86 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
+                 type="text/css"?>
+
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        title="Accessible XUL menu hierarchy tests">
+
+  <script type="application/javascript" 
+          src="chrome://mochikit/content/MochiKit/packed.js" />
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/a11y/accessible/common.js" />
+  <script type="application/javascript"
+          src="chrome://mochikit/content/a11y/accessible/role.js" />
+
+  <script type="application/javascript">
+  <![CDATA[
+    ////////////////////////////////////////////////////////////////////////////
+    // Test
+
+    function doTest()
+    {
+      if (LINUX) {
+        // XXX: bug 527646
+
+        todo(false, "Failure on linux.");
+        SimpleTest.finish();
+        return;
+      }
+
+      var accTree = {
+        role: ROLE_PARENT_MENUITEM,
+        name: "menu",
+        children: [
+          {
+            role: ROLE_MENUPOPUP,
+            children: [
+              {
+                role: ROLE_MENUITEM
+              },
+              {
+                role: ROLE_MENUITEM
+              }
+            ]
+          }
+        ]
+      };
+      testAccessibleTree("menu", accTree);
+
+      SimpleTest.finish();
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addA11yLoadEvent(doTest);
+  ]]>
+  </script>
+
+  <hbox flex="1" style="overflow: auto;">
+    <body xmlns="http://www.w3.org/1999/xhtml">
+      <a target="_blank"
+         href="https://bugzilla.mozilla.org/show_bug.cgi?id=249292"
+         title="Ensure accessible children for toolbarbutton types 'menu' and 'menu-button'">
+        Mozilla Bug 249292
+      </a><br/>
+      <p id="display"></p>
+      <div id="content" style="display: none">
+      </div>
+      <pre id="test">
+      </pre>
+    </body>
+
+    <vbox flex="1">
+      <menu id="menu" label="menu">
+        <menupopup>
+          <menuitem label="menuitem"/>
+          <menuitem label="menuitem"/>
+        </menupopup>
+      </menu>
+    </vbox>
+  </hbox>
+
+</window>
+
rename from accessible/tests/mochitest/test_elm_select.html
rename to accessible/tests/mochitest/tree/test_select.html
rename from accessible/tests/mochitest/test_elm_tree.xul
rename to accessible/tests/mochitest/tree/test_tree.xul
rename from accessible/tests/mochitest/test_elm_txtcntnr.html
rename to accessible/tests/mochitest/tree/test_txtctrl.html
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1283,17 +1283,17 @@ function delayedStartup(isLoadingBlank, 
   try {
     FullZoom.init();
   }
   catch(ex) {
     Components.utils.reportError("Failed to init content pref service:\n" + ex);
   }
 
   let NP = {};
-  Cu.import("resource://gre/modules/NetworkPrioritizer.jsm", NP);
+  Cu.import("resource:///modules/NetworkPrioritizer.jsm", NP);
   NP.trackBrowserWindow(window);
 
   // initialize the session-restore service (in case it's not already running)
   if (document.documentElement.getAttribute("windowtype") == "navigator:browser") {
     try {
       var ss = Cc["@mozilla.org/browser/sessionstore;1"].
                getService(Ci.nsISessionStore);
       ss.init(window);
--- a/browser/base/content/fullscreen-video.xhtml
+++ b/browser/base/content/fullscreen-video.xhtml
@@ -133,16 +133,20 @@ window.addEventListener("unload", functi
     contentVideo.muted = video.muted;
     if (!video.paused && !video.ended) {
       video.pause();
       contentVideo.play();
     }
   }
 }, false);
 
+window.addEventListener("deactivate", function () {
+  window.close();
+}, false);
+
 window.addEventListener("keypress", function (event) {
   if (event.keyCode == event.DOM_VK_ESCAPE) {
     window.close();
     return;
   }
 
   resetIdleTimer();
 
--- a/browser/base/content/openLocation.js
+++ b/browser/base/content/openLocation.js
@@ -44,17 +44,17 @@ var dialog = {};
 var pref = null;
 try {
   pref = Components.classes["@mozilla.org/preferences-service;1"]
                    .getService(Components.interfaces.nsIPrefBranch);
 } catch (ex) {
   // not critical, remain silent
 }
 
-Components.utils.import("resource://gre/modules/openLocationLastURL.jsm");
+Components.utils.import("resource:///modules/openLocationLastURL.jsm");
 
 function onLoad()
 {
   dialog.input         = document.getElementById("dialog.input");
   dialog.open          = document.documentElement.getButton("accept");
   dialog.openWhereList = document.getElementById("openWhereList");
   dialog.openTopWindow = document.getElementById("currentWindow");
   dialog.bundle        = document.getElementById("openLocationBundle");
--- a/browser/base/content/pageinfo/pageInfo.js
+++ b/browser/base/content/pageinfo/pageInfo.js
@@ -278,16 +278,21 @@ function onLoadPageInfo()
   gStrings.mediaEmbed = gBundle.getString("mediaEmbed");
   gStrings.mediaLink = gBundle.getString("mediaLink");
   gStrings.mediaInput = gBundle.getString("mediaInput");
 
   var args = "arguments" in window &&
              window.arguments.length >= 1 &&
              window.arguments[0];
 
+  if (!args || !args.doc) {
+    gWindow = window.opener.content;
+    gDocument = gWindow.document;
+  }
+
   // init media view
   var imageTree = document.getElementById("imagetree");
   imageTree.view = gImageView;
 
   /* Select the requested tab, if the name is specified */
   loadTab(args);
   Components.classes["@mozilla.org/observer-service;1"]
             .getService(Components.interfaces.nsIObserverService)
@@ -334,16 +339,17 @@ function resetPageInfo(args)
   /* Reset Feeds Tab */
   var feedListbox = document.getElementById("feedListbox");
   while (feedListbox.firstChild)
     feedListbox.removeChild(feedListbox.firstChild);
 
   /* Call registered overlay reset functions */
   onResetRegistry.forEach(function(func) { func(); });
 
+  /* Rebuild the data */
   loadTab(args);
 }
 
 function onUnloadPageInfo()
 {
   // Remove the observer, only if there is at least 1 image.
   if (!document.getElementById("mediaTab").hidden) {
     Components.classes["@mozilla.org/observer-service;1"]
@@ -378,28 +384,17 @@ function showTab(id)
 }
 
 function loadTab(args)
 {
   if (args && args.doc) {
     gDocument = args.doc;
     gWindow = gDocument.defaultView;
   }
-  else {
-    if ("gBrowser" in window.opener)
-      gWindow = window.opener.gBrowser.contentWindow;
-    else
-      gWindow = window.opener.frames[0];
-    gDocument = gWindow.document;
-  }
 
-  if (args && args.imageElement)
-    gImageElement = args.imageElement;
-
-  /* Rebuild the data */
   gImageElement = args && args.imageElement;
 
   /* Load the page info */
   loadPageInfo();
 
   var initialTab = (args && args.initialTab) || "generalTab";
   var radioGroup = document.getElementById("viewGroup");
   initialTab = document.getElementById(initialTab) || document.getElementById("generalTab");
@@ -592,16 +587,18 @@ function addImage(url, type, alt, elem, 
       Components.classes["@mozilla.org/observer-service;1"]
                 .getService(Components.interfaces.nsIObserverService)
                 .addObserver(imagePermissionObserver, "perm-changed", false);
     }
   }
   else {
     var i = gImageHash[url][type][alt];
     gImageView.data[i][COL_IMAGE_COUNT]++;
+    if (elem == gImageElement)
+      gImageView.data[i][COL_IMAGE_NODE] = elem;
   }
 }
 
 function grabAll(elem)
 {
   // check for background images, any node may have multiple
   var computedStyle = elem.ownerDocument.defaultView.getComputedStyle(elem, "");
   if (computedStyle) {
@@ -1179,12 +1176,14 @@ function doSelectAll()
 function selectImage() {
   if (!gImageElement)
     return;
 
   var tree = document.getElementById("imagetree");
   for (var i = 0; i < tree.view.rowCount; i++) {
     if (gImageElement == gImageView.data[i][COL_IMAGE_NODE]) {
       tree.view.selection.select(i);
+      tree.treeBoxObject.ensureRowIsVisible(i);
+      tree.focus();
       return;
     }
   }
 }
--- a/browser/base/content/safeMode.js
+++ b/browser/base/content/safeMode.js
@@ -78,30 +78,30 @@ function deleteLocalstore() {
 }
 
 function disableAddons() {
   // Disable addons
   const nsIUpdateItem = Components.interfaces.nsIUpdateItem;
   var em = Components.classes["@mozilla.org/extensions/manager;1"]
                      .getService(Components.interfaces.nsIExtensionManager);
   var type = nsIUpdateItem.TYPE_EXTENSION + nsIUpdateItem.TYPE_LOCALE;
-  var items = em.getItemList(type, { });
+  var items = em.getItemList(type);
   for (var i = 0; i < items.length; ++i)
     em.disableItem(items[i].id);
 
   // Select the default theme
   var prefB = Components.classes["@mozilla.org/preferences-service;1"]
                         .getService(Components.interfaces.nsIPrefBranch);
   if (prefB.prefHasUserValue("general.skins.selectedSkin"))
     prefB.clearUserPref("general.skins.selectedSkin");
 
   // Disable plugins
   var phs = Components.classes["@mozilla.org/plugin/host;1"]
                       .getService(Components.interfaces.nsIPluginHost);
-  var plugins = phs.getPluginTags({ });
+  var plugins = phs.getPluginTags();
   for (i = 0; i < plugins.length; ++i)
     plugins[i].disabled = true;
 }
 
 function restoreDefaultSearchEngines() {
   var searchService = Components.classes["@mozilla.org/browser/search-service;1"]
                                 .getService(Components.interfaces.nsIBrowserSearchService);
 
--- a/browser/base/content/sanitize.js
+++ b/browser/base/content/sanitize.js
@@ -351,29 +351,29 @@ Sanitizer.prototype = {
       }
     },
     
     siteSettings: {
       clear: function ()
       {
         // Clear site-specific permissions like "Allow this site to open popups"
         var pm = Components.classes["@mozilla.org/permissionmanager;1"]
-                          .getService(Components.interfaces.nsIPermissionManager);
+                           .getService(Components.interfaces.nsIPermissionManager);
         pm.removeAll();
         
         // Clear site-specific settings like page-zoom level
         var cps = Components.classes["@mozilla.org/content-pref/service;1"]
-                           .getService(Components.interfaces.nsIContentPrefService);
+                            .getService(Components.interfaces.nsIContentPrefService);
         cps.removeGroupedPrefs();
         
         // Clear "Never remember passwords for this site", which is not handled by
         // the permission manager
         var pwmgr = Components.classes["@mozilla.org/login-manager;1"]
-                   .getService(Components.interfaces.nsILoginManager);
-        var hosts = pwmgr.getAllDisabledHosts({})
+                              .getService(Components.interfaces.nsILoginManager);
+        var hosts = pwmgr.getAllDisabledHosts();
         for each (var host in hosts) {
           pwmgr.setLoginSavingEnabled(host, true);
         }
       },
       
       get canClear()
       {
         return true;
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -1509,19 +1509,19 @@
               if (ds.contentViewer && !ds.contentViewer.permitUnload())
                 return null;
             }
 
             var closeWindow = false;
             var l = this.mTabs.length - this._removingTabs.length;
             var newTab = false;
             if (l == 1) {
-              closeWindow = aCloseWindowWithLastTab != null ?
-                            aCloseWindowWithLastTab :
-                            this.mPrefs.getBoolPref("browser.tabs.closeWindowWithLastTab");
+              closeWindow = aCloseWindowWithLastTab != null ? aCloseWindowWithLastTab :
+                            !window.toolbar.visible ||
+                              this.mPrefs.getBoolPref("browser.tabs.closeWindowWithLastTab");
 
               // Closing the tab and replacing it with a blank one is notably slower
               // than closing the window right away. If the caller opts in, take
               // the fast path.
               if (closeWindow &&
                   aCloseWindowFastpath &&
                   this._removingTabs.length == 0 &&
                   (this._windowIsClosing = window.closeWindow(true)))
--- a/browser/base/content/test/Makefile.in
+++ b/browser/base/content/test/Makefile.in
@@ -92,16 +92,17 @@ include $(topsrcdir)/config/rules.mk
                  browser_bug424101.js \
                  browser_bug427559.js \
                  browser_bug432599.js \
                  browser_bug435035.js \
                  browser_bug441778.js \
                  browser_bug455852.js \
                  browser_bug462673.js \
                  browser_bug481560.js \
+                 browser_bug484315.js \
                  browser_bug477014.js \
                  browser_bug495058.js \
                  browser_bug517902.js \
                  browser_bug521216.js \
                  browser_discovery.js \
                  browser_tabfocus.js \
                  discovery.html \
                  moz.png \
--- a/browser/base/content/test/browser_NetworkPrioritizer.js
+++ b/browser/base/content/test/browser_NetworkPrioritizer.js
@@ -99,41 +99,41 @@ function test() {
       // Next tab is auto selected
       isWindowState(window_A, [0, -10]);
 
       // Open another window then play with focus
       let window_B = openDialog(location, "_blank", "chrome,all,dialog=no", "http://example.com");
       window_B.addEventListener("load", function(aEvent) {
         window_B.removeEventListener("load", arguments.callee, false);
         window_B.gBrowser.addEventListener("load", function(aEvent) {
+          // waitForFocus can attach to the wrong "window" with about:blank loading first
+          // So just ensure that we're getting the load event for the right URI
+          if (window_B.gBrowser.currentURI.spec == "about:blank")
+            return;
           window_B.gBrowser.removeEventListener("load", arguments.callee, true);
 
-          // On Linux, waitForFocus doesn't work if the window is already focused,
-          // so focus window_A first.
           waitForFocus(function() {
+            isWindowState(window_A, [10, 0]);
+            isWindowState(window_B, [-10]);
+
             waitForFocus(function() {
-              isWindowState(window_A, [10, 0]);
-              isWindowState(window_B, [-10]);
+              isWindowState(window_A, [0, -10]);
+              isWindowState(window_B, [0]);
 
               waitForFocus(function() {
-                isWindowState(window_A, [0, -10]);
-                isWindowState(window_B, [0]);
-
-                waitForFocus(function() {
-                  isWindowState(window_A, [10, 0]);
-                  isWindowState(window_B, [-10]);
+                isWindowState(window_A, [10, 0]);
+                isWindowState(window_B, [-10]);
 
-                  // And we're done. Cleanup & run the next test
-                  window_B.close();
-                  window_A.gBrowser.removeTab(tab_A3);
-                  executeSoon(runNextTest);
-                }, window_B);
-              }, window_A);
-            }, window_B);
-          }, window_A);
+                // And we're done. Cleanup & run the next test
+                window_B.close();
+                window_A.gBrowser.removeTab(tab_A3);
+                executeSoon(runNextTest);
+              }, window_B);
+            }, window_A);
+          }, window_B);
 
         }, true);
       }, false);
     }, true);
 
   }
 
 
--- a/browser/base/content/test/browser_bug481560.js
+++ b/browser/base/content/test/browser_bug481560.js
@@ -1,30 +1,23 @@
 function test() {
   waitForExplicitFinish();
 
-  // focus the url field so that it will can ensure the focus is there when
-  // the window is refocused after the dialog closes
-  gURLBar.focus();
-
-  window.addEventListener("focus", function () {
-    window.removeEventListener("focus", arguments.callee, false);
-    finish();
-  }, false);
-
   var win = openDialog(getBrowserURL(), "_blank", "chrome,all,dialog=no");
 
   win.addEventListener("load", function () {
     win.removeEventListener("load", arguments.callee, false);
 
     win.content.addEventListener("focus", function () {
       win.content.removeEventListener("focus", arguments.callee, false);
 
-      EventUtils.synthesizeKey("w", { accelKey: true }, win);
-      ok(win.closed, "accel+w closed the window immediately");
-    }, false);
+      win.gBrowser.selectedTab.addEventListener("TabClose", function () {
+        ok(false, "shouldn't have gotten the TabClose event for the last tab");
+      }, false);
 
-    win.gBrowser.selectedTab.addEventListener("TabClose", function () {
-      ok(false, "shouldn't have gotten the TabClose event for the last tab");
+      EventUtils.synthesizeKey("w", { accelKey: true }, win);
+
+      ok(win.closed, "accel+w closed the window immediately");
+
+      finish();
     }, false);
-
   }, false);
 }
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_bug484315.js
@@ -0,0 +1,25 @@
+function test() {
+  var contentWin = window.open("about:blank", "", "width=100,height=100");
+  var enumerator = Cc["@mozilla.org/appshell/window-mediator;1"]
+                     .getService(Ci.nsIWindowMediator)
+                     .getEnumerator("navigator:browser");
+
+  while (enumerator.hasMoreElements()) {
+    let win = enumerator.getNext();
+    if (win.content == contentWin) {
+      gPrefService.setBoolPref("browser.tabs.closeWindowWithLastTab", false);
+      win.gBrowser.removeCurrentTab();
+      ok(win.closed, "popup is closed");
+
+      // clean up
+      if (!win.closed)
+        win.close();
+      if (gPrefService.prefHasUserValue("browser.tabs.closeWindowWithLastTab"))
+        gPrefService.clearUserPref("browser.tabs.closeWindowWithLastTab");
+
+      return;
+    }
+  }
+
+  throw "couldn't find the content window";
+}
--- a/browser/base/content/test/browser_bug517902.js
+++ b/browser/base/content/test/browser_bug517902.js
@@ -28,10 +28,11 @@ function test() {
       });
     }, true);
   }, true);
 
   content.location =
     "data:text/html," +
     "<img src='about:logo?a' height=200 width=250>" +
     "<img src='about:logo?b' height=200 width=250 alt=1>" +
+    "<img src='about:logo?b' height=200 width=250 alt=2>" +
     "<img src='about:logo?b' height=100 width=150 alt=2 id='test-image'>";
 }
--- a/browser/base/content/test/browser_pluginnotification.js
+++ b/browser/base/content/test/browser_pluginnotification.js
@@ -1,17 +1,17 @@
 const gTestRoot = "chrome://mochikit/content/browser/browser/base/content/test/";
 
 var gTestBrowser = null;
 var gNextTest = null;
 
 function get_test_plugin() {
   var ph = Components.classes["@mozilla.org/plugin/host;1"]
                      .getService(Components.interfaces.nsIPluginHost);
-  var tags = ph.getPluginTags({});
+  var tags = ph.getPluginTags();
   
   // Find the test plugin
   for (var i = 0; i < tags.length; i++) {
     if (tags[i].name == "Test Plug-in")
       return tags[i];
   }
 }
 
--- a/browser/base/content/utilityOverlay.js
+++ b/browser/base/content/utilityOverlay.js
@@ -193,21 +193,25 @@ function openUILinkIn( url, where, allow
   if (!w || where == "window") {
     var sa = Cc["@mozilla.org/supports-array;1"].
              createInstance(Ci.nsISupportsArray);
 
     var wuri = Cc["@mozilla.org/supports-string;1"].
                createInstance(Ci.nsISupportsString);
     wuri.data = url;
 
+    var allowThirdPartyFixupSupports = Cc["@mozilla.org/supports-PRBool;1"].
+                                       createInstance(Ci.nsISupportsPRBool);
+    allowThirdPartyFixupSupports.data = allowThirdPartyFixup;
+
     sa.AppendElement(wuri);
     sa.AppendElement(null);
     sa.AppendElement(referrerUrl);
     sa.AppendElement(postData);
-    sa.AppendElement(allowThirdPartyFixup);
+    sa.AppendElement(allowThirdPartyFixupSupports);
 
     var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
              getService(Ci.nsIWindowWatcher);
 
     ww.openWindow(w || window,
                   getBrowserURL(),
                   null,
                   "chrome,dialog=no,all",
--- a/browser/components/build/Makefile.in
+++ b/browser/components/build/Makefile.in
@@ -31,27 +31,29 @@ OS_LIBS	+= $(call EXPAND_LIBNAME,ole32 s
 endif
 
 LOCAL_INCLUDES = \
 	-I$(srcdir)/../shell/src \
 	-I$(srcdir)/../feeds/src \
 	-I$(srcdir)/../places/src \
 	-I$(srcdir)/../privatebrowsing/src \
 	-I$(srcdir)/../about \
+	-I$(srcdir)/../dirprovider \
 	$(NULL)
 
 ifeq ($(OS_ARCH),WINNT)
 OS_LIBS += $(call EXPAND_LIBNAME,version)
 endif
 
 SHARED_LIBRARY_LIBS = \
 	../feeds/src/$(LIB_PREFIX)browser_feeds_s.$(LIB_SUFFIX) \
 	../places/src/$(LIB_PREFIX)browserplaces_s.$(LIB_SUFFIX) \
 	../privatebrowsing/src/$(LIB_PREFIX)privatebrowsing_s.$(LIB_SUFFIX) \
 	../about/$(LIB_PREFIX)browserabout_s.$(LIB_SUFFIX) \
+	../dirprovider/$(LIB_PREFIX)browserdir_s.$(LIB_SUFFIX) \
 	$(NULL)
 
 ifneq (,$(filter windows cocoa gtk2, $(MOZ_WIDGET_TOOLKIT)))
 SHARED_LIBRARY_LIBS += ../shell/src/$(LIB_PREFIX)shellservice_s.$(LIB_SUFFIX)
 endif
 
 EXTRA_DSO_LDOPTS += $(call EXPAND_LIBNAME_PATH,unicharutil_external_s,$(LIBXUL_DIST)/lib)
 
--- a/browser/components/build/nsBrowserCompsCID.h
+++ b/browser/components/build/nsBrowserCompsCID.h
@@ -101,8 +101,11 @@
 // 136e2c4d-c5a4-477c-b131-d93d7d704f64
 #define NS_PRIVATE_BROWSING_SERVICE_WRAPPER_CID \
 { 0x136e2c4d, 0xc5a4, 0x477c, { 0xb1, 0x31, 0xd9, 0x3d, 0x7d, 0x70, 0x4f, 0x64 } }
 
 // 7e4bb6ad-2fc4-4dc6-89ef-23e8e5ccf980
 #define NS_BROWSER_ABOUT_REDIRECTOR_CID \
 { 0x7e4bb6ad, 0x2fc4, 0x4dc6, { 0x89, 0xef, 0x23, 0xe8, 0xe5, 0xcc, 0xf9, 0x80 } }
 
+// {6DEB193C-F87D-4078-BC78-5E64655B4D62}
+#define NS_BROWSERDIRECTORYPROVIDER_CID \
+{ 0x6deb193c, 0xf87d, 0x4078, { 0xbc, 0x78, 0x5e, 0x64, 0x65, 0x5b, 0x4d, 0x62 } }
--- a/browser/components/build/nsModule.cpp
+++ b/browser/components/build/nsModule.cpp
@@ -34,16 +34,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsIGenericFactory.h"
 
 #include "nsBrowserCompsCID.h"
+#include "DirectoryProvider.h"
 #include "nsPlacesImportExportService.h"
 
 #if defined(XP_WIN)
 #include "nsWindowsShellService.h"
 #elif defined(XP_MACOSX)
 #include "nsMacShellService.h"
 #elif defined(MOZ_WIDGET_GTK2)
 #include "nsGNOMEShellService.h"
@@ -79,16 +80,17 @@
 
 #include "nsPrivateBrowsingServiceWrapper.h"
 #include "nsNetCID.h"
 
 using namespace mozilla::browser;
 
 /////////////////////////////////////////////////////////////////////////////
 
+NS_GENERIC_FACTORY_CONSTRUCTOR(DirectoryProvider)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsPlacesImportExportService)
 #if defined(XP_WIN)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsWindowsShellService)
 #elif defined(XP_MACOSX)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacShellService)
 #elif defined(MOZ_WIDGET_GTK2)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsGNOMEShellService, Init)
 #endif
@@ -119,16 +121,24 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsICabPro
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsFeedSniffer)
 
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrivateBrowsingServiceWrapper, Init)
 
 /////////////////////////////////////////////////////////////////////////////
 
 static const nsModuleComponentInfo components[] =
 {
+  { "Browser Directory Provider",
+    NS_BROWSERDIRECTORYPROVIDER_CID,
+    NS_BROWSERDIRECTORYPROVIDER_CONTRACTID,
+    DirectoryProviderConstructor,
+    DirectoryProvider::Register,
+    DirectoryProvider::Unregister
+  },
+
 #if defined(XP_WIN)
   { "Browser Shell Service",
     NS_SHELLSERVICE_CID,
     NS_SHELLSERVICE_CONTRACTID,
     nsWindowsShellServiceConstructor},
 
 #elif defined(MOZ_WIDGET_GTK2)
   { "Browser Shell Service",
rename from browser/components/dirprovider/nsBrowserDirectoryProvider.cpp
rename to browser/components/dirprovider/DirectoryProvider.cpp
--- a/browser/components/dirprovider/nsBrowserDirectoryProvider.cpp
+++ b/browser/components/dirprovider/DirectoryProvider.cpp
@@ -31,16 +31,17 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsIDirectoryService.h"
+#include "DirectoryProvider.h"
 
 #include "nsIFile.h"
 #include "nsISimpleEnumerator.h"
 #include "nsIPrefService.h"
 #include "nsIPrefBranch.h"
 
 #include "nsArrayEnumerator.h"
 #include "nsEnumeratorUtils.h"
@@ -51,62 +52,25 @@
 #include "nsComponentManagerUtils.h"
 #include "nsCOMArray.h"
 #include "nsDirectoryServiceUtils.h"
 #include "nsIGenericFactory.h"
 #include "nsServiceManagerUtils.h"
 #include "nsStringAPI.h"
 #include "nsXULAppAPI.h"
 
-class nsBrowserDirectoryProvider :
-  public nsIDirectoryServiceProvider2
-{
-public:
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSIDIRECTORYSERVICEPROVIDER
-  NS_DECL_NSIDIRECTORYSERVICEPROVIDER2
-
-  static NS_METHOD Register(nsIComponentManager* aCompMgr,
-                            nsIFile* aPath, const char *aLoaderStr,
-                            const char *aType,
-                            const nsModuleComponentInfo *aInfo);
-
-  static NS_METHOD Unregister(nsIComponentManager* aCompMgr,
-                              nsIFile* aPath, const char *aLoaderStr,
-                              const nsModuleComponentInfo *aInfo);
+namespace mozilla {
+namespace browser {
 
-private:
-  nsresult RestoreBookmarksFromBackup(const nsACString& aLeafName,
-				      nsIFile* aParentDir, nsIFile* aTarget);
-  void EnsureProfileFile(const nsACString& aLeafName,
-			 nsIFile* aParentDir, nsIFile* aTarget);
-
-  class AppendingEnumerator : public nsISimpleEnumerator
-  {
-  public:
-    NS_DECL_ISUPPORTS
-    NS_DECL_NSISIMPLEENUMERATOR
-
-    AppendingEnumerator(nsISimpleEnumerator* aBase,
-                        char const *const *aAppendList);
-
-  private:
-    nsCOMPtr<nsISimpleEnumerator> mBase;
-    char const *const *const      mAppendList;
-    nsCOMPtr<nsIFile>             mNext;
-  };
-};
-
-NS_IMPL_ISUPPORTS2(nsBrowserDirectoryProvider,
+NS_IMPL_ISUPPORTS2(DirectoryProvider,
                    nsIDirectoryServiceProvider,
                    nsIDirectoryServiceProvider2)
 
 NS_IMETHODIMP
-nsBrowserDirectoryProvider::GetFile(const char *aKey, PRBool *aPersist,
-                                    nsIFile* *aResult)
+DirectoryProvider::GetFile(const char *aKey, PRBool *aPersist, nsIFile* *aResult)
 {
   nsresult rv;
 
   *aResult = nsnull;
 
   // NOTE: This function can be reentrant through the NS_GetSpecialDirectory
   // call, so be careful not to cause infinite recursion.
 
@@ -285,18 +249,17 @@ AppendDistroSearchDirs(nsIProperties* aD
         if (NS_SUCCEEDED(rv) && exists)
           array.AppendObject(defLocalePlugins);
       }
     }
   }
 }
 
 NS_IMETHODIMP
-nsBrowserDirectoryProvider::GetFiles(const char *aKey,
-                                     nsISimpleEnumerator* *aResult)
+DirectoryProvider::GetFiles(const char *aKey, nsISimpleEnumerator* *aResult)
 {
   nsresult rv;
 
   if (!strcmp(aKey, NS_APP_SEARCH_DIR_LIST)) {
     nsCOMPtr<nsIProperties> dirSvc
       (do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
     if (!dirSvc)
       return NS_ERROR_FAILURE;
@@ -326,85 +289,64 @@ nsBrowserDirectoryProvider::GetFiles(con
       return NS_ERROR_OUT_OF_MEMORY;
 
     return NS_NewUnionEnumerator(aResult, extEnum, baseEnum);
   }
 
   return NS_ERROR_FAILURE;
 }
 
-static char const kContractID[] = "@mozilla.org/browser/directory-provider;1";
-
-// {6DEB193C-F87D-4078-BC78-5E64655B4D62}
-#define NS_BROWSERDIRECTORYPROVIDER_CID \
-  { 0x6deb193c, 0xf87d, 0x4078, { 0xbc, 0x78, 0x5e, 0x64, 0x65, 0x5b, 0x4d, 0x62 } }
-
 NS_METHOD
-nsBrowserDirectoryProvider::Register(nsIComponentManager* aCompMgr,
-                                     nsIFile* aPath, const char *aLoaderStr,
-                                     const char *aType,
-                                     const nsModuleComponentInfo *aInfo)
+DirectoryProvider::Register(nsIComponentManager* aCompMgr, nsIFile* aPath,
+                            const char *aLoaderStr, const char *aType,
+                            const nsModuleComponentInfo *aInfo)
 {
   nsresult rv;
 
   nsCOMPtr<nsICategoryManager> catMan
     (do_GetService(NS_CATEGORYMANAGER_CONTRACTID));
   if (!catMan)
     return NS_ERROR_FAILURE;
 
   rv = catMan->AddCategoryEntry(XPCOM_DIRECTORY_PROVIDER_CATEGORY,
                                 "browser-directory-provider",
-                                kContractID, PR_TRUE, PR_TRUE, nsnull);
+                                NS_BROWSERDIRECTORYPROVIDER_CONTRACTID,
+                                PR_TRUE, PR_TRUE, nsnull);
   return rv;
 }
 
 
 NS_METHOD
-nsBrowserDirectoryProvider::Unregister(nsIComponentManager* aCompMgr,
-                                       nsIFile* aPath, const char *aLoaderStr,
-                                       const nsModuleComponentInfo *aInfo)
+DirectoryProvider::Unregister(nsIComponentManager* aCompMgr, 
+                              nsIFile* aPath, const char *aLoaderStr,
+                              const nsModuleComponentInfo *aInfo)
 {
   nsresult rv;
 
   nsCOMPtr<nsICategoryManager> catMan
     (do_GetService(NS_CATEGORYMANAGER_CONTRACTID));
   if (!catMan)
     return NS_ERROR_FAILURE;
 
   rv = catMan->DeleteCategoryEntry(XPCOM_DIRECTORY_PROVIDER_CATEGORY,
                                    "browser-directory-provider", PR_TRUE);
   return rv;
 }
 
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsBrowserDirectoryProvider)
-
-static const nsModuleComponentInfo components[] = {
-  {
-    "nsBrowserDirectoryProvider",
-    NS_BROWSERDIRECTORYPROVIDER_CID,
-    kContractID,
-    nsBrowserDirectoryProviderConstructor,
-    nsBrowserDirectoryProvider::Register,
-    nsBrowserDirectoryProvider::Unregister
-  }
-};
-
-NS_IMPL_NSGETMODULE(BrowserDirProvider, components)
-NS_IMPL_ISUPPORTS1(nsBrowserDirectoryProvider::AppendingEnumerator,
-                   nsISimpleEnumerator)
+NS_IMPL_ISUPPORTS1(DirectoryProvider::AppendingEnumerator, nsISimpleEnumerator)
 
 NS_IMETHODIMP
-nsBrowserDirectoryProvider::AppendingEnumerator::HasMoreElements(PRBool *aResult)
+DirectoryProvider::AppendingEnumerator::HasMoreElements(PRBool *aResult)
 {
   *aResult = mNext ? PR_TRUE : PR_FALSE;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsBrowserDirectoryProvider::AppendingEnumerator::GetNext(nsISupports* *aResult)
+DirectoryProvider::AppendingEnumerator::GetNext(nsISupports* *aResult)
 {
   if (aResult)
     NS_ADDREF(*aResult = mNext);
 
   mNext = nsnull;
 
   nsresult rv;
 
@@ -435,17 +377,20 @@ nsBrowserDirectoryProvider::AppendingEnu
       break;
 
     mNext = nsnull;
   }
 
   return NS_OK;
 }
 
-nsBrowserDirectoryProvider::AppendingEnumerator::AppendingEnumerator
+DirectoryProvider::AppendingEnumerator::AppendingEnumerator
     (nsISimpleEnumerator* aBase,
      char const *const *aAppendList) :
   mBase(aBase),
   mAppendList(aAppendList)
 {
   // Initialize mNext to begin.
   GetNext(nsnull);
 }
+
+} // namespace browser
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/browser/components/dirprovider/DirectoryProvider.h
@@ -0,0 +1,89 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla Firefox browser.
+ *
+ * The Initial Developer of the Original Code is
+ * Benjamin Smedberg <benjamin@smedbergs.us>
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2005
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef DirectoryProvider_h__
+#define DirectoryProvider_h__
+
+#include "nsIDirectoryService.h"
+#include "nsComponentManagerUtils.h"
+#include "nsISimpleEnumerator.h"
+#include "nsIFile.h"
+#include "nsIGenericFactory.h"
+
+#define NS_BROWSERDIRECTORYPROVIDER_CONTRACTID \
+  "@mozilla.org/browser/directory-provider;1"
+
+namespace mozilla {
+namespace browser {
+
+class DirectoryProvider : public nsIDirectoryServiceProvider2
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIDIRECTORYSERVICEPROVIDER
+  NS_DECL_NSIDIRECTORYSERVICEPROVIDER2
+
+  static NS_METHOD Register(nsIComponentManager* aCompMgr,
+                            nsIFile* aPath, const char *aLoaderStr,
+                            const char *aType,
+                            const nsModuleComponentInfo *aInfo);
+
+  static NS_METHOD Unregister(nsIComponentManager* aCompMgr,
+                              nsIFile* aPath, const char *aLoaderStr,
+                              const nsModuleComponentInfo *aInfo);
+
+private:
+  class AppendingEnumerator : public nsISimpleEnumerator
+  {
+  public:
+    NS_DECL_ISUPPORTS
+    NS_DECL_NSISIMPLEENUMERATOR
+
+    AppendingEnumerator(nsISimpleEnumerator* aBase,
+                        char const *const *aAppendList);
+
+  private:
+    nsCOMPtr<nsISimpleEnumerator> mBase;
+    char const *const *const      mAppendList;
+    nsCOMPtr<nsIFile>             mNext;
+  };
+};
+
+} // namespace browser
+} // namespace mozilla
+
+#endif // DirectoryProvider_h__
--- a/browser/components/dirprovider/Makefile.in
+++ b/browser/components/dirprovider/Makefile.in
@@ -37,29 +37,35 @@
 
 DEPTH     = ../../..
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE               = browsercomps
-LIBRARY_NAME         = browserdirprovider
-SHORT_LIBNAME        = brwsrdir
-IS_COMPONENT         = 1
-MODULE_NAME          = BrowserDirProvider
-FORCE_SHARED_LIB     = 1
+MODULE = browserdir
+LIBRARY_NAME = browserdir_s
+
+DIRS = tests
+
+FORCE_STATIC_LIB = 1
+FORCE_USE_PIC = 1
 
 # Because we are an application component, link against the CRT statically
 # (on Windows, but only if we're not building our own CRT for jemalloc)
 ifndef MOZ_MEMORY
 USE_STATIC_LIBS      = 1
 endif
 
-CPPSRCS = nsBrowserDirectoryProvider.cpp
+EXPORTS_NAMESPACES = mozilla/browser
+EXPORTS_mozilla/browser = DirectoryProvider.h
+
+CPPSRCS = DirectoryProvider.cpp
+
+LOCAL_INCLUDES = -I$(srcdir)/../build
 
 EXTRA_DSO_LDOPTS = \
 	$(XPCOM_GLUE_LDOPTS) \
 	$(NSPR_LIBS) \
 	$(NULL)
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/browser/components/dirprovider/tests/Makefile.in
@@ -0,0 +1,49 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is Mozilla Foundation.
+# Portions created by the Initial Developer are Copyright (C) 2009
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Ryan Flint <rflint@mozilla.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 *****
+
+DEPTH          = ../../../..
+topsrcdir      = @top_srcdir@
+srcdir         = @srcdir@
+VPATH          = @srcdir@
+relativesrcdir = browser/components/dirprovider/tests
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE = test_browserdir
+
+XPCSHELL_TESTS = unit
+
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/browser/components/dirprovider/tests/unit/head_dirprovider.js
@@ -0,0 +1,52 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Ryan Flint <rflint@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+var gProfD = do_get_profile();
+var gDirSvc = Cc["@mozilla.org/file/directory_service;1"].
+              getService(Ci.nsIProperties);
+var gPrefSvc = Cc["@mozilla.org/preferences-service;1"].
+               getService(Ci.nsIPrefBranch);
+
+function writeTestFile(aParent, aName) {
+  let file = aParent.clone();
+  file.append(aName);
+  file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0644);
+  return file;
+}
+
new file mode 100644
--- /dev/null
+++ b/browser/components/dirprovider/tests/unit/test_bookmark_pref.js
@@ -0,0 +1,46 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Ryan Flint <rflint@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// We need to run this test separately since DirectoryProvider persists BMarks
+
+function run_test() {
+  let dir = gProfD.clone();
+  let tfile = writeTestFile(dir, "bookmarkfile.test");
+  gPrefSvc.setCharPref("browser.bookmarks.file", tfile.path);
+
+  let bmarks = gDirSvc.get("BMarks", Ci.nsIFile);
+  do_check_true(tfile.equals(bmarks));
+}
new file mode 100644
--- /dev/null
+++ b/browser/components/dirprovider/tests/unit/test_keys.js
@@ -0,0 +1,91 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Ryan Flint <rflint@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+function test_usr_micsum() {
+  let mdir = gProfD.clone();
+  mdir.append("microsummary-generators");
+
+  let tmdir = gDirSvc.get("UsrMicsumGens", Ci.nsIFile);
+  do_check_true(tmdir.equals(mdir));
+
+  if (!tmdir.exists())
+    tmdir.create(Ci.nsIFile.DIRECTORY_TYPE, 0777);
+
+  do_check_true(tmdir.isWritable());
+
+  let tfile = writeTestFile(tmdir, "usrmicsum");
+  do_check_true(tfile.exists());
+
+  mdir.append(tfile.leafName);
+  do_check_true(mdir.exists());
+}
+
+function test_app_micsum() {
+  let mdir = gDirSvc.get("XCurProcD", Ci.nsIFile);
+  mdir.append("microsummary-generators");
+
+  let tmdir = gDirSvc.get("MicsumGens", Ci.nsIFile);
+  do_check_true(tmdir.equals(mdir));
+}
+
+function test_bookmarkhtml() {
+  let bmarks = gProfD.clone();
+  bmarks.append("bookmarks.html");
+
+  let tbmarks = gDirSvc.get("BMarks", Ci.nsIFile);
+  do_check_true(bmarks.equals(tbmarks));
+}
+
+function test_prefoverride() {
+  let dir = gDirSvc.get("DefRt", Ci.nsIFile);
+  dir.append("existing-profile-defaults.js");
+
+  let tdir = gDirSvc.get("ExistingPrefOverride", Ci.nsIFile);
+  do_check_true(dir.equals(tdir));
+}
+
+function run_test() {
+  [test_usr_micsum,
+   test_app_micsum,
+   test_bookmarkhtml,
+   test_prefoverride
+  ].forEach(function(f) {
+    do_test_pending();
+    print("Running test: " + f.name);
+    f();
+    do_test_finished();
+  });
+}
--- a/browser/components/feeds/public/nsIWebContentConverterRegistrar.idl
+++ b/browser/components/feeds/public/nsIWebContentConverterRegistrar.idl
@@ -129,17 +129,18 @@ interface nsIWebContentConverterService 
   void removeContentHandler(in AString contentType, in AString uri);
 
   /**
    * Gets the list of content handlers for a particular type.
    * @param   contentType
    *          The content type to get handlers for
    * @returns An array of nsIWebContentHandlerInfo objects
    */
-  void getContentHandlers(in AString contentType, out unsigned long count,
+  void getContentHandlers(in AString contentType,
+                          [optional] out unsigned long count,
                           [retval,array,size_is(count)] out nsIWebContentHandlerInfo handlers);
 
   /**
    * Resets the list of available content handlers to the default set from
    * the distribution.
    * @param   contentType
    *          The content type to reset handlers for
    */
--- a/browser/components/feeds/src/FeedWriter.js
+++ b/browser/components/feeds/src/FeedWriter.js
@@ -1036,17 +1036,17 @@ FeedWriter.prototype = {
 
     var historySvc = Cc["@mozilla.org/browser/nav-history-service;1"].
                      getService(Ci.nsINavHistoryService);
     historySvc.addObserver(this, false);
 
     // List of web handlers
     var wccr = Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
                getService(Ci.nsIWebContentConverterService);
-    var handlers = wccr.getContentHandlers(this._getMimeTypeForFeedType(feedType), {});
+    var handlers = wccr.getContentHandlers(this._getMimeTypeForFeedType(feedType));
     if (handlers.length != 0) {
       for (var i = 0; i < handlers.length; ++i) {
         menuItem = this._document.createElementNS(XUL_NS, "menuitem");
         menuItem.className = "menuitem-iconic";
         menuItem.setAttribute("label", handlers[i].name);
         menuItem.setAttribute("handlerType", "web");
         menuItem.setAttribute("webhandlerurl", handlers[i].uri);
         this._contentSandbox.menuItem = menuItem;
--- a/browser/components/places/content/treeView.js
+++ b/browser/components/places/content/treeView.js
@@ -330,33 +330,34 @@ PlacesTreeView.prototype = {
         selection.rangedSelect(previouslySelectedNodes[0].oldIndex,
                                previouslySelectedNodes[0].oldIndex, true);
       }
     }
     selection.selectEventsSuppressed = false;
   },
 
   _convertPRTimeToString: function PTV__convertPRTimeToString(aTime) {
-    var timeInMilliseconds = aTime / 1000; // PRTime is in microseconds
+    const MS_PER_MINUTE = 60000;
+    const MS_PER_DAY = 86400000;
+    let timeMs = aTime / 1000; // PRTime is in microseconds
 
     // Date is calculated starting from midnight, so the modulo with a day are
     // milliseconds from today's midnight.
-    // getTimezoneOffset corrects that based on local time.
-    // 86400000 = 24 * 60 * 60 * 1000 = 1 day
-    // 60000 = 60 * 1000 = 1 minute
-    var dateObj = new Date();
-    var timeZoneOffsetInMs = dateObj.getTimezoneOffset() * 60000;
-    var now = dateObj.getTime() - timeZoneOffsetInMs;
-    var midnight = now - (now % (86400000));
+    // getTimezoneOffset corrects that based on local time, notice midnight
+    // can have a different offset during DST-change days.
+    let dateObj = new Date();
+    let now = dateObj.getTime() - dateObj.getTimezoneOffset() * MS_PER_MINUTE;
+    let midnight = now - (now % MS_PER_DAY);
+    midnight += new Date(midnight).getTimezoneOffset() * MS_PER_MINUTE;
 
-    var dateFormat = timeInMilliseconds - timeZoneOffsetInMs >= midnight ?
+    let dateFormat = timeMs >= midnight ?
                       Ci.nsIScriptableDateFormat.dateFormatNone :
                       Ci.nsIScriptableDateFormat.dateFormatShort;
 
-    var timeObj = new Date(timeInMilliseconds);
+    let timeObj = new Date(timeMs);
     return (this._dateService.FormatDateTime("", dateFormat,
       Ci.nsIScriptableDateFormat.timeFormatNoSeconds,
       timeObj.getFullYear(), timeObj.getMonth() + 1,
       timeObj.getDate(), timeObj.getHours(),
       timeObj.getMinutes(), timeObj.getSeconds()));
   },
 
   COLUMN_TYPE_UNKNOWN: 0,
--- a/browser/components/places/content/utils.js
+++ b/browser/components/places/content/utils.js
@@ -1133,98 +1133,180 @@ var PlacesUIUtils = {
   get leftPaneQueries() {    
     // build the map
     this.leftPaneFolderId;
     return this.leftPaneQueries;
   },
 
   // Get the folder id for the organizer left-pane folder.
   get leftPaneFolderId() {
-    var leftPaneRoot = -1;
-    var allBookmarksId;
+    let leftPaneRoot = -1;
+    let allBookmarksId;
 
     // Shortcuts to services.
-    var bs = PlacesUtils.bookmarks;
-    var as = PlacesUtils.annotations;
+    let bs = PlacesUtils.bookmarks;
+    let as = PlacesUtils.annotations;
+
+    // This is the list of the left pane queries.
+    let queries = {
+      "PlacesRoot": { title: "" },
+      "History": { title: this.getString("OrganizerQueryHistory") },
+      "Tags": { title: this.getString("OrganizerQueryTags") },
+      "AllBookmarks": { title: this.getString("OrganizerQueryAllBookmarks") },
+      "BookmarksToolbar":
+        { title: null,
+          concreteTitle: PlacesUtils.getString("BookmarksToolbarFolderTitle"),
+          concreteId: PlacesUtils.toolbarFolderId },
+      "BookmarksMenu":
+        { title: null,
+          concreteTitle: PlacesUtils.getString("BookmarksMenuFolderTitle"),
+          concreteId: PlacesUtils.bookmarksMenuFolderId },
+      "UnfiledBookmarks":
+        { title: null,
+          concreteTitle: PlacesUtils.getString("UnsortedBookmarksFolderTitle"),
+          concreteId: PlacesUtils.unfiledBookmarksFolderId },
+    };
+    // All queries but PlacesRoot.
+    const EXPECTED_QUERY_COUNT = 6;
 
-    // Get all items marked as being the left pane folder.  We should only have
-    // one of them.
-    var items = as.getItemsWithAnnotation(ORGANIZER_FOLDER_ANNO);
+    // Removes an item and associated annotations, ignoring eventual errors.
+    function safeRemoveItem(aItemId) {
+      try {
+        if (as.itemHasAnnotation(aItemId, ORGANIZER_QUERY_ANNO) &&
+            !(as.getItemAnnotation(aItemId, ORGANIZER_QUERY_ANNO) in queries)) {
+          // Some extension annotated their roots with our query annotation,
+          // so we should not delete them.
+          return;
+        }
+        // removeItemAnnotation does not check if item exists, nor the anno,
+        // so this is safe to do.
+        as.removeItemAnnotation(aItemId, ORGANIZER_FOLDER_ANNO);
+        as.removeItemAnnotation(aItemId, ORGANIZER_QUERY_ANNO);
+        // This will throw if the annotation is an orphan.
+        bs.removeItem(aItemId);
+      }
+      catch(e) { /* orphan anno */ }
+    }
+
+    // Returns true if item really exists, false otherwise.
+    function itemExists(aItemId) {
+      try {
+        bs.getItemIndex(aItemId);
+        return true;
+      }
+      catch(e) {
+        return false;
+      }
+    }
+
+    // Get all items marked as being the left pane folder.
+    let items = as.getItemsWithAnnotation(ORGANIZER_FOLDER_ANNO, {});
     if (items.length > 1) {
       // Something went wrong, we cannot have more than one left pane folder,
       // remove all left pane folders and continue.  We will create a new one.
-      items.forEach(bs.removeItem);
+      items.forEach(safeRemoveItem);
     }
     else if (items.length == 1 && items[0] != -1) {
       leftPaneRoot = items[0];
-      // Check organizer left pane version.
-      var version = as.getItemAnnotation(leftPaneRoot, ORGANIZER_FOLDER_ANNO);
-      if (version != ORGANIZER_LEFTPANE_VERSION) {
-        // If version is not valid we must rebuild the left pane.
-        bs.removeItem(leftPaneRoot);
+
+      // Check that organizer left pane root is valid.
+      let version = as.getItemAnnotation(leftPaneRoot, ORGANIZER_FOLDER_ANNO);
+      if (version != ORGANIZER_LEFTPANE_VERSION || !itemExists(leftPaneRoot)) {
+        // Invalid root, we must rebuild the left pane.
+        safeRemoveItem(leftPaneRoot);
         leftPaneRoot = -1;
       }
     }
 
-    var queriesTitles = {
-      "PlacesRoot": "",
-      "History": this.getString("OrganizerQueryHistory"),
-      // TODO: Bug 489681, Tags needs its own string in places.properties
-      "Tags": bs.getItemTitle(PlacesUtils.tagsFolderId),
-      "AllBookmarks": this.getString("OrganizerQueryAllBookmarks"),
-      "Downloads": this.getString("OrganizerQueryDownloads"),
-      "BookmarksToolbar": null,
-      "BookmarksMenu": null,
-      "UnfiledBookmarks": null
-    };
-
     if (leftPaneRoot != -1) {
       // A valid left pane folder has been found.
-      // Build the leftPaneQueries Map.  This is used to quickly access them
+      // Build the leftPaneQueries Map.  This is used to quickly access them,
       // associating a mnemonic name to the real item ids.
       delete this.leftPaneQueries;
       this.leftPaneQueries = {};
-      var items = as.getItemsWithAnnotation(ORGANIZER_QUERY_ANNO);
-      // While looping through queries we will also check for titles validity.
-      for (var i = 0; i < items.length; i++) {
-        var queryName = as.getItemAnnotation(items[i], ORGANIZER_QUERY_ANNO);
-        this.leftPaneQueries[queryName] = items[i];
+
+      let items = as.getItemsWithAnnotation(ORGANIZER_QUERY_ANNO, {});
+      // While looping through queries we will also check for their validity.
+      let queriesCount = 0;
+      for(let i = 0; i < items.length; i++) {
+        let queryName = as.getItemAnnotation(items[i], ORGANIZER_QUERY_ANNO);
+        // Some extension did use our annotation to decorate their items
+        // with icons, so we should check only our elements, to avoid dataloss.
+        if (!(queryName in queries))
+          continue;
+
+        let query = queries[queryName];
+        query.itemId = items[i];
+
+        if (!itemExists(query.itemId)) {
+          // Orphan annotation, bail out and create a new left pane root.
+          break;
+        }
+
+        // Check that all queries have valid parents.
+        let parentId = bs.getFolderIdForItem(query.itemId);
+        if (items.indexOf(parentId) == -1 && parentId != leftPaneRoot) {
+          // The parent is not part of the left pane, bail out and create a new
+          // left pane root.
+          break;
+        }
+
         // Titles could have been corrupted or the user could have changed his
-        // locale.  Check title is correctly set and eventually fix it.
-        if (bs.getItemTitle(items[i]) != queriesTitles[queryName])
-          bs.setItemTitle(items[i], queriesTitles[queryName]);
+        // locale.  Check title and eventually fix it.
+        if (bs.getItemTitle(query.itemId) != query.title)
+          bs.setItemTitle(query.itemId, query.title);
+        if ("concreteId" in query) {
+          if (bs.getItemTitle(query.concreteId) != query.concreteTitle)
+            bs.setItemTitle(query.concreteId, query.concreteTitle);
+        }
+
+        // Add the query to our cache.
+        this.leftPaneQueries[queryName] = query.itemId;
+        queriesCount++;
       }
-      delete this.leftPaneFolderId;
-      return this.leftPaneFolderId = leftPaneRoot;
+
+      if (queriesCount != EXPECTED_QUERY_COUNT) {
+        // Queries number is wrong, so the left pane must be corrupt.
+        // Note: we can't just remove the leftPaneRoot, because some query could
+        // have a bad parent, so we have to remove all items one by one.
+        items.forEach(safeRemoveItem);
+        safeRemoveItem(leftPaneRoot);
+      }
+      else {
+        // Everything is fine, return the current left pane folder.
+        delete this.leftPaneFolderId;
+        return this.leftPaneFolderId = leftPaneRoot;
+      }
     }
 
+    // Create a new left pane folder.
     var self = this;
     var callback = {
       // Helper to create an organizer special query.
       create_query: function CB_create_query(aQueryName, aParentId, aQueryUrl) {
         let itemId = bs.insertBookmark(aParentId,
                                        PlacesUtils._uri(aQueryUrl),
                                        bs.DEFAULT_INDEX,
-                                       queriesTitles[aQueryName]);
+                                       queries[aQueryName].title);
         // Mark as special organizer query.
         as.setItemAnnotation(itemId, ORGANIZER_QUERY_ANNO, aQueryName,
                              0, as.EXPIRE_NEVER);
         // We should never backup this, since it changes between profiles.
         as.setItemAnnotation(itemId, EXCLUDE_FROM_BACKUP_ANNO, 1,
                              0, as.EXPIRE_NEVER);
         // Add to the queries map.
         self.leftPaneQueries[aQueryName] = itemId;
         return itemId;
       },
 
       // Helper to create an organizer special folder.
       create_folder: function CB_create_folder(aFolderName, aParentId, aIsRoot) {
               // Left Pane Root Folder.
         let folderId = bs.createFolder(aParentId,
-                                       queriesTitles[aFolderName],
+                                       queries[aFolderName].title,
                                        bs.DEFAULT_INDEX);
         // We should never backup this, since it changes between profiles.
         as.setItemAnnotation(folderId, EXCLUDE_FROM_BACKUP_ANNO, 1,
                              0, as.EXPIRE_NEVER);
         // Disallow manipulating this folder within the organizer UI.
         bs.setFolderReadonly(folderId, true);
 
         if (aIsRoot) {
--- a/browser/components/places/tests/browser/browser_library_left_pane_fixnames.js
+++ b/browser/components/places/tests/browser/browser_library_left_pane_fixnames.js
@@ -57,16 +57,20 @@ var windowObserver = {
       organizer.addEventListener("load", function onLoad(event) {
         organizer.removeEventListener("load", onLoad, false);
         executeSoon(function () {
           // Check titles have been fixed.
           for (var i = 0; i < leftPaneQueries.length; i++) {
             var query = leftPaneQueries[i];
             is(PlacesUtils.bookmarks.getItemTitle(query.itemId),
                query.correctTitle, "Title is correct for query " + query.name);
+            if ("concreteId" in query) {
+              is(PlacesUtils.bookmarks.getItemTitle(query.concreteId),
+               query.concreteTitle, "Concrete title is correct for query " + query.name);
+            }
           }
 
           // Close Library window.
           organizer.close();
           // No need to cleanup anything, we have a correct left pane now.
           finish();
         });
       }, false);
@@ -100,22 +104,38 @@ function test() {
   var items = PlacesUtils.annotations
                          .getItemsWithAnnotation(ORGANIZER_QUERY_ANNO);
   // Get current queries names.
   for (var i = 0; i < items.length; i++) {
     var itemId = items[i];
     var queryName = PlacesUtils.annotations
                                .getItemAnnotation(items[i],
                                                   ORGANIZER_QUERY_ANNO);
-    leftPaneQueries.push({ name: queryName,
-                           itemId: itemId,
-                           correctTitle: PlacesUtils.bookmarks
-                                                    .getItemTitle(itemId) });
+    var query = { name: queryName,
+                  itemId: itemId,
+                  correctTitle: PlacesUtils.bookmarks.getItemTitle(itemId) }
+    switch (queryName) {
+      case "BookmarksToolbar":
+        query.concreteId = PlacesUtils.toolbarFolderId;
+        query.concreteTitle = PlacesUtils.bookmarks.getItemTitle(query.concreteId);
+        break;
+      case "BookmarksMenu":
+        query.concreteId = PlacesUtils.bookmarksMenuFolderId;
+        query.concreteTitle = PlacesUtils.bookmarks.getItemTitle(query.concreteId);
+        break;
+      case "UnfiledBookmarks":
+        query.concreteId = PlacesUtils.unfiledBookmarksFolderId;
+        query.concreteTitle = PlacesUtils.bookmarks.getItemTitle(query.concreteId);
+        break;
+    }
+    leftPaneQueries.push(query);
     // Rename to a bad title.
-    PlacesUtils.bookmarks.setItemTitle(itemId, "badName");
+    PlacesUtils.bookmarks.setItemTitle(query.itemId, "badName");
+    if ("concreteId" in query)
+      PlacesUtils.bookmarks.setItemTitle(query.concreteId, "badName");
   }
 
   // Open Library, this will kick-off left pane code.
   ww.registerNotification(windowObserver);
   ww.openWindow(null,
                 "chrome://browser/content/places/places.xul",
                 "",
                 "chrome,toolbar=yes,dialog=no,resizable",
--- a/browser/components/places/tests/chrome/test_treeview_date.xul
+++ b/browser/components/places/tests/chrome/test_treeview_date.xul
@@ -151,17 +151,21 @@
       for (var r = 0; r < rc; r++) {
         var node = treeView.nodeForTreeIndex(r);
         ok(node, "Places node found");
         for (var ci = 0; ci < columns.count; ci++) {
           var c = columns.getColumnAt(ci);
           var text = treeView.getCellText(r, c);
           switch (c.element.getAttribute("anonid")) {
             case "title":
-              is(text, node.title, "Title is correct");
+              // The title can differ, we did not set any title so we would
+              // expect null, but in such a case the view will generate a title
+              // through PlacesUIUtils.getBestTitle.
+              if (node.title)
+                is(text, node.title, "Title is correct");
               break;
             case "url":
               is(text, node.uri, "Uri is correct");
               break;
             case "date":
               var timeObj = new Date(node.time / 1000);
               // Default is short date format.
               var dateFormat = Ci.nsIScriptableDateFormat.dateFormatShort;
new file mode 100644
--- /dev/null
+++ b/browser/components/places/tests/unit/test_leftpane_corruption_handling.js
@@ -0,0 +1,224 @@
+/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Places Unit Test code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Marco Bonardo <mak77@bonardo.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * Tests that we build a working leftpane in various corruption situations.
+ */
+
+// Used to store the original leftPaneFolderId getter.
+let gLeftPaneFolderIdGetter;
+let gAllBookmarksFolderIdGetter;
+// Used to store the original left Pane status as a JSON string.
+let gReferenceJSON;
+let gLeftPaneFolderId;
+// Third party annotated folder.
+let gFolderId;
+
+// Corruption cases.
+let gTests = [
+
+  function test1() {
+    print("1. Do nothing, checks test calibration.");
+  },
+
+  function test2() {
+    print("2. Delete the left pane folder.");
+    PlacesUtils.bookmarks.removeItem(gLeftPaneFolderId);
+  },
+
+  function test3() {
+    print("3. Delete a child of the left pane folder.");
+    let id = PlacesUtils.bookmarks.getIdForItemAt(gLeftPaneFolderId, 0);
+    PlacesUtils.bookmarks.removeItem(id);
+  },
+
+  function test4() {
+    print("4. Delete AllBookmarks.");
+    PlacesUtils.bookmarks.removeItem(PlacesUIUtils.allBookmarksFolderId);
+  },
+
+  function test5() {
+    print("5. Create a duplicated left pane folder.");
+    let id = PlacesUtils.bookmarks.createFolder(PlacesUtils.unfiledBookmarksFolderId,
+                                                "PlacesRoot",
+                                                PlacesUtils.bookmarks.DEFAULT_INDEX);
+    PlacesUtils.annotations.setItemAnnotation(id, ORGANIZER_FOLDER_ANNO,
+                                              "PlacesRoot", 0,
+                                              PlacesUtils.annotations.EXPIRE_NEVER);
+  },
+
+  function test6() {
+    print("6. Create a duplicated left pane query.");
+    let id = PlacesUtils.bookmarks.createFolder(PlacesUtils.unfiledBookmarksFolderId,
+                                                "AllBookmarks",
+                                                PlacesUtils.bookmarks.DEFAULT_INDEX);
+    PlacesUtils.annotations.setItemAnnotation(id, ORGANIZER_QUERY_ANNO,
+                                              "AllBookmarks", 0,
+                                              PlacesUtils.annotations.EXPIRE_NEVER);
+  },
+
+  function test7() {
+    print("7. Remove the left pane folder annotation.");
+    PlacesUtils.annotations.removeItemAnnotation(gLeftPaneFolderId,
+                                                 ORGANIZER_FOLDER_ANNO);
+  },
+
+  function test8() {
+    print("8. Remove a left pane query annotation.");
+    PlacesUtils.annotations.removeItemAnnotation(PlacesUIUtils.allBookmarksFolderId,
+                                                 ORGANIZER_QUERY_ANNO);
+  },
+
+  function test9() {
+    print("9. Remove a child of AllBookmarks.");
+    let id = PlacesUtils.bookmarks.getIdForItemAt(PlacesUIUtils.allBookmarksFolderId, 0);
+    PlacesUtils.bookmarks.removeItem(id);
+  },
+
+];
+
+function run_test() {
+  // We want empty roots.
+  remove_all_bookmarks();
+
+  // Import PlacesUIUtils.
+  let scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
+                     getService(Ci.mozIJSSubScriptLoader);
+  scriptLoader.loadSubScript("chrome://browser/content/places/utils.js", this);
+  do_check_true(!!PlacesUIUtils);
+
+  // Check getters.
+  gLeftPaneFolderIdGetter = PlacesUIUtils.__lookupGetter__("leftPaneFolderId");
+  do_check_eq(typeof(gLeftPaneFolderIdGetter), "function");
+  gAllBookmarksFolderIdGetter = PlacesUIUtils.__lookupGetter__("allBookmarksFolderId");
+  do_check_eq(typeof(gAllBookmarksFolderIdGetter), "function");
+
+  // Add a third party bogus annotated item.  Should not be removed.
+  gFolderId = PlacesUtils.bookmarks.createFolder(PlacesUtils.unfiledBookmarksFolderId,
+                                                 "test",
+                                                 PlacesUtils.bookmarks.DEFAULT_INDEX);
+  PlacesUtils.annotations.setItemAnnotation(gFolderId, ORGANIZER_QUERY_ANNO,
+                                            "test", 0,
+                                            PlacesUtils.annotations.EXPIRE_NEVER);
+
+  // Create the left pane, and store its current status, it will be used
+  // as reference value.
+  gLeftPaneFolderId = PlacesUIUtils.leftPaneFolderId;
+  gReferenceJSON = folderToJSON(gLeftPaneFolderId);
+
+  // Kick-off tests.
+  do_test_pending();
+  do_timeout(0, "run_next_test();");
+}
+
+function run_next_test() {
+  if (gTests.length) {
+    // Create corruption.
+    let test = gTests.shift();
+    test();
+    // Regenerate getters.
+    PlacesUIUtils.__defineGetter__("leftPaneFolderId", gLeftPaneFolderIdGetter);
+    gLeftPaneFolderId = PlacesUIUtils.leftPaneFolderId;
+    PlacesUIUtils.__defineGetter__("allBookmarksFolderId", gAllBookmarksFolderIdGetter);
+    // Check the new left pane folder.
+    let leftPaneJSON = folderToJSON(gLeftPaneFolderId);
+    do_check_true(compareJSON(gReferenceJSON, leftPaneJSON));
+    do_check_eq(PlacesUtils.bookmarks.getItemTitle(gFolderId), "test");
+    // Go to next test.
+    do_timeout(0, "run_next_test();");
+  }
+  else {
+    // All tests finished.
+    remove_all_bookmarks();
+    do_test_finished();
+  }
+}
+
+/**
+ * Convert a folder item id to a JSON representation of it and its contents.
+ */
+function folderToJSON(aItemId) {
+  let query = PlacesUtils.history.getNewQuery();
+  query.setFolders([aItemId], 1);
+  let options = PlacesUtils.history.getNewQueryOptions();
+  options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS;
+  let root = PlacesUtils.history.executeQuery(query, options).root;
+  let writer = {
+    value: "",
+    write: function PU_wrapNode__write(aStr, aLen) {
+      this.value += aStr;
+    }
+  };
+  PlacesUtils.serializeNodeAsJSONToOutputStream(root, writer, false, false);
+  do_check_true(writer.value.length > 0);
+  return writer.value;
+}
+
+/**
+ * Compare the JSON representation of 2 nodes, skipping everchanging properties
+ * like dates.
+ */
+function compareJSON(aNodeJSON_1, aNodeJSON_2) {
+  let JSON = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON);
+  node1 = JSON.decode(aNodeJSON_1);
+  node2 = JSON.decode(aNodeJSON_2);
+
+  // List of properties we should not compare (expected to be different).
+  const SKIP_PROPS = ["dateAdded", "lastModified", "id"];
+
+  function compareObjects(obj1, obj2) {
+    do_check_eq(obj1.__count__, obj2.__count__);
+    for (let prop in obj1) {
+      // Skip everchanging values.
+      if (SKIP_PROPS.indexOf(prop) != -1)
+        continue;
+      // Skip undefined objects, otherwise we hang on them.
+      if (!obj1[prop])
+        continue;
+      if (typeof(obj1[prop]) == "object")
+        return compareObjects(obj1[prop], obj2[prop]);
+      if (obj1[prop] !== obj2[prop]) {
+        print(prop + ": " + obj1[prop] + "!=" + obj2[prop]);
+        return false;
+      }
+    }
+    return true;
+  }
+
+  return compareObjects(node1, node2);
+}
--- a/browser/components/preferences/applications.js
+++ b/browser/components/preferences/applications.js
@@ -656,17 +656,17 @@ FeedHandlerInfo.prototype = {
     if (preferredAppFile) {
       let preferredApp = getLocalHandlerApp(preferredAppFile);
       let defaultApp = this._defaultApplicationHandler;
       if (!defaultApp || !defaultApp.equals(preferredApp))
         this._possibleApplicationHandlers.appendElement(preferredApp, false);
     }
 
     // Add the registered web handlers.  There can be any number of these.
-    var webHandlers = this._converterSvc.getContentHandlers(this.type, {});
+    var webHandlers = this._converterSvc.getContentHandlers(this.type);
     for each (let webHandler in webHandlers)
       this._possibleApplicationHandlers.appendElement(webHandler, false);
 
     return this._possibleApplicationHandlers;
   },
 
   __defaultApplicationHandler: undefined,
   get _defaultApplicationHandler() {
--- a/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js
+++ b/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js
@@ -360,16 +360,20 @@ PrivateBrowsingService.prototype = {
                   getService(Ci.nsISecretDecoderRing);
         sdr.logoutAndTeardown();
     
         // clear plain HTTP auth sessions
         let authMgr = Cc['@mozilla.org/network/http-auth-manager;1'].
                       getService(Ci.nsIHttpAuthManager);
         authMgr.clearAll();
 
+        try {
+          this._prefs.deleteBranch("geo.wifi.access_token.");
+        } catch (ex) {}
+
         if (!this._inPrivateBrowsing) {
           // Clear the error console
           let consoleService = Cc["@mozilla.org/consoleservice;1"].
                                getService(Ci.nsIConsoleService);
           consoleService.logStringMessage(null); // trigger the listeners
           consoleService.reset();
         }
         break;
@@ -552,27 +556,27 @@ PrivateBrowsingService.prototype = {
       os.notifyObservers(null, "download-manager-remove-download", null);
     }
 
     // Passwords
     let (lm = Cc["@mozilla.org/login-manager;1"].
               getService(Ci.nsILoginManager)) {
       // Clear all passwords for domain
       try {
-        let logins = lm.getAllLogins({});
+        let logins = lm.getAllLogins();
         for (let i = 0; i < logins.length; i++)
           if (logins[i].hostname.hasRootDomain(aDomain))
             lm.removeLogin(logins[i]);
       }
       // XXXehsan: is there a better way to do this rather than this
       // hacky comparison?
       catch (ex if ex.message.indexOf("User canceled Master Password entry") != -1) { }
 
       // Clear any "do not save for this site" for this domain
-      let disabledHosts = lm.getAllDisabledHosts({});
+      let disabledHosts = lm.getAllDisabledHosts();
       for (let i = 0; i < disabledHosts.length; i++)
         if (disabledHosts[i].hasRootDomain(aDomain))
           lm.setLoginSavingEnabled(disabledHosts, true);
     }
 
     // Permissions
     let (pm = Cc["@mozilla.org/permissionmanager;1"].
               getService(Ci.nsIPermissionManager)) {
--- a/browser/components/privatebrowsing/test/browser/staller.sjs
+++ b/browser/components/privatebrowsing/test/browser/staller.sjs
@@ -32,24 +32,28 @@
  * 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 ***** */
 
 // This provides the tests with a download URL which never finishes.
 
+var timer;
+
 function handleRequest(request, response) {
   response.setStatusLine(request.httpVersion, 200, "OK");
   response.processAsync();
 
+  const nsITimer = Components.interfaces.nsITimer;
+
   function stall() {
+    timer = null;
+    // 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);
   stall();
-
-  const nsITimer = Components.interfaces.nsITimer;
-  var timer = Components.classes["@mozilla.org/timer;1"]
-                        .createInstance(nsITimer);
-  timer.initWithCallback(stall, 500, nsITimer.TYPE_REPEATING_SLACK);
 }
new file mode 100644
--- /dev/null
+++ b/browser/components/privatebrowsing/test/unit/test_geoClearCookie.js
@@ -0,0 +1,74 @@
+/* ***** 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 Private Browsing Tests.
+ *
+ * The Initial Developer of the Original Code is
+ * Nochum Sossonko.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Nochum Sossonko <nsossonko@hotmail.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// Test to ensure the geolocation token is cleared when changing the private
+// browsing mode
+
+const accessToken = '{"location":{"latitude":51.5090332,"longitude":-0.1212726,"accuracy":150.0},"access_token":"2:jVhRZJ-j6PiRchH_:RGMrR0W1BiwdZs12"}'
+function run_test_on_service() {
+  var prefBranch = Cc["@mozilla.org/preferences-service;1"].
+                   getService(Ci.nsIPrefBranch2);
+  var pb = Cc[PRIVATEBROWSING_CONTRACT_ID].
+           getService(Ci.nsIPrivateBrowsingService);
+  prefBranch.setCharPref("geo.wifi.access_token.test", accessToken);
+  var token = prefBranch.getCharPref("geo.wifi.access_token.test");
+  do_check_eq(token, accessToken);
+  pb.privateBrowsingEnabled = true;
+  token = "";
+  try {
+    token = prefBranch.getCharPref("geo.wifi.access_token.test");
+  }
+  catch(e){}
+  finally {
+    do_check_eq(token, "");
+  }
+  token = "";
+  prefBranch.setCharPref("geo.wifi.access_token.test", accessToken);
+  pb.privateBrowsingEnabled = false;
+  try {
+    token = prefBranch.getCharPref("geo.wifi.access_token.test");
+  }
+  catch(e){}
+  finally {
+    do_check_eq(token, "");
+  }
+}
+
+// Support running tests on both the service itself and its wrapper
+function run_test() {
+  run_test_on_all_services();
+}
--- a/browser/components/privatebrowsing/test/unit/test_openLocationLastURL.js
+++ b/browser/components/privatebrowsing/test/unit/test_openLocationLastURL.js
@@ -36,17 +36,17 @@
 
 // Test the correct behavior of the openLocationLastURL.jsm JS module.
 
 function run_test_on_service()
 {
   let Cc = Components.classes;
   let Ci = Components.interfaces;
   let Cu = Components.utils;
-  Cu.import("resource://gre/modules/openLocationLastURL.jsm");
+  Cu.import("resource:///modules/openLocationLastURL.jsm");
 
   let pb = Cc[PRIVATEBROWSING_CONTRACT_ID].
            getService(Ci.nsIPrivateBrowsingService);
   let pref = Cc["@mozilla.org/preferences-service;1"].
              getService(Ci.nsIPrefBranch);
   gOpenLocationLastURL.reset();
 
   do_check_eq(typeof gOpenLocationLastURL, "object");
--- a/browser/components/search/content/engineManager.js
+++ b/browser/components/search/content/engineManager.js
@@ -295,23 +295,23 @@ EngineChangeOp.prototype = {
   commit: function ECO_commit() {
     this._engine[this._prop] = this._newValue;
   }
 }
 
 function EngineStore() {
   var searchService = Cc["@mozilla.org/browser/search-service;1"].
                       getService(Ci.nsIBrowserSearchService);
-  this._engines = searchService.getVisibleEngines({}).map(this._cloneEngine);
-  this._defaultEngines = searchService.getDefaultEngines({}).map(this._cloneEngine);
+  this._engines = searchService.getVisibleEngines().map(this._cloneEngine);
+  this._defaultEngines = searchService.getDefaultEngines().map(this._cloneEngine);
 
   this._ops = [];
 
   // check if we need to disable the restore defaults button
-  var someHidden = this._defaultEngines.some(function (e) {return e.hidden;});
+  var someHidden = this._defaultEngines.some(function (e) e.hidden);
   gEngineManagerDialog.showRestoreDefaults(someHidden);
 }
 EngineStore.prototype = {
   _engines: null,
   _defaultEngines: null,
   _ops: null,
 
   get engines() {
--- a/browser/components/search/content/search.xml
+++ b/browser/components/search/content/search.xml
@@ -144,17 +144,17 @@
       <field name="_popup">document.getAnonymousElementByAttribute(this,
           "anonid", "searchbar-popup");</field>
       <field name="_ss">null</field>
       <field name="_engines">null</field>
 
       <property name="engines" readonly="true">
         <getter><![CDATA[
           if (!this._engines)
-            this._engines = this.searchService.getVisibleEngines({ });
+            this._engines = this.searchService.getVisibleEngines();
           return this._engines;
         ]]></getter>
       </property>
 
       <field name="searchButton">document.getAnonymousElementByAttribute(this,
           "anonid", "searchbar-engine-button");</field>
 
       <property name="currentEngine"
--- a/browser/installer/removed-files.in
+++ b/browser/installer/removed-files.in
@@ -64,16 +64,18 @@ XUL
 @DLL_PREFIX@xpistub@DLL_SUFFIX@
 component.reg
 components/aboutCertError.js
 components/aboutPrivateBrowsing.js
 components/aboutRights.js
 components/aboutRobots.js
 components/aboutSessionRestore.js
 components/compreg.dat
+components/@DLL_PREFIX@browserdirprovider@DLL_SUFFIX@
+components/@DLL_PREFIX@brwsrdir@DLL_SUFFIX@
 components/@DLL_PREFIX@myspell@DLL_SUFFIX@
 components/@DLL_PREFIX@spellchecker@DLL_SUFFIX@
 components/@DLL_PREFIX@spellchk@DLL_SUFFIX@
 components/xpti.dat
 components/xptitemp.dat
 components/nsBackgroundUpdateService.js
 components/nsCloseAllWindows.js
 #ifndef XP_MACOSX
--- a/browser/locales/en-US/chrome/browser/places/places.properties
+++ b/browser/locales/en-US/chrome/browser/places/places.properties
@@ -1,18 +1,16 @@
 deleteHost=Delete all from %S
 deleteDomain=Delete entire domain %S
 deleteHostNoSelection=Delete host
 deleteDomainNoSelection=Delete domain
 
 load-js-data-url-error=For security reasons, javascript or data urls cannot be loaded from the history window or sidebar.
 noTitle=(no title)
 
-bookmarksMenuName=Bookmarks Menu
-bookmarksToolbarName=Bookmarks Toolbar
 bookmarksMenuEmptyFolder=(Empty)
 
 # LOCALIZATION NOTE (bookmarksBackupFilename) :
 # %S will be replaced by the current date in ISO 8601 format, YYYY-MM-DD.
 # The resulting string will be suggested as a filename, so make sure that you're
 # only using characters legal for file names. Consider falling back to the
 # en-US value if you have to use non-ascii characters.
 bookmarksBackupFilename=Bookmarks %S.html
@@ -89,16 +87,17 @@ detailsPane.multipleItems=%S items
 smartBookmarksFolderTitle=Smart Bookmarks
 mostVisitedTitle=Most Visited
 recentlyBookmarkedTitle=Recently Bookmarked
 recentTagsTitle=Recent Tags
 
 OrganizerQueryHistory=History
 OrganizerQueryDownloads=Downloads
 OrganizerQueryAllBookmarks=All Bookmarks
+OrganizerQueryTags=Tags
 
 # LOCALIZATION NOTE (tagResultLabel) :
 # This is what we use to form the label (for screen readers)
 # for url bar autocomplete results of type "tag"
 # See createResultLabel() in urlbarBindings.xml 
 tagResultLabel=Tag
 # LOCALIZATION NOTE (bookmarkResultLabel) :
 # This is what we use to form the label (for screen readers)
--- a/browser/themes/winstripe/browser/browser.css
+++ b/browser/themes/winstripe/browser/browser.css
@@ -98,17 +98,17 @@ toolbarbutton.bookmark-item {
   max-width: 13em;
   padding: 2px 3px;
 }
 
 toolbarbutton.bookmark-item-microsummarized {
   max-width: 20em;
 }
 
-toolbarbutton.bookmark-item:hover:active,
+toolbarbutton.bookmark-item:hover:active:not([disabled="true"]),
 toolbarbutton.bookmark-item[open="true"] {
   padding-top: 3px;
   padding-bottom: 1px;
   -moz-padding-start: 4px;
   -moz-padding-end: 2px;
 }
 
 .bookmark-item > .toolbarbutton-icon {
--- a/config/nsinstall_win.c
+++ b/config/nsinstall_win.c
@@ -145,25 +145,28 @@ shellMkdir (wchar_t **pArgv)
                 *pTmpPath++ = *pArg++;
                 if ( *pArg == '\\' )
                     break;
             }
             *pTmpPath = '\0';
 
             /* check if directory already exists */
             _wgetcwd ( path, _MAX_PATH );
-            if ( _wchdir ( tmpPath ) != -1 ) {
-                _wchdir ( path );
+            if ( _wchdir ( tmpPath ) == -1 &&
+                 _wmkdir ( tmpPath ) == -1 && // might have hit EEXIST
+                 _wchdir ( tmpPath ) == -1) { // so try again
+                char buf[2048];
+                _snprintf(buf, 2048, "Could not create the directory: %S",
+                          tmpPath);
+                perror ( buf );
+                retVal = 3;
+                break;
             } else {
-                if ( _wmkdir ( tmpPath ) == -1 ) {
-                    printf ( "%ls: ", tmpPath );
-                    perror ( "Could not create the directory" );
-                    retVal = 3;
-                    break;
-                }
+                // get back to the cwd
+                _wchdir ( path );
             }
             if ( *pArg == '\0' )      /* complete path? */
                 break;
             /* loop for next directory */
         }
 
         pArgv++;
     }
--- a/configure.in
+++ b/configure.in
@@ -7757,24 +7757,20 @@ AC_SUBST(NECKO_COOKIES)
 if test "$NECKO_COOKIES"; then
     AC_DEFINE(NECKO_COOKIES)
 fi
 
 dnl
 dnl Build jsctypes on the platforms we can.
 dnl
 AC_SUBST(BUILD_CTYPES)
-case "$OS_TEST" in
-arm*)
-  ;;
-*)
+if test "$OS_TARGET" != "WINCE" -o `echo $OS_TEST | grep -ic arm` != 1; then
   BUILD_CTYPES=1
   AC_DEFINE(BUILD_CTYPES)
-  ;;
-esac
+fi
 
 dnl NECKO_ configuration options are not global
 _NON_GLOBAL_ACDEFINES="$_NON_GLOBAL_ACDEFINES NECKO_"
 
 dnl Only build Mork if it's required
 AC_SUBST(MOZ_MORK)
 if test "$MOZ_MORK"; then
   AC_DEFINE(MOZ_MORK)
--- a/content/base/public/Makefile.in
+++ b/content/base/public/Makefile.in
@@ -88,17 +88,17 @@ SDK_XPIDLSRCS   = \
 		nsISelection.idl  \
 		$(NULL)
 
 XPIDLSRCS	= \
 		nsIChromeRegistry.idl       \
 		nsIContentPolicy.idl        \
 		nsIDocumentEncoder.idl      \
 		nsIDOMFile.idl \
-		nsIDOMFileRequest.idl \
+		nsIDOMFileReader.idl \
 		nsIDOMFileInternal.idl \
 		nsIDOMFileList.idl \
 		nsIDOMFileException.idl \
 		nsIDOMFileError.idl \
 		nsIDOMParser.idl \
 		nsIDOMSerializer.idl \
 		nsISelection2.idl \
 		nsISelectionController.idl  \
rename from content/base/public/nsIDOMFileRequest.idl
rename to content/base/public/nsIDOMFileReader.idl
--- a/content/base/public/nsIDOMFileRequest.idl
+++ b/content/base/public/nsIDOMFileReader.idl
@@ -36,36 +36,36 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsIDOMEventTarget.idl"
 
 interface nsIDOMEventListener;
 interface nsIDOMFile;
 interface nsIDOMFileError;
 
-[scriptable, uuid(074FEC26-7FAB-4E05-9E60-EC49E148F5EF)]
-interface nsIDOMFileRequest : nsISupports 
+[scriptable, uuid(5db0ce80-de44-40c0-a346-e28aac4aa978)]
+interface nsIDOMFileReader : nsISupports 
 {
   void readAsBinaryString(in nsIDOMFile filedata);
   void readAsText(in nsIDOMFile filedata, [optional] in DOMString encoding);
   void readAsDataURL(in nsIDOMFile file);
 
   void abort();
 
   const unsigned short INITIAL = 0;
   const unsigned short LOADING = 1;
   const unsigned short DONE = 2;
   readonly attribute unsigned short readyState;
 
-  readonly attribute DOMString response;
+  readonly attribute DOMString result;
   readonly attribute nsIDOMFileError error;
 
   // event handler attributes
   attribute nsIDOMEventListener onloadend;
 };
 
 %{ C++
-#define NS_FILEREQUEST_CID                            \
+#define NS_FILEREADER_CID                            \
 {0x06aa7c21, 0xfe05, 0x4cf2,                         \
 {0xb1, 0xc4, 0x0c, 0x71, 0x26, 0xa4, 0xf7, 0x13}}
-#define NS_FILEREQUEST_CONTRACTID \
-"@mozilla.org/files/filerequest;1"
+#define NS_FILEREADER_CONTRACTID \
+"@mozilla.org/files/filereader;1"
 %}
--- a/content/base/public/nsIScriptElement.h
+++ b/content/base/public/nsIScriptElement.h
@@ -39,19 +39,20 @@
 #ifndef nsIScriptElement_h___
 #define nsIScriptElement_h___
 
 #include "nsISupports.h"
 #include "nsIURI.h"
 #include "nsCOMPtr.h"
 #include "nsIScriptLoaderObserver.h"
 
+// e68ddc48-4055-4ba9-978d-c49d9cf3189a
 #define NS_ISCRIPTELEMENT_IID \
-{ 0x4b916da5, 0x82c4, 0x45ab, \
-  { 0x99, 0x15, 0xcc, 0xcd, 0x9e, 0x2c, 0xb1, 0xe6 } }
+{ 0xe68ddc48, 0x4055, 0x4ba9, \
+  { 0x97, 0x8d, 0xc4, 0x9d, 0x9c, 0xf3, 0x18, 0x9a } }
 
 /**
  * Internal interface implemented by script elements
  */
 class nsIScriptElement : public nsIScriptLoaderObserver {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISCRIPTELEMENT_IID)
 
@@ -82,16 +83,21 @@ public:
 
   virtual void GetScriptCharset(nsAString& charset) = 0;
 
   /**
    * Is the script deferred. Currently only supported by HTML scripts.
    */
   virtual PRBool GetScriptDeferred() = 0;
 
+  /**
+   * Is the script async. Currently only supported by HTML scripts.
+   */
+  virtual PRBool GetScriptAsync() = 0;
+
   void SetScriptLineNumber(PRUint32 aLineNumber)
   {
     mLineNumber = aLineNumber;
   }
   PRUint32 GetScriptLineNumber()
   {
     return mLineNumber;
   }
--- a/content/base/src/Makefile.in
+++ b/content/base/src/Makefile.in
@@ -79,17 +79,17 @@ CPPSRCS		= \
 		nsContentUtils.cpp \
 		nsCopySupport.cpp \
 		nsCrossSiteListenerProxy.cpp \
 		nsDataDocumentContentPolicy.cpp \
 		nsDOMAttribute.cpp \
 		nsDOMAttributeMap.cpp \
 		nsDOMDocumentType.cpp \
 		nsDOMFile.cpp \
-		nsDOMFileRequest.cpp \
+		nsDOMFileReader.cpp \
 		nsDOMLists.cpp \
 		nsDOMParser.cpp \
 		nsDOMSerializer.cpp \
 		nsDOMTokenList.cpp \
 		nsDocument.cpp \
 		nsDocumentEncoder.cpp \
 		nsDocumentFragment.cpp \
 		nsFrameLoader.cpp \
--- a/content/base/src/nsCopySupport.cpp
+++ b/content/base/src/nsCopySupport.cpp
@@ -110,18 +110,28 @@ SelectionCopyHelper(nsISelection *aSel, 
   nsAutoString mimeType;
 
   nsCOMPtr<nsIDocumentEncoder> docEncoder;
 
   docEncoder = do_CreateInstance(NS_HTMLCOPY_ENCODER_CONTRACTID);
   NS_ENSURE_TRUE(docEncoder, NS_ERROR_FAILURE);
 
   // We always require a plaintext version
+  
+  // note that we assign text/unicode as mime type, but in fact nsHTMLCopyEncoder
+  // ignore it and use text/html or text/plain depending where the selection
+  // 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);
-  PRUint32 flags = nsIDocumentEncoder::OutputPreformatted;
+  
+  // 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;
 
   nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(aDoc);
   NS_ASSERTION(domDoc, "Need a document");
 
   rv = docEncoder->Init(domDoc, mimeType, flags);
   if (NS_FAILED(rv)) 
     return rv;
 
rename from content/base/src/nsDOMFileRequest.cpp
rename to content/base/src/nsDOMFileReader.cpp
--- a/content/base/src/nsDOMFileRequest.cpp
+++ b/content/base/src/nsDOMFileReader.cpp
@@ -30,17 +30,17 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-#include "nsDOMFileRequest.h"
+#include "nsDOMFileReader.h"
 
 #include "nsContentCID.h"
 #include "nsContentUtils.h"
 #include "nsDOMClassInfo.h"
 #include "nsDOMFile.h"
 #include "nsDOMError.h"
 #include "nsICharsetAlias.h"
 #include "nsICharsetDetector.h"
@@ -84,100 +84,100 @@
 #define ABORT_STR "abort"
 #define LOADSTART_STR "loadstart"
 #define PROGRESS_STR "progress"
 #define UPLOADPROGRESS_STR "uploadprogress"
 #define LOADEND_STR "loadend"
 
 #define NS_PROGRESS_EVENT_INTERVAL 50
 
-NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMFileRequest)
+NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMFileReader)
 
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMFileRequest,
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMFileReader,
                                                   nsXHREventTarget)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnLoadEndListener)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFile)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mProgressNotifier)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mPrincipal)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mChannel)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMFileRequest,
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMFileReader,
                                                 nsXHREventTarget)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnLoadEndListener)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFile)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mProgressNotifier)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mPrincipal)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mChannel)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMFileRequest)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMFileRequest)
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMFileReader)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMFileReader)
   NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
   NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
   NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer)
   NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
   NS_INTERFACE_MAP_ENTRY(nsICharsetDetectionObserver)
-  NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(FileRequest)
+  NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(FileReader)
 NS_INTERFACE_MAP_END_INHERITING(nsXHREventTarget)
 
-NS_IMPL_ADDREF_INHERITED(nsDOMFileRequest, nsXHREventTarget)
-NS_IMPL_RELEASE_INHERITED(nsDOMFileRequest, nsXHREventTarget)
+NS_IMPL_ADDREF_INHERITED(nsDOMFileReader, nsXHREventTarget)
+NS_IMPL_RELEASE_INHERITED(nsDOMFileReader, nsXHREventTarget)
 
 static const PRUint32 FILE_AS_BINARY   = 1;
 static const PRUint32 FILE_AS_TEXT     = 2;
 static const PRUint32 FILE_AS_DATAURL  = 3;
 
 NS_IMETHODIMP
-nsDOMFileRequest::GetOnloadend(nsIDOMEventListener** aOnloadend)
+nsDOMFileReader::GetOnloadend(nsIDOMEventListener** aOnloadend)
 {
   return GetInnerEventListener(mOnLoadEndListener, aOnloadend);
 }
 
 NS_IMETHODIMP
-nsDOMFileRequest::SetOnloadend(nsIDOMEventListener* aOnloadend)
+nsDOMFileReader::SetOnloadend(nsIDOMEventListener* aOnloadend)
 {
   return RemoveAddEventListener(NS_LITERAL_STRING(LOADEND_STR),
                                 mOnLoadEndListener, aOnloadend);
 }
 
 //nsICharsetDetectionObserver
 
 NS_IMETHODIMP
-nsDOMFileRequest::Notify(const char *aCharset, nsDetectionConfident aConf)
+nsDOMFileReader::Notify(const char *aCharset, nsDetectionConfident aConf)
 {
   CopyASCIItoUTF16(aCharset, mCharset);
   return NS_OK;
 }
 
-//nsDOMFileRequest constructors/initializers
+//nsDOMFileReader constructors/initializers
 
-nsDOMFileRequest::nsDOMFileRequest()
+nsDOMFileReader::nsDOMFileReader()
   : mFileData(nsnull), mReadCount(0),
     mDataLen(0), mDataFormat(0),
-    mReadyState(nsIDOMFileRequest::INITIAL),
+    mReadyState(nsIDOMFileReader::INITIAL),
     mProgressEventWasDelayed(PR_FALSE),
     mTimerIsActive(PR_FALSE),
     mReadTotal(0), mReadTransferred(0),
     mReadComplete(PR_TRUE)
 {
   nsLayoutStatics::AddRef();
 }
 
-nsDOMFileRequest::~nsDOMFileRequest()
+nsDOMFileReader::~nsDOMFileReader()
 {
   if (mListenerManager) 
     mListenerManager->Disconnect();
 
   nsLayoutStatics::Release();
 }
 
 nsresult
-nsDOMFileRequest::Init()
+nsDOMFileReader::Init()
 {
   // Set the original mScriptContext and mPrincipal, if available.
   // Get JSContext from stack.
   nsCOMPtr<nsIJSContextStack> stack =
     do_GetService("@mozilla.org/js/xpc/ContextStack;1");
 
   if (!stack) {
     return NS_OK;
@@ -206,18 +206,18 @@ nsDOMFileRequest::Init()
       mOwner = window->GetCurrentInnerWindow();
     }
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMFileRequest::Initialize(nsISupports* aOwner, JSContext* cx, JSObject* obj,
-                             PRUint32 argc, jsval *argv)
+nsDOMFileReader::Initialize(nsISupports* aOwner, JSContext* cx, JSObject* obj,
+                            PRUint32 argc, jsval *argv)
 {
   mOwner = do_QueryInterface(aOwner);
   if (!mOwner) {
     NS_WARNING("Unexpected nsIJSNativeInitializer owner");
     return NS_OK;
   }
 
   // This object is bound to a |window|,
@@ -231,81 +231,81 @@ nsDOMFileRequest::Initialize(nsISupports
   NS_ENSURE_STATE(mScriptContext);
 
   return NS_OK; 
 }
 
 // nsIInterfaceRequestor
 
 NS_IMETHODIMP
-nsDOMFileRequest::GetInterface(const nsIID & aIID, void **aResult)
+nsDOMFileReader::GetInterface(const nsIID & aIID, void **aResult)
 {
   return QueryInterface(aIID, aResult);
 }
 
-// nsIDOMFileRequest
+// nsIDOMFileReader
 
 NS_IMETHODIMP
-nsDOMFileRequest::GetReadyState(PRUint16 *aReadyState)
+nsDOMFileReader::GetReadyState(PRUint16 *aReadyState)
 {
   *aReadyState = mReadyState;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMFileRequest::GetResponse(nsAString& aResponse)
+nsDOMFileReader::GetResult(nsAString& aResult)
 {
-  aResponse = mResponse;
+  aResult = mResult;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMFileRequest::GetError(nsIDOMFileError** aError)
+nsDOMFileReader::GetError(nsIDOMFileError** aError)
 {
   NS_IF_ADDREF(*aError = mError);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMFileRequest::ReadAsBinaryString(nsIDOMFile* aFile)
+nsDOMFileReader::ReadAsBinaryString(nsIDOMFile* aFile)
 {
   return ReadFileContent(aFile, EmptyString(), FILE_AS_BINARY);
 }
 
 NS_IMETHODIMP
-nsDOMFileRequest::ReadAsText(nsIDOMFile* aFile,
-                             const nsAString &aCharset)
+nsDOMFileReader::ReadAsText(nsIDOMFile* aFile,
+                            const nsAString &aCharset)
 {
   return ReadFileContent(aFile, aCharset, FILE_AS_TEXT);
 }
 
 NS_IMETHODIMP
-nsDOMFileRequest::ReadAsDataURL(nsIDOMFile* aFile)
+nsDOMFileReader::ReadAsDataURL(nsIDOMFile* aFile)
 {
   return ReadFileContent(aFile, EmptyString(), FILE_AS_DATAURL);
 }
 
 NS_IMETHODIMP
-nsDOMFileRequest::Abort()
+nsDOMFileReader::Abort()
 {
-  if (mReadyState != nsIDOMFileRequest::LOADING)
+  if (mReadyState != nsIDOMFileReader::LOADING)
     return NS_OK;
 
   //Clear progress and file data
   mProgressEventWasDelayed = PR_FALSE;
   mTimerIsActive = PR_FALSE;
   if (mProgressNotifier) {
     mProgressNotifier->Cancel();
   }
   mReadCount = 0;
   mDataLen = 0;
 
-  //Revert status, response and readystate attributes
-  SetDOMStringToNull(mResponse);
-  mReadyState = nsIDOMFileRequest::DONE;
+  //Revert status, result and readystate attributes
+  SetDOMStringToNull(mResult);
+  mReadyState = nsIDOMFileReader::DONE;
   mError = new nsDOMFileError(nsIDOMFileError::ABORT_ERR);
     
   //Non-null channel indicates a read is currently active
   if (mChannel) {
     //Cancel request requires an error status
     mChannel->Cancel(NS_ERROR_FAILURE);
     mChannel = nsnull;
   }
@@ -314,79 +314,79 @@ nsDOMFileRequest::Abort()
   //Clean up memory buffer
   PR_Free(mFileData);
   mFileData = nsnull;
 
   //Dispatch the abort event
   DispatchProgressEvent(NS_LITERAL_STRING(ABORT_STR));
   DispatchProgressEvent(NS_LITERAL_STRING(LOADEND_STR));
 
-  mReadyState = nsIDOMFileRequest::INITIAL;
+  mReadyState = nsIDOMFileReader::INITIAL;
 
   return NS_OK;
 }
 
 // nsITimerCallback
 NS_IMETHODIMP
-nsDOMFileRequest::Notify(nsITimer* aTimer)
+nsDOMFileReader::Notify(nsITimer* aTimer)
 {
   mTimerIsActive = PR_FALSE;
   if (mProgressEventWasDelayed) {
     DispatchProgressEvent(NS_LITERAL_STRING(PROGRESS_STR));
     StartProgressEventTimer();
   }
 
   return NS_OK;
 }
 
 void
-nsDOMFileRequest::StartProgressEventTimer()
+nsDOMFileReader::StartProgressEventTimer()
 {
   if (!mProgressNotifier) {
     mProgressNotifier = do_CreateInstance(NS_TIMER_CONTRACTID);
   }
   if (mProgressNotifier) {
     mProgressEventWasDelayed = PR_FALSE;
     mTimerIsActive = PR_TRUE;
     mProgressNotifier->Cancel();
     mProgressNotifier->InitWithCallback(this, NS_PROGRESS_EVENT_INTERVAL,
                                               nsITimer::TYPE_ONE_SHOT);
   }
 }
 
 // nsIStreamListener
 
 NS_IMETHODIMP
-nsDOMFileRequest::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
+nsDOMFileReader::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMFileRequest::OnDataAvailable(nsIRequest *aRequest,
-                                  nsISupports *aContext,
-                                  nsIInputStream *aInputStream,
-                                  PRUint32 aOffset,
-                                  PRUint32 aCount)
+nsDOMFileReader::OnDataAvailable(nsIRequest *aRequest,
+                                 nsISupports *aContext,
+                                 nsIInputStream *aInputStream,
+                                 PRUint32 aOffset,
+                                 PRUint32 aCount)
 {
   //Update memory buffer to reflect the contents of the file
   mFileData = (char *)PR_Realloc(mFileData, aOffset + aCount);
   NS_ENSURE_TRUE(mFileData, NS_ERROR_OUT_OF_MEMORY);
 
   aInputStream->Read(mFileData + aOffset, aCount, &mReadCount);
   mDataLen += aCount;
   mReadTransferred = mDataLen;
 
   //Continuously update our binary string as data comes in
   if (mDataFormat == FILE_AS_BINARY) {
-    PRUint32 oldLen = mResponse.Length();
+    PRUint32 oldLen = mResult.Length();
     PRUint32 newLen = oldLen + aCount;
     PRUnichar *buf; 
 
-    if (mResponse.GetMutableData(&buf, newLen) != newLen) {
+    if (mResult.GetMutableData(&buf, newLen) != newLen) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
 
     PRUnichar *bufEnd = buf + newLen;
     buf += oldLen;
 
     char *source = mFileData + aOffset;
     while (buf < bufEnd) {
@@ -404,68 +404,68 @@ nsDOMFileRequest::OnDataAvailable(nsIReq
     DispatchProgressEvent(NS_LITERAL_STRING(PROGRESS_STR));
     StartProgressEventTimer();
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMFileRequest::OnStopRequest(nsIRequest *aRequest,
-                                nsISupports *aContext,
-                                nsresult aStatus)
+nsDOMFileReader::OnStopRequest(nsIRequest *aRequest,
+                               nsISupports *aContext,
+                               nsresult aStatus)
 {
   //If we're here as a result of a call from Abort(),
   //simply ignore the request.
   if (aRequest != mChannel)
     return NS_OK;
 
   //Cancel the progress event timer
   mProgressEventWasDelayed = PR_FALSE;
   mTimerIsActive = PR_FALSE;
   if (mProgressNotifier) {
     mProgressNotifier->Cancel();
   }
 
-  //FileRequest must be in DONE stage after a load
-  mReadyState = nsIDOMFileRequest::DONE;
+  //FileReader must be in DONE stage after a load
+  mReadyState = nsIDOMFileReader::DONE;
 
   //Set the status field as appropriate
   if (NS_FAILED(aStatus)) {
     DispatchError(aStatus);
     return NS_OK;
   }
 
   nsresult rv;
   switch (mDataFormat) {
     case FILE_AS_BINARY:
-      break; //Already accumulated mResponse
+      break; //Already accumulated mResult
     case FILE_AS_TEXT:
-      rv = GetAsText(mCharset, mFileData, mDataLen, mResponse);
+      rv = GetAsText(mCharset, mFileData, mDataLen, mResult);
       break;
     case FILE_AS_DATAURL:
-      rv = GetAsDataURL(mFile, mFileData, mDataLen, mResponse);
+      rv = GetAsDataURL(mFile, mFileData, mDataLen, mResult);
       break;
     default:
      return NS_ERROR_FAILURE;
   }
 
   //Dispatch load event to signify end of a successful load
   DispatchProgressEvent(NS_LITERAL_STRING(LOAD_STR));
   DispatchProgressEvent(NS_LITERAL_STRING(LOADEND_STR));
 
   return rv;
 }
 
 // Helper methods
 
 nsresult
-nsDOMFileRequest::ReadFileContent(nsIDOMFile* aFile,
-                                  const nsAString &aCharset,
-                                  PRUint32 aDataFormat)
+nsDOMFileReader::ReadFileContent(nsIDOMFile* aFile,
+                                 const nsAString &aCharset,
+                                 PRUint32 aDataFormat)
 { 
   NS_ENSURE_TRUE(aFile, NS_ERROR_NULL_POINTER);
 
   //Implicit abort to clear any other activity going on
   Abort();
   mDataFormat = aDataFormat;
   mCharset = aCharset;
   mError = nsnull;
@@ -485,25 +485,25 @@ nsDOMFileRequest::ReadFileContent(nsIDOM
   NS_ENSURE_SUCCESS(rv, rv);
 
   //Obtain the total size of the file before reading
   aFile->GetSize(&mReadTotal);
 
   rv = mChannel->AsyncOpen(this, nsnull);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  //FileRequest should be in loading state here
-  mReadyState = nsIDOMFileRequest::LOADING;
+  //FileReader should be in loading state here
+  mReadyState = nsIDOMFileReader::LOADING;
   DispatchProgressEvent(NS_LITERAL_STRING(LOADSTART_STR));
  
   return NS_OK;
 }
 
 void
-nsDOMFileRequest::DispatchError(nsresult rv)
+nsDOMFileReader::DispatchError(nsresult rv)
 {
   //Set the status attribute, and dispatch the error event
   switch (rv) {
     case NS_ERROR_FILE_NOT_FOUND:
       mError = new nsDOMFileError(nsIDOMFileError::NOT_FOUND_ERR);
       break;
     case NS_ERROR_FILE_ACCESS_DENIED:
       mError = new nsDOMFileError(nsIDOMFileError::SECURITY_ERR);
@@ -514,17 +514,17 @@ nsDOMFileRequest::DispatchError(nsresult
   }
 
   //Dispatch error event to signify load failure
   DispatchProgressEvent(NS_LITERAL_STRING(ERROR_STR));
   DispatchProgressEvent(NS_LITERAL_STRING(LOADEND_STR));
 }
 
 void
-nsDOMFileRequest::DispatchProgressEvent(const nsAString& aType)
+nsDOMFileReader::DispatchProgressEvent(const nsAString& aType)
 {
   nsCOMPtr<nsIDOMEvent> event;
   nsresult rv = nsEventDispatcher::CreateEvent(nsnull, nsnull,
                                                NS_LITERAL_STRING("ProgressEvent"),
                                                getter_AddRefs(event));
   if (NS_FAILED(rv))
     return;
 
@@ -542,20 +542,20 @@ nsDOMFileRequest::DispatchProgressEvent(
 
   progress->InitProgressEvent(aType, PR_FALSE, PR_FALSE, mReadComplete,
                               mReadTransferred, (mReadTotal == LL_MAXUINT) ? 0 : mReadTotal);
 
   this->DispatchDOMEvent(nsnull, event, nsnull, nsnull);
 }
 
 nsresult
-nsDOMFileRequest::GetAsText(const nsAString &aCharset,
-                            const char *aFileData,
-                            PRUint32 aDataLen,
-                            nsAString& aResult)
+nsDOMFileReader::GetAsText(const nsAString &aCharset,
+                           const char *aFileData,
+                           PRUint32 aDataLen,
+                           nsAString& aResult)
 {
   nsresult rv;
   nsCAutoString charsetGuess;
   if (!aCharset.IsEmpty()) {
     CopyUTF16toUTF8(aCharset, charsetGuess);
   } else {
     rv = GuessCharset(aFileData, aDataLen, charsetGuess);
     NS_ENSURE_SUCCESS(rv, rv);
@@ -569,20 +569,20 @@ nsDOMFileRequest::GetAsText(const nsAStr
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = ConvertStream(aFileData, aDataLen, charset.get(), aResult);
 
   return NS_OK;
 }
 
 nsresult
-nsDOMFileRequest::GetAsDataURL(nsIFile *aFile,
-                               const char *aFileData,
-                               PRUint32 aDataLen,
-                               nsAString& aResult)
+nsDOMFileReader::GetAsDataURL(nsIFile *aFile,
+                              const char *aFileData,
+                              PRUint32 aDataLen,
+                              nsAString& aResult)
 {
   aResult.AssignLiteral("data:");
 
   nsresult rv;
   nsCOMPtr<nsIMIMEService> mimeService =
     do_GetService(NS_MIMESERVICE_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -616,20 +616,20 @@ nsDOMFileRequest::GetAsDataURL(nsIFile *
     totalRead += numEncode;
 
   } while (aDataLen > totalRead);
 
   return NS_OK;
 }
 
 nsresult
-nsDOMFileRequest::ConvertStream(const char *aFileData,
-                                PRUint32 aDataLen,
-                                const char *aCharset,
-                                nsAString &aResult)
+nsDOMFileReader::ConvertStream(const char *aFileData,
+                               PRUint32 aDataLen,
+                               const char *aCharset,
+                               nsAString &aResult)
 {
   nsresult rv;
   nsCOMPtr<nsICharsetConverterManager> charsetConverter = 
     do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIUnicodeDecoder> unicodeDecoder;
   rv = charsetConverter->GetUnicodeDecoder(aCharset, getter_AddRefs(unicodeDecoder));
@@ -645,19 +645,19 @@ nsDOMFileRequest::ConvertStream(const ch
   PRInt32 srcLength = aDataLen;
   rv = unicodeDecoder->Convert(aFileData, &srcLength, aResult.BeginWriting(), &destLength);
   aResult.SetLength(destLength); //Trim down to the correct size
 
   return rv;
 }
 
 nsresult
-nsDOMFileRequest::GuessCharset(const char *aFileData,
-                               PRUint32 aDataLen,
-                               nsACString &aCharset)
+nsDOMFileReader::GuessCharset(const char *aFileData,
+                              PRUint32 aDataLen,
+                              nsACString &aCharset)
 {
   // First try the universal charset detector
   nsCOMPtr<nsICharsetDetector> detector
     = do_CreateInstance(NS_CHARSET_DETECTOR_CONTRACTID_BASE
                         "universal_charset_detector");
   if (!detector) {
     // No universal charset detector, try the default charset detector
     const nsAdoptingString& detectorName =
rename from content/base/src/nsDOMFileRequest.h
rename to content/base/src/nsDOMFileReader.h
--- a/content/base/src/nsDOMFileRequest.h
+++ b/content/base/src/nsDOMFileReader.h
@@ -30,61 +30,61 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-#ifndef nsDOMFileRequest_h__
-#define nsDOMFileRequest_h__
+#ifndef nsDOMFileReader_h__
+#define nsDOMFileReader_h__
 
 #include "nsISupportsUtils.h"      
 #include "nsString.h"              
 #include "nsIStreamListener.h"     
 #include "nsIScriptContext.h"      
 #include "nsIInterfaceRequestor.h" 
 #include "nsJSUtils.h"             
 #include "nsTArray.h"              
 #include "nsIJSNativeInitializer.h"
 #include "prtime.h"                
 #include "nsITimer.h"              
 #include "nsDOMEventTargetHelper.h"
 #include "nsICharsetDetector.h"
 #include "nsICharsetDetectionObserver.h"
 
 #include "nsIDOMFile.h"
-#include "nsIDOMFileRequest.h"
+#include "nsIDOMFileReader.h"
 #include "nsIDOMFileList.h"
 #include "nsIDOMFileError.h"
 #include "nsIInputStream.h"
 #include "nsCOMPtr.h"
 #include "nsIStreamLoader.h"
 #include "nsIChannel.h"
 
 #include "nsXMLHttpRequest.h"
 
-class nsDOMFileRequest : public nsXHREventTarget,
-                         public nsIDOMFileRequest,
-                         public nsIStreamListener,
-                         public nsIInterfaceRequestor,
-                         public nsSupportsWeakReference,
-                         public nsIJSNativeInitializer,
-                         public nsITimerCallback,
-                         public nsICharsetDetectionObserver
+class nsDOMFileReader : public nsXHREventTarget,
+                        public nsIDOMFileReader,
+                        public nsIStreamListener,
+                        public nsIInterfaceRequestor,
+                        public nsSupportsWeakReference,
+                        public nsIJSNativeInitializer,
+                        public nsITimerCallback,
+                        public nsICharsetDetectionObserver
 {
 public:
-  nsDOMFileRequest();
-  virtual ~nsDOMFileRequest();
+  nsDOMFileReader();
+  virtual ~nsDOMFileReader();
 
   NS_DECL_ISUPPORTS_INHERITED
 
-  NS_DECL_NSIDOMFILEREQUEST
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDOMFileRequest, nsXHREventTarget)
+  NS_DECL_NSIDOMFILEREADER
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDOMFileReader, nsXHREventTarget)
 
   NS_FORWARD_NSIXMLHTTPREQUESTEVENTTARGET(nsXHREventTarget::);
         
   // nsIStreamListener
   NS_DECL_NSISTREAMLISTENER
                                
   // nsIRequestObserver
   NS_DECL_NSIREQUESTOBSERVER
@@ -121,17 +121,17 @@ protected:
 
   char *mFileData;
   nsCOMPtr<nsIFile> mFile;
   nsString mCharset;
   PRUint32 mReadCount;
   PRUint32 mDataLen;
   PRUint32 mDataFormat;
 
-  nsString mResponse;
+  nsString mResult;
   PRUint16 mReadyState;
 
   PRBool mProgressEventWasDelayed;
   PRBool mTimerIsActive;
   nsCOMPtr<nsIDOMFileError> mError;
 
   nsCOMPtr<nsITimer> mProgressNotifier;
   nsCOMPtr<nsIPrincipal> mPrincipal;
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -106,16 +106,17 @@ GK_ATOM(any, "any")
 GK_ATOM(applet, "applet")
 GK_ATOM(applyImports, "apply-imports")
 GK_ATOM(applyTemplates, "apply-templates")
 GK_ATOM(archive, "archive")
 GK_ATOM(area, "area")
 GK_ATOM(ascending, "ascending")
 GK_ATOM(aspectRatio, "aspect-ratio")
 GK_ATOM(assign, "assign")
+GK_ATOM(async, "async")
 GK_ATOM(attribute, "attribute")
 GK_ATOM(attributeSet, "attribute-set")
 GK_ATOM(aural, "aural")
 GK_ATOM(_auto, "auto")
 #ifdef MOZ_MEDIA
 GK_ATOM(autobuffer, "autobuffer")
 #endif
 GK_ATOM(autocheck, "autocheck")
--- a/content/base/src/nsScriptLoader.cpp
+++ b/content/base/src/nsScriptLoader.cpp
@@ -134,16 +134,20 @@ nsScriptLoader::nsScriptLoader(nsIDocume
 nsScriptLoader::~nsScriptLoader()
 {
   mObservers.Clear();
 
   for (PRInt32 i = 0; i < mRequests.Count(); i++) {
     mRequests[i]->FireScriptAvailable(NS_ERROR_ABORT);
   }
 
+  for (PRInt32 i = 0; i < mAsyncRequests.Count(); i++) {
+    mAsyncRequests[i]->FireScriptAvailable(NS_ERROR_ABORT);
+  }
+
   // Unblock the kids, in case any of them moved to a different document
   // subtree in the meantime and therefore aren't actually going away.
   for (PRUint32 j = 0; j < mPendingChildLoaders.Length(); ++j) {
     mPendingChildLoaders[j]->RemoveExecuteBlocker();
   }  
 }
 
 NS_IMPL_ISUPPORTS1(nsScriptLoader, nsIStreamLoaderObserver)
@@ -496,79 +500,96 @@ nsScriptLoader::ProcessScriptElement(nsI
   nsRefPtr<nsScriptLoadRequest> request;
   if (scriptURI) {
     nsTArray<PreloadInfo>::index_type i =
       mPreloads.IndexOf(scriptURI.get(), 0, PreloadURIComparator());
     if (i != nsTArray<PreloadInfo>::NoIndex) {
       request = mPreloads[i].mRequest;
       request->mElement = aElement;
       request->mJSVersion = version;
-      request->mDefer = mDeferEnabled && aElement->GetScriptDeferred();
+      request->mDefer = mDeferEnabled && aElement->GetScriptDeferred() &&
+        !aElement->GetScriptAsync();
       mPreloads.RemoveElementAt(i);
 
       rv = CheckContentPolicy(mDocument, aElement, request->mURI, type);
       if (NS_FAILED(rv)) {
         // Note, we're dropping our last ref to request here.
         return rv;
       }
 
-      if (!request->mLoading && !request->mDefer && !hadPendingRequests &&
-            ReadyToExecuteScripts() && nsContentUtils::IsSafeToRunScript()) {
+      // Can we run the script now?
+      // This is true if we're done loading, the script isn't deferred and
+      // there are either no scripts or stylesheets to wait for, or the
+      // script is async
+      PRBool readyToRun =
+        !request->mLoading && !request->mDefer &&
+        ((!hadPendingRequests && ReadyToExecuteScripts()) ||
+         aElement->GetScriptAsync());
+
+      if (readyToRun && nsContentUtils::IsSafeToRunScript()) {
         return ProcessRequest(request);
       }
 
       // Not done loading yet. Move into the real requests queue and wait.
-      mRequests.AppendObject(request);
+      if (aElement->GetScriptAsync()) {
+        mAsyncRequests.AppendObject(request);
+      }
+      else {
+        mRequests.AppendObject(request);
+      }
 
-      if (!request->mLoading && !hadPendingRequests && ReadyToExecuteScripts() &&
-          !request->mDefer) {
+      if (readyToRun) {
         nsContentUtils::AddScriptRunner(new nsRunnableMethod<nsScriptLoader>(this,
           &nsScriptLoader::ProcessPendingRequests));
       }
 
-      return request->mDefer ? NS_OK : NS_ERROR_HTMLPARSER_BLOCK;
+      return request->mDefer || aElement->GetScriptAsync() ?
+        NS_OK : NS_ERROR_HTMLPARSER_BLOCK;
     }
   }
 
   // Create a request object for this script
   request = new nsScriptLoadRequest(aElement, version);
   NS_ENSURE_TRUE(request, NS_ERROR_OUT_OF_MEMORY);
 
-  request->mDefer = mDeferEnabled && aElement->GetScriptDeferred();
-
   // First check to see if this is an external script
   if (scriptURI) {
+    request->mDefer = mDeferEnabled && aElement->GetScriptDeferred() &&
+      !aElement->GetScriptAsync();
     request->mURI = scriptURI;
     request->mIsInline = PR_FALSE;
     request->mLoading = PR_TRUE;
 
     rv = StartLoad(request, type);
     if (NS_FAILED(rv)) {
       return rv;
     }
   } else {
+    request->mDefer = PR_FALSE;
     request->mLoading = PR_FALSE;
     request->mIsInline = PR_TRUE;
     request->mURI = mDocument->GetDocumentURI();
 
     request->mLineNo = aElement->GetScriptLineNumber();
 
     // If we've got existing pending requests, add ourselves
     // to this list.
-    if (!request->mDefer && !hadPendingRequests &&
-        ReadyToExecuteScripts() && nsContentUtils::IsSafeToRunScript()) {
+    if (!hadPendingRequests && ReadyToExecuteScripts() &&
+        nsContentUtils::IsSafeToRunScript()) {
       return ProcessRequest(request);
     }
   }
 
   // Add the request to our requests list
-  NS_ENSURE_TRUE(mRequests.AppendObject(request),
+  NS_ENSURE_TRUE(aElement->GetScriptAsync() ?
+                 mAsyncRequests.AppendObject(request) :
+                 mRequests.AppendObject(request),
                  NS_ERROR_OUT_OF_MEMORY);
 
-  if (request->mDefer) {
+  if (request->mDefer || aElement->GetScriptAsync()) {
     return NS_OK;
   }
 
   // If there weren't any pending requests before, and this one is
   // ready to execute, do that as soon as it's safe.
   if (!request->mLoading && !hadPendingRequests && ReadyToExecuteScripts()) {
     nsContentUtils::AddScriptRunner(new nsRunnableMethod<nsScriptLoader>(this,
       &nsScriptLoader::ProcessPendingRequests));
@@ -731,32 +752,51 @@ nsScriptLoader::ProcessPendingRequestsAs
 
     NS_DispatchToCurrentThread(ev);
   }
 }
 
 void
 nsScriptLoader::ProcessPendingRequests()
 {
-  nsRefPtr<nsScriptLoadRequest> request;
-  while (ReadyToExecuteScripts() &&
-         (request = GetFirstPendingRequest()) &&
-         !request->mLoading) {
-    mRequests.RemoveObject(request);
+  while (1) {
+    nsRefPtr<nsScriptLoadRequest> request;
+    if (ReadyToExecuteScripts()) {
+      request = GetFirstPendingRequest();
+      if (request && !request->mLoading) {
+        mRequests.RemoveObject(request);
+      }
+      else {
+        request = nsnull;
+      }
+    }
+
+    for (PRInt32 i = 0;
+         !request && mEnabled && i < mAsyncRequests.Count();
+         ++i) {
+      if (!mAsyncRequests[i]->mLoading) {
+        request = mAsyncRequests[i];
+        mAsyncRequests.RemoveObjectAt(i);
+      }
+    }
+
+    if (!request)
+      break;
+
     ProcessRequest(request);
   }
 
   while (!mPendingChildLoaders.IsEmpty() && ReadyToExecuteScripts()) {
     nsRefPtr<nsScriptLoader> child = mPendingChildLoaders[0];
     mPendingChildLoaders.RemoveElementAt(0);
     child->RemoveExecuteBlocker();
   }
 
   if (mUnblockOnloadWhenDoneProcessing && mDocument &&
-      !GetFirstPendingRequest()) {
+      !GetFirstPendingRequest() && !mAsyncRequests.Count()) {
     // No more pending scripts; time to unblock onload.
     // OK to unblock onload synchronously here, since callers must be
     // prepared for the world changing anyway.
     mUnblockOnloadWhenDoneProcessing = PR_FALSE;
     mDocument->UnblockOnload(PR_TRUE);
   }
 }
 
@@ -915,20 +955,21 @@ nsScriptLoader::OnStreamComplete(nsIStre
 {
   nsScriptLoadRequest* request = static_cast<nsScriptLoadRequest*>(aContext);
   NS_ASSERTION(request, "null request in stream complete handler");
   NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
 
   nsresult rv = PrepareLoadedRequest(request, aLoader, aStatus, aStringLen,
                                      aString);
   if (NS_FAILED(rv)) {
-    if (!mRequests.RemoveObject(request)) {
+    if (mRequests.RemoveObject(request) ||
+        mAsyncRequests.RemoveObject(request)) {
+      FireScriptAvailable(rv, request);
+    } else {
       mPreloads.RemoveElement(request, PreloadRequestComparator());
-    } else {
-      FireScriptAvailable(rv, request);
     }
   }
 
   // Process our request and/or any pending ones
   ProcessPendingRequests();
 
   return NS_OK;
 }
@@ -988,16 +1029,17 @@ nsScriptLoader::PrepareLoadedRequest(nsS
     }
   }
 
   // This assertion could fire errorously if we ran out of memory when
   // inserting the request in the array. However it's an unlikely case
   // so if you see this assertion it is likely something else that is
   // wrong, especially if you see it more than once.
   NS_ASSERTION(mRequests.IndexOf(aRequest) >= 0 ||
+               mAsyncRequests.IndexOf(aRequest) >= 0 ||
                mPreloads.Contains(aRequest, PreloadRequestComparator()),
                "aRequest should be pending!");
 
   // Mark this as loaded
   aRequest->mLoading = PR_FALSE;
 
   return NS_OK;
 }
--- a/content/base/src/nsScriptLoader.h
+++ b/content/base/src/nsScriptLoader.h
@@ -295,16 +295,17 @@ protected:
                                 const PRUint8* aString);
 
   // Returns the first pending (non deferred) request
   nsScriptLoadRequest* GetFirstPendingRequest();
 
   nsIDocument* mDocument;                   // [WEAK]
   nsCOMArray<nsIScriptLoaderObserver> mObservers;
   nsCOMArray<nsScriptLoadRequest> mRequests;
+  nsCOMArray<nsScriptLoadRequest> mAsyncRequests;
 
   // In mRequests, the additional information here is stored by the element.
   struct PreloadInfo {
     nsRefPtr<nsScriptLoadRequest> mRequest;
     nsString mCharset;
   };
 
   struct PreloadRequestComparator {
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -318,16 +318,21 @@ include $(topsrcdir)/config/rules.mk
 		bug466409-page.html \
 		bug466409-empty.css \
 		test_bug466409.html \
 		test_classList.html \
 		test_bug514487.html \
 		test_range_bounds.html \
 		test_bug475156.html \
 		bug475156.sjs \
+		test_copypaste.html \
+		test_bug503481.html \
+		file_bug503481.sjs \
+		test_bug503481b.html \
+		file_bug503481b_inner.html \
 		$(NULL)
 
 # Disabled; see bug 492181
 #		test_plugin_freezing.html
 
 # Disabled for now. Mochitest isn't reliable enough for these.
 # test_bug444546.html \
 # bug444546.sjs \
new file mode 100644
--- /dev/null
+++ b/content/base/test/file_bug503481.sjs
@@ -0,0 +1,43 @@
+// 'timer' is global to avoid getting GCed which would cancel the timer
+var timer;
+const nsITimer = Components.interfaces.nsITimer;
+
+function attemptUnblock(s) {
+  try {
+    let blockedResponse = null;
+    getObjectState("bug503481_" + s, function(x) {blockedResponse = x.wrappedJSObject.r});
+    blockedResponse.finish();
+    setObjectState("bug503481_" + s, null);
+  } catch(e) {
+    dump("unable to unblock " + s + "retrying in half a second\n");
+    timer = Components.classes["@mozilla.org/timer;1"]
+                      .createInstance(nsITimer);
+    timer.initWithCallback(function () { attemptUnblock(s) }, 500, nsITimer.TYPE_ONE_SHOT);
+  }
+}
+
+function handleRequest(request, response)
+{
+  var query = {};
+  request.queryString.split('&').forEach(function (val) {
+    var [name, value] = val.split('=');
+    query[name] = unescape(value);
+  });
+
+  dump("processing:" + request.queryString + "\n");
+
+  if (query.unblock) {
+    attemptUnblock(query.unblock);
+  }
+
+  if (query.blockOn) {
+    response.processAsync();
+    x = { r: response, QueryInterface: function(iid) { return this } };
+    x.wrappedJSObject = x;
+    setObjectState("bug503481_" + query.blockOn, x);
+  }
+
+  response.setHeader("Cache-Control", "no-cache", false);
+  response.setHeader("Content-Type", "text/plain", false);
+  response.write(query.body);
+}
new file mode 100644
--- /dev/null
+++ b/content/base/test/file_bug503481b_inner.html
@@ -0,0 +1,85 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<!-- Async script that isn't preloaded -->
+<script async src="file_bug503481.sjs?blockOn=R&body=runFirst();"></script>
+<script>
+firstRan = false;
+secondRan = false;
+thirdRan = false;
+forthRan = false;
+fifthRan = false;
+sixthRan = false;
+function runFirst() {
+  firstRan = true;
+}
+function runThird() {
+  parent.is(forthRan, false, "forth should still be blocked");
+  unblock("T");
+  thirdRan = true;
+}
+function runForth() {
+  forthRan = true;
+}
+function runFifth() {
+  parent.is(sixthRan, false, "sixth should be not run before non-async fifth");
+  fifthRan = true;
+}
+function runSixth() {
+  parent.is(fifthRan, true, "fifth should run before async sixth");
+  sixthRan = true;
+}
+
+function done() {
+  parent.is(firstRan, true, "first should have run by onload");
+  parent.is(secondRan, true, "second should have run by onload");
+  parent.is(thirdRan, true, "third should have run by onload");
+  parent.is(forthRan, true, "forth should have run by onload");
+  parent.is(fifthRan, true, "fifth should have run by onload");
+  parent.is(sixthRan, true, "sixth should have run by onload");
+  parent.SimpleTest.finish();
+}
+
+var reqs = [];
+function unblock(s) {
+  xhr = new XMLHttpRequest();
+  xhr.open("GET", "file_bug503481.sjs?unblock=" + s);
+  xhr.send();
+  reqs.push(xhr);
+}
+
+
+parent.is(firstRan, false, "First async script shouldn't have run");
+unblock("R");
+</script>
+
+<!-- test that inline async isn't actually async -->
+<script async>
+secondRan = true;
+</script>
+<script async>
+parent.is(secondRan, true, "Second script shouldn't be async");
+</script>
+
+<!-- test that setting both defer and async treats the script as async -->
+<script defer async src="file_bug503481.sjs?blockOn=S&body=runThird();"></script>
+<script>
+parent.is(thirdRan, false, "third should not have run yet");
+unblock("S");
+</script>
+<script src="file_bug503481.sjs?blockOn=T&body=runForth();"></script>
+
+<!-- test that preloading an async script works -->
+<script>
+setTimeout(function () { unblock("U"); }, 1000);
+</script>
+<script src="file_bug503481.sjs?blockOn=U&body=runFifth();"></script>
+<script async src="file_bug503481.sjs?blockOn=V&body=runSixth();"></script>
+<script>
+parent.is(fifthRan, true, "fifth should have run by now");
+parent.is(sixthRan, false, "sixth should not have run yet");
+unblock("V");
+</script>
+</head>
+
+<body onload="done()">
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_bug503481.html
@@ -0,0 +1,70 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=503481
+-->
+<head>
+  <title>Test for Bug 503481</title>
+  <script src="/MochiKit/packed.js"></script>
+  <script src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body onload="done();">
+
+<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=503481"
+   target="_blank" >Mozilla Bug 503481</a>
+
+<p id="display"></p>
+
+<script>
+SimpleTest.waitForExplicitFinish();
+function done() {
+  is(firstRan, true, "first has run");
+  is(secondRan, true, "second has run");
+  is(thirdRan, true, "third has run");
+  SimpleTest.finish();
+}
+var reqs = [];
+function unblock(s) {
+  xhr = new XMLHttpRequest();
+  xhr.open("GET", "file_bug503481.sjs?unblock=" + s);
+  xhr.send();
+  reqs.push(xhr);
+}
+var firstRan = false, secondRan = false, thirdRan = false;
+function runFirst() { firstRan = true; }
+function runSecond() {
+  is(thirdRan, true, "should have run third already");
+  secondRan = true;
+}
+function runThird() {
+  is(secondRan, false, "shouldn't have unblocked second yet");
+  thirdRan = true;
+  unblock("B");
+}
+</script>
+<script id=firstScript async src="file_bug503481.sjs?blockOn=A&body=runFirst();"></script>
+<script id=firstScriptHelper>
+is(document.getElementById("firstScript").async, true,
+   "async set");
+is(document.getElementById("firstScriptHelper").async, false,
+   "async not set");
+document.getElementById("firstScript").async = false;
+is(document.getElementById("firstScript").async, false,
+   "async no longer set");
+is(document.getElementById("firstScript").hasAttribute("async"), false,
+   "async attribute no longer set");
+is(firstRan, false, "First async script shouldn't have run");
+unblock("A");
+</script>
+
+<script async src="file_bug503481.sjs?blockOn=B&body=runSecond();"></script>
+<script async src="file_bug503481.sjs?blockOn=C&body=runThird();"></script>
+<script>
+is(secondRan, false, "Second async script shouldn't have run");
+is(thirdRan, false, "Third async script shouldn't have run");
+unblock("C");
+</script>
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_bug503481b.html
@@ -0,0 +1,23 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=503481
+-->
+<head>
+  <title>Test for Bug 503481</title>
+  <script src="/MochiKit/packed.js"></script>
+  <script src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+
+<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=503481"
+   target="_blank" >Mozilla Bug 503481</a>
+
+<iframe src="file_bug503481b_inner.html"></iframe>
+<script>
+SimpleTest.waitForExplicitFinish();
+// script in the iframe will call SimpleTest.finish()
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_copypaste.html
@@ -0,0 +1,94 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+-->
+<head>
+  <title>Test for copy/paste</title>
+  <script type="text/javascript" src="/MochiKit/packed.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=524975">Mozilla Bug </a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+function testCopyPaste () {
+  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+
+  // selection of the node
+  var node = document.getElementById('draggable');
+  window.getSelection().selectAllChildren(node);
+  
+  // let's copy the selection
+  var webnav = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
+                     .getInterface(Components.interfaces.nsIWebNavigation)
+
+  var docShell = webnav.QueryInterface(Components.interfaces.nsIDocShell);
+
+  var documentViewer = docShell.contentViewer
+                               .QueryInterface(Components.interfaces.nsIContentViewerEdit);
+  documentViewer.copySelection();
+  
+  //--------- now check the content of the clipboard
+  var clipboard = Components.classes["@mozilla.org/widget/clipboard;1"]
+                            .getService(Components.interfaces.nsIClipboard);
+  
+  // is the clipboard contain a text/unicode data ?
+  var transferable = Components.classes['@mozilla.org/widget/transferable;1']
+                               .createInstance(Components.interfaces.nsITransferable);
+  transferable.addDataFlavor("text/unicode");
+  clipboard.getData(transferable, 1);
+  var data = {}
+  transferable.getTransferData ("text/unicode", data, {} ) ;
+  is (data.value.QueryInterface(Components.interfaces.nsISupportsString).data,
+      "This is a draggable bit of text.");
+  
+  // is the clipboard contain a text/html data ?
+  transferable = Components.classes['@mozilla.org/widget/transferable;1']
+        .createInstance(Components.interfaces.nsITransferable);
+  transferable.addDataFlavor("text/html");
+  clipboard.getData(transferable, 1); 
+  transferable.getTransferData ("text/html", data, {} ) ;
+  is (data.value.QueryInterface(Components.interfaces.nsISupportsString).data,
+      "<div id=\"draggable\" title=\"title to have a long HTML line\">This is a <em>draggable</em>\n bit of text.</div>");
+  
+  //------ let's paste now in the textarea and verify its content
+  var textarea = document.getElementById('input');
+  textarea.focus();
+  textarea.QueryInterface(Components.interfaces.nsIDOMNSEditableElement)
+          .editor.paste(1);
+  is(textarea.value, "This is a draggable bit of text.");
+
+
+  // test copy/paste from/to textarea
+  var val = "1\n 2\n  3"
+  textarea.value=val;
+  textarea.select();
+  textarea.editor.copy();
+  
+  textarea.value="";
+  textarea.editor.paste(1);
+  is(textarea.value, val);
+
+  SimpleTest.finish();
+}
+
+
+SimpleTest.waitForExplicitFinish();
+
+addLoadEvent(testCopyPaste);
+
+</script>
+</pre>
+<div>
+
+  <div id="draggable" title="title to have a long HTML line">This is a <em>draggable</em> bit of text.</div>
+  <textarea id="input"></textarea>
+
+</div>
+</body>
+</html>
--- a/content/base/test/test_fileapi.html
+++ b/content/base/test/test_fileapi.html
@@ -56,80 +56,80 @@ var utf32File = createFileWithData(utf32
 //Obtain a variety of encodings so we can test async return values
 var file = createFileWithData(testData, "00");
 var domFileData = file.getAsDataURL();
 var domFileBinary = file.getAsBinary();
 
 var domFileBinary2 = utf16File.getAsBinary();
 var domFileBinary3 = utf32File.getAsBinary();
 
-var request1 = new FileRequest();
+var request1 = new FileReader();
 request1.onload = handleTextISO1;
 request1.readAsText(file, "iso-8859-1");
 
-var request2 = new FileRequest();
+var request2 = new FileReader();
 request2.onload = handleTextUTF8;
 request2.readAsText(file);
 
-var request3 = new FileRequest();
+var request3 = new FileReader();
 request3.onload = handleTextUTF8;
 request3.readAsText(file, "");
 
-var request4 = new FileRequest();
+var request4 = new FileReader();
 request4.onload = handleTextUTF8;
 request4.readAsText(file, "UTF-8");
 
 //Test a variety of encodings, and make sure they work properly
 //Also, test a variety of the same calls with different numbers of arguments
-var request5 = new FileRequest();
+var request5 = new FileReader();
 request5.onload = handleTextUTF16;
 request5.readAsText(utf16File, "UTF-16");
 
-var request6 = new FileRequest();
+var request6 = new FileReader();
 request6.onload = handleTextUTF32;
 request6.readAsText(utf32File, "UTF-32");
 
 //Test binary data accessor
-var request7 = new FileRequest();
+var request7 = new FileReader();
 request7.onload = handleDataBinary;
 request7.readAsBinaryString(file);
 
-var request71 = new FileRequest();
+var request71 = new FileReader();
 request71.onload = handleDataBinary16;
 request71.readAsBinaryString(utf16File);
 
-var request72 = new FileRequest();
+var request72 = new FileReader();
 request72.onload = handleDataBinary32;
 request72.readAsBinaryString(utf32File);
 
 //Test data URI encoding on differing file sizes
 //Testing data URI when length % 3 == 0
-var request8 = new FileRequest();
+var request8 = new FileReader();
 request8.onload = handleDataURI;
 request8.readAsDataURL(file);
 
 //Testing data URI when length % 3 == 1
 var file2 = createFileWithData(testData2, "02");
 var domFileData1 = file2.getAsDataURL();
 
-var request9 = new FileRequest();
+var request9 = new FileReader();
 request9.onload = handleDataURI1;
 request9.readAsDataURL(file2);
 
 //Testing data URI when length % 3 == 2
 var file3 = createFileWithData(testData3, "03");
 var domFileData2 = file3.getAsDataURL();
 
-var request10 = new FileRequest();
+var request10 = new FileReader();
 request10.onload = handleDataURI2;
 request10.readAsDataURL(file3);
 
 //Test asynchronous property of file access
 var globalVar = 0;
-var request105 = new FileRequest();
+var request105 = new FileReader();
 request105.onload = incGlobalVar;
 request105.readAsText(file, "");
 is(globalVar, 0, "testing to make sure getAsText doesn't block subsequent execution");
 
 //Create second file for testing cancelReads()
 var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties);
 var testFile4 = dirSvc.get("ProfD", Components.interfaces.nsIFile);
 testFile4.append("testfile04");
@@ -137,136 +137,136 @@ var outStream4 = Components.classes["@mo
 outStream4.init(testFile4, 0x02 | 0x08 | 0x20, 0666, 0);
 outStream4.write(testData, testData.length);
 outStream4.close();
 
 var fileList = document.getElementById('fileList');
 fileList.value = testFile4.path;
 var file4 = fileList.files[0];
 
-var request11 = new FileRequest();
+var request11 = new FileReader();
 request11.onabort = handleCancel;
 request11.readAsText(file4);
 request11.abort();
 
 //Test error handling - Note: currently throws exceptions
 /*testFile4.permissions = 0;
-var request12 = new FileRequest();
+var request12 = new FileReader();
 request12.onerror = handleSecurityError;
 request12.readAsText(file4, "");
 
 testFile4.remove(false);
-var request13 = new FileRequest();
+var request13 = new FileReader();
 request13.onerror = handleNotFoundError;
 request13.readAsText(file4, "");*/
 
 //Corresponding callback functions
 function incGlobalVar(fileAsText) {
   globalVar++;
 }
 
 function handleCancel(event) {
-  var fileAsText = event.target.response;
+  var fileAsText = event.target.result;
   var error = event.target.error;
   is(error.code, FileError.ABORT_ERR, "error code set to CANCELED for canceled reads");
   is(fileAsText, null, "file data should be null on canceled reads");
   testHasRun();
 }
 
 function handleTextISO1(event) {
-  var fileAsText = event.target.response;
+  var fileAsText = event.target.result;
   var error = event.target.error;
   is(error, null, "error code set to null for successful data accesses");
   is(testData.length, fileAsText.length, "iso-1 async length should match testdata");
   is(testData, fileAsText, "iso-1 async string result should match testdata");
   testHasRun();
 }
 
 function handleTextUTF8(event) {
-  var fileAsUTF8 = event.target.response;
+  var fileAsUTF8 = event.target.result;
   var error = event.target.error;
   is(error, null, "error code set to null for successful data accesses");
   is(testData.length, fileAsUTF8.length, "UTF-8 async length should match testdata");
   is(testData, fileAsUTF8, "UTF-8 async string result should match testdata");
   testHasRun();
 }
 
 function handleTextUTF16(event) {
-  var fileAsUTF16 = event.target.response;
+  var fileAsUTF16 = event.target.result;
   var error = event.target.error;
   is(error, null, "error code set to SUCCESS for successful data accesses");
   is(testData.length, fileAsUTF16.length, "UTF-16 async length should match testdata");
   is(testData, fileAsUTF16, "UTF-16 async string result should match testdata");
   testHasRun();
 }
 
 function handleTextUTF32(event) {
-  var fileAsUTF32 = event.target.response;
+  var fileAsUTF32 = event.target.result;
   var error = event.target.error;
   is(error, null, "error code set to SUCCESS for successful data accesses");
   is(testData.length, fileAsUTF32.length, "UTF-32 async length should match testdata");
   is(testData, fileAsUTF32, "UTF-32 async string result should match testdata");
   testHasRun();
 }
 
 //Tests dataURI.length % 3 == 0
 function handleDataURI(event) {
-  var fileAsDataURI = event.target.response;
+  var fileAsDataURI = event.target.result;
   is(domFileData.length, fileAsDataURI.length, "data URI async length should match dom file data");
   is(domFileData, fileAsDataURI, "data URI async string result should match dom file data");
   testHasRun();
 }
 
 //Tests dataURI.length % 3 == 1
 function handleDataURI1(event) {
-  var fileAsDataURI = event.target.response;
+  var fileAsDataURI = event.target.result;
   is(domFileData1.length, fileAsDataURI.length, "data URI async length should match dom file data1");
   is(domFileData1, fileAsDataURI, "data URI async string result should match dom file data1");
   testHasRun();
 }
 
 //Tests dataURI.length % 3 == 2
 function handleDataURI2(event) {
-  var fileAsDataURI = event.target.response;
+  var fileAsDataURI = event.target.result;
   is(domFileData2.length, fileAsDataURI.length, "data URI async length should match dom file data2");
   is(domFileData2, fileAsDataURI, "data URI async string result should match dom file data2");
   testHasRun();
 }
 
 function handleDataBinary(event) {
-  var fileAsBinary = event.target.response;
+  var fileAsBinary = event.target.result;
   is(domFileBinary.length, fileAsBinary.length, "binary data async length should match dom file binary");
   is(domFileBinary, fileAsBinary, "binary data async string result should match dom file binary");
   testHasRun();
 }
 
 function handleDataBinary16(event) {
-  var fileAsBinary = event.target.response;
+  var fileAsBinary = event.target.result;
   is(domFileBinary2.length, fileAsBinary.length, "binary data async length should match dom file binary16");
   is(domFileBinary2, fileAsBinary, "binary data async string result should match dom file binary16");
   testHasRun();
 }
 
 function handleDataBinary32(event) {
-  var fileAsBinary = event.target.response;
+  var fileAsBinary = event.target.result;
   is(domFileBinary3.length, fileAsBinary.length, "binary data async length should match dom file binary32");
   is(domFileBinary3, fileAsBinary, "binary data async string result should match dom file binary32");
   testHasRun();
 }
 
 function handleSecurityError(event) {
-  var fileAsText = event.target.response;
+  var fileAsText = event.target.result;
   var error = event.target.error;
   is(error.code, FileError.SECURITY_ERR, "code for file security error should have value 18");
   is(fileAsText, null, "file content should be null when error is encountered");
   testHasRun();
 }
 
 function handleNotFoundError(event) {
-  var fileAsText = event.target.response;
+  var fileAsText = event.target.result;
   var error = event.target.error;
   is(error.code, FileError.NOT_FOUND_ERR, "code for file not found error should have value 8");
   is(fileAsText, null, "file content should be null when error is encountered");
   testHasRun();
 }
 
 function testHasRun() {
   if (++testCounter == 13) SimpleTest.finish();
--- a/content/events/src/nsEventStateManager.cpp
+++ b/content/events/src/nsEventStateManager.cpp
@@ -1978,19 +1978,23 @@ nsEventStateManager::GenerateDragGesture
         event = &gestureEvent;
       }
 
       // now that the dataTransfer has been updated in the dragstart and
       // draggesture events, make it read only so that the data doesn't
       // change during the drag.
       dataTransfer->SetReadOnly();
 
-      if (status != nsEventStatus_eConsumeNoDefault)
-        DoDefaultDragStart(aPresContext, event, dataTransfer,
-                           targetContent, isSelection);
+      if (status != nsEventStatus_eConsumeNoDefault) {
+        PRBool dragStarted = DoDefaultDragStart(aPresContext, event, dataTransfer,
+                                                targetContent, isSelection);
+        if (dragStarted) {
+          aEvent->flags |= NS_EVENT_FLAG_STOP_DISPATCH;
+        }
+      }
 
       // Note that frame event handling doesn't care about NS_DRAGDROP_GESTURE,
       // which is just as well since we don't really know which frame to
       // send it to
 
       // Reset mCurretTargetContent to what it was
       mCurrentTargetContent = targetBeforeEvent;
     }
@@ -2101,59 +2105,60 @@ nsEventStateManager::DetermineDragTarget
     // XXXndeakin rework this a bit. Find a way to just not call GetDragData if we don't need to.
     if (dragContent != originalDragContent)
       aDataTransfer->ClearAll();
     *aTargetNode = dragContent;
     NS_ADDREF(*aTargetNode);
   }
 }
 
-void
+PRBool
 nsEventStateManager::DoDefaultDragStart(nsPresContext* aPresContext,
                                         nsDragEvent* aDragEvent,
                                         nsDOMDataTransfer* aDataTransfer,
                                         nsIContent* aDragTarget,
                                         PRBool aIsSelection)
 {
   nsCOMPtr<nsIDragService> dragService =
     do_GetService("@mozilla.org/widget/dragservice;1");
   if (!dragService)
-    return;
+    return PR_FALSE;
 
   // Default handling for the draggesture/dragstart event.
   //
   // First, check if a drag session already exists. This means that the drag
   // service was called directly within a draggesture handler. In this case,
   // don't do anything more, as it is assumed that the handler is managing
-  // drag and drop manually.
+  // drag and drop manually. Make sure to return true to indicate that a drag
+  // began.
   nsCOMPtr<nsIDragSession> dragSession;
   dragService->GetCurrentSession(getter_AddRefs(dragSession));
   if (dragSession)
-    return; // already a drag in progress
+    return PR_TRUE;
 
   // No drag session is currently active, so check if a handler added
   // any items to be dragged. If not, there isn't anything to drag.
   PRUint32 count = 0;
   if (aDataTransfer)
     aDataTransfer->GetMozItemCount(&count);
   if (!count)
-    return;
+    return PR_FALSE;
 
   // Get the target being dragged, which may not be the same as the
   // target of the mouse event. If one wasn't set in the
   // aDataTransfer during the event handler, just use the original
   // target instead.
   nsCOMPtr<nsIDOMNode> dragTarget;
   nsCOMPtr<nsIDOMElement> dragTargetElement;
   aDataTransfer->GetDragTarget(getter_AddRefs(dragTargetElement));
   dragTarget = do_QueryInterface(dragTargetElement);
   if (!dragTarget) {
     dragTarget = do_QueryInterface(aDragTarget);
     if (!dragTarget)
-      return;
+      return PR_FALSE;
   }
 
   // check which drag effect should initially be used. If the effect was not
   // set, just use all actions, otherwise Windows won't allow a drop.
   PRUint32 action;
   aDataTransfer->GetEffectAllowedInt(&action);
   if (action == nsIDragService::DRAGDROP_ACTION_UNINITIALIZED)
     action = nsIDragService::DRAGDROP_ACTION_COPY |
@@ -2178,17 +2183,17 @@ nsEventStateManager::DoDefaultDragStart(
                       nsISelectionController::SELECTION_NORMAL);
       }
     }
   }
 
   nsCOMPtr<nsISupportsArray> transArray;
   aDataTransfer->GetTransferables(getter_AddRefs(transArray));
   if (!transArray)
-    return;
+    return PR_FALSE;
 
   // XXXndeakin don't really want to create a new drag DOM event
   // here, but we need something to pass to the InvokeDragSession
   // methods.
   nsCOMPtr<nsIDOMEvent> domEvent;
   NS_NewDOMDragEvent(getter_AddRefs(domEvent), aPresContext, aDragEvent);
 
   nsCOMPtr<nsIDOMDragEvent> domDragEvent = do_QueryInterface(domEvent);
@@ -2226,16 +2231,18 @@ nsEventStateManager::DoDefaultDragStart(
     }
 #endif
 
     dragService->InvokeDragSessionWithImage(dragTarget, transArray,
                                             region, action, dragImage,
                                             imageX, imageY, domDragEvent,
                                             aDataTransfer);
   }
+
+  return PR_TRUE;
 }
 
 nsresult
 nsEventStateManager::GetMarkupDocumentViewer(nsIMarkupDocumentViewer** aMv)
 {
   *aMv = nsnull;
 
   nsIFocusManager* fm = nsFocusManager::GetFocusManager();
@@ -3593,17 +3600,17 @@ nsEventStateManager::DispatchMouseEvent(
   nsEventStatus status = nsEventStatus_eIgnore;
   nsMouseEvent event(NS_IS_TRUSTED_EVENT(aEvent), aMessage, aEvent->widget,
                      nsMouseEvent::eReal);
   event.refPoint = aEvent->refPoint;
   event.isShift = ((nsMouseEvent*)aEvent)->isShift;
   event.isControl = ((nsMouseEvent*)aEvent)->isControl;
   event.isAlt = ((nsMouseEvent*)aEvent)->isAlt;
   event.isMeta = ((nsMouseEvent*)aEvent)->isMeta;
-  event.nativeMsg = ((nsMouseEvent*)aEvent)->nativeMsg;
+  event.pluginEvent = ((nsMouseEvent*)aEvent)->pluginEvent;
   event.relatedTarget = aRelatedContent;
 
   mCurrentTargetContent = aTargetContent;
 
   nsIFrame* targetFrame = nsnull;
   if (aTargetContent) {
     nsESMEventCB callback(aTargetContent);
     nsEventDispatcher::Dispatch(aTargetContent, mPresContext, &event, nsnull,
--- a/content/events/src/nsEventStateManager.h
+++ b/content/events/src/nsEventStateManager.h
@@ -317,28 +317,29 @@ protected:
                            nsIContent* aSelectionTarget,
                            nsDOMDataTransfer* aDataTransfer,
                            PRBool* aIsSelection,
                            PRBool* aIsInEditor,
                            nsIContent** aTargetNode);
 
   /*
    * Perform the default handling for the dragstart/draggesture event and set up a
-   * drag for aDataTransfer if it contains any data.
+   * drag for aDataTransfer if it contains any data. Returns true if a drag has
+   * started.
    *
    * aDragEvent - the dragstart/draggesture event
    * aDataTransfer - the data transfer that holds the data to be dragged
    * aDragTarget - the target of the drag
    * aIsSelection - true if a selection is being dragged
    */
-  void DoDefaultDragStart(nsPresContext* aPresContext,
-                          nsDragEvent* aDragEvent,
-                          nsDOMDataTransfer* aDataTransfer,
-                          nsIContent* aDragTarget,
-                          PRBool aIsSelection);
+  PRBool DoDefaultDragStart(nsPresContext* aPresContext,
+                            nsDragEvent* aDragEvent,
+                            nsDOMDataTransfer* aDataTransfer,
+                            nsIContent* aDragTarget,
+                            PRBool aIsSelection);
 
   PRBool IsTrackingDragGesture ( ) const { return mGestureDownContent != nsnull; }
   /**
    * Set the fields of aEvent to reflect the mouse position and modifier keys
    * that were set when the user first pressed the mouse button (stored by
    * BeginTrackingDragGesture). aEvent->widget must be
    * mCurrentTarget->GetWindow().
    */
--- a/content/events/test/test_bug299673-1.html
+++ b/content/events/test/test_bug299673-1.html
@@ -49,17 +49,17 @@ SELECT(Select1): blur \n\
 INPUT(popupText1): blur \n\
 : blur popup-doc\n\
 : focus top-doc\n\
 '
 
   setPrefAndDoTest(eventLogForNewWindow,'Body',2);  // 2 = open new window as window
 }
 
-if (navigator.platform.indexOf("Lin") == -1) {
+if (navigator.platform.indexOf("Lin") == -1 && navigator.platform.indexOf("SunOS") == -1) {
   SimpleTest.waitForExplicitFinish(); // the finish() call is in bug299673.js
   addLoadEvent(doTest);
 } else {
   todo(false, "Please write a better test for bug 299673 that also works on Linux");
 }
 
 </script>
 </pre>
--- a/content/html/content/src/nsHTMLLinkElement.cpp
+++ b/content/html/content/src/nsHTMLLinkElement.cpp
@@ -263,25 +263,19 @@ nsHTMLLinkElement::CreateAndDispatchEven
   if (!nsContentUtils::HasNonEmptyAttr(this, kNameSpaceID_None,
                                        nsGkAtoms::rev) &&
       FindAttrValueIn(kNameSpaceID_None, nsGkAtoms::rel,
                       strings, eIgnoreCase) != ATTR_VALUE_NO_MATCH)
     return;
 
   nsRefPtr<nsPLDOMEvent> event = new nsPLDOMEvent(this, aEventName, PR_TRUE);
   if (event) {
-    // If we have script blockers on the stack then we want to run as soon as
-    // they are removed. Otherwise punt the runable to the event loop as we
-    // don't know when it will be safe to run script.  In particular, we might
-    // be in the middle of a pagehide right now, and firing this event at that
-    // point is not such a great idea.
-    if (nsContentUtils::IsSafeToRunScript())
-      event->PostDOMEvent();
-    else
-      event->RunDOMEventWhenSafe();
+    // Always run async in order to avoid running script when the content
+    // sink isn't expecting it.
+    event->PostDOMEvent();
   }
 }
 
 nsresult
 nsHTMLLinkElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
                            nsIAtom* aPrefix, const nsAString& aValue,
                            PRBool aNotify)
 {
--- a/content/html/content/src/nsHTMLScriptElement.cpp
+++ b/content/html/content/src/nsHTMLScriptElement.cpp
@@ -31,16 +31,17 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 #include "nsIDOMHTMLScriptElement.h"
+#include "nsIDOMNSHTMLScriptElement.h"
 #include "nsIDOMEventTarget.h"
 #include "nsGenericHTMLElement.h"
 #include "nsGkAtoms.h"
 #include "nsStyleConsts.h"
 #include "nsIDocument.h"
 #include "nsScriptElement.h"
 #include "nsIURI.h"
 #include "nsNetUtil.h"
@@ -299,16 +300,17 @@ nsHTMLScriptEventHandler::Invoke(nsISupp
   nsCOMPtr<nsIVariant> ret;
   return scriptContext->CallEventHandler(aTargetObject, scope, funcObject,
                                          argarray, getter_AddRefs(ret));
 }
 
 
 class nsHTMLScriptElement : public nsGenericHTMLElement,
                             public nsIDOMHTMLScriptElement,
+                            public nsIDOMNSHTMLScriptElement,
                             public nsScriptElement
 {
 public:
   nsHTMLScriptElement(nsINodeInfo *aNodeInfo, PRBool aFromParser);
   virtual ~nsHTMLScriptElement();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
@@ -317,25 +319,26 @@ public:
   NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
 
   // nsIDOMElement
   NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
   // nsIDOMHTMLElement
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
-  // nsIDOMHTMLScriptElement
   NS_DECL_NSIDOMHTMLSCRIPTELEMENT
+  NS_DECL_NSIDOMNSHTMLSCRIPTELEMENT
 
   // nsIScriptElement
   virtual void GetScriptType(nsAString& type);
   virtual already_AddRefed<nsIURI> GetScriptURI();
   virtual void GetScriptText(nsAString& text);
   virtual void GetScriptCharset(nsAString& charset);
   virtual PRBool GetScriptDeferred();
+  virtual PRBool GetScriptAsync();
 
   // nsIContent
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               PRBool aCompileEventHandlers);
 
   virtual nsresult GetInnerHTML(nsAString& aInnerHTML);
   virtual nsresult SetInnerHTML(const nsAString& aInnerHTML);
@@ -373,20 +376,21 @@ nsHTMLScriptElement::~nsHTMLScriptElemen
 }
 
 
 NS_IMPL_ADDREF_INHERITED(nsHTMLScriptElement, nsGenericElement)
 NS_IMPL_RELEASE_INHERITED(nsHTMLScriptElement, nsGenericElement)
 
 // QueryInterface implementation for nsHTMLScriptElement
 NS_INTERFACE_TABLE_HEAD(nsHTMLScriptElement)
-  NS_HTML_CONTENT_INTERFACE_TABLE4(nsHTMLScriptElement,
+  NS_HTML_CONTENT_INTERFACE_TABLE5(nsHTMLScriptElement,
                                    nsIDOMHTMLScriptElement,
                                    nsIScriptLoaderObserver,
                                    nsIScriptElement,
+                                   nsIDOMNSHTMLScriptElement,
                                    nsIMutationObserver)
   NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLScriptElement,
                                                nsGenericHTMLElement)
   if (mScriptEventHandler && aIID.Equals(NS_GET_IID(nsIScriptEventHandler)))
     foundInterface = static_cast<nsIScriptEventHandler*>
                                 (mScriptEventHandler);
   else
   NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(HTMLScriptElement)
@@ -445,16 +449,17 @@ NS_IMETHODIMP
 nsHTMLScriptElement::SetText(const nsAString& aValue)
 {
   return nsContentUtils::SetNodeTextContent(this, aValue, PR_TRUE);
 }
 
 
 NS_IMPL_STRING_ATTR(nsHTMLScriptElement, Charset, charset)
 NS_IMPL_BOOL_ATTR(nsHTMLScriptElement, Defer, defer)
+NS_IMPL_BOOL_ATTR(nsHTMLScriptElement, Async, async)
 NS_IMPL_URI_ATTR(nsHTMLScriptElement, Src, src)
 NS_IMPL_STRING_ATTR(nsHTMLScriptElement, Type, type)
 NS_IMPL_STRING_ATTR(nsHTMLScriptElement, HtmlFor, _for)
 NS_IMPL_STRING_ATTR(nsHTMLScriptElement, Event, event)
 
 nsresult
 nsHTMLScriptElement::GetInnerHTML(nsAString& aInnerHTML)
 {
@@ -514,21 +519,32 @@ void
 nsHTMLScriptElement::GetScriptCharset(nsAString& charset)
 {
   GetCharset(charset);
 }
 
 PRBool
 nsHTMLScriptElement::GetScriptDeferred()
 {
-  PRBool defer;
+  PRBool defer, async;
+  GetAsync(&async);
   GetDefer(&defer);
   nsCOMPtr<nsIURI> uri = GetScriptURI();
 
-  return defer && uri;
+  return !async && defer && uri;
+}
+
+PRBool
+nsHTMLScriptElement::GetScriptAsync()
+{
+  PRBool async;
+  GetAsync(&async);
+  nsCOMPtr<nsIURI> uri = GetScriptURI();
+
+  return async && uri;
 }
 
 PRBool
 nsHTMLScriptElement::HasScriptContent()
 {
   return HasAttr(kNameSpaceID_None, nsGkAtoms::src) ||
          nsContentUtils::HasNonEmptyTextContent(this);
 }
--- a/content/media/test/Makefile.in
+++ b/content/media/test/Makefile.in
@@ -150,17 +150,17 @@ endif
 		bug523816.ogv \
 		chain.ogv \
 		dirac.ogg \
 		seek.ogv \
 		short-video.ogv \
 		small-shot.ogg \
 		sound.ogg \
 		$(NULL)
-		
+
 # Wave sample files
 _TEST_FILES += \
 		big.wav \
 		bogus.wav \
 		r11025_msadpcm_c1.wav \
 		r11025_s16_c1.wav \
 		r11025_s16_c1_trailing.wav \
 		r11025_u8_c1.wav \
@@ -173,17 +173,16 @@ endif
 		bogus.duh \
 		$(NULL)
 
 # These tests need to be converted to be backend-independent. This list
 # is deprecated, do not add to it.
 ifdef MOZ_OGG
 _TEST_FILES += \
 		dynamic_redirect.sjs \
-		test_access_control.html \
 		file_access_controls.html \
 		test_bug448534.html \
 		test_bug468190.html \
 		test_bug486646.html \
 		test_bug493187.html \
 		test_bug495145.html \
 		test_bug495319.html \
 		test_closing_connections.html \
@@ -220,19 +219,20 @@ ifdef MOZ_OGG
 		$(NULL)
 # These tests disabled until we figure out random failures.
 # Bug 492821:
 # test_videoDocumentTitle.html
 # Bug 493692:
 # test_autobuffer2.html
 ifneq ($(OS_ARCH),WINNT)
 # These tests are disabled on windows until we
-# figure out the random failures. See bug 475369.
+# figure out the random failures. See bug 475369 and bug 526323
 _TEST_FILES += \
 		test_timeupdate3.html \
+		test_access_control.html \
 		$(NULL)
 endif
 endif
 
 ifdef MOZ_OGG
 _TEST_FILES += \
 		test_can_play_type_ogg.html \
 		$(NULL)
--- a/content/svg/content/src/nsSVGFilters.cpp
+++ b/content/svg/content/src/nsSVGFilters.cpp
@@ -4079,17 +4079,17 @@ ConvolvePixel(const PRUint8 *aSourceData
             aSourceData[sampleY * aStride + 4 * sampleX + offsets[i]] *
             aKernel[aOrderX * y + x];
         }
       }
     }
   }
   for (PRInt32 i = 0; i < channels; i++) {
     aTargetData[aY * aStride + 4 * aX + offsets[i]] =
-      BoundInterval(static_cast<PRInt32>(sum[i] / aDivisor + aBias * 255), 256);
+      BoundInterval(static_cast<PRInt32>(sum[i] / aDivisor + aBias), 256);
   }
   if (aPreserveAlpha) {
     aTargetData[aY * aStride + 4 * aX + GFX_ARGB32_OFFSET_A] =
       aSourceData[aY * aStride + 4 * aX + GFX_ARGB32_OFFSET_A];
   }
 }
 
 nsresult
--- a/content/svg/content/src/nsSVGScriptElement.cpp
+++ b/content/svg/content/src/nsSVGScriptElement.cpp
@@ -75,16 +75,17 @@ public:
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGScriptElementBase::)
 
   // nsIScriptElement
   virtual void GetScriptType(nsAString& type);
   virtual already_AddRefed<nsIURI> GetScriptURI();
   virtual void GetScriptText(nsAString& text);
   virtual void GetScriptCharset(nsAString& charset);
   virtual PRBool GetScriptDeferred();
+  virtual PRBool GetScriptAsync();
 
   // nsScriptElement
   virtual PRBool HasScriptContent();
 
   // nsSVGElement specializations:
   virtual void DidChangeString(PRUint8 aAttrEnum);
 
   // nsIContent specializations:
@@ -227,16 +228,22 @@ nsSVGScriptElement::GetScriptCharset(nsA
 }
 
 PRBool
 nsSVGScriptElement::GetScriptDeferred()
 {
   return PR_FALSE;
 }
 
+PRBool
+nsSVGScriptElement::GetScriptAsync()
+{
+  return PR_FALSE;
+}
+
 //----------------------------------------------------------------------
 // nsScriptElement methods
 
 PRBool
 nsSVGScriptElement::HasScriptContent()
 {
   nsAutoString str;
   mStringAttributes[HREF].GetAnimValue(str, this);
--- a/content/xul/document/src/nsXULDocument.cpp
+++ b/content/xul/document/src/nsXULDocument.cpp
@@ -2887,17 +2887,18 @@ nsXULDocument::ResumeWalk()
     // is, a parent is built before any of its children; a node is
     // only built after all of its siblings to the left are fully
     // constructed.
     //
     // It is interruptable so that transcluded documents (e.g.,
     // <html:script src="..." />) can be properly re-loaded if the
     // cached copy of the document becomes stale.
     nsresult rv;
-    nsCOMPtr<nsIURI> overlayURI = mCurrentPrototype->GetURI();
+    nsCOMPtr<nsIURI> overlayURI =
+        mCurrentPrototype ? mCurrentPrototype->GetURI() : nsnull;
 
     while (1) {
         // Begin (or resume) walking the current prototype.
 
         while (mContextStack.Depth() > 0) {
             // Look at the top of the stack to determine what we're
             // currently working on.
             // This will always be a node already constructed and
--- a/content/xul/document/test/Makefile.in
+++ b/content/xul/document/test/Makefile.in
@@ -51,10 +51,18 @@ include $(topsrcdir)/config/rules.mk
 		test_bug403868.xul \
 		test_bug414907.xul \
 		test_bug418216.xul \
 		test_bug445177.xul \
 		test_bug449457.xul \
 		test_bug468176.xul \
 		$(NULL)
 
+_CHROME_FILES = \
+		test_bug497875.xul \
+		     bug497875-iframe.xul \
+		$(NULL)
+
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
+
+libs:: $(_CHROME_FILES)
+	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/chrome/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/content/xul/document/test/bug497875-iframe.xul
@@ -0,0 +1,6 @@
+<?xml-stylesheet href="chrome://browser/skin/" type="text/css"?>
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns:html="http://www.w3.org/1999/xhtml">
+<box onerror="document.loadOverlay('file:///does-not-exist', null);" >
+<html:script src="ftp://mozilla.org"/>
+</box>
+</window>
new file mode 100644
--- /dev/null
+++ b/content/xul/document/test/test_bug497875.xul
@@ -0,0 +1,56 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
+                 type="text/css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=497875
+-->
+<window title="Mozilla Bug 497875"
+  xmlns:html="http://www.w3.org/1999/xhtml"
+  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+  <title>Test for Bug 497875</title>
+  <script type="application/javascript" 
+   src="chrome://mochikit/content/MochiKit/packed.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
+
+<body  xmlns="http://www.w3.org/1999/xhtml">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=497875">Mozilla Bug 497875</a>
+<p id="display"><iframe id="iframe" src="bug497875-iframe.xul"></iframe></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+</pre>
+</body>
+
+<script class="testbody" type="application/javascript">
+<![CDATA[
+
+/** Test for Bug 497875 **/
+
+SimpleTest.waitForExplicitFinish();
+
+function done_test() {
+  var f = document.getElementById('iframe')
+  f.src="about:blank"
+  f.parentNode.removeChild(f)
+  ok(true, "this is a crashtest");
+  SimpleTest.finish();
+}
+
+function do_test() {
+  setTimeout(function () {document.getElementById('iframe').contentWindow.location.reload()}, 500);
+  setTimeout(function () {document.getElementById('iframe').contentWindow.location.reload()}, 1000);
+  setTimeout(function () {document.getElementById('iframe').contentWindow.location.reload()}, 1500);
+  setTimeout(done_test, 2000);
+}
+
+do_test();
+
+
+]]>
+</script>
+
+</window>
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -288,16 +288,17 @@
 #include "nsIDOMHTMLOListElement.h"
 #include "nsIDOMHTMLObjectElement.h"
 #include "nsIDOMHTMLOptGroupElement.h"
 #include "nsIDOMHTMLParagraphElement.h"
 #include "nsIDOMHTMLParamElement.h"
 #include "nsIDOMHTMLPreElement.h"
 #include "nsIDOMHTMLQuoteElement.h"
 #include "nsIDOMHTMLScriptElement.h"
+#include "nsIDOMNSHTMLScriptElement.h"
 #include "nsIDOMNSHTMLSelectElement.h"
 #include "nsIDOMHTMLStyleElement.h"
 #include "nsIDOMHTMLTableCaptionElem.h"
 #include "nsIDOMHTMLTableCellElement.h"
 #include "nsIDOMHTMLTableColElement.h"
 #include "nsIDOMHTMLTableElement.h"
 #include "nsIDOMHTMLTableRowElement.h"
 #include "nsIDOMHTMLTableSectionElem.h"
@@ -450,17 +451,17 @@
 #include "nsIDOMGeoPosition.h"
 #include "nsIDOMGeoPositionCoords.h"
 #include "nsIDOMGeoPositionError.h"
 
 // Workers
 #include "nsDOMWorker.h"
 
 #include "nsDOMFile.h"
-#include "nsDOMFileRequest.h"
+#include "nsDOMFileReader.h"
 #include "nsIDOMFileException.h"
 #include "nsIDOMFileError.h"
 
 // Simple gestures include
 #include "nsIDOMSimpleGestureEvent.h"
 
 #include "nsIDOMNSMouseEvent.h"
 
@@ -1249,17 +1250,17 @@ static nsDOMClassInfoData sClassInfoData
   NS_DEFINE_CLASSINFO_DATA(FileList, nsFileListSH,
                            ARRAY_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(File, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(FileException, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(FileError, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(FileRequest, nsEventTargetSH,
+  NS_DEFINE_CLASSINFO_DATA(FileReader, nsEventTargetSH,
                            EVENTTARGET_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(ModalContentWindow, nsWindowSH,
                            DEFAULT_SCRIPTABLE_FLAGS |
                            WINDOW_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(DataContainerEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
@@ -1371,17 +1372,17 @@ struct nsContractIDMapData
 };
 
 #define NS_DEFINE_CONSTRUCTOR_DATA(_class, _contract_id)                      \
   { eDOMClassInfo_##_class##_id, _contract_id },
 
 static const nsContractIDMapData kConstructorMap[] =
 {
   NS_DEFINE_CONSTRUCTOR_DATA(DOMParser, NS_DOMPARSER_CONTRACTID)
-  NS_DEFINE_CONSTRUCTOR_DATA(FileRequest, NS_FILEREQUEST_CONTRACTID)
+  NS_DEFINE_CONSTRUCTOR_DATA(FileReader, NS_FILEREADER_CONTRACTID)
   NS_DEFINE_CONSTRUCTOR_DATA(XMLSerializer, NS_XMLSERIALIZER_CONTRACTID)
   NS_DEFINE_CONSTRUCTOR_DATA(XMLHttpRequest, NS_XMLHTTPREQUEST_CONTRACTID)
   NS_DEFINE_CONSTRUCTOR_DATA(XPathEvaluator, NS_XPATH_EVALUATOR_CONTRACTID)
   NS_DEFINE_CONSTRUCTOR_DATA(XSLTProcessor,
                              "@mozilla.org/document-transformer;1?type=xslt")
 };
 
 struct nsConstructorFuncMapData
@@ -2507,16 +2508,17 @@ nsDOMClassInfo::Init()
 
   DOM_CLASSINFO_MAP_BEGIN(HTMLQuoteElement, nsIDOMHTMLQuoteElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLQuoteElement)
     DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(HTMLScriptElement, nsIDOMHTMLScriptElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLScriptElement)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSHTMLScriptElement)
     DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(HTMLSelectElement, nsIDOMHTMLSelectElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLSelectElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSHTMLSelectElement)
     DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
@@ -3577,18 +3579,18 @@ nsDOMClassInfo::Init()
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMFile)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(FileException, nsIDOMFileException)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMFileException)
     DOM_CLASSINFO_MAP_ENTRY(nsIException)
   DOM_CLASSINFO_MAP_END
 
-  DOM_CLASSINFO_MAP_BEGIN(FileRequest, nsIDOMFileRequest)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMFileRequest)
+  DOM_CLASSINFO_MAP_BEGIN(FileReader, nsIDOMFileReader)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMFileReader)
     DOM_CLASSINFO_MAP_ENTRY(nsIXMLHttpRequestEventTarget)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
     DOM_CLASSINFO_MAP_ENTRY(nsIInterfaceRequestor)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(ModalContentWindow, nsIDOMWindow)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMWindow)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMJSWindow)
--- a/dom/base/nsDOMClassInfoID.h
+++ b/dom/base/nsDOMClassInfoID.h
@@ -411,17 +411,17 @@ enum nsDOMClassInfoID {
   eDOMClassInfo_CommandEvent_id,
   eDOMClassInfo_OfflineResourceList_id,
   eDOMClassInfo_LoadStatus_id,
 
   eDOMClassInfo_FileList_id,
   eDOMClassInfo_File_id,
   eDOMClassInfo_FileException_id,
   eDOMClassInfo_FileError_id,
-  eDOMClassInfo_FileRequest_id,
+  eDOMClassInfo_FileReader_id,
 
   // DOM modal content window class, almost identical to Window
   eDOMClassInfo_ModalContentWindow_id,
 
   // Data Events
   eDOMClassInfo_DataContainerEvent_id,
 
   // event used for cross-domain message-passing and for server-sent events in
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -235,16 +235,20 @@ static PRBool               gDOMWindowDu
 
 #if defined(DEBUG_bryner) || defined(DEBUG_chb)
 #define DEBUG_PAGE_CACHE
 #endif
 
 // The shortest interval/timeout we permit
 #define DOM_MIN_TIMEOUT_VALUE 10 // 10ms
 
+// The number of nested timeouts before we start clamping. HTML5 says 1, WebKit
+// uses 5.
+#define DOM_CLAMP_TIMEOUT_NESTING_LEVEL 5
+
 // The longest interval (as PRIntervalTime) we permit, or that our
 // timer code can handle, really. See DELAY_INTERVAL_LIMIT in
 // nsTimerImpl.h for details.
 #define DOM_MAX_TIMEOUT_VALUE    PR_BIT(8 * sizeof(PRIntervalTime) - 1)
 
 #define FORWARD_TO_OUTER(method, args, err_rval)                              \
   PR_BEGIN_MACRO                                                              \
   if (IsInnerWindow()) {                                                      \
@@ -548,16 +552,22 @@ nsDummyJavaPluginOwner::ForceRedraw()
 }
 
 NS_IMETHODIMP
 nsDummyJavaPluginOwner::GetNetscapeWindow(void *value)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
+NS_IMETHODIMP
+nsDummyJavaPluginOwner::SetEventModel(PRInt32 eventModel)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
 /**
  * An indirect observer object that means we don't have to implement nsIObserver
  * on nsGlobalWindow, where any script could see it.
  */
 class nsGlobalWindowObserver : public nsIObserver {
 public:
   nsGlobalWindowObserver(nsGlobalWindow* aWindow) : mWindow(aWindow) {}
   NS_DECL_ISUPPORTS
@@ -7654,31 +7664,35 @@ nsGlobalWindow::ClearWindowScope(nsISupp
     }
   }
 }
 
 //*****************************************************************************
 // nsGlobalWindow: Timeout Functions
 //*****************************************************************************
 
+PRUint32 sNestingLevel;
+
 nsresult
 nsGlobalWindow::SetTimeoutOrInterval(nsIScriptTimeoutHandler *aHandler,
                                      PRInt32 interval,
                                      PRBool aIsInterval, PRInt32 *aReturn)
 {
   FORWARD_TO_INNER(SetTimeoutOrInterval, (aHandler, interval, aIsInterval, aReturn),
                    NS_ERROR_NOT_INITIALIZED);
 
   // If we don't have a document (we could have been unloaded since
   // the call to setTimeout was made), do nothing.
   if (!mDocument) {
     return NS_OK;
   }
 
-  if (interval < DOM_MIN_TIMEOUT_VALUE) {
+  PRUint32 nestingLevel = sNestingLevel + 1;
+  if (interval < DOM_MIN_TIMEOUT_VALUE &&
+      (aIsInterval || nestingLevel >= DOM_CLAMP_TIMEOUT_NESTING_LEVEL)) {
     // Don't allow timeouts less than DOM_MIN_TIMEOUT_VALUE from
     // now...
 
     interval = DOM_MIN_TIMEOUT_VALUE;
   }
 
   NS_ASSERTION(interval >= 0, "DOM_MIN_TIMEOUT_VALUE lies");
   PRUint32 realInterval = interval;
@@ -7770,16 +7784,20 @@ nsGlobalWindow::SetTimeoutOrInterval(nsI
     // don't create a timer for it, since that will happen when we are thawed
     // and the timeout will then get a timer and run to completion.
 
     timeout->mWhen = delta;
   }
 
   timeout->mWindow = this;
 
+  if (!aIsInterval) {
+    timeout->mNestingLevel = nestingLevel;
+  }
+
   // No popups from timeouts by default
   timeout->mPopupState = openAbused;
 
   if (gRunningTimeoutDepth == 0 && gPopupControlState < openAbused) {
     // This timeout is *not* set from another timeout and it's set
     // while popups are enabled. Propagate the state to the timeout if
     // its delay (interval) is equal to or less than what
     // "dom.disable_open_click_delay" is set to (in ms).
@@ -7987,16 +8005,23 @@ nsGlobalWindow::RunTimeout(nsTimeout *aT
 
     // Hold on to the timeout in case mExpr or mFunObj releases its
     // doc.
     timeout->AddRef();
 
     ++gRunningTimeoutDepth;
     ++mTimeoutFiringDepth;
 
+    PRBool trackNestingLevel = !timeout->mInterval;
+    PRUint32 nestingLevel;
+    if (trackNestingLevel) {
+      nestingLevel = sNestingLevel;
+      sNestingLevel = timeout->mNestingLevel;
+    }
+
     nsCOMPtr<nsIScriptTimeoutHandler> handler(timeout->mScriptHandler);
     void *scriptObject = handler->GetScriptObject();
     if (!scriptObject) {
       // Evaluate the timeout expression.
       const PRUnichar *script = handler->GetHandlerText();
       NS_ASSERTION(script, "timeout has no script nor handler text!");
 
       const char *filename = nsnull;
@@ -8027,16 +8052,20 @@ nsGlobalWindow::RunTimeout(nsTimeout *aT
                             scriptObject, handler->GetArgv(),
                             // XXXmarkh - consider allowing CallEventHandler to
                             // accept nsnull?
                             getter_AddRefs(dummy));
 
     }
     handler = nsnull; // drop reference before dropping timeout refs.
 
+    if (trackNestingLevel) {
+      sNestingLevel = nestingLevel;
+    }
+
     --mTimeoutFiringDepth;
     --gRunningTimeoutDepth;
 
     mRunningTimeout = last_running_timeout;
     timeout->mRunning = PR_FALSE;
 
     // We ignore any failures from calling EvaluateString() or
     // CallEventHandler() on the context here since we're in a loop
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -180,16 +180,19 @@ struct nsTimeout : PRCList
   PRTime mWhen;
 
   // Principal with which to execute
   nsCOMPtr<nsIPrincipal> mPrincipal;
 
   // stack depth at which timeout is firing
   PRUint32 mFiringDepth;
 
+  // 
+  PRUint32 mNestingLevel;
+
   // The popup state at timeout creation time if not created from
   // another timeout
   PopupControlState mPopupState;
 
   // The language-specific information about the callback.
   nsCOMPtr<nsIScriptTimeoutHandler> mScriptHandler;
 
 private:
--- a/dom/interfaces/events/nsIDOMDataTransfer.idl
+++ b/dom/interfaces/events/nsIDOMDataTransfer.idl
@@ -157,17 +157,17 @@ interface nsIDOMDataTransfer : nsISuppor
    * default target is the node that was dragged.
    *
    * @param element drag source to use
    * @throws NO_MODIFICATION_ALLOWED_ERR if the item cannot be modified
    */
   void addElement(in nsIDOMElement element);
 };
 
-[scriptable, uuid(53C854FC-33F9-4647-B045-46D7AB06A6F1)]
+[scriptable, uuid(990758e9-fd38-4444-a1e8-395195802bda)]
 interface nsIDOMNSDataTransfer : nsISupports
 {
   /*
    * Integer version of dropEffect, set to one of the constants in nsIDragService.
    */
   [noscript] attribute unsigned long dropEffectInt;
 
   /*
--- a/dom/interfaces/events/nsIDOMNotifyPaintEvent.idl
+++ b/dom/interfaces/events/nsIDOMNotifyPaintEvent.idl
@@ -40,17 +40,17 @@
 
 interface nsIDOMPaintRequestList;
 
 /**
  * The nsIDOMNotifyPaintEvent interface is used for the MozDOMAfterPaint
  * event, which fires at a window when painting has happened in
  * that window.
  */
-[scriptable, uuid(dec5582e-5cea-412f-bf98-6b27480fb46a)]
+[scriptable, uuid(792e5779-7c39-4817-91a7-fdb3fba6428f)]
 interface nsIDOMNotifyPaintEvent : nsIDOMEvent
 {
   /**
    * Get a list of rectangles which are affected. The rectangles are in CSS pixels
    * relative to the viewport origin.
    * If the caller is not trusted (e.g., regular Web content) then only painting
    * caused by the current document is reported; in particular, painting in subdocuments
    * is not reported.
--- a/dom/interfaces/html/Makefile.in
+++ b/dom/interfaces/html/Makefile.in
@@ -128,11 +128,12 @@ XPIDLSRCS = 					\
 	nsIDOMNSHTMLFrameElement.idl		\
 	nsIDOMNSHTMLHRElement.idl		\
 	nsIDOMNSHTMLImageElement.idl		\
 	nsIDOMNSHTMLInputElement.idl		\
 	nsIDOMNSHTMLOptionCollectn.idl		\
 	nsIDOMNSHTMLOptionElement.idl		\
 	nsIDOMNSHTMLSelectElement.idl		\
 	nsIDOMNSHTMLTextAreaElement.idl		\
+	nsIDOMNSHTMLScriptElement.idl		\
 	$(NULL)
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/dom/interfaces/html/nsIDOMNSHTMLScriptElement.idl
@@ -0,0 +1,44 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "domstubs.idl"
+
+[scriptable, uuid(5b2065d7-7888-4529-8a29-e58390a40bd2)]
+interface nsIDOMNSHTMLScriptElement : nsISupports
+{
+	attribute boolean async;
+};
--- a/dom/src/geolocation/NetworkGeolocationProvider.js
+++ b/dom/src/geolocation/NetworkGeolocationProvider.js
@@ -144,56 +144,40 @@ function WifiGeoPositionProvider() {
 };
 
 WifiGeoPositionProvider.prototype = {
     classDescription: "A component that returns a geolocation based on WIFI",
     classID:          Components.ID("{77DA64D3-7458-4920-9491-86CC9914F904}"),
     contractID:       "@mozilla.org/geolocation/provider;1",
     QueryInterface:   XPCOMUtils.generateQI([Ci.nsIGeolocationProvider,
                                              Ci.nsIWifiListener,
-                                             Ci.nsITimerCallback,
-                                             Ci.nsISupportsWeakReference]),
+                                             Ci.nsITimerCallback]),
 
     prefService:     null,
 
     provider_url:    null,
     wifi_service:    null,
     timer:           null,
     hasSeenWiFi:     false,
 
-    observe: function (aSubject, aTopic, aData) {
-        if (aTopic == "private-browsing") {
-            if (aData == "enter" || aData == "exit") {
-                try {
-                    let branch = this.prefService.getBranch("geo.wifi.access_token.");
-                    branch.deleteBranch("");
-                } catch (e) {}
-            }
-        }
-    },
-
     startup:         function() {
         LOG("startup called");
 
         this.provider_url = this.prefService.getCharPref("geo.wifi.uri");
         LOG("provider url = " + this.provider_url);
 
         // if we don't see anything in 5 seconds, kick of one IP geo lookup.
         // if we are testing, just hammer this callback so that we are more or less
         // always sending data.  It doesn't matter if we have an access point or not.
         this.hasSeenWiFi = false;
         this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
         if (gTestingEnabled == false)
             this.timer.initWithCallback(this, 5000, this.timer.TYPE_ONE_SHOT);
         else
             this.timer.initWithCallback(this, 200, this.timer.TYPE_REPEATING_SLACK);
-
-
-        let os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
-        os.addObserver(this, "private-browsing", true);
     },
 
     watch: function(c) {
         LOG("watch called");
         if (!this.wifi_service) {
             this.wifi_service = Cc["@mozilla.org/wifi/monitor;1"].getService(Components.interfaces.nsIWifiMonitor);
             this.wifi_service.startWatching(this);
         }
--- a/dom/src/threads/nsDOMThreadService.cpp
+++ b/dom/src/threads/nsDOMThreadService.cpp
@@ -367,17 +367,20 @@ public:
     NS_ASSERTION(!NS_IsMainThread(),
                  "This should *never* run on the main thread!");
 
     // This must have been set up by the thread service
     NS_ASSERTION(gJSContextIndex != BAD_TLS_INDEX, "No context index!");
 
     // Make sure we have a JSContext to run everything on.
     JSContext* cx = (JSContext*)PR_GetThreadPrivate(gJSContextIndex);
-    NS_ASSERTION(cx, "nsDOMThreadService didn't give us a context!");
+    if (!cx) {
+        NS_ERROR("nsDOMThreadService didn't give us a context! Are we out of memory?");
+        return NS_ERROR_FAILURE;
+    }
 
     NS_ASSERTION(!JS_GetGlobalObject(cx), "Shouldn't have a global!");
 
     JS_SetContextPrivate(cx, mWorker);
 
     PRBool killWorkerWhenDone;
 
     // Tell the worker which context it will be using
--- a/editor/libeditor/text/nsTextEditRules.cpp
+++ b/editor/libeditor/text/nsTextEditRules.cpp
@@ -105,16 +105,19 @@ nsTextEditRules::nsTextEditRules()
 , mDidExplicitlySetInterline(PR_FALSE)
 , mTheAction(0)
 {
 }
 
 nsTextEditRules::~nsTextEditRules()
 {
    // do NOT delete mEditor here.  We do not hold a ref count to mEditor.  mEditor owns our lifespan.
+
+  if (mTimer)
+    mTimer->Cancel();
 }
 
 /********************************************************
  *  XPCOM Cruft
  ********************************************************/
 
 NS_IMPL_CYCLE_COLLECTION_2(nsTextEditRules, mBogusNode, mCachedSelectionNode)
 
@@ -189,16 +192,19 @@ nsTextEditRules::Init(nsPlaintextEditor 
   mDeleteBidiImmediately = deleteBidiImmediately;
 
   return res;
 }
 
 NS_IMETHODIMP
 nsTextEditRules::DetachEditor()
 {
+  if (mTimer)
+    mTimer->Cancel();
+
   mEditor = nsnull;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsTextEditRules::GetFlags(PRUint32 *aFlags)
 {
   if (!aFlags) { return NS_ERROR_NULL_POINTER; }
--- a/extensions/pref/system-pref/src/gconf/nsSystemPrefService.cpp
+++ b/extensions/pref/system-pref/src/gconf/nsSystemPrefService.cpp
@@ -360,17 +360,17 @@ NS_IMETHODIMP nsSystemPrefService::Unloc
 }
 
 /* void deleteBranch (in string aStartingAt); */
 NS_IMETHODIMP nsSystemPrefService::DeleteBranch(const char *aStartingAt)
 {
     return NS_ERROR_NOT_IMPLEMENTED;
 }
 
-/* void getChildList (in string aStartingAt, out unsigned long aCount, [array, size_is (aCount), retval] out string aChildArray); */
+/* void getChildList (in string aStartingAt, [optional] out unsigned long aCount, [array, size_is (aCount), retval] out string aChildArray); */
 NS_IMETHODIMP nsSystemPrefService::GetChildList(const char *aStartingAt, PRUint32 *aCount, char ***aChildArray)
 {
     return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 /* void resetBranch (in string aStartingAt); */
 NS_IMETHODIMP nsSystemPrefService::ResetBranch(const char *aStartingAt)
 {
--- a/gfx/public/nsRegion.h
+++ b/gfx/public/nsRegion.h
@@ -34,23 +34,26 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 
 #ifndef nsRegion_h__
 #define nsRegion_h__
 
 
-// Implementation of region.
-// Region is represented as circular double-linked list of nsRegion::RgnRect structures.
-// Rectangles in this list do not overlap and are sorted by (y, x) coordinates.
-
 #include "nsRect.h"
 #include "nsPoint.h"
 
+/**
+ * Implementation of regions.
+ * A region is represented as circular double-linked list of nsRegion::RgnRect structures.
+ * Rectangles in this list do not overlap and are sorted by (y, x) coordinates.
+ *
+ * nsRegions use nscoord coordinates and nsRects.
+ */
 class NS_GFX nsRegion
 {
   friend class nsRegionRectIterator;
   friend class RgnRectMemoryAllocator;
 
 
 // Special version of nsRect structure for speed optimizations in nsRegion code.
 // Most important functions could be made inline and be sure that passed rectangles
@@ -271,10 +274,225 @@ public:
   }
 
   void Reset ()
   {
     mCurPtr = &mRegion->mRectListHead;
   }
 };
 
+/**
+ * nsIntRegions use PRInt32 coordinates and nsIntRects.
+ */
+class NS_GFX nsIntRegion
+{
+  friend class nsIntRegionRectIterator;
+
+public:
+  nsIntRegion () {}
+  nsIntRegion (const nsIntRect& aRect) : mImpl (ToRect(aRect)) {}
+  nsIntRegion (const nsIntRegion& aRegion) : mImpl (aRegion.mImpl) {}
+  nsIntRegion& operator = (const nsIntRect& aRect) { mImpl = ToRect (aRect); return *this; }
+  nsIntRegion& operator = (const nsIntRegion& aRegion) { mImpl = aRegion.mImpl; return *this; }
+
+  nsIntRegion& And  (const nsIntRegion& aRgn1,   const nsIntRegion& aRgn2)
+  {
+    mImpl.And (aRgn1.mImpl, aRgn2.mImpl);
+    return *this;
+  }
+  nsIntRegion& And  (const nsIntRegion& aRegion, const nsIntRect& aRect)
+  {
+    mImpl.And (aRegion.mImpl, ToRect (aRect));
+    return *this;
+  }
+  nsIntRegion& And  (const nsIntRect& aRect, const nsIntRegion& aRegion)
+  {
+    return  And  (aRegion, aRect);
+  }
+  nsIntRegion& And  (const nsIntRect& aRect1, const nsIntRect& aRect2)
+  {
+    nsIntRect TmpRect;
+
+    TmpRect.IntersectRect (aRect1, aRect2);
+    mImpl = ToRect (TmpRect);
+    return *this;
+  }
+
+  nsIntRegion& Or   (const nsIntRegion& aRgn1,   const nsIntRegion& aRgn2)
+  {
+    mImpl.Or (aRgn1.mImpl, aRgn2.mImpl);
+    return *this;
+  }
+  nsIntRegion& Or   (const nsIntRegion& aRegion, const nsIntRect& aRect)
+  {
+    mImpl.Or (aRegion.mImpl, ToRect (aRect));
+    return *this;
+  }
+  nsIntRegion& Or   (const nsIntRect& aRect, const nsIntRegion& aRegion)
+  {
+    return  Or   (aRegion, aRect);
+  }
+  nsIntRegion& Or   (const nsIntRect& aRect1, const nsIntRect& aRect2)
+  {
+    mImpl = ToRect (aRect1);
+    return Or (*this, aRect2);
+  }
+
+  nsIntRegion& Xor  (const nsIntRegion& aRgn1,   const nsIntRegion& aRgn2)
+  {
+    mImpl.Xor (aRgn1.mImpl, aRgn2.mImpl);
+    return *this;
+  }
+  nsIntRegion& Xor  (const nsIntRegion& aRegion, const nsIntRect& aRect)
+  {
+    mImpl.Xor (aRegion.mImpl, ToRect (aRect));
+    return *this;
+  }
+  nsIntRegion& Xor  (const nsIntRect& aRect, const nsIntRegion& aRegion)
+  {
+    return  Xor  (aRegion, aRect);
+  }
+  nsIntRegion& Xor  (const nsIntRect& aRect1, const nsIntRect& aRect2)
+  {
+    mImpl = ToRect (aRect1);
+    return Xor (*this, aRect2);
+  }
+
+  nsIntRegion& Sub  (const nsIntRegion& aRgn1,   const nsIntRegion& aRgn2)
+  {
+    mImpl.Sub (aRgn1.mImpl, aRgn2.mImpl);
+    return *this;
+  }
+  nsIntRegion& Sub  (const nsIntRegion& aRegion, const nsIntRect& aRect)
+  {
+    mImpl.Sub (aRegion.mImpl, ToRect (aRect));
+    return *this;
+  }
+  nsIntRegion& Sub  (const nsIntRect& aRect, const nsIntRegion& aRegion)
+  {
+    return Sub (nsIntRegion (aRect), aRegion);
+  }
+  nsIntRegion& Sub  (const nsIntRect& aRect1, const nsIntRect& aRect2)
+  {
+    mImpl = ToRect (aRect1);
+    return Sub (*this, aRect2);
+  }
+
+  PRBool Contains (const nsIntRect& aRect) const
+  {
+    return mImpl.Contains (ToRect (aRect));
+  }
+  PRBool Intersects (const nsIntRect& aRect) const
+  {
+    return mImpl.Intersects (ToRect (aRect));
+  }
+
+  void MoveBy (PRInt32 aXOffset, PRInt32 aYOffset)
+  {
+    MoveBy (nsIntPoint (aXOffset, aYOffset));
+  }
+  void MoveBy (nsIntPoint aPt)
+  {
+    mImpl.MoveBy (aPt.x, aPt.y);
+  }
+  void SetEmpty ()
+  {
+    mImpl.SetEmpty  ();
+  }
+
+  PRBool IsEmpty () const { return mImpl.IsEmpty (); }
+  PRBool IsComplex () const { return mImpl.IsComplex (); }
+  PRBool IsEqual (const nsIntRegion& aRegion) const
+  {
+    return mImpl.IsEqual (aRegion.mImpl);
+  }
+  PRUint32 GetNumRects () const { return mImpl.GetNumRects (); }
+  nsIntRect GetBounds () const { return FromRect (mImpl.GetBounds ()); }
+
+  /**
+   * Make sure the region has at most aMaxRects by adding area to it
+   * if necessary. The simplified region will be a superset of the
+   * original region. The simplified region's bounding box will be
+   * the same as for the current region.
+   */
+  void SimplifyOutward (PRUint32 aMaxRects)
+  {
+    mImpl.SimplifyOutward (aMaxRects);
+  }
+  /**
+   * Make sure the region has at most aMaxRects by removing area from
+   * it if necessary. The simplified region will be a subset of the
+   * original region.
+   */
+  void SimplifyInward (PRUint32 aMaxRects)
+  {
+    mImpl.SimplifyInward (aMaxRects);
+  }
+  /**
+   * Efficiently try to remove a rectangle from this region. The actual
+   * area removed could be some sub-area contained by the rectangle
+   * (even possibly nothing at all).
+   * 
+   * We remove all rectangles that are contained by aRect.
+   */
+  void SimpleSubtract (const nsIntRect& aRect)
+  {
+    mImpl.SimpleSubtract (ToRect (aRect));
+  }
+  /**
+   * Efficiently try to remove a region from this region. The actual
+   * area removed could be some sub-area contained by aRegion
+   * (even possibly nothing at all).
+   * 
+   * We remove all rectangles of this region that are contained by
+   * a rectangle of aRegion.
+   */
+  void SimpleSubtract (const nsIntRegion& aRegion)
+  {
+    mImpl.SimpleSubtract (aRegion.mImpl);
+  }
+
+private:
+  nsRegion mImpl;
+
+  static nsRect ToRect(const nsIntRect& aRect)
+  {
+    return nsRect (aRect.x, aRect.y, aRect.width, aRect.height);
+  }
+  static nsIntRect FromRect(const nsRect& aRect)
+  {
+    return nsIntRect (aRect.x, aRect.y, aRect.width, aRect.height);
+  }
+};
+
+class NS_GFX nsIntRegionRectIterator
+{
+  nsRegionRectIterator mImpl;
+  nsIntRect mTmp;
+
+public:
+  nsIntRegionRectIterator (const nsIntRegion& aRegion) : mImpl (aRegion.mImpl) {}
+
+  const nsIntRect* Next ()
+  {
+    const nsRect* r = mImpl.Next();
+    if (!r)
+      return nsnull;
+    mTmp = nsIntRegion::FromRect (*r);
+    return &mTmp;
+  }
+
+  const nsIntRect* Prev ()
+  {
+    const nsRect* r = mImpl.Prev();
+    if (!r)
+      return nsnull;
+    mTmp = nsIntRegion::FromRect (*r);
+    return &mTmp;
+  }
+
+  void Reset ()
+  {
+    mImpl.Reset ();
+  }
+};
 
 #endif
--- a/gfx/thebes/src/gfxCoreTextFonts.cpp
+++ b/gfx/thebes/src/gfxCoreTextFonts.cpp
@@ -98,21 +98,24 @@ dumpFontDescriptor(CTFontRef font)
 }
 #endif
 
 gfxCoreTextFont::gfxCoreTextFont(MacOSFontEntry *aFontEntry,
                                  const gfxFontStyle *aFontStyle,
                                  PRBool aNeedsBold)
     : gfxFont(aFontEntry, aFontStyle),
       mFontStyle(aFontStyle),
+      mCTFont(nsnull),
+      mAttributesDict(nsnull),
       mHasMetrics(PR_FALSE),
+      mFontFace(nsnull),
+      mScaledFont(nsnull),
       mAdjustedSize(0.0f)
 {
     mATSFont = aFontEntry->GetFontRef();
-    mCTFont = NULL;
 
     // determine whether synthetic bolding is needed
     PRInt8 baseWeight, weightDistance;
     mFontStyle->ComputeWeightAndOffset(&baseWeight, &weightDistance);
     PRUint16 targetWeight = (baseWeight * 100) + (weightDistance * 100);
 
     // synthetic bolding occurs when font itself is not a bold-face and either the absolute weight
     // is at least 600 or the relative weight (e.g. 402) implies a darker face than the ones available.
@@ -139,16 +142,28 @@ gfxCoreTextFont::gfxCoreTextFont(MacOSFo
                            &kCFTypeDictionaryKeyCallBacks,
                            &kCFTypeDictionaryValueCallBacks);
 
     // Remaining initialization is largely based on CommonInit() in the gfxAtsuiFont code
     CGFontRef cgFont = ::CGFontCreateWithPlatformFont(&mATSFont);
     mFontFace = cairo_quartz_font_face_create_for_cgfont(cgFont);
     ::CGFontRelease(cgFont);
 
+    cairo_status_t cairoerr = cairo_font_face_status(mFontFace);
+    if (cairoerr != CAIRO_STATUS_SUCCESS) {
+        mIsValid = PR_FALSE;
+#ifdef DEBUG
+        char warnBuf[1024];
+        sprintf(warnBuf, "Failed to create Cairo font face: %s status: %d",
+                NS_ConvertUTF16toUTF8(GetName()).get(), cairoerr);
+        NS_WARNING(warnBuf);
+#endif
+        return;
+    }
+
     cairo_matrix_t sizeMatrix, ctm;
     cairo_matrix_init_identity(&ctm);
     cairo_matrix_init_scale(&sizeMatrix, mAdjustedSize, mAdjustedSize);
 
     // synthetic oblique by skewing via the font matrix
     PRBool needsOblique =
         (mFontEntry != NULL) &&
         (!mFontEntry->IsItalic() && (mFontStyle->style & (FONT_STYLE_ITALIC | FONT_STYLE_OBLIQUE)));
@@ -163,33 +178,35 @@ gfxCoreTextFont::gfxCoreTextFont(MacOSFo
                           -1 * skewfactor,   //xy
                           1,                //yy
                           0,                //x0
                           0);               //y0
         cairo_matrix_multiply(&sizeMatrix, &sizeMatrix, &style);
     }
 
     cairo_font_options_t *fontOptions = cairo_font_options_create();
+    // if this fails (out of memory), the pointer is still safe to use
+    // although we're almost certainly going to fail below anyway
 
     // turn off font anti-aliasing based on user pref setting
     if (mAdjustedSize <= (float) gfxPlatformMac::GetPlatform()->GetAntiAliasingThreshold()) {
         cairo_font_options_set_antialias(fontOptions, CAIRO_ANTIALIAS_NONE);
         //printf("font: %s, size: %f, disabling anti-aliasing\n", NS_ConvertUTF16toUTF8(GetName()).get(), mAdjustedSize);
     }
 
     mScaledFont = cairo_scaled_font_create(mFontFace, &sizeMatrix, &ctm, fontOptions);
     cairo_font_options_destroy(fontOptions);
 
-    cairo_status_t cairoerr = cairo_scaled_font_status(mScaledFont);
+    cairoerr = cairo_scaled_font_status(mScaledFont);
     if (cairoerr != CAIRO_STATUS_SUCCESS) {
         mIsValid = PR_FALSE;
-
 #ifdef DEBUG
         char warnBuf[1024];
-        sprintf(warnBuf, "Failed to create scaled font: %s status: %d", NS_ConvertUTF16toUTF8(GetName()).get(), cairoerr);
+        sprintf(warnBuf, "Failed to create scaled font: %s status: %d",
+                NS_ConvertUTF16toUTF8(GetName()).get(), cairoerr);
         NS_WARNING(warnBuf);
 #endif
     }
 }
 
 static double
 RoundToNearestMultiple(double aValue, double aFraction)
 {
@@ -248,21 +265,25 @@ gfxCoreTextFont::GetCharHeight(PRUnichar
     }
 
     // couldn't get glyph for the char
     return 0;
 }
 
 gfxCoreTextFont::~gfxCoreTextFont()
 {
-    cairo_scaled_font_destroy(mScaledFont);
-    cairo_font_face_destroy(mFontFace);
+    if (mScaledFont)
+        cairo_scaled_font_destroy(mScaledFont);
+    if (mFontFace)
+        cairo_font_face_destroy(mFontFace);
 
-    CFRelease(mAttributesDict);
-    CFRelease(mCTFont);
+    if (mAttributesDict)
+        CFRelease(mAttributesDict);
+    if (mCTFont)
+        CFRelease(mCTFont);
 }
 
 MacOSFontEntry*
 gfxCoreTextFont::GetFontEntry()
 {
     return static_cast<MacOSFontEntry*>(mFontEntry.get());
 }
 
--- a/js/ctypes/libffi/src/arm/sysv.S
+++ b/js/ctypes/libffi/src/arm/sysv.S
@@ -62,21 +62,28 @@
 	|| defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
 	|| defined(__ARM_ARCH_5TEJ__)
 # undef __ARM_ARCH__
 # define __ARM_ARCH__ 5
 #endif
 
 #if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
         || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
-        || defined(__ARM_ARCH_6ZK__)
+        || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) \
+	|| defined(__ARM_ARCH_6M__)
 # undef __ARM_ARCH__
 # define __ARM_ARCH__ 6
 #endif
 
+#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
+        || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__)
+# undef __ARM_ARCH__
+# define __ARM_ARCH__ 7
+#endif
+
 #if __ARM_ARCH__ >= 5
 # define call_reg(x)	blx	x
 #elif defined (__ARM_ARCH_4T__)
 # define call_reg(x)	mov	lr, pc ; bx	x
 # if defined(__thumb__) || defined(__THUMB_INTERWORK__)
 #  define __INTERWORKING__
 # endif
 #else
@@ -184,30 +191,30 @@ ARM_FUNC_START ffi_call_SYSV
 	ldr	r3, [sp, #12]
 
 	@ If the return value pointer is NULL, assume no return value.
 	cmp	r2, #0
 	beq	LSYM(Lepilogue)
 
 @ return INT
 	cmp	r3, #FFI_TYPE_INT
-#ifdef __SOFTFP__
+#if defined(__SOFTFP__) || defined(__ARM_EABI__)
 	cmpne	r3, #FFI_TYPE_FLOAT
 #endif
 	streq	r0, [r2]
 	beq	LSYM(Lepilogue)
 
 	@ return INT64
 	cmp	r3, #FFI_TYPE_SINT64
-#ifdef __SOFTFP__
+#if defined(__SOFTFP__) || defined(__ARM_EABI__)
 	cmpne	r3, #FFI_TYPE_DOUBLE
 #endif
 	stmeqia	r2, {r0, r1}
 
-#ifndef __SOFTFP__
+#if !defined(__SOFTFP__) && !defined(__ARM_EABI__)
 	beq	LSYM(Lepilogue)
 
 @ return FLOAT
 	cmp	r3, #FFI_TYPE_FLOAT
 	stfeqs	f0, [r2]
 	beq	LSYM(Lepilogue)
 
 @ return DOUBLE or LONGDOUBLE
@@ -240,31 +247,31 @@ ARM_FUNC_START ffi_closure_SYSV
 	sub	sp, sp, #16
 	str	sp, [sp, #8]
 	add	r1, sp, #8
 	bl	ffi_closure_SYSV_inner
 	cmp	r0, #FFI_TYPE_INT
 	beq	.Lretint
 
 	cmp	r0, #FFI_TYPE_FLOAT
-#ifdef __SOFTFP__
+#if defined(__SOFTFP__) || defined(__ARM_EABI__)
 	beq	.Lretint
 #else
 	beq	.Lretfloat
 #endif
 
 	cmp	r0, #FFI_TYPE_DOUBLE
-#ifdef __SOFTFP__
+#if defined(__SOFTFP__) || defined(__ARM_EABI__)
 	beq	.Lretlonglong
 #else
 	beq	.Lretdouble
 #endif
 
 	cmp	r0, #FFI_TYPE_LONGDOUBLE
-#ifdef __SOFTFP__
+#if defined(__SOFTFP__) || defined(__ARM_EABI__)
 	beq	.Lretlonglong
 #else
 	beq	.Lretlongdouble
 #endif
 
 	cmp	r0, #FFI_TYPE_SINT64
 	beq	.Lretlonglong
 .Lclosure_epilogue:
@@ -273,17 +280,17 @@ ARM_FUNC_START ffi_closure_SYSV
 .Lretint:
 	ldr	r0, [sp]
 	b	.Lclosure_epilogue
 .Lretlonglong:
 	ldr	r0, [sp]
 	ldr	r1, [sp, #4]
 	b	.Lclosure_epilogue
 
-#ifndef __SOFTFP__
+#if !defined(__SOFTFP__) && !defined(__ARM_EABI__)
 .Lretfloat:
 	ldfs	f0, [sp]
 	b	.Lclosure_epilogue
 .Lretdouble:
 	ldfd	f0, [sp]
 	b	.Lclosure_epilogue
 .Lretlongdouble:
 	ldfd	f0, [sp]
--- a/js/ctypes/tests/Makefile.in
+++ b/js/ctypes/tests/Makefile.in
@@ -61,16 +61,16 @@ include $(topsrcdir)/config/rules.mk
 
 xpctestdir = $(testxpcobjdir)/$(MODULE)/unit
 
 # preprocess and install our unit test into the appropriate directory,
 # and install the test library as well. the xpcshell test rules will
 # install the .js.in from the tests srcdir, so remove it when we're done.
 libs:: unit/test_jsctypes.js.in
 	$(PYTHON) $(MOZILLA_DIR)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) \
-	  $^ > $(xpctestdir)/test_jsctypes.js
+	  -DCTYPES_TEST_LIB=\"$(SHARED_LIBRARY)\" $^ > $(xpctestdir)/test_jsctypes.js
 	$(TEST_INSTALLER) $(SHARED_LIBRARY) $(xpctestdir)
 	$(RM) $(xpctestdir)/test_jsctypes.js.in
 
 GARBAGE += \
     $(xpctestdir)/test_jsctypes.js \
     $(xpctestdir)/$(SHARED_LIBRARY) \
     $(NULL)
--- a/js/ctypes/tests/unit/test_jsctypes.js.in
+++ b/js/ctypes/tests/unit/test_jsctypes.js.in
@@ -38,16 +38,18 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 Components.utils.import("resource://gre/modules/ctypes.jsm");
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 
+#expand const CTYPES_TEST_LIB = __CTYPES_TEST_LIB__;
+
 function do_check_throws(f, type, stack)
 {
   if (!stack)
     stack = Components.stack.caller;
 
   try {
     f();
   } catch (exc) {
@@ -55,26 +57,17 @@ function do_check_throws(f, type, stack)
       return;
     do_throw("expected " + type.name + " exception, caught " + exc, stack);
   }
   do_throw("expected " + type.name + " exception, none thrown", stack);
 }
 
 function run_test()
 {
-#ifdef XP_WIN
-  var libfile = do_get_file("jsctypes-test.dll");
-#elifdef XP_MACOSX
-  var libfile = do_get_file("libjsctypes-test.dylib");
-#elifdef XP_UNIX
-  var libfile = do_get_file("libjsctypes-test.so");
-#else
-  // unsupported OS - don't run the test
-  return;
-#endif
+  var libfile = do_get_file(CTYPES_TEST_LIB);
 
   // open the library with an nsILocalFile
   var library = ctypes.open(libfile);
 
   run_void_tests(library);
   run_int8_tests(library);
   run_int16_tests(library);
   run_int32_tests(library);
--- a/js/src/config/nsinstall_win.c
+++ b/js/src/config/nsinstall_win.c
@@ -145,25 +145,28 @@ shellMkdir (wchar_t **pArgv)
                 *pTmpPath++ = *pArg++;
                 if ( *pArg == '\\' )
                     break;
             }
             *pTmpPath = '\0';
 
             /* check if directory already exists */
             _wgetcwd ( path, _MAX_PATH );
-            if ( _wchdir ( tmpPath ) != -1 ) {
-                _wchdir ( path );
+            if ( _wchdir ( tmpPath ) == -1 &&
+                 _wmkdir ( tmpPath ) == -1 && // might have hit EEXIST
+                 _wchdir ( tmpPath ) == -1) { // so try again
+                char buf[2048];
+                _snprintf(buf, 2048, "Could not create the directory: %S",
+                          tmpPath);
+                perror ( buf );
+                retVal = 3;
+                break;
             } else {
-                if ( _wmkdir ( tmpPath ) == -1 ) {
-                    printf ( "%ls: ", tmpPath );
-                    perror ( "Could not create the directory" );
-                    retVal = 3;
-                    break;
-                }
+                // get back to the cwd
+                _wchdir ( path );
             }
             if ( *pArg == '\0' )      /* complete path? */
                 break;
             /* loop for next directory */
         }
 
         pArgv++;
     }
--- a/js/src/jsapi-tests/testXDR.cpp
+++ b/js/src/jsapi-tests/testXDR.cpp
@@ -1,9 +1,10 @@
 #include "tests.h"
+#include "jsscript.h"
 #include "jsxdrapi.h"
 
 BEGIN_TEST(testXDR_bug506491)
 {
     const char *s =
         "function makeClosure(s, name, value) {\n"
         "    eval(s);\n"
         "    return let (n = name, v = value) function () { return String(v); };\n"
@@ -19,17 +20,17 @@ BEGIN_TEST(testXDR_bug506491)
 
     // freeze
     JSXDRState *w = JS_XDRNewMem(cx, JSXDR_ENCODE);
     CHECK(w);
     CHECK(JS_XDRScript(w, &script));
     uint32 nbytes;
     void *p = JS_XDRMemGetData(w, &nbytes);
     CHECK(p);
-    void *frozen = malloc(nbytes);
+    void *frozen = JS_malloc(cx, nbytes);
     CHECK(frozen);
     memcpy(frozen, p, nbytes);
     JS_XDRDestroy(w);
 
     // thaw
     script = NULL;
     JSXDRState *r = JS_XDRNewMem(cx, JSXDR_DECODE);
     JS_XDRMemSetData(r, frozen, nbytes);
@@ -65,17 +66,17 @@ BEGIN_TEST(testXDR_bug516827)
 
     // freeze
     JSXDRState *w = JS_XDRNewMem(cx, JSXDR_ENCODE);
     CHECK(w);
     CHECK(JS_XDRScript(w, &script));
     uint32 nbytes;
     void *p = JS_XDRMemGetData(w, &nbytes);
     CHECK(p);
-    void *frozen = malloc(nbytes);
+    void *frozen = JS_malloc(cx, nbytes);
     CHECK(frozen);
     memcpy(frozen, p, nbytes);
     JS_XDRDestroy(w);
 
     // thaw
     script = NULL;
     JSXDRState *r = JS_XDRNewMem(cx, JSXDR_DECODE);
     JS_XDRMemSetData(r, frozen, nbytes);
@@ -85,8 +86,40 @@ BEGIN_TEST(testXDR_bug516827)
     CHECK(scrobj);
     v = OBJECT_TO_JSVAL(scrobj);
 
     // execute with null result meaning no result wanted
     CHECK(JS_ExecuteScript(cx, global, script, NULL));
     return true;
 }
 END_TEST(testXDR_bug516827)
+
+BEGIN_TEST(testXDR_bug525481)
+{
+    // get the empty script const singleton
+    JSScript *script = JSScript::emptyScript();
+    CHECK(script);
+
+    // freeze with junk after the empty script shorthand
+    JSXDRState *w = JS_XDRNewMem(cx, JSXDR_ENCODE);
+    CHECK(w);
+    CHECK(JS_XDRScript(w, &script));
+    const char s[] = "don't decode me; don't encode me";
+    char b[sizeof s - 1];
+    memcpy(b, s, sizeof b);
+    CHECK(JS_XDRBytes(w, b, sizeof b));
+    uint32 nbytes;
+    void *p = JS_XDRMemGetData(w, &nbytes);
+    CHECK(p);
+    void *frozen = JS_malloc(cx, nbytes);
+    CHECK(frozen);
+    memcpy(frozen, p, nbytes);
+    JS_XDRDestroy(w);
+
+    // thaw, reading junk if bug 525481 is not patched
+    script = NULL;
+    JSXDRState *r = JS_XDRNewMem(cx, JSXDR_DECODE);
+    JS_XDRMemSetData(r, frozen, nbytes);
+    CHECK(JS_XDRScript(r, &script));
+    JS_XDRDestroy(r);  // this frees `frozen`
+    return true;
+}
+END_TEST(testXDR_bug525481)
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -2701,17 +2701,17 @@ FinalizeGCThing(JSContext *cx, JSObject 
         OBJ_SCOPE(obj)->drop(cx, obj);
     js_FreeSlots(cx, obj);
 }
 
 static inline void
 FinalizeGCThing(JSContext *cx, JSFunction *fun, unsigned thingKind)
 {
     JS_ASSERT(thingKind == FINALIZE_FUNCTION);
-    FinalizeGCThing(cx, FUN_OBJECT(fun), thingKind);
+    ::FinalizeGCThing(cx, FUN_OBJECT(fun), thingKind);
 }
 
 #if JS_HAS_XML_SUPPORT
 static inline void
 FinalizeGCThing(JSContext *cx, JSXML *xml, unsigned thingKind)
 {
     js_FinalizeXML(cx, xml);
 }
@@ -2853,17 +2853,17 @@ FinalizeArenaList(JSContext *cx, unsigne
                     continue;
                 }
 
                 /*
                  * Call the finalizer with cleared flags so
                  * js_IsAboutToBeFinalized will be false.
                  */
                 *flagp = 0;
-                FinalizeGCThing(cx, reinterpret_cast<T *>(thing), thingKind);
+                ::FinalizeGCThing(cx, reinterpret_cast<T *>(thing), thingKind);
 #ifdef DEBUG
                 memset(thing, JS_FREE_PATTERN, sizeof(T));
 #endif
             }
             *tailp = thing;
             tailp = &thing->link;
         }
 
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -77,17 +77,17 @@ static const char js_script_compile_str[
  */
 static jsint
 GetScriptExecDepth(JSContext *cx, JSObject *obj)
 {
     jsval v;
 
     JS_ASSERT(JS_IS_OBJ_LOCKED(cx, obj));
     v = LOCKED_OBJ_GET_SLOT(obj, JSSLOT_START(&js_ScriptClass));
-    return JSVAL_TO_INT(v);
+    return JSVAL_IS_VOID(v) ? 0 : JSVAL_TO_INT(v);
 }
 
 static void
 AdjustScriptExecDepth(JSContext *cx, JSObject *obj, jsint delta)
 {
     jsint execDepth;
 
     JS_LOCK_OBJ(cx, obj);
@@ -132,17 +132,19 @@ script_toSource(JSContext *cx, uintN arg
     } else {
         str = JS_DecompileScript(cx, script, "Script.prototype.toSource",
                                  (uintN)indent);
         if (!str)
             return JS_FALSE;
         str = js_QuoteString(cx, str, '\'');
         if (!str)
             return JS_FALSE;
-        str->getCharsAndLength(s, k);
+        const jschar *cs;
+        str->getCharsAndLength(cs, k);
+        s = const_cast<jschar *>(cs);
         n += k;
     }
 
     /* Allocate the source string and copy into it. */
     t = (jschar *) cx->malloc((n + 1) * sizeof(jschar));
     if (!t)
         return JS_FALSE;
     for (i = 0; i < j; i++)
@@ -456,37 +458,52 @@ js_XDRScript(JSXDRState *xdr, JSScript *
         *hasMagic = JS_FALSE;
         return JS_TRUE;
     }
     if (hasMagic)
         *hasMagic = JS_TRUE;
 
     /*
      * Since the shortest possible script has JSOP_STOP as its only bytecode,
-     * encode only the length 1 for the emptyScript singleton, and return the
-     * emptyScript instead of a new script when decoding a script of length 1.
+     * encode only the length 0 for the emptyScript singleton, and return the
+     * emptyScript instead of a new script when decoding a script of length 0.
      */
     if (xdr->mode == JSXDR_ENCODE)
-        length = (script == JSScript::emptyScript()) ? 1 : script->length;
+        length = (script == JSScript::emptyScript()) ? 0 : script->length;
     if (!JS_XDRUint32(xdr, &length))
         return JS_FALSE;
-    JS_ASSERT(length != 0);
-    if (length == 1) {
+    if (length == 0) {
         if (xdr->mode == JSXDR_ENCODE) {
             JS_ASSERT(*scriptp == JSScript::emptyScript());
             return JS_TRUE;
         }
 
         /* Decoding: check whether we need a mutable empty script. */
         if (cx->debugHooks->newScriptHook)
             needMutableScript = true;
-        if (!needMutableScript) {
-            *scriptp = JSScript::emptyScript();
+        if (needMutableScript) {
+            /*
+             * We need a mutable empty script but the encoder serialized only
+             * the shorthand (0 length word) for us. Make a new mutable empty
+             * script here and return it immediately.
+             */
+            script = js_NewScript(cx, 1, 1, 0, 0, 0, 0, 0);
+            if (!script)
+                return JS_FALSE;
+
+            script->version = JSVERSION_DEFAULT;
+            script->noScriptRval = true;
+            script->code[0] = JSOP_STOP;
+            script->code[1] = SRC_NULL;
+            *scriptp = script;
             return JS_TRUE;
         }
+
+        *scriptp = JSScript::emptyScript();
+        return JS_TRUE;
     }
 
     if (xdr->mode == JSXDR_ENCODE) {
         prologLength = script->main - script->code;
         JS_ASSERT((int16)script->version != JSVERSION_UNKNOWN);
         version = (uint32)script->version | (script->nfixed << 16);
         lineno = (uint32)script->lineno;
         nslots = (uint32)script->nslots;
@@ -779,18 +796,17 @@ out:
 
 static JSBool
 script_thaw(JSContext *cx, uintN argc, jsval *vp)
 {
     JSObject *obj;
     JSXDRState *xdr;
     JSString *str;
     void *buf;
-    uint32 len;
-    jsval v;
+    size_t len;
     JSScript *script, *oldscript;
     JSBool ok, hasMagic;
     jsint execDepth;
 
     obj = JS_THIS_OBJECT(cx, vp);
     if (!JS_InstanceOf(cx, obj, &js_ScriptClass, vp + 2))
         return JS_FALSE;
 
@@ -801,17 +817,19 @@ script_thaw(JSContext *cx, uintN argc, j
         return JS_FALSE;
     vp[2] = STRING_TO_JSVAL(str);
 
     /* create new XDR */
     xdr = JS_XDRNewMem(cx, JSXDR_DECODE);
     if (!xdr)
         return JS_FALSE;
 
-    str->getCharsAndLength(buf, len);
+    const jschar *cs;
+    str->getCharsAndLength(cs, len);
+    buf = const_cast<jschar *>(cs);
 #if IS_BIG_ENDIAN
   {
     jschar *from, *to;
     uint32 i;
 
     /* Swap bytes in Unichars to keep frozen strings machine-independent. */
     from = (jschar *)buf;
     to = (jschar *) cx->malloc(len * sizeof(jschar));
@@ -1395,26 +1413,16 @@ JSScript *
 js_NewScript(JSContext *cx, uint32 length, uint32 nsrcnotes, uint32 natoms,
              uint32 nobjects, uint32 nupvars, uint32 nregexps,
              uint32 ntrynotes)
 {
     size_t size, vectorSize;
     JSScript *script;
     uint8 *cursor;
 
-    if (length == 1) {
-        JS_ASSERT(nsrcnotes == 1);
-        JS_ASSERT(natoms == 0);
-        JS_ASSERT(nobjects == 0);
-        JS_ASSERT(nupvars == 0);
-        JS_ASSERT(nregexps == 0);
-        JS_ASSERT(ntrynotes == 0);
-        return JSScript::emptyScript();
-    }
-
     size = sizeof(JSScript) +
            sizeof(JSAtom *) * natoms +
            length * sizeof(jsbytecode) +
            nsrcnotes * sizeof(jssrcnote);
     if (nobjects != 0)
         size += sizeof(JSObjectArray) + nobjects * sizeof(JSObject *);
     if (nupvars != 0)
         size += sizeof(JSUpvarArray) + nupvars * sizeof(uint32);
@@ -1522,34 +1530,40 @@ js_NewScriptFromCG(JSContext *cx, JSCode
     /* The counts of indexed things must be checked during code generation. */
     JS_ASSERT(cg->atomList.count <= INDEX_LIMIT);
     JS_ASSERT(cg->objectList.length <= INDEX_LIMIT);
     JS_ASSERT(cg->regexpList.length <= INDEX_LIMIT);
 
     mainLength = CG_OFFSET(cg);
     prologLength = CG_PROLOG_OFFSET(cg);
 
-    if (!cx->debugHooks->newScriptHook &&
-        !(cg->flags & TCF_NEED_MUTABLE_SCRIPT) &&
-        prologLength + mainLength <= 3) {
+    if (prologLength + mainLength <= 3) {
         /*
          * Check very short scripts to see whether they are "empty" and return
          * the const empty-script singleton if so. We are deliberately flexible
          * about whether JSOP_TRACE is in the prolog.
          */
         jsbytecode *pc = prologLength ? CG_PROLOG_BASE(cg) : CG_BASE(cg);
 
         if (JSOp(*pc) == JSOP_TRACE) {
             ++pc;
             if (pc == CG_PROLOG_BASE(cg) + prologLength)
                 pc = CG_BASE(cg);
         }
         if ((cg->flags & TCF_NO_SCRIPT_RVAL) && JSOp(*pc) == JSOP_FALSE)
             ++pc;
-        if (JSOp(*pc) == JSOP_STOP) {
+
+        if (JSOp(*pc) == JSOP_STOP &&
+            !cx->debugHooks->newScriptHook &&
+            !(cg->flags & TCF_NEED_MUTABLE_SCRIPT))
+        {
+            /*
+             * We can probably use the immutable empty script singleton, just
+             * one hard case (nupvars != 0) may stand in our way.
+             */
             JSScript *empty = JSScript::emptyScript();
 
             if (cg->flags & TCF_IN_FUNCTION) {
                 fun = cg->fun;
                 JS_ASSERT(FUN_INTERPRETED(fun) && !FUN_SCRIPT(fun));
                 if (fun->u.i.nupvars != 0) {
                     /*
                      * FIXME: upvar uses that were all optimized away may leave
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -270,16 +270,22 @@ js_SweepScriptFilenames(JSRuntime *rt);
  * does *not* call a non-null cx->runtime->newScriptHook -- only the second,
  * js_NewScriptFromCG, calls this optional debugger hook.
  *
  * The js_NewScript function can't know whether the script it creates belongs
  * to a function, or is top-level or eval code, but the debugger wants access
  * to the newly made script's function, if any -- so callers of js_NewScript
  * are responsible for notifying the debugger after successfully creating any
  * kind (function or other) of new JSScript.
+ *
+ * NB: js_NewScript always creates a new script; it never returns the empty
+ * script singleton (JSScript::emptyScript()). Callers who know they can use
+ * that read-only singleton are responsible for choosing it instead of calling
+ * js_NewScript with length and nsrcnotes equal to 1 and other parameters save
+ * cx all zero.
  */
 extern JSScript *
 js_NewScript(JSContext *cx, uint32 length, uint32 nsrcnotes, uint32 natoms,
              uint32 nobjects, uint32 nupvars, uint32 nregexps,
              uint32 ntrynotes);
 
 extern JSScript *
 js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg);
--- a/js/src/jsxdrapi.h
+++ b/js/src/jsxdrapi.h
@@ -200,17 +200,17 @@ JS_XDRFindClassById(JSXDRState *xdr, uin
  * Bytecode version number. Increment the subtrahend whenever JS bytecode
  * changes incompatibly.
  *
  * This version number should be XDR'ed once near the front of any file or
  * larger storage unit containing XDR'ed bytecode and other data, and checked
  * before deserialization of bytecode.  If the saved version does not match
  * the current version, abort deserialization and invalidate the file.
  */
-#define JSXDR_BYTECODE_VERSION      (0xb973c0de - 57)
+#define JSXDR_BYTECODE_VERSION      (0xb973c0de - 58)
 
 /*
  * Library-private functions.
  */
 extern JSBool
 js_XDRAtom(JSXDRState *xdr, JSAtom **atomp);
 
 extern JSBool
--- a/js/src/xpconnect/src/nsXPConnect.cpp
+++ b/js/src/xpconnect/src/nsXPConnect.cpp
@@ -2461,29 +2461,29 @@ nsXPConnect::GetWrapperForObject(JSConte
     //   - We're not about to force a XOW (e.g. for "window") OR
     //   - We're not actually going to create a XOW (we're wrapping for
     //     chrome).
     if(aObject->isSystem() ||
        (sameScope &&
         (!forceXOW || (aFilenameFlags & JSFILENAME_SYSTEM))))
         return NS_OK;
 
-    if(!wrapper)
-    {
-        SLIM_LOG_WILL_MORPH(aJSContext, aObject);
-        if(!MorphSlimWrapper(aJSContext, aObject))
-            return NS_ERROR_FAILURE;
-
-        wrapper = static_cast<XPCWrappedNative*>(xpc_GetJSPrivate(aObject));
-    }
-
     JSObject* wrappedObj = nsnull;
 
     if(aFilenameFlags & JSFILENAME_PROTECTED)
     {
+        if(!wrapper)
+        {
+            SLIM_LOG_WILL_MORPH(aJSContext, aObject);
+            if(!MorphSlimWrapper(aJSContext, aObject))
+                return NS_ERROR_FAILURE;
+
+            wrapper = static_cast<XPCWrappedNative*>(xpc_GetJSPrivate(aObject));
+        }
+
         wrappedObj = XPCNativeWrapper::GetNewOrUsed(aJSContext, wrapper,
                                                     aPrincipal);
     }
     else if(aFilenameFlags & JSFILENAME_SYSTEM)
     {
         jsval val = OBJECT_TO_JSVAL(aObject);
         if(XPC_SJOW_Construct(aJSContext, nsnull, 1, &val, &val))
             wrappedObj = JSVAL_TO_OBJECT(val);
@@ -2499,17 +2499,17 @@ nsXPConnect::GetWrapperForObject(JSConte
         if(XPC_XOW_WrapObject(aJSContext, aScope, &val, wrapper))
             wrappedObj = JSVAL_TO_OBJECT(val);
     }
 
     if(!wrappedObj)
         return NS_ERROR_FAILURE;
 
     *_retval = OBJECT_TO_JSVAL(wrappedObj);
-    if(wrapper->NeedsChromeWrapper() &&
+    if(wrapper && wrapper->NeedsChromeWrapper() &&
        !XPC_SOW_WrapObject(aJSContext, aScope, *_retval, _retval))
         return NS_ERROR_FAILURE;
     return NS_OK;
 }
 
 /* attribute JSRuntime runtime; */
 NS_IMETHODIMP
 nsXPConnect::GetRuntime(JSRuntime **runtime)
--- a/layout/base/nsBidiPresUtils.cpp
+++ b/layout/base/nsBidiPresUtils.cpp
@@ -830,17 +830,18 @@ nsBidiPresUtils::Reorder(PRBool& aReorde
   return mSuccess;
 }
 
 nsBidiLevel
 nsBidiPresUtils::GetFrameEmbeddingLevel(nsIFrame* aFrame)
 {
   nsIFrame* firstLeaf = aFrame;
   while (!IsBidiLeaf(firstLeaf)) {
-    firstLeaf = firstLeaf->GetFirstChild(nsnull);
+    firstLeaf = 
+      nsPlaceholderFrame::GetRealFrameFor(firstLeaf->GetFirstChild(nsnull));
   }
   return NS_GET_EMBEDDING_LEVEL(firstLeaf);
 }
 
 nsBidiLevel
 nsBidiPresUtils::GetFrameBaseLevel(nsIFrame* aFrame)
 {
   nsIFrame* firstLeaf = aFrame;
--- a/layout/build/nsLayoutModule.cpp
+++ b/layout/build/nsLayoutModule.cpp
@@ -113,17 +113,17 @@
 
 // view stuff
 #include "nsViewsCID.h"
 #include "nsViewManager.h"
 #include "nsContentCreatorFunctions.h"
 
 // DOM includes
 #include "nsDOMException.h"
-#include "nsDOMFileRequest.h"
+#include "nsDOMFileReader.h"
 #include "nsGlobalWindowCommands.h"
 #include "nsIControllerCommandTable.h"
 #include "nsJSProtocolHandler.h"
 #include "nsScriptNameSpaceManager.h"
 #include "nsIControllerContext.h"
 #include "nsDOMScriptObjectFactory.h"
 #include "nsDOMStorage.h"
 #include "nsJSON.h"
@@ -286,17 +286,17 @@ static void Shutdown();
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsXPath1SchemeProcessor)
 
 // Factory Constructor
 NS_GENERIC_FACTORY_CONSTRUCTOR(txMozillaXSLTProcessor)
 NS_GENERIC_AGGREGATED_CONSTRUCTOR_INIT(nsXPathEvaluator, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(txNodeSetAdaptor, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsDOMSerializer)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsXMLHttpRequest, Init)
-NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsDOMFileRequest, Init)
+NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsDOMFileReader, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsDOMParser)
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsDOMStorageManager,
                                          nsDOMStorageManager::GetInstance)
 
 //-----------------------------------------------------------------------------
 
 // Per bug 209804, it is necessary to observe the "xpcom-shutdown" event and
 // perform shutdown of the layout modules at that time instead of waiting for
@@ -1371,20 +1371,20 @@ static const nsModuleComponentInfo gComp
     TRANSFORMIIX_NODESET_CONTRACTID,
     txNodeSetAdaptorConstructor },
 
   { "XML Serializer",
     NS_XMLSERIALIZER_CID,
     NS_XMLSERIALIZER_CONTRACTID,
     nsDOMSerializerConstructor },
 
-  { "FileRequest",
-    NS_FILEREQUEST_CID,
-    NS_FILEREQUEST_CONTRACTID,
-    nsDOMFileRequestConstructor },
+  { "FileReader",
+    NS_FILEREADER_CID,
+    NS_FILEREADER_CONTRACTID,
+    nsDOMFileReaderConstructor },
 
   { "XMLHttpRequest",
     NS_XMLHTTPREQUEST_CID,
     NS_XMLHTTPREQUEST_CONTRACTID,
     nsXMLHttpRequestConstructor },
 
   { "DOM Parser",
     NS_DOMPARSER_CID,
--- a/layout/generic/nsObjectFrame.cpp
+++ b/layout/generic/nsObjectFrame.cpp
@@ -295,17 +295,17 @@ public:
 
   nsresult Destroy();  
 
   void PrepareToStop(PRBool aDelayedStop);
   
 #ifdef XP_WIN
   void Paint(const RECT& aDirty, HDC aDC);
 #elif defined(XP_MACOSX)
-  void Paint(const gfxRect& aDirtyRect);  
+  void Paint(const gfxRect& aDirtyRect, CGContextRef cgContext);  
 #elif defined(MOZ_X11) || defined(MOZ_DFB)
   void Paint(gfxContext* aContext,
              const gfxRect& aFrameRect,
              const gfxRect& aDirtyRect);
 #elif defined(XP_OS2)
   void Paint(const nsRect& aDirtyRect, HPS aHPS);
 #endif
 
@@ -359,17 +359,17 @@ public:
   // been called from nsObjectFrame::PaintPlugin() when we're using the
   // CoreGraphics drawing model).
   void BeginCGPaint();
   void EndCGPaint();
 #endif
 
   void SetOwner(nsObjectFrame *aOwner)
   {
-    mOwner = aOwner;
+    mObjectFrame = aOwner;
   }
 
   PRUint32 GetLastEventloopNestingLevel() const {
     return mLastEventloopNestingLevel; 
   }
 
   static PRUint32 GetEventloopNestingLevel();
       
@@ -405,17 +405,17 @@ public:
     return strncmp(GetPluginName(), aPluginName, strlen(aPluginName)) == 0;
   }
 
 private:
   void FixUpURLS(const nsString &name, nsAString &value);
 
   nsPluginNativeWindow       *mPluginWindow;
   nsCOMPtr<nsIPluginInstance> mInstance;
-  nsObjectFrame              *mOwner;
+  nsObjectFrame              *mObjectFrame; // owns nsPluginInstanceOwner
   nsCOMPtr<nsIContent>        mContent;
   nsCString                   mDocumentBase;
   char                       *mTagText;
   nsCOMPtr<nsIWidget>         mWidget;
   nsCOMPtr<nsITimer>          mPluginTimer;
   nsCOMPtr<nsIPluginHost>     mPluginHost;
 
 #ifdef XP_MACOSX
@@ -440,16 +440,20 @@ private:
   PRUint16          mNumCachedParams;
   char              **mCachedAttrParamNames;
   char              **mCachedAttrParamValues;
 
 #ifdef MOZ_COMPOSITED_PLUGINS
   nsIntPoint        mLastPoint;
 #endif
 
+#ifdef XP_MACOSX
+  NPEventModel mEventModel;
+#endif
+
   // pointer to wrapper for nsIDOMContextMenuListener
   nsRefPtr<nsPluginDOMContextMenuListener> mCXMenuListener;
 
   nsresult DispatchKeyToPlugin(nsIDOMEvent* aKeyEvent);
   nsresult DispatchMouseToPlugin(nsIDOMEvent* aMouseEvent);
   nsresult DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent);
 
   nsresult EnsureCachedAttrParamArrays();
@@ -708,16 +712,25 @@ nsObjectFrame::CreateWidget(nscoord aWid
     // case, walk up the frame tree until we do find a frame with a background color
     for (nsIFrame* frame = this; frame; frame = frame->GetParent()) {
       const nsStyleBackground* background = frame->GetStyleBackground();
       if (!background->IsTransparent()) {  // make sure we got an actual color
         mWidget->SetBackgroundColor(background->mBackgroundColor);
         break;
       }
     }
+
+#ifdef XP_MACOSX
+    // Now that we have a widget we want to set the event model before
+    // any events are processed.
+    nsCOMPtr<nsIPluginWidget> pluginWidget = do_QueryInterface(mWidget);
+    if (!pluginWidget)
+      return NS_ERROR_FAILURE;
+    pluginWidget->SetPluginEventModel(mInstanceOwner->GetEventModel());
+#endif
   }
 
   if (!IsHidden()) {
     viewMan->SetViewVisibility(view, nsViewVisibility_kShow);
   }
 
   return NS_OK;
 }
@@ -1529,43 +1542,48 @@ nsObjectFrame::PaintPlugin(nsIRenderingC
         nativeDrawing.EndNativeDrawing();
         return;
       }
       if (!mInstanceOwner->SetPluginPortAndDetectChange()) {
         NS_WARNING("null plugin port during PaintPlugin");
         nativeDrawing.EndNativeDrawing();
         return;
       }
+      
+#ifndef NP_NO_CARBON
+      // In the Carbon event model...
       // If gfxQuartzNativeDrawing hands out a CGContext different from the
       // one set by SetPluginPortAndDetectChange(), we need to pass it to the
       // plugin via SetWindow().  This will happen in nsPluginInstanceOwner::
       // FixUpPluginWindow(), called from nsPluginInstanceOwner::Paint().
       // (If SetPluginPortAndDetectChange() made any changes itself, this has
       // already been detected in that method, and will likewise result in a
       // call to SetWindow() from FixUpPluginWindow().)
       NP_CGContext* windowContext = static_cast<NP_CGContext*>(window->window);
-      if (windowContext->context != cgContext) {
+      if (mInstanceOwner->GetEventModel() == NPEventModelCarbon &&
+          windowContext->context != cgContext) {
         windowContext->context = cgContext;
         cgPluginPortCopy->context = cgContext;
         mInstanceOwner->SetPluginPortChanged(PR_TRUE);
       }
+#endif
 
       mInstanceOwner->BeginCGPaint();
-      mInstanceOwner->Paint(nativeClipRect - offset);
+      mInstanceOwner->Paint(nativeClipRect - offset, cgContext);
       mInstanceOwner->EndCGPaint();
 
       nativeDrawing.EndNativeDrawing();
     } else {
       // FIXME - Bug 385435: Doesn't aDirtyRect need translating too?
       nsIRenderingContext::AutoPushTranslation
         translate(&aRenderingContext, aPluginRect.x, aPluginRect.y);
 
       // this rect is used only in the CoreGraphics drawing model
       gfxRect tmpRect(0, 0, 0, 0);
-      mInstanceOwner->Paint(tmpRect);
+      mInstanceOwner->Paint(tmpRect, NULL);
     }
   }
 #elif defined(MOZ_X11) || defined(MOZ_DFB)
   if (mInstanceOwner) {
     NPWindow *window;
     mInstanceOwner->GetWindow(window);
 #ifdef MOZ_COMPOSITED_PLUGINS
     {
@@ -1830,37 +1848,30 @@ nsObjectFrame::HandleEvent(nsPresContext
   }
 
 #ifdef XP_WIN
   rv = nsObjectFrameSuper::HandleEvent(aPresContext, anEvent, anEventStatus);
   return rv;
 #endif
 
 #ifdef XP_MACOSX
-  // we want to process native mouse enter events in the cocoa event model
-  if (anEvent->message == NS_MOUSE_ENTER && mInstanceOwner->GetEventModel() == NPEventModelCocoa) {
+  // we want to process some native mouse events in the cocoa event model
+  if ((anEvent->message == NS_MOUSE_ENTER || anEvent->message == NS_MOUSE_SCROLL) &&
+      mInstanceOwner->GetEventModel() == NPEventModelCocoa) {
     *anEventStatus = mInstanceOwner->ProcessEvent(*anEvent);
     return rv;
   }
 #endif
 
-  switch (anEvent->message) {
-  case NS_DESTROY:
+  if (anEvent->message == NS_DESTROY) {
     mInstanceOwner->CancelTimer();
-    break;
-  case NS_ACTIVATE:
-  case NS_DEACTIVATE:
-    *anEventStatus = mInstanceOwner->ProcessEvent(*anEvent);
-    break;
-    
-  default:
-    rv = nsObjectFrameSuper::HandleEvent(aPresContext, anEvent, anEventStatus);
+    return rv;
   }
 
-  return rv;
+  return nsObjectFrameSuper::HandleEvent(aPresContext, anEvent, anEventStatus);
 }
 
 nsresult
 nsObjectFrame::GetPluginInstance(nsIPluginInstance*& aPluginInstance)
 {
   aPluginInstance = nsnull;
 
   if (!mInstanceOwner)
@@ -2325,17 +2336,17 @@ nsPluginInstanceOwner::nsPluginInstanceO
   // create nsPluginNativeWindow object, it is derived from NPWindow
   // struct and allows to manipulate native window procedure
   nsCOMPtr<nsIPluginHost> ph = do_GetService(MOZ_PLUGIN_HOST_CONTRACTID);
   if (ph)
     ph->NewPluginNativeWindow(&mPluginWindow);
   else
     mPluginWindow = nsnull;
 
-  mOwner = nsnull;
+  mObjectFrame = nsnull;
   mTagText = nsnull;
 #ifdef XP_MACOSX
   memset(&mCGPluginPortCopy, 0, sizeof(NP_CGContext));
   memset(&mQDPluginPortCopy, 0, sizeof(NP_Port));
   mInCGPaintLevel = 0;
 #endif
   mContentFocused = PR_FALSE;
   mWidgetVisible = PR_TRUE;
@@ -2350,31 +2361,38 @@ nsPluginInstanceOwner::nsPluginInstanceO
 #ifdef MOZ_COMPOSITED_PLUGINS
   mLastPoint = nsIntPoint(0,0);
 #endif
 
 #ifdef MOZ_PLATFORM_HILDON
   mImageExposeBuffer = nsnull;
   mImageExposeBufferSize = gfxIntSize(0,0);
 #endif
+#ifdef XP_MACOSX
+#ifndef NP_NO_QUICKDRAW
+  mEventModel = NPEventModelCarbon;
+#else
+  mEventModel = NPEventModelCocoa;
+#endif
+#endif
   PR_LOG(nsObjectFrameLM, PR_LOG_DEBUG,
          ("nsPluginInstanceOwner %p created\n", this));
 }
 
 nsPluginInstanceOwner::~nsPluginInstanceOwner()
 {
   PRInt32 cnt;
 
   PR_LOG(nsObjectFrameLM, PR_LOG_DEBUG,
          ("nsPluginInstanceOwner %p deleted\n", this));
 
   // shut off the timer.
   CancelTimer();
 
-  mOwner = nsnull;
+  mObjectFrame = nsnull;
 
   for (cnt = 0; cnt < (mNumCachedAttrs + 1 + mNumCachedParams); cnt++) {
     if (mCachedAttrParamNames && mCachedAttrParamNames[cnt]) {
       NS_Free(mCachedAttrParamNames[cnt]);
       mCachedAttrParamNames[cnt] = nsnull;
     }
 
     if (mCachedAttrParamValues && mCachedAttrParamValues[cnt]) {
@@ -2513,24 +2531,24 @@ NS_IMETHODIMP nsPluginInstanceOwner::Get
   NS_IF_ADDREF(aInstance = mInstance);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP nsPluginInstanceOwner::GetURL(const char *aURL, const char *aTarget, void *aPostData, PRUint32 aPostDataLen, void *aHeadersData, 
                                             PRUint32 aHeadersDataLen, PRBool isFile)
 {
-  NS_ENSURE_TRUE(mOwner,NS_ERROR_NULL_POINTER);
+  NS_ENSURE_TRUE(mObjectFrame, NS_ERROR_NULL_POINTER);
 
   if (mContent->IsEditable()) {
     return NS_OK;
   }
 
   // the container of the pres context will give us the link handler
-  nsCOMPtr<nsISupports> container = mOwner->PresContext()->GetContainer();
+  nsCOMPtr<nsISupports> container = mObjectFrame->PresContext()->GetContainer();
   NS_ENSURE_TRUE(container,NS_ERROR_FAILURE);
   nsCOMPtr<nsILinkHandler> lh = do_QueryInterface(container);
   NS_ENSURE_TRUE(lh, NS_ERROR_FAILURE);
 
   nsAutoString  unitarget;
   unitarget.AssignASCII(aTarget); // XXX could this be nonascii?
 
   nsCOMPtr<nsIURI> baseURI = mContent->GetBaseURI();
@@ -2584,20 +2602,20 @@ NS_IMETHODIMP nsPluginInstanceOwner::Sho
   
   return rv;
 }
 
 NS_IMETHODIMP nsPluginInstanceOwner::ShowStatus(const PRUnichar *aStatusMsg)
 {
   nsresult  rv = NS_ERROR_FAILURE;
 
-  if (!mOwner) {
+  if (!mObjectFrame) {
     return rv;
   }
-  nsCOMPtr<nsISupports> cont = mOwner->PresContext()->GetContainer();
+  nsCOMPtr<nsISupports> cont = mObjectFrame->PresContext()->GetContainer();
   if (!cont) {
     return NS_OK;
   }
 
   nsCOMPtr<nsIDocShellTreeItem> docShellItem(do_QueryInterface(cont, &rv));
   if (NS_FAILED(rv) || !docShellItem) {
     return rv;
   }
@@ -2626,66 +2644,66 @@ NS_IMETHODIMP nsPluginInstanceOwner::Get
   // XXX sXBL/XBL2 issue: current doc or owner doc?
   // But keep in mind bug 322414 comment 33
   NS_IF_ADDREF(*aDocument = mContent->GetOwnerDoc());
   return NS_OK;
 }
 
 NS_IMETHODIMP nsPluginInstanceOwner::InvalidateRect(NPRect *invalidRect)
 {
-  if (!mOwner || !invalidRect || !mWidgetVisible)
+  if (!mObjectFrame || !invalidRect || !mWidgetVisible)
     return NS_ERROR_FAILURE;
 
 #ifndef XP_MACOSX
   // Windowed plugins should not be calling NPN_InvalidateRect, but
   // Silverlight does and expects it to "work"
   if (mWidget) {
     mWidget->Invalidate(nsIntRect(invalidRect->left, invalidRect->top,
                                   invalidRect->right - invalidRect->left,
                                   invalidRect->bottom - invalidRect->top),
                         PR_FALSE);
     return NS_OK;
   }
 #endif
 
-  nsPresContext* presContext = mOwner->PresContext();
+  nsPresContext* presContext = mObjectFrame->PresContext();
   nsRect rect(presContext->DevPixelsToAppUnits(invalidRect->left),
               presContext->DevPixelsToAppUnits(invalidRect->top),
               presContext->DevPixelsToAppUnits(invalidRect->right - invalidRect->left),
               presContext->DevPixelsToAppUnits(invalidRect->bottom - invalidRect->top));
-  mOwner->Invalidate(rect + mOwner->GetUsedBorderAndPadding().TopLeft());
+  mObjectFrame->Invalidate(rect + mObjectFrame->GetUsedBorderAndPadding().TopLeft());
   return NS_OK;
 }
 
 NS_IMETHODIMP nsPluginInstanceOwner::InvalidateRegion(NPRegion invalidRegion)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP nsPluginInstanceOwner::ForceRedraw()
 {
-  NS_ENSURE_TRUE(mOwner,NS_ERROR_NULL_POINTER);
-  nsIView* view = mOwner->GetView();
+  NS_ENSURE_TRUE(mObjectFrame, NS_ERROR_NULL_POINTER);
+  nsIView* view = mObjectFrame->GetView();
   if (view) {
     return view->GetViewManager()->Composite();
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP nsPluginInstanceOwner::GetNetscapeWindow(void *value)
 {
-  if (!mOwner) {
+  if (!mObjectFrame) {
     NS_WARNING("plugin owner has no owner in getting doc's window handle");
     return NS_ERROR_FAILURE;
   }
   
 #if defined(XP_WIN) || defined(XP_OS2)
   void** pvalue = (void**)value;
-  nsIViewManager* vm = mOwner->PresContext()->GetPresShell()->GetViewManager();
+  nsIViewManager* vm = mObjectFrame->PresContext()->GetPresShell()->GetViewManager();
   if (!vm)
     return NS_ERROR_FAILURE;
 #if defined(XP_WIN)
   // This property is provided to allow a "windowless" plugin to determine the window it is drawing
   // in, so it can translate mouse coordinates it receives directly from the operating system
   // to coordinates relative to itself.
   
   // The original code (outside this #if) returns the document's window, which is OK if the window the "windowless" plugin
@@ -2707,17 +2725,17 @@ NS_IMETHODIMP nsPluginInstanceOwner::Get
     // unable to show a caret correctly if we return the enclosing window. Therefore for
     // now we only return the enclosing window when there is an actual offset which
     // would otherwise cause coordinates to be offset incorrectly. (i.e.
     // if the enclosing window if offset from the document window)
     //
     // fixing both the caret and ability to interact issues for a windowless control in a non document aligned windw
     // does not seem to be possible without a change to the flash plugin
     
-    nsIWidget* win = mOwner->GetWindow();
+    nsIWidget* win = mObjectFrame->GetWindow();
     if (win) {
       nsIView *view = nsIView::GetViewFor(win);
       NS_ASSERTION(view, "No view for widget");
       nsPoint offset = view->GetOffsetTo(nsnull);
       
       if (offset.x || offset.y) {
         // in the case the two windows are offset from eachother, we do go ahead and return the correct enclosing window
         // so that mouse co-ordinates are not messed up.
@@ -2735,32 +2753,42 @@ NS_IMETHODIMP nsPluginInstanceOwner::Get
     *pvalue = (void*)widget->GetNativeData(NS_NATIVE_WINDOW);
   } else {
     NS_ASSERTION(widget, "couldn't get doc's widget in getting doc's window handle");
   }
 
   return rv;
 #elif defined(MOZ_WIDGET_GTK2)
   // X11 window managers want the toplevel window for WM_TRANSIENT_FOR.
-  nsIWidget* win = mOwner->GetWindow();
+  nsIWidget* win = mObjectFrame->GetWindow();
   if (!win)
     return NS_ERROR_FAILURE;
   GdkWindow* gdkWindow = static_cast<GdkWindow*>(win->GetNativeData(NS_NATIVE_WINDOW));
   if (!gdkWindow)
     return NS_ERROR_FAILURE;
   gdkWindow = gdk_window_get_toplevel(gdkWindow);
 #ifdef MOZ_X11
   *static_cast<Window*>(value) = GDK_WINDOW_XID(gdkWindow);
 #endif
   return NS_OK;
 #else
   return NS_ERROR_NOT_IMPLEMENTED;
 #endif
 }
 
+NS_IMETHODIMP nsPluginInstanceOwner::SetEventModel(PRInt32 eventModel)
+{
+#ifdef XP_MACOSX
+  mEventModel = static_cast<NPEventModel>(eventModel);
+  return NS_OK;
+#else
+  return NS_ERROR_NOT_IMPLEMENTED;
+#endif
+}
+
 NPError nsPluginInstanceOwner::ShowNativeContextMenu(NPMenu* menu, void* event)
 {
   if (!menu || !event)
     return NPERR_GENERIC_ERROR;
 
 #ifdef XP_MACOSX
   if (GetEventModel() != NPEventModelCocoa)
     return NPERR_INCOMPATIBLE_VERSION_ERROR;
@@ -2886,17 +2914,17 @@ NS_IMETHODIMP nsPluginInstanceOwner::Get
   return NS_ERROR_FAILURE;
 }
   
 NS_IMETHODIMP nsPluginInstanceOwner::GetDocumentBase(const char* *result)
 {
   NS_ENSURE_ARG_POINTER(result);
   nsresult rv = NS_OK;
   if (mDocumentBase.IsEmpty()) {
-    if (!mOwner) {
+    if (!mObjectFrame) {
       *result = nsnull;
       return NS_ERROR_FAILURE;
     }
 
     nsIDocument* doc = mContent->GetOwnerDoc();
     NS_ASSERTION(doc, "Must have an owner doc");
     rv = doc->GetBaseURI()->GetSpec(mDocumentBase);
   }
@@ -3078,17 +3106,17 @@ NS_IMETHODIMP nsPluginInstanceOwner::Get
     *result = 0;
 
   return rv;
 }
 
 NS_IMETHODIMP nsPluginInstanceOwner::GetUniqueID(PRUint32 *result)
 {
   NS_ENSURE_ARG_POINTER(result);
-  *result = NS_PTR_TO_INT32(mOwner);
+  *result = NS_PTR_TO_INT32(mObjectFrame);
   return NS_OK;
 }
 
 // Cache the attributes and/or parameters of our tag into a single set
 // of arrays to be compatible with 4.x. The attributes go first,
 // followed by a PARAM/null and then any PARAM tags. Also, hold the
 // cached array around for the duration of the life of the instance
 // because 4.x did. See bug 111008.
@@ -3097,17 +3125,17 @@ nsresult nsPluginInstanceOwner::EnsureCa
 {
   if (mCachedAttrParamValues)
     return NS_OK;
 
   NS_PRECONDITION(((mNumCachedAttrs + mNumCachedParams) == 0) &&
                   !mCachedAttrParamNames,
                   "re-cache of attrs/params not implemented! use the DOM "
                   "node directy instead");
-  NS_ENSURE_TRUE(mOwner, NS_ERROR_NULL_POINTER);
+  NS_ENSURE_TRUE(mObjectFrame, NS_ERROR_NULL_POINTER);
 
   // first, we need to find out how much we need to allocate for our
   // arrays count up attributes
   mNumCachedAttrs = 0;
 
   PRUint32 cattrs = mContent->GetAttrCount();
 
   if (cattrs < 0x0000FFFF) {
@@ -3191,17 +3219,17 @@ nsresult nsPluginInstanceOwner::EnsureCa
             }
           }
         }
       }
     }
   }
 
   // We're done with DOM method calls now; make sure we still have a frame.
-  NS_ENSURE_TRUE(mOwner, NS_ERROR_OUT_OF_MEMORY);
+  NS_ENSURE_TRUE(mObjectFrame, NS_ERROR_OUT_OF_MEMORY);
 
   PRUint32 cparams = ourParams.Count(); // unsigned 32 bits to unsigned 16 bits conversion
   if (cparams < 0x0000FFFF)
     mNumCachedParams = static_cast<PRUint16>(cparams);
   else 
     mNumCachedParams = 0xFFFF;
 
   // Some plugins were never written to understand the "data" attribute of the OBJECT tag.
@@ -3349,27 +3377,17 @@ NPDrawingModel nsPluginInstanceOwner::Ge
     return drawingModel;
 
   mInstance->GetDrawingModel((PRInt32*)&drawingModel);
   return drawingModel;
 }
 
 NPEventModel nsPluginInstanceOwner::GetEventModel()
 {
-#ifndef NP_NO_QUICKDRAW
-  NPEventModel eventModel = NPEventModelCarbon;
-#else
-  NPEventModel eventModel = NPEventModelCocoa;
-#endif
-
-  if (!mInstance)
-    return eventModel;
-
-  mInstance->GetEventModel((PRInt32*)&eventModel);
-  return eventModel;
+  return mEventModel;
 }
 
 void* nsPluginInstanceOwner::GetPluginPortCopy()
 {
 #ifndef NP_NO_QUICKDRAW
   if (GetDrawingModel() == NPDrawingModelQuickDraw)
     return &mQDPluginPortCopy;
 #endif
@@ -3405,23 +3423,27 @@ void* nsPluginInstanceOwner::SetPluginPo
     NP_Port* windowQDPort = static_cast<NP_Port*>(mPluginWindow->window);
     if (windowQDPort->port != mQDPluginPortCopy.port) {
       mQDPluginPortCopy.port = windowQDPort->port;
       mPluginPortChanged = PR_TRUE;
     }
   } else if (drawingModel == NPDrawingModelCoreGraphics)
 #endif
   {
-    NP_CGContext* windowCGPort = static_cast<NP_CGContext*>(mPluginWindow->window);
-    if ((windowCGPort->context != mCGPluginPortCopy.context) ||
-        (windowCGPort->window != mCGPluginPortCopy.window)) {
-      mCGPluginPortCopy.context = windowCGPort->context;
-      mCGPluginPortCopy.window = windowCGPort->window;
-      mPluginPortChanged = PR_TRUE;
+#ifndef NP_NO_CARBON
+    if (GetEventModel() == NPEventModelCarbon) {
+      NP_CGContext* windowCGPort = static_cast<NP_CGContext*>(mPluginWindow->window);
+      if ((windowCGPort->context != mCGPluginPortCopy.context) ||
+          (windowCGPort->window != mCGPluginPortCopy.window)) {
+        mCGPluginPortCopy.context = windowCGPort->context;
+        mCGPluginPortCopy.window = windowCGPort->window;
+        mPluginPortChanged = PR_TRUE;
+      }
     }
+#endif
   }
 
   return mPluginWindow->window;
 }
 
 void nsPluginInstanceOwner::BeginCGPaint()
 {
   ++mInCGPaintLevel;
@@ -3582,17 +3604,17 @@ nsresult nsPluginInstanceOwner::KeyPress
 
   // KeyPress events are really synthesized keyDown events.
   // Here we check the native message of the event so that
   // we won't send the plugin two keyDown events.
   nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(aKeyEvent));
   if (privateEvent) {
     nsEvent *theEvent = privateEvent->GetInternalNSEvent();
     const nsGUIEvent *guiEvent = (nsGUIEvent*)theEvent;
-    const EventRecord *ev = (EventRecord*)(guiEvent->nativeMsg); 
+    const EventRecord *ev = (EventRecord*)(guiEvent->pluginEvent); 
     if (guiEvent &&
         guiEvent->message == NS_KEY_PRESS &&
         ev &&
         ev->what == keyDown)
       return aKeyEvent->PreventDefault(); // consume event
   }
 
   // Nasty hack to avoid recursive event dispatching with Java. Java can
@@ -3689,17 +3711,17 @@ nsPluginInstanceOwner::MouseDown(nsIDOME
 #if !defined(XP_MACOSX) && !defined(MOZ_COMPOSITED_PLUGINS)
   if (!mPluginWindow || (mPluginWindow->type == NPWindowTypeWindow))
     return aMouseEvent->PreventDefault(); // consume event
   // continue only for cases without child window
 #endif
 
   // if the plugin is windowless, we need to set focus ourselves
   // otherwise, we might not get key events
-  if (mOwner && mPluginWindow &&
+  if (mObjectFrame && mPluginWindow &&
       mPluginWindow->type == NPWindowTypeDrawable) {
     
     nsIFocusManager* fm = nsFocusManager::GetFocusManager();
     if (fm) {
       nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(mContent);
       fm->SetFocus(elem, 0);
     }
   }
@@ -3857,17 +3879,17 @@ loop:
 }
 #endif
 
 #ifdef MOZ_COMPOSITED_PLUGINS
 nsEventStatus nsPluginInstanceOwner::ProcessEventX11Composited(const nsGUIEvent& anEvent)
 {
   //printf("nsGUIEvent.message: %d\n", anEvent.message);
   nsEventStatus rv = nsEventStatus_eIgnore;
-  if (!mInstance || !mOwner)   // if mInstance is null, we shouldn't be here
+  if (!mInstance || !mObjectFrame)   // if mInstance is null, we shouldn't be here
     return rv;
 
   // this code supports windowless plugins
   nsIWidget* widget = anEvent.widget;
   XEvent pluginEvent;
   pluginEvent.type = 0;
 
   switch(anEvent.eventStructType)
@@ -3878,20 +3900,20 @@ nsEventStatus nsPluginInstanceOwner::Pro
           {
           case NS_MOUSE_CLICK:
           case NS_MOUSE_DOUBLECLICK:
             // Button up/down events sent instead.
             return rv;
           }
 
         // Get reference point relative to plugin origin.
-        const nsPresContext* presContext = mOwner->PresContext();
+        const nsPresContext* presContext = mObjectFrame->PresContext();
         nsPoint appPoint =
-          nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mOwner) -
-          mOwner->GetUsedBorderAndPadding().TopLeft();
+          nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mObjectFrame) -
+          mObjectFrame->GetUsedBorderAndPadding().TopLeft();
         nsIntPoint pluginPoint(presContext->AppUnitsToDevPixels(appPoint.x),
                                presContext->AppUnitsToDevPixels(appPoint.y));
         mLastPoint = pluginPoint;
         const nsMouseEvent& mouseEvent =
           static_cast<const nsMouseEvent&>(anEvent);
         // Get reference point relative to screen:
         nsIntPoint rootPoint(-1,-1);
         if (widget)
@@ -3997,37 +4019,37 @@ nsEventStatus nsPluginInstanceOwner::Pro
             break;
           }
       }
       break;
 
    //XXX case NS_MOUSE_SCROLL_EVENT: not received.
  
    case NS_KEY_EVENT:
-      if (anEvent.nativeMsg)
+      if (anEvent.pluginEvent)
         {
           XKeyEvent &event = pluginEvent.xkey;
 #ifdef MOZ_WIDGET_GTK2
           event.root = GDK_ROOT_WINDOW();
           event.time = anEvent.time;
           const GdkEventKey* gdkEvent =
-            static_cast<const GdkEventKey*>(anEvent.nativeMsg);
+            static_cast<const GdkEventKey*>(anEvent.pluginEvent);
           event.keycode = gdkEvent->hardware_keycode;
           event.state = gdkEvent->state;
           switch (anEvent.message)
             {
             case NS_KEY_DOWN:
               event.type = XKeyPress;
               break;
             case NS_KEY_UP:
               event.type = KeyRelease;
               break;
             }
 #endif
-          // Information that could be obtained from nativeMsg but we may not
+          // Information that could be obtained from pluginEvent but we may not
           // want to promise to provide:
           event.subwindow = None;
           event.x = 0;
           event.y = 0;
           event.x_root = -1;
           event.y_root = -1;
           event.same_screen = False;
           XEvent be;
@@ -4108,17 +4130,17 @@ nsEventStatus nsPluginInstanceOwner::Pro
 
 #ifdef MOZ_COMPOSITED_PLUGINS
   if (mPluginWindow && (mPluginWindow->type != NPWindowTypeDrawable))
     return ProcessEventX11Composited(anEvent);
 #endif
 
   nsEventStatus rv = nsEventStatus_eIgnore;
 
-  if (!mInstance || !mOwner)   // if mInstance is null, we shouldn't be here
+  if (!mInstance || !mObjectFrame)   // if mInstance is null, we shouldn't be here
     return nsEventStatus_eIgnore;
 
 #ifdef XP_MACOSX
   if (mWidget) {
     // we never care about synthesized mouse enter
     if (anEvent.message == NS_MOUSE_ENTER_SYNTH)
       return nsEventStatus_eIgnore;
 
@@ -4127,22 +4149,22 @@ nsEventStatus nsPluginInstanceOwner::Pro
       NPEventModel eventModel = GetEventModel();
 
       // If we have to synthesize an event we'll use one of these.
 #ifndef NP_NO_CARBON
       EventRecord synthCarbonEvent;
 #endif
       NPCocoaEvent synthCocoaEvent;
 
-      void* event = anEvent.nativeMsg;
+      void* event = anEvent.pluginEvent;
 
       if (!event) {
-        nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mOwner)
-          - mOwner->GetUsedBorderAndPadding().TopLeft();
-        nsPresContext* presContext = mOwner->PresContext();
+        nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mObjectFrame)
+          - mObjectFrame->GetUsedBorderAndPadding().TopLeft();
+        nsPresContext* presContext = mObjectFrame->PresContext();
         nsIntPoint ptPx(presContext->AppUnitsToDevPixels(pt.x),
                         presContext->AppUnitsToDevPixels(pt.y));
 
 #ifndef NP_NO_CARBON
         if (eventModel == NPEventModelCarbon) {
           Point carbonPt = { ptPx.y + mPluginWindow->y, ptPx.x + mPluginWindow->x };
 
           event = &synthCarbonEvent;
@@ -4233,19 +4255,19 @@ nsEventStatus nsPluginInstanceOwner::Pro
 
       pluginWidget->EndDrawPlugin();
     }
   }
 #endif
 
 #ifdef XP_WIN
   // this code supports windowless plugins
-  NPEvent *pPluginEvent = (NPEvent*)anEvent.nativeMsg;
+  NPEvent *pPluginEvent = (NPEvent*)anEvent.pluginEvent;
   // we can get synthetic events from the nsEventStateManager... these
-  // have no nativeMsg
+  // have no pluginEvent
   NPEvent pluginEvent;
   if (anEvent.eventStructType == NS_MOUSE_EVENT) {
     if (!pPluginEvent) {
       // XXX Should extend this list to synthesize events for more event
       // types
       pluginEvent.event = 0;
       const nsMouseEvent* mouseEvent = static_cast<const nsMouseEvent*>(&anEvent);
       switch (anEvent.message) {
@@ -4293,22 +4315,22 @@ nsEventStatus nsPluginInstanceOwner::Pro
       NS_ASSERTION(anEvent.message == NS_MOUSE_BUTTON_DOWN ||
                    anEvent.message == NS_MOUSE_BUTTON_UP ||
                    anEvent.message == NS_MOUSE_DOUBLECLICK ||
                    anEvent.message == NS_MOUSE_ENTER_SYNTH ||
                    anEvent.message == NS_MOUSE_EXIT_SYNTH ||
                    anEvent.message == NS_MOUSE_MOVE,
                    "Incorrect event type for coordinate translation");
       nsPoint pt =
-        nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mOwner) -
-        mOwner->GetUsedBorderAndPadding().TopLeft();
-      nsPresContext* presContext = mOwner->PresContext();
+        nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mObjectFrame) -
+        mObjectFrame->GetUsedBorderAndPadding().TopLeft();
+      nsPresContext* presContext = mObjectFrame->PresContext();
       nsIntPoint ptPx(presContext->AppUnitsToDevPixels(pt.x),
                       presContext->AppUnitsToDevPixels(pt.y));
-      nsIntPoint widgetPtPx = ptPx + mOwner->GetWindowOriginInPixels(PR_TRUE);
+      nsIntPoint widgetPtPx = ptPx + mObjectFrame->GetWindowOriginInPixels(PR_TRUE);
       pPluginEvent->lParam = MAKELPARAM(widgetPtPx.x, widgetPtPx.y);
     }
   }
   else if (!pPluginEvent) {
     switch (anEvent.message) {
       case NS_FOCUS_CONTENT:
         pluginEvent.event = WM_SETFOCUS;
         pluginEvent.wParam = 0;
@@ -4346,20 +4368,20 @@ nsEventStatus nsPluginInstanceOwner::Pro
           {
           case NS_MOUSE_CLICK:
           case NS_MOUSE_DOUBLECLICK:
             // Button up/down events sent instead.
             return rv;
           }
 
         // Get reference point relative to plugin origin.
-        const nsPresContext* presContext = mOwner->PresContext();
+        const nsPresContext* presContext = mObjectFrame->PresContext();
         nsPoint appPoint =
-          nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mOwner) -
-          mOwner->GetUsedBorderAndPadding().TopLeft();
+          nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mObjectFrame) -
+          mObjectFrame->GetUsedBorderAndPadding().TopLeft();
         nsIntPoint pluginPoint(presContext->AppUnitsToDevPixels(appPoint.x),
                                presContext->AppUnitsToDevPixels(appPoint.y));
         const nsMouseEvent& mouseEvent =
           static_cast<const nsMouseEvent&>(anEvent);
         // Get reference point relative to screen:
         nsIntPoint rootPoint(-1,-1);
         if (widget)
           rootPoint = anEvent.refPoint + widget->WidgetToScreenOffset();
@@ -4441,37 +4463,37 @@ nsEventStatus nsPluginInstanceOwner::Pro
             break;
           }
       }
       break;
 
    //XXX case NS_MOUSE_SCROLL_EVENT: not received.
  
    case NS_KEY_EVENT:
-      if (anEvent.nativeMsg)
+      if (anEvent.pluginEvent)
         {
           XKeyEvent &event = pluginEvent.xkey;
 #ifdef MOZ_WIDGET_GTK2
           event.root = GDK_ROOT_WINDOW();
           event.time = anEvent.time;
           const GdkEventKey* gdkEvent =
-            static_cast<const GdkEventKey*>(anEvent.nativeMsg);
+            static_cast<const GdkEventKey*>(anEvent.pluginEvent);
           event.keycode = gdkEvent->hardware_keycode;
           event.state = gdkEvent->state;
           switch (anEvent.message)
             {
             case NS_KEY_DOWN:
               event.type = XKeyPress;
               break;
             case NS_KEY_UP:
               event.type = KeyRelease;
               break;
             }
 #endif
-          // Information that could be obtained from nativeMsg but we may not
+          // Information that could be obtained from pluginEvent but we may not
           // want to promise to provide:
           event.subwindow = None;
           event.x = 0;
           event.y = 0;
           event.x_root = -1;
           event.y_root = -1;
           event.same_screen = False;
         }
@@ -4606,92 +4628,92 @@ nsPluginInstanceOwner::PrepareToStop(PRB
     // parent.
     mWidget->SetParent(nsnull);
 
     mDestroyWidget = PR_TRUE;
   }
 #endif
 
   // Unregister scroll position listener
-  nsIFrame* parentWithView = mOwner->GetAncestorWithView();
+  nsIFrame* parentWithView = mObjectFrame->GetAncestorWithView();
   nsIView* curView = parentWithView ? parentWithView->GetView() : nsnull;
   while (curView) {
     nsIScrollableView* scrollingView = curView->ToScrollableView();
     if (scrollingView)
       scrollingView->RemoveScrollPositionListener((nsIScrollPositionListener *)this);
     
     curView = curView->GetParent();
   }
 }
 
 // Paints are handled differently, so we just simulate an update event.
 
 #ifdef XP_MACOSX
-void nsPluginInstanceOwner::Paint(const gfxRect& aDirtyRect)
+void nsPluginInstanceOwner::Paint(const gfxRect& aDirtyRect, CGContextRef cgContext)
 {
-  if (!mInstance || !mOwner)
+  if (!mInstance || !mObjectFrame)
     return;
  
   nsCOMPtr<nsIPluginWidget> pluginWidget = do_QueryInterface(mWidget);
   if (pluginWidget && NS_SUCCEEDED(pluginWidget->StartDrawPlugin())) {
+#ifndef NP_NO_CARBON
     void* window = FixUpPluginWindow(ePluginPaintEnable);
-#ifndef NP_NO_CARBON
     if (GetEventModel() == NPEventModelCarbon && window) {
       EventRecord updateEvent;
       InitializeEventRecord(&updateEvent, nsnull);
       updateEvent.what = updateEvt;
       updateEvent.message = UInt32(window);
 
       PRBool eventHandled = PR_FALSE;
       mInstance->HandleEvent(&updateEvent, &eventHandled);
-    } else
+    } else if (GetEventModel() == NPEventModelCocoa)
 #endif
     {
       // The context given here is only valid during the HandleEvent call.
       NPCocoaEvent updateEvent;
       InitializeNPCocoaEvent(&updateEvent);
       updateEvent.type = NPCocoaEventDrawRect;
-      updateEvent.data.draw.context = mCGPluginPortCopy.context;
+      updateEvent.data.draw.context = cgContext;
       updateEvent.data.draw.x = aDirtyRect.X();
       updateEvent.data.draw.y = aDirtyRect.Y();
       updateEvent.data.draw.width = aDirtyRect.Width();
       updateEvent.data.draw.height = aDirtyRect.Height();
 
       PRBool eventHandled = PR_FALSE;
       mInstance->HandleEvent(&updateEvent, &eventHandled);
     }
     pluginWidget->EndDrawPlugin();
   }
 }
 #endif
 
 #ifdef XP_WIN
 void nsPluginInstanceOwner::Paint(const RECT& aDirty, HDC aDC)
 {
-  if (!mInstance || !mOwner)
+  if (!mInstance || !mObjectFrame)
     return;
 
   NPEvent pluginEvent;
   pluginEvent.event = WM_PAINT;
   pluginEvent.wParam = WPARAM(aDC);
   pluginEvent.lParam = LPARAM(&aDirty);
   PRBool eventHandled = PR_FALSE;
   mInstance->HandleEvent(&pluginEvent, &eventHandled);
 }
 #endif
 
 #ifdef XP_OS2
 void nsPluginInstanceOwner::Paint(const nsRect& aDirtyRect, HPS aHPS)
 {
-  if (!mInstance || !mOwner)
+  if (!mInstance || !mObjectFrame)
     return;
 
   NPWindow *window;
   GetWindow(window);
-  nsIntRect relDirtyRect = aDirtyRect.ToOutsidePixels(mOwner->PresContext()->AppUnitsPerDevPixel());
+  nsIntRect relDirtyRect = aDirtyRect.ToOutsidePixels(mObjectFrame->PresContext()->AppUnitsPerDevPixel());
 
   // we got dirty rectangle in relative window coordinates, but we
   // need it in absolute units and in the (left, top, right, bottom) form
   RECTL rectl;
   rectl.xLeft   = relDirtyRect.x + window->x;
   rectl.yBottom = relDirtyRect.y + window->y;
   rectl.xRight  = rectl.xLeft + relDirtyRect.width;
   rectl.yTop    = rectl.yBottom + relDirtyRect.height;
@@ -4705,17 +4727,17 @@ void nsPluginInstanceOwner::Paint(const 
 }
 #endif
 
 #if defined(MOZ_X11) || defined(MOZ_DFB)
 void nsPluginInstanceOwner::Paint(gfxContext* aContext,
                                   const gfxRect& aFrameRect,
                                   const gfxRect& aDirtyRect)
 {
-  if (!mInstance || !mOwner)
+  if (!mInstance || !mObjectFrame)
     return;
 
   // Align to device pixels where sensible
   // to provide crisper and faster drawing.
   gfxRect pluginRect = aFrameRect;
   if (aContext->UserToDevicePixelSnapped(pluginRect)) {
     pluginRect = aContext->DeviceToUser(pluginRect);
   }
@@ -5211,17 +5233,17 @@ nsresult nsPluginInstanceOwner::Init(nsP
                                      nsIContent*    aContent)
 {
   mLastEventloopNestingLevel = GetEventloopNestingLevel();
 
   PR_LOG(nsObjectFrameLM, PR_LOG_DEBUG,
          ("nsPluginInstanceOwner::Init() called on %p for frame %p\n", this,
           aFrame));
 
-  mOwner = aFrame;
+  mObjectFrame = aFrame;
   mContent = aContent;
 
   nsWeakFrame weakFrame(aFrame);
 
   // Some plugins require a specific sequence of shutdown and startup when
   // a page is reloaded. Shutdown happens usually when the last instance
   // is destroyed. Here we make sure the plugin instance in the old
   // document is destroyed before we try to create the new one.
@@ -5272,17 +5294,17 @@ nsresult nsPluginInstanceOwner::Init(nsP
     target->AddEventListener(NS_LITERAL_STRING("dragstart"), listener, PR_TRUE);
     target->AddEventListener(NS_LITERAL_STRING("draggesture"), listener, PR_TRUE);
     target->AddEventListener(NS_LITERAL_STRING("dragend"), listener, PR_TRUE);
   }
   
   // Register scroll position listener
   // We need to register a scroll pos listener on every scrollable
   // view up to the top
-  nsIFrame* parentWithView = mOwner->GetAncestorWithView();
+  nsIFrame* parentWithView = mObjectFrame->GetAncestorWithView();
   nsIView* curView = parentWithView ? parentWithView->GetView() : nsnull;
   while (curView) {
     nsIScrollableView* scrollingView = curView->ToScrollableView();
     if (scrollingView)
       scrollingView->AddScrollPositionListener((nsIScrollPositionListener *)this);
     
     curView = curView->GetParent();
   }
@@ -5323,44 +5345,44 @@ void nsPluginInstanceOwner::ReleasePlugi
 
 NS_IMETHODIMP nsPluginInstanceOwner::CreateWidget(void)
 {
   NS_ENSURE_TRUE(mPluginWindow, NS_ERROR_NULL_POINTER);
 
   nsIView   *view;
   nsresult  rv = NS_ERROR_FAILURE;
 
-  if (mOwner) {
+  if (mObjectFrame) {
     // Create view if necessary
 
-    view = mOwner->GetView();
+    view = mObjectFrame->GetView();
 
     if (!view || !mWidget) {
       PRBool windowless = PR_FALSE;
       mInstance->IsWindowless(&windowless);
 
       // always create widgets in Twips, not pixels
-      nsPresContext* context = mOwner->PresContext();
-      rv = mOwner->CreateWidget(context->DevPixelsToAppUnits(mPluginWindow->width),
-                                context->DevPixelsToAppUnits(mPluginWindow->height),
-                                windowless);
+      nsPresContext* context = mObjectFrame->PresContext();
+      rv = mObjectFrame->CreateWidget(context->DevPixelsToAppUnits(mPluginWindow->width),
+                                      context->DevPixelsToAppUnits(mPluginWindow->height),
+                                      windowless);
       if (NS_OK == rv) {
-        mWidget = mOwner->GetWidget();
+        mWidget = mObjectFrame->GetWidget();
 
         if (PR_TRUE == windowless) {
           mPluginWindow->type = NPWindowTypeDrawable;
 
           // this needs to be a HDC according to the spec, but I do
           // not see the right way to release it so let's postpone
           // passing HDC till paint event when it is really
           // needed. Change spec?
           mPluginWindow->window = nsnull;
 #ifdef MOZ_X11
           // Fill in the display field.
-          nsIWidget* win = mOwner->GetWindow();
+          nsIWidget* win = mObjectFrame->GetWindow();
           NPSetWindowCallbackStruct* ws_info = 
             static_cast<NPSetWindowCallbackStruct*>(mPluginWindow->ws_info);
           if (win) {
             ws_info->display =
               static_cast<Display*>(win->GetNativeData(NS_NATIVE_DISPLAY));
           }
 #ifdef MOZ_WIDGET_GTK2
           else {
@@ -5398,22 +5420,22 @@ NS_IMETHODIMP nsPluginInstanceOwner::Cre
 void nsPluginInstanceOwner::SetPluginHost(nsIPluginHost* aHost)
 {
   mPluginHost = aHost;
 }
 
 #ifdef MOZ_PLATFORM_HILDON
 PRBool nsPluginInstanceOwner::UpdateVisibility(PRBool aForce)
 {
-  if (!mPluginWindow || !mInstance || !mOwner)
+  if (!mPluginWindow || !mInstance || !mObjectFrame)
     return PR_FALSE;
 
   // first, check our view for CSS visibility style
   PRBool isVisible =
-    mOwner->GetView()->GetVisibility() == nsViewVisibility_kShow;
+    mObjectFrame->GetView()->GetVisibility() == nsViewVisibility_kShow;
 
   if (aForce || mWidgetVisible != isVisible) {
     PRBool handled;
     NPEvent pluginEvent;
     XVisibilityEvent& visibilityEvent = pluginEvent.xvisibility;
     visibilityEvent.type = VisibilityNotify;
     visibilityEvent.display = 0;
     visibilityEvent.state = isVisible ? VisibilityUnobscured : VisibilityFullyObscured;
@@ -5425,28 +5447,25 @@ PRBool nsPluginInstanceOwner::UpdateVisi
 }
 #endif
 
   // Mac specific code to fix up the port location and clipping region
 #ifdef XP_MACOSX
 
 void* nsPluginInstanceOwner::FixUpPluginWindow(PRInt32 inPaintState)
 {
-  if (!mWidget || !mPluginWindow || !mInstance || !mOwner)
+  if (!mWidget || !mPluginWindow || !mInstance || !mObjectFrame)
     return nsnull;
 
   NPDrawingModel drawingModel = GetDrawingModel();
-  NPEventModel eventModel = GetEventModel();
 
   nsCOMPtr<nsIPluginWidget> pluginWidget = do_QueryInterface(mWidget);
   if (!pluginWidget)
     return nsnull;
 
-  pluginWidget->SetPluginEventModel(eventModel);
-
   // If we've already set up a CGContext in nsObjectFrame::PaintPlugin(), we
   // don't want calls to SetPluginPortAndDetectChange() to step on our work.
   void* pluginPort = nsnull;
   if (mInCGPaintLevel > 0) {
     pluginPort = mPluginWindow->window;
   } else {
     pluginPort = SetPluginPortAndDetectChange();
   }
@@ -5475,21 +5494,29 @@ void* nsPluginInstanceOwner::FixUpPlugin
     // but we can't. Since we have only nsIWidget and we can't
     // use its native widget (an obj-c object) we have to go
     // from the widget's screen coordinates to its window coords
     // instead of straight to window coords.
     nsIntPoint geckoScreenCoords = mWidget->WidgetToScreenOffset();
 
     nsRect windowRect;
 #ifndef NP_NO_CARBON
-    if (eventModel == NPEventModelCarbon)
+    if (GetEventModel() == NPEventModelCarbon)
       NS_NPAPI_CarbonWindowFrame(static_cast<WindowRef>(static_cast<NP_CGContext*>(pluginPort)->window), windowRect);
     else
 #endif
-      NS_NPAPI_CocoaWindowFrame(static_cast<NP_CGContext*>(pluginPort)->window, windowRect);
+    {
+      nsIWidget* widget = mObjectFrame->GetWindow();
+      if (!widget)
+        return nsnull;
+      void* nativeData = widget->GetNativeData(NS_NATIVE_WINDOW);
+      if (!nativeData)
+        return nsnull;
+      NS_NPAPI_CocoaWindowFrame(nativeData, windowRect);
+    }
 
     mPluginWindow->x = geckoScreenCoords.x - windowRect.x;
     mPluginWindow->y = geckoScreenCoords.y - windowRect.y;
   }
 
   NPRect oldClipRect = mPluginWindow->clipRect;
   
   // fix up the clipping region
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bidi/525740-1-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+ <head>
+  <style type="text/css">
+   div:first-letter { float: right; color: lime; }
+  </style>
+ </head>
+ <body dir="rtl">
+  <div>ab &#x06CD; c</div>
+ </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bidi/525740-1.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+ <head>
+  <style type="text/css">
+   div:first-letter { float: right; color: lime; }
+  </style>
+ </head>
+ <body dir="rtl">
+  <div><span>ab &#x06CD; c</span></div>
+ </body>
+</html>
--- a/layout/reftests/bidi/reftest.list
+++ b/layout/reftests/bidi/reftest.list
@@ -38,8 +38,9 @@ random-if(MOZ_WIDGET_TOOLKIT=="gtk2") ==
 == 425338-1a.html 425338-1-ref.html
 == 425338-1b.html 425338-1-ref.html
 == 489517-1.html 489517-1-ref.html
 == 489887-1.html 489887-1-ref.html
 == 492231-1.html 492231-1-ref.html
 == 496006-1.html 496006-1-ref.html
 == 503269-1.html 503269-1-ref.html
 == 503957-1.html 503957-1-ref.html
+== 525740-1.html 525740-1-ref.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/border-radius/border-reduce-height-ref.html
@@ -0,0 +1,20 @@
+<html>
+  <head>
+    <style>
+      div { -moz-box-sizing: border-box;
+            box-sizing: border-box;
+            width: 60px;
+            height: 20px;
+            border: 2px solid black;
+            background: green;
+            position: absolute;
+            top: 12px;
+            left: 12px;
+            -moz-border-radius: 4px 16px 4px 16px;
+          }
+    </style>
+  </head>
+  <body>
+    <div></div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/border-radius/border-reduce-height.html
@@ -0,0 +1,20 @@
+<html>
+  <head>
+    <style>
+      div { -moz-box-sizing: border-box;
+            box-sizing: border-box;
+            width: 60px;
+            height: 20px;
+            border: 2px solid black;
+            background: green;
+            position: absolute;
+            top: 12px;
+            left: 12px;
+            -moz-border-radius: 5px 20px 5px 20px;
+          }
+    </style>
+  </head>
+  <body>
+    <div></div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/border-radius/border-value-interpret-ref.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<html>
+  <head>
+    <title>Test different types of values with border radius</title>
+    <!-- This bug will break when bug 451134 is fixed -->
+    <style>
+      div { width: 200px;
+            height: 200px;
+            background: green;
+            border: 10px dashed black;
+            -moz-border-radius-topleft: 2em 10px;
+            -moz-border-radius-topright: 10px 0.5em;
+            -moz-border-radius-bottomright: 3em 10px;
+            -moz-border-radius-bottomleft: 10px 0.5em;
+          }
+
+</style>
+</head>
+<body>
+  <div></div>
+</body></html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/border-radius/border-value-interpret.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<html>
+  <head>
+    <title>Test different types of values with border radius</title>
+    <style>
+      div { width: 200px;
+            height: 200px;
+            background: green;
+            border: 10px dashed black}
+
+      /* Test interpreted values */
+      #test1 { -moz-border-radius: 2em 10px 3em / 10px 0.5em }
+
+</style>
+</head>
+<body>
+  <div id="test1"></div>
+</body></html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/border-radius/clipping-1-ref.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<html><head>
+<title>Border clipping</title>
+<style>
+.div1 { width: 50px; height: 50px;
+      border: 10px solid black; 
+      -moz-border-radius: 20px;
+      position: fixed;
+      left: 50px;
+      top: 50px;
+}
+
+.div2 {
+      width: 40px; height: 40px;
+      border: 10px solid black;
+      background: black; 
+      -moz-border-radius: 10px;
+      position: fixed;
+      left: 55px;
+      top: 55px;
+}
+
+</style>
+</head>
+<body>
+  <div class="div1"/>
+  <div class="div2"/>
+</body></html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/border-radius/clipping-1.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<html><head>
+<title>Border clipping</title>
+<style>
+.div1 { width: 50px; height: 50px;
+      border: 10px solid black; 
+      -moz-border-radius: 20px;
+      position: absolute;
+      background: black;
+      left: 50px;
+      top: 50px;
+      -moz-background-clip: padding;
+}
+
+</style>
+</head>
+<body>
+  <div class="div1"></div>
+</body></html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/border-radius/clipping-2.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<html><head>
+<title>Border clipping</title>
+<style>
+.div1 { width: 50px; height: 50px;
+      border: 4px dotted black; 
+      -moz-border-radius: 10px;
+      position: fixed;
+      background: red;
+      left: 50px;
+      top: 50px;
+      -moz-background-clip: padding;
+}
+
+.div2 { width: 50px; height: 50px;
+      border: 4px dotted black; 
+      -moz-border-radius: 10px;
+      position: fixed;
+      background: red;
+      left: 50px;
+      top: 140px;
+      -moz-background-clip: border;
+}
+
+</style>
+</head>
+<body>
+  <div class="div1"/>
+  <div class="div2"/>
+</body></html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/border-radius/clipping-3-ref.xhtml
@@ -0,0 +1,19 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<body style="margin: 0">
+  <div class="div1"/>
+  
+ <svg width="200px" height="200px" version="1.1"
+      xmlns="http://www.w3.org/2000/svg">
+      
+      <rect style="fill: blue; stroke: none"
+            width="70" height="70"
+   	 x="50" y="50"/>
+
+   <rect style="fill: red; stroke: none"
+         width="70" height="70"
+	 x="80" y="80"
+	 rx="10" ry="10"/>
+
+ </svg>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/border-radius/clipping-3.html
@@ -0,0 +1,27 @@
+<!doctype html>
+<html><head>
+<title>Border clipping</title>
+<style>
+.div1 { width: 50px; height: 50px;
+      border: 10px solid blue; 
+      position: fixed;
+      background: blue;
+      left: 50px;
+      top: 50px;
+}
+
+.div2 { width: 50px; height: 50px;
+      border: 10px solid red; 
+      position: fixed;
+      background: red;
+      left: 80px;
+      top: 80px;
+      -moz-border-radius: 10px;
+}
+
+</style>
+</head>
+<body>
+  <div class="div1"/>
+  <div class="div2"/>
+</body></html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/border-radius/corner-1-ref.svg
@@ -0,0 +1,13 @@
+<svg width="200px" height="200px" version="1.1"
+    xmlns="http://www.w3.org/2000/svg">
+  <rect style="fill: black; stroke: none"
+       width="70" height="50"
+  x="50" y="50"
+  rx="10" ry="10"/>
+
+  <rect style="fill: black; stroke: none"
+       width="70" height="40"
+  x="50" y="80"
+  rx="6" ry="6"/>
+</svg>
+
new file mode 100644
--- /dev/null
+++ b/layout/reftests/border-radius/corner-1.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<html><head>
+<title>Corners different</title>
+<style>
+.div1 { width: 50px; height: 50px;
+      border: 10px solid black; 
+      -moz-border-radius: 10px 10px 6px 6px;
+      position: absolute;
+      background: black;
+      left: 50px;
+      top: 50px;
+}
+
+</style>
+</head>
+<body>
+  <div class="div1"></div>
+</body></html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/border-radius/corner-2-ref.svg
@@ -0,0 +1,12 @@
+<svg width="200px" height="200px" version="1.1"
+    xmlns="http://www.w3.org/2000/svg">
+  <rect style="fill: black; stroke: none"
+       width="50" height="70"
+  x="50" y="50"
+  rx="10" ry="10"/>
+
+  <rect style="fill: black; stroke: none"
+       width="50" height="70"
+  x="70" y="50"
+  rx="6" ry="6"/>
+</svg>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/border-radius/corner-2.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<html><head>
+<title>Corners different</title>
+<style>
+.div1 { width: 50px; height: 50px;
+      border: 10px solid black; 
+      -moz-border-radius: 10px 6px 6px 10px;
+      position: absolute;
+      background: black;
+      left: 50px;
+      top: 50px;
+}
+
+</style>
+</head>
+<body>
+  <div class="div1"></div>
+</body></html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/border-radius/curved-borders-all-styles.html
@@ -0,0 +1,29 @@
+<html>
+
+<head>
+ <title>testcase for bug #382721</title>
+<style>
+ div {
+	background: beige;
+	margin: 1ex;
+	padding: 1ex;
+	-moz-border-radius: 3ex;
+	}
+</style>
+<script>
+ function ini() {
+  var s,i,d;
+  s=['none','hidden','dotted','dashed','solid',
+     'double','groove','ridge','inset','outset'];
+  for (i=0; i<s.length; i++) {
+   d=document.createElement('div');
+   d.style.border=d.innerHTML=s[i];
+   document.body.appendChild(d);
+ }}
+</script>
+</head>
+
+<body onload="ini()"></body>
+
+</html>
+
new file mode 100644
--- /dev/null
+++ b/layout/reftests/border-radius/curved-stripe-border-ref.svg
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<svg xmlns="http://www.w3.org/2000/svg"
+     width="200px" height="200px">
+<title>Curved stripe border (SVG)</title>
+<style type="text/css">
+path { stroke: none; }
+</style>
+<path
+ d="M20,60 a60,40 0 0,1 60,-40
+    h60 a60,40 0 0,1 60,40
+    v100 a60,40 0 0,1 -60,40
+    h-60 a60,40 0 0,1 -60,-40 z
+    M30,160 a50,30 0 0,0 50,30
+    h60 a50,30 0 0,0 50,-30
+    v-100 a50,30 0 0,0 -50,-30
+    h-60 a50,30 0 0,0 -50,30 z"/>
+<path
+ d="M40,60 a40,20 0 0,1 40,-20
+    h60 a40,20 0 0,1 40,20
+    v100 a40,20 0 0,1 -40,20
+    h-60 a40,20 0 0,1 -40,-20 z
+    M50,160 a30,10 0 0,0 30,10
+    h60 a30,10 0 0,0 30,-10
+    v-100 a30,10 0 0,0 -30,-10
+    h-60 a30,10 0 0,0 -30,10 z"/>
+</svg>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/border-radius/curved-stripe-border.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<html><head>
+<title>Curved stripe border (HTML)</title>
+<style>
+body { margin: 0 }
+div {
+  -moz-box-sizing: border-box;
+  width: 180px;
+  height: 180px;
+  border: 30px double black;
+  -moz-border-radius: 60px / 40px;
+  margin: 20px;
+}
+</style>
+</head><body>
+<div></div>
+</body></html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/border-radius/inherit-1-ref.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<html><head>
+<title>Border-radius inheritance</title>
+<style>
+.div1 { width: 100px; height: 100px;
+      border: 10px solid black; 
+      -moz-border-radius: 10px;
+      left: 50px;
+      top: 50px;
+}
+
+div > div {
+  width: 40px; height: 40px;
+  border: 10px solid black;
+  position: absolute;
+  -moz-border-radius: 0px;
+  left: 40px;
+  top: 40px;
+}
+
+</style>
+</head>
+<body>
+  <div class="div1"><div></div></div>
+</body></html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/border-radius/inherit-1.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<html><head>
+<title>Border-radius inheritance</title>
+<style>
+.div1 { width: 100px; height: 100px;
+      border: 10px solid black; 
+      -moz-border-radius: 10px;
+      left: 50px;
+      top: 50px;
+}
+
+div > div {
+  width: 40px; height: 40px;
+  border: 10px solid black;
+  position: absolute;
+  left: 40px;
+  top: 40px;
+}
+
+</style>
+</head>
+<body>
+  <div class="div1"><div></div></div>
+</body></html>
--- a/layout/reftests/border-radius/reftest.list
+++ b/layout/reftests/border-radius/reftest.list
@@ -8,14 +8,38 @@
 != border-circle.html border-ellips.html
 
 != outline-square.html about:blank
 != outline-circle.html about:blank
 != outline-ellips.html about:blank
 != outline-square.html outline-circle.html
 != outline-square.html outline-ellips.html
 != outline-circle.html outline-ellips.html
+== border-value-interpret.html border-value-interpret-ref.html
+!= curved-borders-all-styles.html about:blank # no way to generate reference for dotted/dashed/inset/outset
+# ridge/groove borders
 
 # more serious tests, using SVG reference
 == border-circle-2.html border-circle-2-ref.xhtml
+fails == curved-stripe-border.html curved-stripe-border-ref.svg # bug 459945
+
+# Corners
+== corner-1.html corner-1-ref.svg # bottom corners different radius than top corners
+random == corner-2.html corner-2-ref.svg # right corners different radius than left corners; see bug 500804
+
+# Test that radii too long are reduced
+== border-reduce-height.html border-reduce-height-ref.html
+
+# Tests for border clipping
+fails == clipping-1.html clipping-1-ref.html # background color should completely fill box; bug 466572
+!= clipping-2.html about:blank # background color clipped to inner/outer border, can't get
+# great tests for this due to antialiasing problems described in bug 466572
+== clipping-3.html clipping-3-ref.xhtml # edge of border-radius clips an underlying object's background
+
+# Inheritance
+== inherit-1.html inherit-1-ref.html # border-radius shouldn't inherit
+
+# Table elements
+== table-collapse-1.html table-collapse-1-ref.html # border-radius is ignored on internal table elements
+# when border-collapse: collapse
 
 == invalidate-1a.html invalidate-1-ref.html
 == invalidate-1b.html invalidate-1-ref.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/border-radius/table-collapse-1-ref.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<html><head>
+<title>Table border collapse</title>
+<style>
+table {
+  border: 2px solid black;
+  border-collapse: collapse;
+}
+
+td {
+  border: 2px solid black;
+  width: 50px;
+  height: 50px;
+}
+
+</style>
+</head>
+<body>
+  <table>
+    <tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>
+    <tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>
+    <tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>
+  </table>
+</body></html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/border-radius/table-collapse-1.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<html><head>
+<title>Table border collapse</title>
+<style>
+table {
+  border: 2px solid black;
+  border-collapse: collapse;
+}
+
+td {
+  border: 2px solid black;
+  width: 50px;
+  height: 50px;
+  -moz-border-radius: 4px;
+}
+
+</style>
+</head>
+<body>
+  <table>
+    <tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>
+    <tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>
+    <tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>
+  </table>
+</body></html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/296361-1.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait"><head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+
+<style>
+
+table { border-right: solid 16px gold; }
+
+a:hover { color: red; }
+
+</style>
+   <script>
+   function doTest() {
+      var s1 = document.getElementById("target");
+      s1.style.color="red" 
+      document.documentElement.removeAttribute('class');
+   }
+   document.addEventListener("MozReftestInvalidate", doTest, false);
+    </script>
+
+</head><body>
+<table cellpadding="4" rules="rows">
+
+ <tbody><tr>
+  <td><a href="#" id ="target"> move mouse over this text </a></td>
+  <td></td>
+ </tr>
+
+</tbody></table>
+</body></html>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/296361-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE HTML>
+<html><head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+
+<style>
+
+table { border-right: solid 16px gold; }
+
+a{ color: red; }
+
+</style>
+  
+
+</head><body>
+<table cellpadding="4" rules="rows">
+
+ <tbody><tr>
+  <td><a href="#" id ="target"> move mouse over this text </a></td>
+  <td></td>
+ </tr>
+
+</tbody></table>
+</body></html>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/348597-1.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html class="reftest-wait"><head>
+
+  <style type="text/css">
+	table.suchergebnis, table.suchergebnis tr, table.suchergebnis tdx, table.suchergebnis th {
+			border: 1px solid #ccc;
+			border-collapse: collapse;
+			text-align: center; 
+	}     	
+  </style>
+   <script>
+   function doTest() {
+      var s1 = document.getElementById("screen");
+      s1.parentNode.removeChild(s1); 
+      document.documentElement.removeAttribute('class');
+   }
+   document.addEventListener("MozReftestInvalidate", doTest, false);
+    </script>
+  <title>PomPIS Liste</title>
+</head>
+<body>
+<div id="screen" style="position: fixed; left:50px; top: 20px; height:8px; width: 200px; background-color:white; border:1px solid green;"></div>
+  <table class="suchergebnis" border="1" style="width: 100%">
+	  <tr><td>Frage</td></tr>
+	  <tr style="border-bottom: 10px solid green;">
+	    <td>Verhalten</td>
+	  </tr>	
+  </table>    
+</body>
+</html>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/348597-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head>
+
+  <style type="text/css">
+	table.suchergebnis, table.suchergebnis tr, table.suchergebnis tdx, table.suchergebnis th {
+			border: 1px solid #ccc;
+			border-collapse: collapse;
+			text-align: center; 
+	}     	
+  </style>
+   
+  <title>PomPIS Liste</title>
+</head>
+<body>
+
+  <table class="suchergebnis" border="1" style="width: 100%">
+	  <tr><td>Frage</td></tr>
+	  <tr style="border-bottom: 10px solid green;">
+	    <td>Verhalten</td>
+	  </tr>	
+  </table>    
+</body>
+</html>
\ No newline at end of file
--- a/layout/reftests/bugs/375716-1.html
+++ b/layout/reftests/bugs/375716-1.html
@@ -1,24 +1,25 @@
-<html><head>
+<html class="reftest-wait"><head>
 <title>Bug 375716 - Incremental reflow bug with direction: rtl and bidi-override</title>
 <style>
 
 div {
 border: 1px solid black;
 width:200px;
 }
 </style>
 <script>
 function boom() {
   var div = document.getElementById('div');
   div.removeAttribute('style')
+  document.documentElement.removeAttribute("class");
 }
 </script>
-</head><body onload="setTimeout(boom,10)">
+</head><body onload="boom()">
 <div id="div" style="font-size:120%">
 <i style="direction: rtl;">
 text text text text 
 <b style="unicode-bidi: bidi-override;">text text text text text</b>
 text
 </i>
 </div>
 </body></html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/501627-1-ref.html
@@ -0,0 +1,7 @@
+<!DOCTYPE HTML>
+<html reftest-zoom="2">
+<body style="overflow:hidden"
+background="data:image/gif;base64,R0lGODlhEgASALMAANbv9////8bp9LXi8aTc7pPV6////////////////////////////////////////ywAAAAAEgASAAAEIlCASaul8uo6tgfdpxHiWF7FaaVqe2YqfIYqfZItrrK7K0YAOw==">
+<div style="height: 2000px;"></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/501627-1.html
@@ -0,0 +1,7 @@
+<!DOCTYPE HTML>
+<html reftest-zoom="2">
+<body style="overflow:hidden"
+background="data:image/gif;base64,R0lGODlhEgASALMAANbv9////8bp9LXi8aTc7pPV6////////////////////////////////////////ywAAAAAEgASAAAEIlCASaul8uo6tgfdpxHiWF7FaaVqe2YqfIYqfZItrrK7K0YAOw==">
+<div style="height: 100000px;"></div>
+</body>
+</html>
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -253,16 +253,17 @@ skip-if(MOZ_WIDGET_TOOLKIT=="cocoa") != 
 == 283686-3.html about:blank
 fails-if(MOZ_WIDGET_TOOLKIT!="cocoa") HTTP == 289480.html#top 289480-ref.html # basically-verbatim acid2 test, HTTP for a 404 page -- bug 409329 for the non-Mac failures
 == 290129-1.html 290129-1-ref.html
 == 291078-1.html 291078-1-ref.html
 == 291078-2.html 291078-2-ref.html
 == 291262-1.html 291262-1-ref.html
 == 294306-1.html 294306-1a-ref.html
 != 294306-1.html 294306-1b-ref.html
+== 296361-1.html 296361-ref.html
 == 296904-1.html 296904-1-ref.html
 == 299136-1.html 299136-1-ref.html
 == 299837-1.html 299837-1-ref.html
 == 299837-2.xul 299837-2-ref.xul
 == 299837-3.xul 299837-3-ref.xul
 == 300691-1a.html 300691-1-ref.html
 == 300691-1b.html 300691-1-ref.html
 == 300691-1c.html 300691-1-ref.html
@@ -410,16 +411,17 @@ random-if(MOZ_WIDGET_TOOLKIT=="gtk2") ==
 == 347348-1.xhtml 347348-1-ref.xhtml
 == 347496-1.xhtml 347496-1-ref.xhtml
 == 347912-1.html 347912-1-ref.html
 == 348049-1.xhtml 348049-1-ref.xhtml
 == 348516-1.html 348516-1-ref.html
 == 348516-2.html 348516-2-ref.html
 != 348516-2.html 348516-2-notref.html
 != 348516-3.html 348516-3-notref.html
+== 348597-1.html 348597-ref.html
 == 348809-1a.html 348809-1-ref.html
 == 348809-1b.html 348809-1-ref.html
 == 348809-1c.html 348809-1-ref.html
 == 348809-1d.html 348809-1-ref.html
 == 348809-1e.html 348809-1-ref.html
 == 348809-1f.html 348809-1-ref.html
 == 348809-2a.html 348809-2-ref.html
 == 348809-2b.html 348809-2-ref.html
@@ -1293,16 +1295,17 @@ fails-if(MOZ_WIDGET_TOOLKIT!="cocoa") ==
 == 495385-3.html 495385-3-ref.html
 == 495385-4.html 495385-4-ref.html
 == 495385-5.html 495385-5-ref.html
 == 498228-1.xul 498228-1-ref.xul
 == 496032-1.html 496032-1-ref.html
 == 501257-1a.html 501257-1-ref.html
 == 501257-1b.html 501257-1-ref.html
 == 501257-1.xhtml 501257-1-ref.xhtml
+== 501627-1.html 501627-1-ref.html
 == 502288-1.html 502288-1-ref.html
 == 502942-1.html 502942-1-ref.html
 == 502447-1.html 502447-1-ref.html
 == 502795-1.html 502795-1-ref.html
 == 503364-1a.html 503364-1-ref.html
 == 503364-1b.html 503364-1-ref.html
 == 504032-1.html 504032-1-ref.html
 == 505743-1.html about:blank
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/filters/feConvolveMatrix-bias-01-ref.svg
@@ -0,0 +1,9 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/licenses/publicdomain/
+-->
+<svg xmlns="http://www.w3.org/2000/svg">
+  <title>Reference for feConvolveMatrix with bias</title>
+  <!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=527325 -->
+  <rect x="0" y="0" width="100" height="100" fill="rgb(187,255,187)"/>
+</svg>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/filters/feConvolveMatrix-bias-01.svg
@@ -0,0 +1,14 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/licenses/publicdomain/
+-->
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <title>Testcase for feConvolveMatrix with bias</title>
+  <!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=527325 -->
+  <defs>
+    <filter id="filter" filterUnits="objectBoundingBox" x="0%" y="0%" width="100%" height="100%">
+      <feConvolveMatrix kernelMatrix="1 1 1 1 1 1 1 1 1" bias="0.5"/>
+    </filter>
+  </defs>
+  <rect x="0" y="0" width="100" height="100" fill="rgb(0,255,0)" filter="url(#filter)"/>
+</svg>
--- a/layout/reftests/svg/filters/reftest.list
+++ b/layout/reftests/svg/filters/reftest.list
@@ -63,16 +63,17 @@ fails == filter-marked-line-01.svg pass.
 == filter-marked-line-08.svg pass.svg
 == filter-marked-line-09.svg pass.svg
 == filter-nested-filtering-01.svg pass.svg
 == filter-nested-filtering-02.svg pass.svg
 == filter-patterned-rect-01.svg pass.svg
 == filter-patterned-rect-02.svg pass.svg
 
 == feComposite-arguments-01.svg pass.svg
+== feConvolveMatrix-bias-01.svg feConvolveMatrix-bias-01-ref.svg
 == feConvolveMatrix-order-01.svg feConvolveMatrix-order-01-ref.svg
 
 == feMorphology-radius-negative-01.svg pass.svg
 == feMorphology-radius-negative-02.svg pass.svg
 == feMorphology-radius-zero-01.svg pass.svg
 == feMorphology-radius-zero-02.svg pass.svg
 
 == feTile-large-01.svg pass.svg
new file mode 100644
--- /dev/null
+++ b/layout/tables/crashtests/267418.html
@@ -0,0 +1,122 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en-US" class="reftest-wait">
+<head>
+	<title>Testcase, bug 174470</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+	<meta http-equiv="Content-Style-Type" content="text/css">
+	<style type="text/css">
+
+	table {
+		border-collapse: collapse;
+		margin: 1em;
+		border: thick solid;
+		border-color: #f0f #c0c #909 #606; /* purple */
+	}
+
+	colgroup:first-child + colgroup {
+		border: thick solid;
+		border-color: #f66 #f00 #a00 #600; /* red */
+	}
+
+	colgroup:first-child + colgroup + colgroup > col:first-child + col {
+		border: thick solid;
+		border-color: #ff0 #cc0 #990 #660; /* yellow */
+	}
+
+	colgroup + tbody + tbody {
+		border: thick solid;
+		border-color: #6f6 #0f0 #0a0 #060; /* green */
+	}
+
+	colgroup + tbody > tr:first-child + tr {
+		border: thick solid;
+		border-color: #0ff #0cc #099 #066; /* aqua */
+	}
+
+	colgroup + tbody + tbody + tbody > tr:first-child + tr > td:first-child + td {
+		border: thick solid;
+		border-color: #66f #00f #00a #006; /* blue */
+	}
+
+	</style>
+    <script>
+   function doTest() {
+      var s1 = document.getElementById("screen");
+      s1.parentNode.removeChild(s1); 
+      document.documentElement.removeAttribute('class');
+   }
+   document.addEventListener("MozReftestInvalidate", doTest, false);
+    </script>
+</head>
+<body>
+
+<div id="screen" style="position: fixed; left:50px; height:200px; width: 200px; background-color:white; border:1px solid green;"></div>
+
+<p>The following two tables should be mirrors of each other, except that
+(1) the digits should still be normal left-to-right digits and (2) the
+color changes for each of the 6 colors should, in both, be lightest on top
+clockwise to darkest on the left.</p>
+
+<table dir="ltr" >
+	<colgroup>
+		<col>
+	</colgroup>
+	<colgroup>
+		<col>
+		<col>
+	</colgroup>
+	<colgroup>
+		<col>
+		<col>
+		<col>
+	</colgroup>
+	<tbody>
+		<tr><td>1</td><td>22</td><td>333</td><td>4444</td><td>55555</td><td>666666</td></tr>
+		<tr><td>1</td><td>22</td><td>333</td><td>4444</td><td>55555</td><td>666666</td></tr>
+		<tr><td>1</td><td>22</td><td>333</td><td>4444</td><td>55555</td><td>666666</td></tr>
+	</tbody>
+	<tbody>
+		<tr><td>1</td><td>22</td><td>333</td><td>4444</td><td>55555</td><td>666666</td></tr>
+		<tr><td>1</td><td>22</td><td>333</td><td>4444</td><td>55555</td><td>666666</td></tr>
+		<tr><td>1</td><td>22</td><td>333</td><td>4444</td><td>55555</td><td>666666</td></tr>
+	</tbody>
+	<tbody>
+		<tr><td>1</td><td>22</td><td>333</td><td>4444</td><td>55555</td><td>666666</td></tr>
+		<tr><td>1</td><td>22</td><td>333</td><td>4444</td><td>55555</td><td>666666</td></tr>
+		<tr><td>1</td><td>22</td><td>333</td><td>4444</td><td>55555</td><td>666666</td></tr>
+	</tbody>
+</table>
+
+<table dir="rtl">
+	<colgroup>
+		<col>
+	</colgroup>
+	<colgroup>
+		<col>
+		<col>
+	</colgroup>
+	<colgroup>
+		<col>
+		<col>
+		<col>
+	</colgroup>
+	<tbody>
+		<tr><td>1</td><td>22</td><td>333</td><td>4444</td><td>55555</td><td>666666</td></tr>
+		<tr><td>1</td><td>22</td><td>333</td><td>4444</td><td>55555</td><td>666666</td></tr>
+		<tr><td>1</td><td>22</td><td>333</td><td>4444</td><td>55555</td><td>666666</td></tr>
+	</tbody>
+	<tbody>
+		<tr><td>1</td><td>22</td><td>333</td><td>4444</td><td>55555</td><td>666666</td></tr>
+		<tr><td>1</td><td>22</td><td>333</td><td>4444</td><td>55555</td><td>666666</td></tr>
+		<tr><td>1</td><td>22</td><td>333</td><td>4444</td><td>55555</td><td>666666</td></tr>
+	</tbody>
+	<tbody>
+		<tr><td>1</td><td>22</td><td>333</td><td>4444</td><td>55555</td><td>666666</td></tr>
+		<tr><td>1</td><td>22</td><td>333</td><td>4444</td><td>55555</td><td>666666</td></tr>
+		<tr><td>1</td><td>22</td><td>333</td><td>4444</td><td>55555</td><td>666666</td></tr>
+	</tbody>
+</table>
+
+</body>
+</html>
--- a/layout/tables/crashtests/crashtests.list
+++ b/layout/tables/crashtests/crashtests.list
@@ -12,16 +12,17 @@ load 197015-1.html
 load 220536-1.html
 load 223458-1.html
 load 237421-1.html
 load 237421-2.html
 load 238909-1.html
 load 239294-1.html
 load 240854-1.html
 load 266015-1.html
+load 267418.html
 load 277062-1.html
 load 278385-1.html
 load 282175-1.html
 load 284844-1.html
 load 284844-1.html
 load 284852.html
 load 300912.html
 load 308752-1.html
--- a/modules/libimg/png/CHANGES
+++ b/modules/libimg/png/CHANGES
@@ -1,9 +1,9 @@
-
+/*
 CHANGES - changes for libpng
 
 version 0.2
   added reader into png.h
   fixed small problems in stub file
 
 version 0.3
   added pull reader
@@ -534,17 +534,18 @@ version 1.0.5c [November 26, 1999]
   Removed some extraneous "-I" from contrib/pngminus/makefile.std
   Changed the PNG_sRGB_INTENT macros in png.h to be consistent with PNG-1.2.
   Change PNG_SRGB_INTENT to PNG_sRGB_INTENT in libpng.txt and libpng.3
 version 1.0.5d [November 29, 1999]
   Add type cast (png_const_charp) two places in png.c
   Eliminated pngtypes.h; use macros instead to declare PNG_CHNK arrays.
   Renamed "PNG_GLOBAL_ARRAYS" to "PNG_USE_GLOBAL_ARRAYS" and made available
     to applications a macro "PNG_USE_LOCAL_ARRAYS".
-  #ifdef out all the new declarations when PNG_USE_GLOBAL_ARRAYS is defined.
+  Remove all the new declarations with #ifdef/#endif when
+    PNG_USE_GLOBAL_ARRAYS is defined.
   Added PNG_EXPORT_VAR macro to accommodate making DLL's.
 version 1.0.5e [November 30, 1999]
   Added iCCP, iTXt, and sPLT support; added "lang" member to the png_text
     structure; refactored the inflate/deflate support to make adding new chunks
     with trailing compressed parts easier in the future, and added new functions
     png_free_iCCP, png_free_pCAL, png_free_sPLT, png_free_text, png_get_iCCP,
     png_get_spalettes, png_set_iCCP, png_set_spalettes (Eric S. Raymond).
   NOTE: Applications that write text chunks MUST define png_text->lang
@@ -1174,17 +1175,17 @@ version 1.2.4beta2 [June 25, 2002]
   Added -soname to the loader flags in makefile.dec, makefile.sgi, and
     makefile.sggcc.
   Added "test-installed" target to makefile.linux, makefile.gcmmx,
     makefile.sgi, and makefile.sggcc.
 version 1.2.4beta3 [June 28, 2002]
   Plugged memory leak of row_buf in pngtest.c when there is a png_error().
   Detect buffer overflow in pngpread.c when IDAT is corrupted with extra data.
   Added "test-installed" target to makefile.32sunu, makefile.64sunu,
-    makefile.beos, makefile.darwin, makefile.dec, makefile.macosx, 
+    makefile.beos, makefile.darwin, makefile.dec, makefile.macosx,
     makefile.solaris, makefile.hpux, makefile.hpgcc, and makefile.so9.
 version 1.2.4rc1 and 1.0.14rc1 [July 2, 2002]
   Added "test-installed" target to makefile.cygwin and makefile.sco.
   Revised pnggccrd.c to be able to back out version 1.0.x via PNG_1_0_X macro.
 
 version 1.2.4 and 1.0.14 [July 8, 2002]
   Changed png_warning() to png_error() when width is too large to process.
 version 1.2.4patch01 [July 20, 2002]
@@ -1295,17 +1296,17 @@ version 1.2.6beta4 [July 28, 2004]
     overflow.
   Turn on PNG_NO_ZALLOC_ZERO by default in version 1.2.x
   Revised "clobber list" in pnggccrd.c so it will compile under gcc-3.4.
   Revised Borland portion of png_malloc() to return NULL or issue
     png_error() according to setting of PNG_FLAG_MALLOC_NULL_MEM_OK.
   Added PNG_NO_SEQUENTIAL_READ_SUPPORTED macro to conditionally remove
     sequential read support.
   Added some "#if PNG_WRITE_SUPPORTED" blocks.
-  #ifdef'ed out some redundancy in png_malloc_default().
+  Removed some redundancy with #ifdef/#endif in png_malloc_default().