Merge from mozilla-central.
authorDavid Anderson <danderson@mozilla.com>
Wed, 23 May 2012 14:33:15 -0700
changeset 112538 a15a3a3b4647fa24609d08706ea35e9cd5998c52
parent 112537 abe401869582dd4746162d6dbafb54c505c197c7 (current diff)
parent 98717 320b16daa7c077157b3e51e03a11fff06d395c84 (diff)
child 112539 bc9132845c4d7480999363308b0dd3bcd3eadf99
push id1708
push userakeybl@mozilla.com
push dateMon, 19 Nov 2012 21:10:21 +0000
treeherdermozilla-beta@27b14fe50103 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone15.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge from mozilla-central.
accessible/src/atk/nsAccessibleWrap.cpp
accessible/src/base/AccEvent.cpp
accessible/src/base/nsAccessible.h
accessible/src/generic/ARIAGridAccessible.cpp
accessible/src/generic/ARIAGridAccessible.h
accessible/src/generic/RootAccessible.cpp
accessible/src/html/nsHTMLImageAccessible.h
accessible/src/html/nsHTMLTableAccessible.cpp
accessible/src/html/nsHTMLTableAccessible.h
accessible/src/msaa/CAccessibleImage.cpp
accessible/src/msaa/CAccessibleImage.h
accessible/src/xul/nsXULListboxAccessible.cpp
accessible/src/xul/nsXULListboxAccessible.h
accessible/src/xul/nsXULTreeGridAccessible.cpp
accessible/src/xul/nsXULTreeGridAccessible.h
b2g/installer/package-manifest.in
browser/components/tabview/test/browser_tabview_bug587276.js
browser/components/tabview/test/browser_tabview_privatebrowsing.js
config/autoconf.mk.in
configure.in
content/base/public/nsDOMFile.h
content/base/public/nsDeprecatedOperationList.h
content/base/public/nsIDocument.h
content/base/src/nsContentSink.cpp
content/base/src/nsDOMAttributeMap.cpp
content/base/src/nsDOMAttributeMap.h
content/base/src/nsGenericElement.cpp
content/base/src/nsGkAtomList.h
content/base/src/nsTreeSanitizer.cpp
content/base/src/nsXMLHttpRequest.h
content/events/src/nsEventListenerManager.cpp
content/html/content/src/nsHTMLAnchorElement.cpp
content/media/nsBuiltinDecoderStateMachine.cpp
content/media/ogg/nsOggCodecState.cpp
content/smil/nsSMILTimedElement.cpp
content/xbl/src/nsXBLDocumentInfo.cpp
content/xul/document/src/nsXULPrototypeDocument.cpp
dom/Makefile.in
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfoClasses.h
dom/base/nsFocusManager.h
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
dom/base/nsIScriptContext.h
dom/base/nsJSEnvironment.cpp
dom/base/nsJSEnvironment.h
dom/base/nsPIDOMWindow.h
dom/ipc/Makefile.in
dom/ipc/TabChild.cpp
dom/locales/en-US/chrome/dom/dom.properties
dom/plugins/base/nsPluginInstanceOwner.cpp
dom/workers/WorkerPrivate.cpp
dom/workers/WorkerScope.cpp
dom/workers/XMLHttpRequest.cpp
gfx/gl/GLContext.cpp
gfx/gl/GLContext.h
gfx/layers/ImageLayers.h
gfx/layers/Layers.h
gfx/layers/basic/BasicLayers.cpp
gfx/layers/basic/BasicLayers.h
gfx/layers/d3d10/ImageLayerD3D10.cpp
gfx/layers/d3d10/LayerManagerD3D10.h
gfx/layers/d3d9/ImageLayerD3D9.cpp
gfx/layers/d3d9/LayerManagerD3D9.h
gfx/layers/ipc/PLayers.ipdl
gfx/layers/ipc/ShadowLayers.cpp
gfx/layers/ipc/ShadowLayers.h
gfx/layers/ipc/ShadowLayersParent.cpp
gfx/layers/opengl/ImageLayerOGL.cpp
gfx/layers/opengl/LayerManagerOGL.h
gfx/thebes/gfxAndroidPlatform.cpp
gfx/thebes/gfxContext.cpp
gfx/thebes/gfxContext.h
gfx/thebes/gfxFT2FontBase.cpp
gfx/thebes/gfxFT2FontBase.h
gfx/thebes/gfxFT2FontList.cpp
gfx/thebes/gfxFT2Fonts.cpp
gfx/thebes/gfxFont.h
gfx/thebes/gfxPattern.cpp
gfx/thebes/gfxPlatform.cpp
gfx/thebes/gfxPlatform.h
gfx/thebes/gfxPlatformGtk.cpp
js/src/configure.in
js/src/frontend/BytecodeCompiler.cpp
js/src/frontend/Parser.cpp
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jscntxt.h
js/src/jscompartment.cpp
js/src/jsfriendapi.cpp
js/src/jsfriendapi.h
js/src/jsgc.cpp
js/src/jsproxy.cpp
js/src/jsproxy.h
js/src/jsscript.h
js/src/jsval.h
js/src/jswrapper.cpp
js/src/jswrapper.h
js/src/vm/ScopeObject.cpp
js/xpconnect/loader/mozJSComponentLoader.cpp
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/XPCWrappedNativeScope.cpp
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/xpcprivate.h
js/xpconnect/src/xpcpublic.h
layout/base/FrameLayerBuilder.cpp
layout/base/nsCSSRendering.cpp
layout/build/Makefile.in
layout/generic/nsGfxScrollFrame.cpp
layout/ipc/RenderFrameParent.cpp
layout/ipc/RenderFrameParent.h
mobile/android/base/GeckoApp.java
mobile/android/base/Makefile.in
mobile/android/base/resources/drawable/progress_spinner_13.png
mobile/android/base/resources/drawable/progress_spinner_14.png
mobile/android/base/resources/drawable/progress_spinner_15.png
mobile/android/base/resources/drawable/progress_spinner_16.png
mobile/android/base/resources/drawable/progress_spinner_17.png
mobile/android/base/resources/drawable/progress_spinner_18.png
mobile/xul/installer/package-manifest.in
modules/libpref/src/init/all.js
netwerk/base/public/nsNetUtil.h
netwerk/base/src/nsAsyncStreamCopier.cpp
netwerk/base/src/nsFileStreams.cpp
netwerk/base/src/nsFileStreams.h
netwerk/base/src/nsStreamTransportService.cpp
netwerk/protocol/http/nsHttpConnectionMgr.cpp
netwerk/protocol/http/nsHttpConnectionMgr.h
nsprpub/TAG-INFO
nsprpub/config/prdepend.h
parser/html/nsHtml5StreamParser.cpp
parser/html/nsHtml5TreeOpExecutor.cpp
parser/html/nsHtml5TreeOpExecutor.h
services/sync/modules/service.js
testing/jetpack/jetpack-location.txt
toolkit/components/startup/nsAppStartup.cpp
toolkit/mozapps/installer/packager.mk
toolkit/xre/nsAppRunner.cpp
uriloader/prefetch/OfflineCacheUpdateChild.cpp
uriloader/prefetch/OfflineCacheUpdateChild.h
uriloader/prefetch/OfflineCacheUpdateGlue.h
uriloader/prefetch/OfflineCacheUpdateParent.cpp
uriloader/prefetch/nsOfflineCacheUpdate.cpp
uriloader/prefetch/nsOfflineCacheUpdate.h
widget/android/nsWindow.cpp
widget/xpwidgets/nsBaseWidget.cpp
widget/xpwidgets/nsBaseWidget.h
--- a/accessible/src/atk/nsAccessibleWrap.cpp
+++ b/accessible/src/atk/nsAccessibleWrap.cpp
@@ -357,83 +357,69 @@ nsAccessibleWrap::GetAtkObject(nsIAccess
     acc->GetNativeInterface(&atkObjPtr);
     return atkObjPtr ? ATK_OBJECT(atkObjPtr) : nsnull;    
 }
 
 /* private */
 PRUint16
 nsAccessibleWrap::CreateMaiInterfaces(void)
 {
-    PRUint16 interfacesBits = 0;
+  PRUint16 interfacesBits = 0;
     
-    // Add Interfaces for each nsIAccessible.ext interfaces
-
-    // the Component interface are supported by all nsIAccessible
-    interfacesBits |= 1 << MAI_INTERFACE_COMPONENT;
+  // The Component interface is supported by all accessibles.
+  interfacesBits |= 1 << MAI_INTERFACE_COMPONENT;
 
   // Add Action interface if the action count is more than zero.
   if (ActionCount() > 0)
     interfacesBits |= 1 << MAI_INTERFACE_ACTION;
 
-    //nsIAccessibleText
-    nsCOMPtr<nsIAccessibleText> accessInterfaceText;
-    QueryInterface(NS_GET_IID(nsIAccessibleText),
-                   getter_AddRefs(accessInterfaceText));
-    if (accessInterfaceText) {
-        interfacesBits |= 1 << MAI_INTERFACE_TEXT;
-    }
-
-    //nsIAccessibleEditableText
-    nsCOMPtr<nsIAccessibleEditableText> accessInterfaceEditableText;
-    QueryInterface(NS_GET_IID(nsIAccessibleEditableText),
-                   getter_AddRefs(accessInterfaceEditableText));
-    if (accessInterfaceEditableText) {
-        interfacesBits |= 1 << MAI_INTERFACE_EDITABLE_TEXT;
-    }
+  // Text, Editabletext, and Hypertext interface.
+  nsHyperTextAccessible* hyperText = AsHyperText();
+  if (hyperText && hyperText->IsTextRole()) {
+    interfacesBits |= 1 << MAI_INTERFACE_TEXT;
+    interfacesBits |= 1 << MAI_INTERFACE_EDITABLE_TEXT;
+    if (!nsAccUtils::MustPrune(this))
+      interfacesBits |= 1 << MAI_INTERFACE_HYPERTEXT;
+  }
 
-    //nsIAccessibleValue
-    nsCOMPtr<nsIAccessibleValue> accessInterfaceValue;
-    QueryInterface(NS_GET_IID(nsIAccessibleValue),
-                   getter_AddRefs(accessInterfaceValue));
-    if (accessInterfaceValue) {
-       interfacesBits |= 1 << MAI_INTERFACE_VALUE; 
-    }
+  // Value interface.
+  nsCOMPtr<nsIAccessibleValue> accessInterfaceValue;
+  QueryInterface(NS_GET_IID(nsIAccessibleValue),
+                 getter_AddRefs(accessInterfaceValue));
+  if (accessInterfaceValue) {
+    interfacesBits |= 1 << MAI_INTERFACE_VALUE; 
+  }
 
-    // document accessible
-    if (IsDoc())
-        interfacesBits |= 1 << MAI_INTERFACE_DOCUMENT;
+  // Document interface.
+  if (IsDoc())
+    interfacesBits |= 1 << MAI_INTERFACE_DOCUMENT;
 
-    if (IsImageAccessible())
-        interfacesBits |= 1 << MAI_INTERFACE_IMAGE;
+  if (IsImage())
+    interfacesBits |= 1 << MAI_INTERFACE_IMAGE;
 
-  // HyperLinkAccessible
+  // HyperLink interface.
   if (IsLink())
     interfacesBits |= 1 << MAI_INTERFACE_HYPERLINK_IMPL;
 
-    if (!nsAccUtils::MustPrune(this)) {  // These interfaces require children
-      //nsIAccessibleHypertext
-      if (IsHyperText()) {
-          interfacesBits |= 1 << MAI_INTERFACE_HYPERTEXT;
-      }
+  if (!nsAccUtils::MustPrune(this)) {  // These interfaces require children
+    // Table interface.
+    nsCOMPtr<nsIAccessibleTable> accessInterfaceTable;
+    QueryInterface(NS_GET_IID(nsIAccessibleTable),
+                   getter_AddRefs(accessInterfaceTable));
+    if (accessInterfaceTable) {
+      interfacesBits |= 1 << MAI_INTERFACE_TABLE;
+    }
+      
+    // Selection interface.
+    if (IsSelect()) {
+      interfacesBits |= 1 << MAI_INTERFACE_SELECTION;
+    }
+  }
 
-      //nsIAccessibleTable
-      nsCOMPtr<nsIAccessibleTable> accessInterfaceTable;
-      QueryInterface(NS_GET_IID(nsIAccessibleTable),
-                     getter_AddRefs(accessInterfaceTable));
-      if (accessInterfaceTable) {
-          interfacesBits |= 1 << MAI_INTERFACE_TABLE;
-      }
-      
-      //nsIAccessibleSelection
-      if (IsSelect()) {
-          interfacesBits |= 1 << MAI_INTERFACE_SELECTION;
-      }
-    }
-
-    return interfacesBits;
+  return interfacesBits;
 }
 
 static GType
 GetMaiAtkType(PRUint16 interfacesBits)
 {
     GType type;
     static const GTypeInfo tinfo = {
         sizeof(MaiAtkObjectClass),
--- a/accessible/src/atk/nsMaiInterfaceImage.cpp
+++ b/accessible/src/atk/nsMaiInterfaceImage.cpp
@@ -9,45 +9,45 @@
 #include "nsAccessibleWrap.h"
 #include "nsHTMLImageAccessible.h"
 #include "nsMai.h"
 
 extern "C" {
 const gchar* getDescriptionCB(AtkObject* aAtkObj);
 
 static void
-getImagePositionCB(AtkImage *aImage, gint *aAccX, gint *aAccY,
+getImagePositionCB(AtkImage* aImage, gint* aAccX, gint* aAccY,
                    AtkCoordType aCoordType)
 {
-    nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aImage));
-    if (!accWrap || !accWrap->IsImageAccessible())
-      return;
+  nsAccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aImage));
+  if (!accWrap || !accWrap->IsImage())
+    return;
 
-    nsHTMLImageAccessible* image = accWrap->AsImage();
-    PRUint32 geckoCoordType = (aCoordType == ATK_XY_WINDOW) ?
-      nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE :
-      nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE;
-    // Returned in screen coordinates
-    image->GetImagePosition(geckoCoordType, aAccX, aAccY);
+  nsHTMLImageAccessible* image = accWrap->AsImage();
+  PRUint32 geckoCoordType = (aCoordType == ATK_XY_WINDOW) ?
+    nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE :
+    nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE;
+  // Returned in screen coordinates
+  image->GetImagePosition(geckoCoordType, aAccX, aAccY);
 }
 
 static const gchar*
-getImageDescriptionCB(AtkImage *aImage)
+getImageDescriptionCB(AtkImage* aImage)
 {
-   return getDescriptionCB(ATK_OBJECT(aImage));
+  return getDescriptionCB(ATK_OBJECT(aImage));
 }
 
 static void
-getImageSizeCB(AtkImage *aImage, gint *aAccWidth, gint *aAccHeight)
+getImageSizeCB(AtkImage* aImage, gint* aAccWidth, gint* aAccHeight)
 {
-    nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aImage));
-    if (!accWrap || !accWrap->IsImageAccessible())
-      return;
+  nsAccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aImage));
+  if (!accWrap || !accWrap->IsImage())
+    return;
 
-    accWrap->AsImage()->GetImageSize(aAccWidth, aAccHeight);
+  accWrap->AsImage()->GetImageSize(aAccWidth, aAccHeight);
 }
 }
 
 void
 imageInterfaceInitCB(AtkImageIface* aIface)
 {
   NS_ASSERTION(aIface, "no interface!");
   if (NS_UNLIKELY(!aIface))
--- a/accessible/src/base/AccEvent.cpp
+++ b/accessible/src/base/AccEvent.cpp
@@ -103,17 +103,24 @@ NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(Acc
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(AccEvent, Release)
 
 ////////////////////////////////////////////////////////////////////////////////
 // AccEvent protected methods
 
 nsAccessible*
 AccEvent::GetAccessibleForNode() const
 {
-  return mNode ? GetAccService()->GetAccessible(mNode, nsnull) : nsnull;
+  if (mNode) {
+    nsDocAccessible* document =
+      GetAccService()->GetDocAccessible(mNode->OwnerDoc());
+    if (document)
+      return document->GetAccessible(mNode);
+  }
+
+  return nsnull;
 }
 
 void
 AccEvent::CaptureIsFromUserInput(EIsFromUserInput aIsFromUserInput)
 {
   nsINode *targetNode = GetNode();
 
 #ifdef DEBUG
--- a/accessible/src/base/FocusManager.cpp
+++ b/accessible/src/base/FocusManager.cpp
@@ -340,25 +340,18 @@ FocusManager::FocusedDOMNode() const
   // keeps the focus.
   if (focusedElm) {
     if (nsEventStateManager::IsRemoteTarget(focusedElm))
       return nsnull;
     return focusedElm;
   }
 
   // Otherwise the focus can be on DOM document.
-  nsCOMPtr<nsIDOMWindow> focusedWnd;
-  DOMFocusManager->GetFocusedWindow(getter_AddRefs(focusedWnd));
-  if (focusedWnd) {
-    nsCOMPtr<nsIDOMDocument> DOMDoc;
-    focusedWnd->GetDocument(getter_AddRefs(DOMDoc));
-    nsCOMPtr<nsIDocument> DOMDocNode(do_QueryInterface(DOMDoc));
-    return DOMDocNode;
-  }
-  return nsnull;
+  nsPIDOMWindow* focusedWnd = DOMFocusManager->GetFocusedWindow();
+  return focusedWnd ? focusedWnd->GetExtantDoc() : nsnull;
 }
 
 nsIDocument*
 FocusManager::FocusedDOMDocument() const
 {
   nsINode* focusedNode = FocusedDOMNode();
   return focusedNode ? focusedNode->OwnerDoc() : nsnull;
 }
--- a/accessible/src/base/nsAccessible.h
+++ b/accessible/src/base/nsAccessible.h
@@ -456,17 +456,17 @@ public:
   inline bool IsHyperText() const { return mFlags & eHyperTextAccessible; }
   nsHyperTextAccessible* AsHyperText();
 
   inline bool IsHTMLFileInput() const { return mFlags & eHTMLFileInputAccessible; }
 
   inline bool IsHTMLListItem() const { return mFlags & eHTMLListItemAccessible; }
   mozilla::a11y::HTMLLIAccessible* AsHTMLListItem();
 
-  inline bool IsImageAccessible() const { return mFlags & eImageAccessible; }
+  inline bool IsImage() const { return mFlags & eImageAccessible; }
   nsHTMLImageAccessible* AsImage();
 
   bool IsImageMapAccessible() const { return mFlags & eImageMapAccessible; }
   nsHTMLImageMapAccessible* AsImageMap();
 
   inline bool IsXULTree() const { return mFlags & eXULTreeAccessible; }
   nsXULTreeAccessible* AsXULTree();
 
--- a/accessible/src/generic/ARIAGridAccessible.cpp
+++ b/accessible/src/generic/ARIAGridAccessible.cpp
@@ -75,34 +75,24 @@ ARIAGridAccessible::RowCount()
   PRUint32 rowCount = 0;
   AccIterator rowIter(this, filters::GetRow);
   while (rowIter.Next())
     rowCount++;
 
   return rowCount;
 }
 
-NS_IMETHODIMP
-ARIAGridAccessible::GetCellAt(PRInt32 aRowIndex, PRInt32 aColumnIndex,
-                              nsIAccessible** aCell)
-{
-  NS_ENSURE_ARG_POINTER(aCell);
-  *aCell = nsnull;
+nsAccessible*
+ARIAGridAccessible::CellAt(PRUint32 aRowIndex, PRUint32 aColumnIndex)
+{ 
+  nsAccessible* row = GetRowAt(aRowIndex);
+  if (!row)
+    return nsnull;
 
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  nsAccessible *row = GetRowAt(aRowIndex);
-  NS_ENSURE_ARG(row);
-
-  nsAccessible *cell = GetCellInRowAt(row, aColumnIndex);
-  NS_ENSURE_ARG(cell);
-
-  NS_ADDREF(*aCell = cell);
-  return NS_OK;
+  return GetCellInRowAt(row, aColumnIndex);
 }
 
 NS_IMETHODIMP
 ARIAGridAccessible::GetColumnIndexAt(PRInt32 aCellIndex,
                                      PRInt32* aColumnIndex)
 {
   NS_ENSURE_ARG_POINTER(aColumnIndex);
   *aColumnIndex = -1;
--- a/accessible/src/generic/ARIAGridAccessible.h
+++ b/accessible/src/generic/ARIAGridAccessible.h
@@ -36,16 +36,17 @@ public:
   virtual mozilla::a11y::TableAccessible* AsTable() { return this; }
 
   // nsAccessNode
   virtual void Shutdown();
 
   // TableAccessible
   virtual PRUint32 ColCount();
   virtual PRUint32 RowCount();
+  virtual nsAccessible* CellAt(PRUint32 aRowIndex, PRUint32 aColumnIndex);
   virtual void UnselectCol(PRUint32 aColIdx);
   virtual void UnselectRow(PRUint32 aRowIdx);
 
 protected:
   /**
    * Return true if the given row index is valid.
    */
   bool IsValidRow(PRInt32 aRow);
--- a/accessible/src/generic/RootAccessible.cpp
+++ b/accessible/src/generic/RootAccessible.cpp
@@ -97,27 +97,20 @@ RootAccessible::Name(nsString& aName)
   document->GetTitle(aName);
   return eNameOK;
 }
 
 role
 RootAccessible::NativeRole()
 {
   // If it's a <dialog> or <wizard>, use roles::DIALOG instead
-  dom::Element *root = mDocument->GetRootElement();
-  if (root) {
-    nsCOMPtr<nsIDOMElement> rootElement(do_QueryInterface(root));
-    if (rootElement) {
-      nsAutoString name;
-      rootElement->GetLocalName(name);
-      if (name.EqualsLiteral("dialog") || name.EqualsLiteral("wizard")) {
-        return roles::DIALOG; // Always at the root
-      }
-    }
-  }
+  dom::Element* rootElm = mDocument->GetRootElement();
+  if (rootElm && (rootElm->Tag() == nsGkAtoms::dialog ||
+                  rootElm->Tag() == nsGkAtoms::wizard))
+    return roles::DIALOG;
 
   return nsDocAccessibleWrap::NativeRole();
 }
 
 // RootAccessible protected member
 #ifdef MOZ_XUL
 PRUint32
 RootAccessible::GetChromeFlags()
@@ -139,43 +132,38 @@ RootAccessible::GetChromeFlags()
   xulWin->GetChromeFlags(&chromeFlags);
   return chromeFlags;
 }
 #endif
 
 PRUint64
 RootAccessible::NativeState()
 {
-  PRUint64 states = nsDocAccessibleWrap::NativeState();
+  PRUint64 state = nsDocAccessibleWrap::NativeState();
+  if (state & states::DEFUNCT)
+    return state;
 
 #ifdef MOZ_XUL
   PRUint32 chromeFlags = GetChromeFlags();
   if (chromeFlags & nsIWebBrowserChrome::CHROME_WINDOW_RESIZE)
-    states |= states::SIZEABLE;
+    state |= states::SIZEABLE;
     // If it has a titlebar it's movable
     // XXX unless it's minimized or maximized, but not sure
     //     how to detect that
   if (chromeFlags & nsIWebBrowserChrome::CHROME_TITLEBAR)
-    states |= states::MOVEABLE;
+    state |= states::MOVEABLE;
   if (chromeFlags & nsIWebBrowserChrome::CHROME_MODAL)
-    states |= states::MODAL;
+    state |= states::MODAL;
 #endif
 
   nsFocusManager* fm = nsFocusManager::GetFocusManager();
-  if (fm) {
-    nsCOMPtr<nsIDOMWindow> rootWindow;
-    GetWindow(getter_AddRefs(rootWindow));
+  if (fm && fm->GetActiveWindow() == mDocument->GetWindow())
+    state |= states::ACTIVE;
 
-    nsCOMPtr<nsIDOMWindow> activeWindow;
-    fm->GetActiveWindow(getter_AddRefs(activeWindow));
-    if (activeWindow == rootWindow)
-      states |= states::ACTIVE;
-  }
-
-  return states;
+  return state;
 }
 
 const char* const docEvents[] = {
 #ifdef DEBUG_DRAGDROPSTART
   // Capture mouse over events and fire fake DRAGDROPSTART event to simplify
   // debugging a11y objects with event viewers
   "mouseover",
 #endif
--- a/accessible/src/html/nsHTMLImageAccessible.h
+++ b/accessible/src/html/nsHTMLImageAccessible.h
@@ -72,14 +72,14 @@ private:
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessible downcasting method
 
 inline nsHTMLImageAccessible*
 nsAccessible::AsImage()
 {
-  return IsImageAccessible() ?
+  return IsImage() ?
     static_cast<nsHTMLImageAccessible*>(this) : nsnull;
 }
 
 #endif
 
--- a/accessible/src/html/nsHTMLTableAccessible.cpp
+++ b/accessible/src/html/nsHTMLTableAccessible.cpp
@@ -528,26 +528,30 @@ nsHTMLTableAccessible::Summary(nsString&
   if (table)
     table->GetSummary(aSummary);
 }
 
 PRUint32
 nsHTMLTableAccessible::ColCount()
 {
   nsITableLayout* tableLayout = GetTableLayout();
+  if (!tableLayout)
+    return 0;
 
   PRInt32 rowCount = 0, colCount = 0;
   tableLayout->GetTableSize(rowCount, colCount);
   return colCount;
 }
 
 PRUint32
 nsHTMLTableAccessible::RowCount()
 {
   nsITableLayout* tableLayout = GetTableLayout();
+  if (!tableLayout)
+    return 0;
 
   PRInt32 rowCount = 0, colCount = 0;
   tableLayout->GetTableSize(rowCount, colCount);
   return rowCount;
 }
 
 NS_IMETHODIMP
 nsHTMLTableAccessible::GetSelectedCellCount(PRUint32* aCount)
@@ -837,38 +841,33 @@ nsHTMLTableAccessible::GetSelectedRowInd
     }
   }
 
   delete []states;
   *aRows = outArray;
   return rv;
 }
 
-NS_IMETHODIMP
-nsHTMLTableAccessible::GetCellAt(PRInt32 aRow, PRInt32 aColumn,
-                                 nsIAccessible **aTableCellAccessible)
-{
+nsAccessible*
+nsHTMLTableAccessible::CellAt(PRUint32 aRowIndex, PRUint32 aColumnIndex)
+{ 
   nsCOMPtr<nsIDOMElement> cellElement;
-  nsresult rv = GetCellAt(aRow, aColumn, *getter_AddRefs(cellElement));
-  NS_ENSURE_SUCCESS(rv, rv);
+  GetCellAt(aRowIndex, aColumnIndex, *getter_AddRefs(cellElement));
+  if (!cellElement)
+    return nsnull;
 
   nsCOMPtr<nsIContent> cellContent(do_QueryInterface(cellElement));
+  if (!cellContent)
+    return nsnull;
+
   nsAccessible* cell = mDoc->GetAccessible(cellContent);
 
-  if (!cell) {
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  if (cell != this) {
-    // XXX bug 576838: crazy tables (like table6 in tables/test_table2.html) may
-    // return itself as a cell what makes Orca hang.
-    NS_ADDREF(*aTableCellAccessible = cell);
-  }
-
-  return NS_OK;
+  // XXX bug 576838: crazy tables (like table6 in tables/test_table2.html) may
+  // return itself as a cell what makes Orca hang.
+  return cell == this ? nsnull : cell;
 }
 
 PRInt32
 nsHTMLTableAccessible::CellIndexAt(PRUint32 aRowIdx, PRUint32 aColIdx)
 {
   nsITableLayout* tableLayout = GetTableLayout();
 
   PRInt32 index = -1;
--- a/accessible/src/html/nsHTMLTableAccessible.h
+++ b/accessible/src/html/nsHTMLTableAccessible.h
@@ -94,16 +94,17 @@ public:
   // nsIAccessible Table
   NS_DECL_OR_FORWARD_NSIACCESSIBLETABLE_WITH_XPCACCESSIBLETABLE
 
   // TableAccessible
   virtual nsAccessible* Caption();
   virtual void Summary(nsString& aSummary);
   virtual PRUint32 ColCount();
   virtual PRUint32 RowCount();
+  virtual nsAccessible* CellAt(PRUint32 aRowIndex, PRUint32 aColumnIndex);
   virtual PRInt32 CellIndexAt(PRUint32 aRowIdx, PRUint32 aColIdx);
   virtual void UnselectCol(PRUint32 aColIdx);
   virtual void UnselectRow(PRUint32 aRowIdx);
   virtual bool IsProbablyLayoutTable();
 
   // nsAccessNode
   virtual void Shutdown();
 
--- a/accessible/src/jsat/AccessFu.jsm
+++ b/accessible/src/jsat/AccessFu.jsm
@@ -69,16 +69,17 @@ var AccessFu = {
 
     VirtualCursorController.attach(this.chromeWin);
 
     Services.obs.addObserver(this, 'accessible-event', false);
     this.chromeWin.addEventListener('DOMActivate', this, true);
     this.chromeWin.addEventListener('resize', this, true);
     this.chromeWin.addEventListener('scroll', this, true);
     this.chromeWin.addEventListener('TabOpen', this, true);
+    this.chromeWin.addEventListener('focus', this, true);
   },
 
   /**
    * Disable AccessFu and return to default interaction mode.
    */
   _disable: function _disable() {
     if (!this._enabled)
       return;
@@ -91,16 +92,17 @@ var AccessFu = {
 
     VirtualCursorController.detach();
 
     Services.obs.removeObserver(this, 'accessible-event');
     this.chromeWin.removeEventListener('DOMActivate', this, true);
     this.chromeWin.removeEventListener('resize', this, true);
     this.chromeWin.removeEventListener('scroll', this, true);
     this.chromeWin.removeEventListener('TabOpen', this, true);
+    this.chromeWin.removeEventListener('focus', this, true);
   },
 
   _processPreferences: function _processPreferences(aPref) {
     if (Services.appinfo.OS == 'Android') {
       if (aPref == ACCESSFU_AUTO) {
         if (!this._observingSystemSettings) {
           Services.obs.addObserver(this, 'Accessibility:Settings', false);
           this._observingSystemSettings = true;
@@ -125,16 +127,29 @@ var AccessFu = {
 
   addPresenter: function addPresenter(presenter) {
     this.presenters.push(presenter);
     presenter.attach(this.chromeWin);
   },
 
   handleEvent: function handleEvent(aEvent) {
     switch (aEvent.type) {
+      case 'focus':
+      {
+        if (aEvent.target instanceof Ci.nsIDOMWindow) {
+          let docAcc = getAccessible(aEvent.target.document);
+          let docContext = new PresenterContext(docAcc, null);
+          let cursorable = docAcc.QueryInterface(Ci.nsIAccessibleCursorable);
+          let vcContext = new PresenterContext(
+            (cursorable) ? cursorable.virtualCursor.position : null, null);
+          this.presenters.forEach(
+            function(p) { p.tabSelected(docContext, vcContext); });
+        }
+        break;
+      }
       case 'TabOpen':
       {
         let browser = aEvent.target.linkedBrowser || aEvent.target;
         // Store the new browser node. We will need to check later when a new
         // content document is attached if it has been attached to this new tab.
         // If it has, than we will need to send a 'loading' message along with
         // the usual 'newdoc' to presenters.
         this._pendingDocuments[browser] = true;
@@ -197,17 +212,18 @@ var AccessFu = {
         {
           let pivot = aEvent.accessible.
             QueryInterface(Ci.nsIAccessibleCursorable).virtualCursor;
           let event = aEvent.
             QueryInterface(Ci.nsIAccessibleVirtualCursorChangeEvent);
           let position = pivot.position;
           let doc = aEvent.DOMNode;
 
-          if (doc instanceof Ci.nsIDOMDocument && position.DOMNode) {
+          if (position && position.DOMNode &&
+              doc instanceof Ci.nsIDOMDocument) {
             // Set the caret to the start of the pivot position, and move
             // the focus in the same manner as browse with caret mode.
             // This blurs the focus on the previous pivot position (if it
             // was activated), and keeps us in a predictable spot for tab
             // focus.
             let sel = doc.getSelection();
             sel.collapse(position.DOMNode, 0);
             Cc["@mozilla.org/focus-manager;1"]
@@ -302,30 +318,16 @@ var AccessFu = {
         {
           this.presenters.forEach(
             function(p) {
               p.tabStateChanged(aEvent.accessible, 'reload');
             }
           );
           break;
         }
-      case Ci.nsIAccessibleEvent.EVENT_FOCUS:
-        {
-          if (this._isBrowserDoc(aEvent.accessible)) {
-            // The document recieved focus, call tabSelected to present current tab.
-            let docContext = new PresenterContext(aEvent.accessible, null);
-            let cursorable = aEvent.accessible.
-              QueryInterface(Ci.nsIAccessibleCursorable);
-            let vcContext = new PresenterContext(
-              (cursorable) ? cursorable.virtualCursor.position : null, null);
-            this.presenters.forEach(
-              function(p) { p.tabSelected(docContext, vcContext); });
-          }
-          break;
-        }
       case Ci.nsIAccessibleEvent.EVENT_TEXT_INSERTED:
       case Ci.nsIAccessibleEvent.EVENT_TEXT_REMOVED:
       {
         if (aEvent.isFromUserInput) {
           // XXX support live regions as well.
           let event = aEvent.QueryInterface(Ci.nsIAccessibleTextChangeEvent);
           let isInserted = event.isInserted();
           let textIface = aEvent.accessible.QueryInterface(Ci.nsIAccessibleText);
--- a/accessible/src/jsat/Presenters.jsm
+++ b/accessible/src/jsat/Presenters.jsm
@@ -229,16 +229,19 @@ AndroidPresenter.prototype = {
   ANDROID_VIEW_CLICKED: 0x01,
   ANDROID_VIEW_LONG_CLICKED: 0x02,
   ANDROID_VIEW_SELECTED: 0x04,
   ANDROID_VIEW_FOCUSED: 0x08,
   ANDROID_VIEW_TEXT_CHANGED: 0x10,
   ANDROID_WINDOW_STATE_CHANGED: 0x20,
 
   pivotChanged: function AndroidPresenter_pivotChanged(aContext) {
+    if (!aContext.accessible)
+      return;
+
     let output = [];
     for (let i in aContext.newAncestry)
       output.push.apply(
         output, UtteranceGenerator.genForObject(aContext.newAncestry[i]));
 
     output.push.apply(output,
                       UtteranceGenerator.genForObject(aContext.accessible,
                                                       true));
@@ -332,17 +335,18 @@ DummyAndroidPresenter.prototype = {
 };
 
 /**
  * PresenterContext: An object that generates and caches context information
  * for a given accessible and its relationship with another accessible.
  */
 function PresenterContext(aAccessible, aOldAccessible) {
   this._accessible = aAccessible;
-  this._oldAccessible = aOldAccessible;
+  this._oldAccessible =
+    this._isDefunct(aOldAccessible) ? null : aOldAccessible;
 }
 
 PresenterContext.prototype = {
   get accessible() {
     return this._accessible;
   },
 
   get oldAccessible() {
@@ -382,10 +386,20 @@ PresenterContext.prototype = {
         if (newAncestor != oldAncestor)
           this._newAncestry.push(newAncestor);
         i++;
       }
 
     }
 
     return this._newAncestry;
+  },
+
+  _isDefunct: function _isDefunct(aAccessible) {
+    try {
+      let extstate = {};
+      aAccessible.getState({}, extstate);
+      return !!(aAccessible.value & Ci.nsIAccessibleStates.EXT_STATE_DEFUNCT);
+    } catch (x) {
+      return true;
+    }
   }
 };
--- a/accessible/src/jsat/VirtualCursorController.jsm
+++ b/accessible/src/jsat/VirtualCursorController.jsm
@@ -104,26 +104,36 @@ var VirtualCursorController = {
     return this.NOT_EDITABLE;
   },
 
   moveForward: function moveForward(document, last) {
     let virtualCursor = this.getVirtualCursor(document);
     if (last) {
       virtualCursor.moveLast(this.SimpleTraversalRule);
     } else {
-      virtualCursor.moveNext(this.SimpleTraversalRule);
+      try {
+        virtualCursor.moveNext(this.SimpleTraversalRule);
+      } catch (x) {
+        virtualCursor.position =
+          gAccRetrieval.getAccessibleFor(document.activeElement);
+      }
     }
   },
 
   moveBackward: function moveBackward(document, first) {
     let virtualCursor = this.getVirtualCursor(document);
     if (first) {
       virtualCursor.moveFirst(this.SimpleTraversalRule);
     } else {
-      virtualCursor.movePrevious(this.SimpleTraversalRule);
+      try {
+        virtualCursor.movePrevious(this.SimpleTraversalRule);
+      } catch (x) {
+        virtualCursor.position =
+          gAccRetrieval.getAccessibleFor(document.activeElement);
+      }
     }
   },
 
   activateCurrent: function activateCurrent(document) {
     let virtualCursor = this.getVirtualCursor(document);
     let acc = virtualCursor.position;
 
     if (acc.numActions > 0)
--- a/accessible/src/msaa/Makefile.in
+++ b/accessible/src/msaa/Makefile.in
@@ -27,17 +27,17 @@ CPPSRCS = \
   nsXULListboxAccessibleWrap.cpp \
   nsXULTreeGridAccessibleWrap.cpp \
   nsHyperTextAccessibleWrap.cpp \
   nsHTMLImageAccessibleWrap.cpp \
   nsHTMLTableAccessibleWrap.cpp \
   nsWinUtils.cpp \
   ia2AccessibleAction.cpp \
   ia2AccessibleComponent.cpp \
-  CAccessibleImage.cpp \
+  ia2AccessibleImage.cpp \
   CAccessibleText.cpp \
   CAccessibleEditableText.cpp \
   CAccessibleHyperlink.cpp \
   ia2AccessibleHypertext.cpp \
   ia2AccessibleRelation.cpp \
   CAccessibleTable.cpp \
   CAccessibleTableCell.cpp \
   CAccessibleValue.cpp \
rename from accessible/src/msaa/CAccessibleImage.cpp
rename to accessible/src/msaa/ia2AccessibleImage.cpp
--- a/accessible/src/msaa/CAccessibleImage.cpp
+++ b/accessible/src/msaa/ia2AccessibleImage.cpp
@@ -1,58 +1,57 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:expandtab:shiftwidth=2:tabstop=2:
  */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "CAccessibleImage.h"
+#include "ia2AccessibleImage.h"
 
 #include "AccessibleImage_i.c"
 
+#include "nsHTMLImageAccessibleWrap.h"
+#include "nsHTMLImageAccessible.h"
+
 #include "nsIAccessible.h"
 #include "nsIAccessibleImage.h"
 #include "nsIAccessibleTypes.h"
 #include "nsAccessNodeWrap.h"
 
-#include "nsCOMPtr.h"
 #include "nsString.h"
 
 // IUnknown
 
 STDMETHODIMP
-CAccessibleImage::QueryInterface(REFIID iid, void** ppv)
+ia2AccessibleImage::QueryInterface(REFIID iid, void** ppv)
 {
   *ppv = NULL;
 
   if (IID_IAccessibleImage == iid) {
-    nsCOMPtr<nsIAccessibleImage> imageAcc(do_QueryObject(this));
-    if (!imageAcc)
-      return E_FAIL;
-
     *ppv = static_cast<IAccessibleImage*>(this);
-    (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
+    (static_cast<IUnknown*>(*ppv))->AddRef();
     return S_OK;
   }
 
   return E_NOINTERFACE;
 }
 
 // IAccessibleImage
 
 STDMETHODIMP
-CAccessibleImage::get_description(BSTR *aDescription)
+ia2AccessibleImage::get_description(BSTR* aDescription)
 {
 __try {
   *aDescription = NULL;
 
-  nsCOMPtr<nsIAccessible> acc(do_QueryObject(this));
-  if (!acc)
-    return E_FAIL;
+  nsHTMLImageAccessibleWrap* acc =
+    static_cast<nsHTMLImageAccessibleWrap*>(this);
+  if (acc->IsDefunct())
+    return CO_E_OBJNOTCONNECTED;
 
   nsAutoString description;
   nsresult rv = acc->GetName(description);
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
 
   if (description.IsEmpty())
     return S_FALSE;
@@ -60,58 +59,60 @@ CAccessibleImage::get_description(BSTR *
   *aDescription = ::SysAllocStringLen(description.get(), description.Length());
   return *aDescription ? S_OK : E_OUTOFMEMORY;
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
-CAccessibleImage::get_imagePosition(enum IA2CoordinateType aCoordType,
-                                    long *aX,
-                                    long *aY)
+ia2AccessibleImage::get_imagePosition(enum IA2CoordinateType aCoordType,
+                                      long* aX,
+                                      long* aY)
 {
 __try {
   *aX = 0;
   *aY = 0;
 
+  nsHTMLImageAccessibleWrap* imageAcc =
+    static_cast<nsHTMLImageAccessibleWrap*>(this);
+  if (imageAcc->IsDefunct())
+    return CO_E_OBJNOTCONNECTED;
+
   PRUint32 geckoCoordType = (aCoordType == IA2_COORDTYPE_SCREEN_RELATIVE) ?
     nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE :
     nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE;
+  PRInt32 x = 0, y = 0;
 
-  nsCOMPtr<nsIAccessibleImage> imageAcc(do_QueryObject(this));
-  if (!imageAcc)
-    return E_FAIL;
-
-  PRInt32 x = 0, y = 0;
   nsresult rv = imageAcc->GetImagePosition(geckoCoordType, &x, &y);
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
 
   *aX = x;
   *aY = y;
   return S_OK;
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
 
   return E_FAIL;
 }
 
 STDMETHODIMP
-CAccessibleImage::get_imageSize(long *aHeight, long *aWidth)
+ia2AccessibleImage::get_imageSize(long* aHeight, long* aWidth)
 {
 __try {
   *aHeight = 0;
   *aWidth = 0;
 
-  nsCOMPtr<nsIAccessibleImage> imageAcc(do_QueryObject(this));
-  if (!imageAcc)
-    return E_FAIL;
+  nsHTMLImageAccessibleWrap* imageAcc =
+    static_cast<nsHTMLImageAccessibleWrap*>(this);
+  if (imageAcc->IsDefunct())
+    return CO_E_OBJNOTCONNECTED;
 
-  PRInt32 x = 0, y = 0, width = 0, height = 0;
+  PRInt32 width = 0, height = 0;
   nsresult rv = imageAcc->GetImageSize(&width, &height);
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
 
   *aHeight = width;
   *aWidth = height;
   return S_OK;
 
rename from accessible/src/msaa/CAccessibleImage.h
rename to accessible/src/msaa/ia2AccessibleImage.h
--- a/accessible/src/msaa/CAccessibleImage.h
+++ b/accessible/src/msaa/ia2AccessibleImage.h
@@ -3,21 +3,19 @@
  */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef _ACCESSIBLE_IMAGE_H
 #define _ACCESSIBLE_IMAGE_H
 
-#include "nsISupports.h"
-
 #include "AccessibleImage.h"
 
-class CAccessibleImage: public IAccessibleImage
+class ia2AccessibleImage : public IAccessibleImage
 {
 public:
 
   // IUnknown
   STDMETHODIMP QueryInterface(REFIID, void**);
 
   // IAccessibleImage
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_description(
@@ -26,16 +24,12 @@ public:
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_imagePosition(
       /* [in] */ enum IA2CoordinateType coordinateType,
       /* [out] */ long *x,
       /* [retval][out] */ long *y);
 
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_imageSize(
       /* [out] */ long *height,
       /* [retval][out] */ long *width);
-
-  // nsISupports
-  NS_IMETHOD QueryInterface(const nsIID& uuid, void** result) = 0;
-
 };
 
 #endif
 
--- a/accessible/src/msaa/nsHTMLImageAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsHTMLImageAccessibleWrap.cpp
@@ -7,10 +7,10 @@
 
 #include "nsHTMLImageAccessibleWrap.h"
 
 NS_IMPL_ISUPPORTS_INHERITED0(nsHTMLImageAccessibleWrap,
                              nsHTMLImageAccessible)
 
 IMPL_IUNKNOWN_INHERITED1(nsHTMLImageAccessibleWrap,
                          nsAccessibleWrap,
-                         CAccessibleImage);
+                         ia2AccessibleImage);
 
--- a/accessible/src/msaa/nsHTMLImageAccessibleWrap.h
+++ b/accessible/src/msaa/nsHTMLImageAccessibleWrap.h
@@ -4,20 +4,20 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef _NSHTMLIMAGEACCESSIBLEWRAP_H
 #define _NSHTMLIMAGEACCESSIBLEWRAP_H
 
 #include "nsHTMLImageAccessible.h"
-#include "CAccessibleImage.h"
+#include "ia2AccessibleImage.h"
 
 class nsHTMLImageAccessibleWrap : public nsHTMLImageAccessible,
-                                  public CAccessibleImage
+                                  public ia2AccessibleImage
 {
 public:
   nsHTMLImageAccessibleWrap(nsIContent* aContent, nsDocAccessible* aDoc) :
     nsHTMLImageAccessible(aContent, aDoc) {}
 
   // IUnknown
   DECL_IUNKNOWN_INHERITED
 
--- a/accessible/src/xpcom/xpcAccessibleTable.cpp
+++ b/accessible/src/xpcom/xpcAccessibleTable.cpp
@@ -43,16 +43,34 @@ xpcAccessibleTable::GetRowCount(PRInt32*
   if (!mTable)
     return NS_ERROR_FAILURE;
 
   *aRowCount = mTable->RowCount();
   return NS_OK;
 }
 
 nsresult
+xpcAccessibleTable::GetCellAt(PRInt32 aRowIndex, PRInt32 aColumnIndex,
+                              nsIAccessible** aCell)
+{ 
+  NS_ENSURE_ARG_POINTER(aCell);
+  *aCell = nsnull;
+
+  if (!mTable)
+    return NS_ERROR_FAILURE;
+
+  if (aRowIndex < 0 || aRowIndex >= mTable->RowCount() ||
+      aColumnIndex < 0 || aColumnIndex >= mTable->ColCount())
+    return NS_ERROR_INVALID_ARG;
+
+  NS_IF_ADDREF(*aCell = mTable->CellAt(aRowIndex, aColumnIndex));
+  return NS_OK;
+}
+
+nsresult
 xpcAccessibleTable::GetCellIndexAt(PRInt32 aRowIndex, PRInt32 aColumnIndex,
                                    PRInt32* aCellIndex)
 {
   NS_ENSURE_ARG_POINTER(aCellIndex);
   *aCellIndex = -1;
 
   if (!mTable)
     return NS_ERROR_FAILURE;
--- a/accessible/src/xpcom/xpcAccessibleTable.h
+++ b/accessible/src/xpcom/xpcAccessibleTable.h
@@ -21,16 +21,18 @@ class xpcAccessibleTable
 {
 public:
   xpcAccessibleTable(mozilla::a11y::TableAccessible* aTable) : mTable(aTable) { }
 
   nsresult GetCaption(nsIAccessible** aCaption);
   nsresult GetSummary(nsAString& aSummary);
   nsresult GetColumnCount(PRInt32* aColumnCount);
   nsresult GetRowCount(PRInt32* aRowCount);
+  nsresult GetCellAt(PRInt32 aRowIndex, PRInt32 aColumnIndex,
+                     nsIAccessible** aCell);
   nsresult GetCellIndexAt(PRInt32 aRowIndex, PRInt32 aColumnIndex,
                           PRInt32* aCellIndex);
   nsresult UnselectColumn(PRInt32 aColIdx);
   nsresult UnselectRow(PRInt32 aRowIdx);
   nsresult IsProbablyForLayout(bool* aIsForLayout);
 
 protected:
   mozilla::a11y::TableAccessible* mTable;
@@ -40,17 +42,18 @@ protected:
   NS_IMETHOD GetCaption(nsIAccessible** aCaption) \
     { return xpcAccessibleTable::GetCaption(aCaption); } \
   NS_SCRIPTABLE NS_IMETHOD GetSummary(nsAString & aSummary) \
     { return xpcAccessibleTable::GetSummary(aSummary); } \
   NS_SCRIPTABLE NS_IMETHOD GetColumnCount(PRInt32* aColumnCount) \
     { return xpcAccessibleTable::GetColumnCount(aColumnCount); } \
   NS_SCRIPTABLE NS_IMETHOD GetRowCount(PRInt32* aRowCount) \
     { return xpcAccessibleTable::GetRowCount(aRowCount); } \
-  NS_SCRIPTABLE NS_IMETHOD GetCellAt(PRInt32 rowIndex, PRInt32 columnIndex, nsIAccessible * *_retval NS_OUTPARAM); \
+  NS_SCRIPTABLE NS_IMETHOD GetCellAt(PRInt32 rowIndex, PRInt32 columnIndex, nsIAccessible** _retval NS_OUTPARAM) \
+    { return xpcAccessibleTable::GetCellAt(rowIndex, columnIndex, _retval); } \
   NS_SCRIPTABLE NS_IMETHOD GetCellIndexAt(PRInt32 rowIndex, PRInt32 columnIndex, PRInt32 *_retval NS_OUTPARAM) \
     { return xpcAccessibleTable::GetCellIndexAt(rowIndex, columnIndex, _retval); } \
   NS_SCRIPTABLE NS_IMETHOD GetColumnIndexAt(PRInt32 cellIndex, PRInt32 *_retval NS_OUTPARAM); \
   NS_SCRIPTABLE NS_IMETHOD GetRowIndexAt(PRInt32 cellIndex, PRInt32 *_retval NS_OUTPARAM); \
   NS_SCRIPTABLE NS_IMETHOD GetRowAndColumnIndicesAt(PRInt32 cellIndex, PRInt32 *rowIndex NS_OUTPARAM, PRInt32 *columnIndex NS_OUTPARAM); \
   NS_SCRIPTABLE NS_IMETHOD GetColumnExtentAt(PRInt32 row, PRInt32 column, PRInt32 *_retval NS_OUTPARAM); \
   NS_SCRIPTABLE NS_IMETHOD GetRowExtentAt(PRInt32 row, PRInt32 column, PRInt32 *_retval NS_OUTPARAM); \
   NS_SCRIPTABLE NS_IMETHOD GetColumnDescription(PRInt32 columnIndex, nsAString & _retval NS_OUTPARAM); \
--- a/accessible/src/xul/nsXULListboxAccessible.cpp
+++ b/accessible/src/xul/nsXULListboxAccessible.cpp
@@ -239,42 +239,36 @@ nsXULListboxAccessible::RowCount()
 
   PRUint32 itemCount = 0;
   if(element)
     element->GetItemCount(&itemCount);
 
   return itemCount;
 }
 
-NS_IMETHODIMP
-nsXULListboxAccessible::GetCellAt(PRInt32 aRow, PRInt32 aColumn,
-                                  nsIAccessible **aAccessibleCell)
-{
-  NS_ENSURE_ARG_POINTER(aAccessibleCell);
-  *aAccessibleCell = nsnull;
-
-  if (IsDefunct())
-    return NS_OK;
-
+nsAccessible*
+nsXULListboxAccessible::CellAt(PRUint32 aRowIndex, PRUint32 aColumnIndex)
+{ 
   nsCOMPtr<nsIDOMXULSelectControlElement> control =
     do_QueryInterface(mContent);
+  NS_ENSURE_TRUE(control, nsnull);
 
   nsCOMPtr<nsIDOMXULSelectControlItemElement> item;
-  control->GetItemAtIndex(aRow, getter_AddRefs(item));
-  NS_ENSURE_TRUE(item, NS_ERROR_INVALID_ARG);
+  control->GetItemAtIndex(aRowIndex, getter_AddRefs(item));
+  if (!item)
+    return nsnull;
 
   nsCOMPtr<nsIContent> itemContent(do_QueryInterface(item));
-  NS_ENSURE_TRUE(mDoc, NS_ERROR_FAILURE);
-  nsAccessible *row = mDoc->GetAccessible(itemContent);
-  NS_ENSURE_STATE(row);
+  if (!itemContent)
+    return nsnull;
 
-  nsresult rv = row->GetChildAt(aColumn, aAccessibleCell);
-  NS_ENSURE_SUCCESS(rv, NS_ERROR_INVALID_ARG);
+  nsAccessible* row = mDoc->GetAccessible(itemContent);
+  NS_ENSURE_TRUE(row, nsnull);
 
-  return NS_OK;
+  return row->GetChildAt(aColumnIndex);
 }
 
 NS_IMETHODIMP
 nsXULListboxAccessible::GetColumnIndexAt(PRInt32 aIndex, PRInt32 *aColumn)
 {
   NS_ENSURE_ARG_POINTER(aColumn);
   *aColumn = -1;
 
--- a/accessible/src/xul/nsXULListboxAccessible.h
+++ b/accessible/src/xul/nsXULListboxAccessible.h
@@ -67,16 +67,17 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIAccessibleTable
   NS_DECL_OR_FORWARD_NSIACCESSIBLETABLE_WITH_XPCACCESSIBLETABLE
 
   // TableAccessible
   virtual PRUint32 ColCount();
   virtual PRUint32 RowCount();
+  virtual nsAccessible* CellAt(PRUint32 aRowIndex, PRUint32 aColumnIndex);
   virtual void UnselectRow(PRUint32 aRowIdx);
 
   // nsAccessNode
   virtual void Shutdown();
 
   // nsAccessible
   virtual void Value(nsString& aValue);
   virtual mozilla::a11y::TableAccessible* AsTable() { return this; }
--- a/accessible/src/xul/nsXULTreeGridAccessible.cpp
+++ b/accessible/src/xul/nsXULTreeGridAccessible.cpp
@@ -293,39 +293,33 @@ nsXULTreeGridAccessible::GetSelectedRowI
       outArray[arrayIdx++] = rowIdx;
   }
 
   *arowCount = selectedrowCount;
   *aRows = outArray;
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsXULTreeGridAccessible::GetCellAt(PRInt32 aRowIndex, PRInt32 aColumnIndex,
-                                   nsIAccessible **aCell)
-{
-  NS_ENSURE_ARG_POINTER(aCell);
-  *aCell = nsnull;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  nsAccessible *rowAccessible = GetTreeItemAccessible(aRowIndex);
-  if (!rowAccessible)
-    return NS_ERROR_INVALID_ARG;
+nsAccessible*
+nsXULTreeGridAccessible::CellAt(PRUint32 aRowIndex, PRUint32 aColumnIndex)
+{ 
+  nsAccessible* row = GetTreeItemAccessible(aRowIndex);
+  if (!row)
+    return nsnull;
 
   nsCOMPtr<nsITreeColumn> column =
-  nsCoreUtils::GetSensibleColumnAt(mTree, aColumnIndex);
+    nsCoreUtils::GetSensibleColumnAt(mTree, aColumnIndex);
   if (!column)
-    return NS_ERROR_INVALID_ARG;
+    return nsnull;
 
-  nsRefPtr<nsXULTreeItemAccessibleBase> rowAcc = do_QueryObject(rowAccessible);
+  nsRefPtr<nsXULTreeItemAccessibleBase> rowAcc = do_QueryObject(row);
+  if (!rowAcc)
+    return nsnull;
 
-  NS_IF_ADDREF(*aCell = rowAcc->GetCellAccessible(column));
-  return NS_OK;
+  return rowAcc->GetCellAccessible(column);
 }
 
 NS_IMETHODIMP
 nsXULTreeGridAccessible::GetColumnIndexAt(PRInt32 aCellIndex,
                                           PRInt32 *aColumnIndex)
 {
   NS_ENSURE_ARG_POINTER(aColumnIndex);
   *aColumnIndex = -1;
--- a/accessible/src/xul/nsXULTreeGridAccessible.h
+++ b/accessible/src/xul/nsXULTreeGridAccessible.h
@@ -25,16 +25,17 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIAccessibleTable
   NS_DECL_OR_FORWARD_NSIACCESSIBLETABLE_WITH_XPCACCESSIBLETABLE
 
   // TableAccessible
   virtual PRUint32 ColCount();
   virtual PRUint32 RowCount();
+  virtual nsAccessible* CellAt(PRUint32 aRowIndex, PRUint32 aColumnIndex);
   virtual void UnselectRow(PRUint32 aRowIdx);
 
   // nsAccessNode
   virtual void Shutdown();
 
   // nsAccessible
   virtual mozilla::a11y::TableAccessible* AsTable() { return this; }
   virtual mozilla::a11y::role NativeRole();
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -159,16 +159,17 @@
 @BINPATH@/components/dom_battery.xpt
 #ifdef MOZ_B2G_BT
 @BINPATH@/components/dom_bluetooth.xpt
 #endif
 @BINPATH@/components/dom_canvas.xpt
 @BINPATH@/components/dom_contacts.xpt
 @BINPATH@/components/dom_core.xpt
 @BINPATH@/components/dom_css.xpt
+@BINPATH@/components/dom_devicestorage.xpt
 @BINPATH@/components/dom_events.xpt
 @BINPATH@/components/dom_geolocation.xpt
 @BINPATH@/components/dom_network.xpt
 @BINPATH@/components/dom_notification.xpt
 @BINPATH@/components/dom_html.xpt
 @BINPATH@/components/dom_indexeddb.xpt
 @BINPATH@/components/dom_offline.xpt
 @BINPATH@/components/dom_json.xpt
--- a/browser/base/content/test/browser_tabMatchesInAwesomebar.js
+++ b/browser/base/content/test/browser_tabMatchesInAwesomebar.js
@@ -97,17 +97,17 @@ var gTestSteps = [
     tab.linkedBrowser.addEventListener("load", function () {
       tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
       gBrowser.swapBrowsersAndCloseOther(tabToKeep, tab);
       ensure_opentabs_match_db(function () {
         gBrowser.removeTab(tabToKeep);
         ensure_opentabs_match_db(nextStep);
       });
     }, true);
-    tab.linkedBrowser.loadURI('about:robots');
+    tab.linkedBrowser.loadURI("about:mozilla");
   },
   function() {
     info("Running step 9 - enter private browsing mode, without keeping session");
     let ps = Services.prefs;
     ps.setBoolPref("browser.privatebrowsing.keep_current_session", false);
     ps.setBoolPref("browser.tabs.warnOnClose", false);
 
     Services.obs.addObserver(function(aSubject, aTopic, aData) {
--- a/browser/base/content/test/browser_visibleTabs_bookmarkAllTabs.js
+++ b/browser/base/content/test/browser_visibleTabs_bookmarkAllTabs.js
@@ -10,17 +10,17 @@ function test() {
   is(gBrowser.visibleTabs.length, 1, "1 tab should be open");  
   is(Disabled(), true, "Bookmark All Tabs should be disabled");
 
   // Add a tab
   let testTab1 = gBrowser.addTab();
   is(gBrowser.visibleTabs.length, 2, "2 tabs should be open");
   is(Disabled(), true, "Bookmark All Tabs should be disabled since there are two tabs with the same address");
 
-  let testTab2 = gBrowser.addTab("about:robots");
+  let testTab2 = gBrowser.addTab("about:mozilla");
   is(gBrowser.visibleTabs.length, 3, "3 tabs should be open");
   // Wait for tab load, the code checks for currentURI.
   testTab2.linkedBrowser.addEventListener("load", function () {
     testTab2.linkedBrowser.removeEventListener("load", arguments.callee, true);
     is(Disabled(), false, "Bookmark All Tabs should be enabled since there are two tabs with different addresses");
 
     // Hide the original tab
     gBrowser.selectedTab = testTab2;
--- a/browser/components/places/tests/browser/framedPage.html
+++ b/browser/components/places/tests/browser/framedPage.html
@@ -1,9 +1,9 @@
 <html>
   <head>
     <title>Framed page</title>
   </head>
   <frameset cols="*,*">
     <frame name="left" src="frameLeft.html">
-    <frame name="right" src="about:robots">
+    <frame name="right" src="about:mozilla">
   </frameset>
 </html>
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_zoom.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_zoom.js
@@ -15,48 +15,48 @@ function test() {
   pb.privateBrowsingEnabled = true;
 
   let tabAbout = gBrowser.addTab();
   gBrowser.selectedTab = tabAbout;
 
   waitForExplicitFinish();
 
   let aboutBrowser = gBrowser.getBrowserForTab(tabAbout);
-  aboutBrowser.addEventListener("load", function () {
-    aboutBrowser.removeEventListener("load", arguments.callee, true);
-    let tabRobots = gBrowser.addTab();
-    gBrowser.selectedTab = tabRobots;
+  aboutBrowser.addEventListener("load", function onAboutBrowserLoad() {
+    aboutBrowser.removeEventListener("load", onAboutBrowserLoad, true);
+    let tabMozilla = gBrowser.addTab();
+    gBrowser.selectedTab = tabMozilla;
 
-    let robotsBrowser = gBrowser.getBrowserForTab(tabRobots);
-    robotsBrowser.addEventListener("load", function () {
-      robotsBrowser.removeEventListener("load", arguments.callee, true);
-      let robotsZoom = ZoomManager.zoom;
+    let mozillaBrowser = gBrowser.getBrowserForTab(tabMozilla);
+    mozillaBrowser.addEventListener("load", function onMozillaBrowserLoad() {
+      mozillaBrowser.removeEventListener("load", onMozillaBrowserLoad, true);
+      let mozillaZoom = ZoomManager.zoom;
 
-      // change the zoom on the robots page
+      // change the zoom on the mozilla page
       FullZoom.enlarge();
       // make sure the zoom level has been changed
-      isnot(ZoomManager.zoom, robotsZoom, "Zoom level can be changed");
-      robotsZoom = ZoomManager.zoom;
+      isnot(ZoomManager.zoom, mozillaZoom, "Zoom level can be changed");
+      mozillaZoom = ZoomManager.zoom;
 
       // switch to about: tab
       gBrowser.selectedTab = tabAbout;
 
-      // switch back to robots tab
-      gBrowser.selectedTab = tabRobots;
+      // switch back to mozilla tab
+      gBrowser.selectedTab = tabMozilla;
 
       // make sure the zoom level has not changed
-      is(ZoomManager.zoom, robotsZoom,
+      is(ZoomManager.zoom, mozillaZoom,
         "Entering private browsing should not reset the zoom on a tab");
 
       // leave private browsing mode
       pb.privateBrowsingEnabled = false;
 
       // cleanup
       gPrefService.clearUserPref("browser.privatebrowsing.keep_current_session");
       FullZoom.reset();
-      gBrowser.removeTab(tabRobots);
+      gBrowser.removeTab(tabMozilla);
       gBrowser.removeTab(tabAbout);
       finish();
     }, true);
-    robotsBrowser.contentWindow.location = "about:robots";
+    mozillaBrowser.contentWindow.location = "about:mozilla";
   }, true);
   aboutBrowser.contentWindow.location = "about:";
 }
--- a/browser/components/tabview/test/browser_tabview_bug586553.js
+++ b/browser/components/tabview/test/browser_tabview_bug586553.js
@@ -19,20 +19,20 @@ function onTabMove(e) {
 }
 
 function onTabViewWindowLoaded() {
   window.removeEventListener("tabviewshown", onTabViewWindowLoaded, false);
   
   contentWindow = document.getElementById("tab-view").contentWindow;
   
   originalTab = gBrowser.selectedTab;
-  newTabs = [gBrowser.addTab("about:robots"), gBrowser.addTab("about:mozilla"), gBrowser.addTab("about:license")];
+  newTabs = [gBrowser.addTab("about:rights"), gBrowser.addTab("about:mozilla"), gBrowser.addTab("about:license")];
 
   is(originalTab._tPos, 0, "Original tab is in position 0");
-  is(newTabs[0]._tPos, 1, "Robots is in position 1");
+  is(newTabs[0]._tPos, 1, "Rights is in position 1");
   is(newTabs[1]._tPos, 2, "Mozilla is in position 2");
   is(newTabs[2]._tPos, 3, "License is in position 3");
   
   gBrowser.tabContainer.addEventListener("TabMove", onTabMove, false);
     
   let groupItem = contentWindow.GroupItems.getActiveGroupItem();
   
   // move 3 > 0 (and therefore 0 > 1, 1 > 2, 2 > 3)
@@ -46,16 +46,16 @@ function onTabViewWindowLoaded() {
 function onTabViewWindowHidden() {
   window.removeEventListener("tabviewhidden", onTabViewWindowHidden, false);
   gBrowser.tabContainer.removeEventListener("TabMove", onTabMove, false);
   
   is(moves, 1, "Only one move should be necessary for this basic move.");
 
   is(newTabs[2]._tPos, 0, "License is in position 0");
   is(originalTab._tPos, 1, "Original tab is in position 1");
-  is(newTabs[0]._tPos, 2, "Robots is in position 2");
+  is(newTabs[0]._tPos, 2, "Rights is in position 2");
   is(newTabs[1]._tPos, 3, "Mozilla is in position 3");
   
   gBrowser.removeTab(newTabs[0]);
   gBrowser.removeTab(newTabs[1]);
   gBrowser.removeTab(newTabs[2]);
   finish();
 }
--- a/browser/components/tabview/test/browser_tabview_bug587276.js
+++ b/browser/components/tabview/test/browser_tabview_bug587276.js
@@ -35,17 +35,17 @@ function test2() {
 function test3() {
   ok(!contentWindow.Search.isEnabled(), "The search is disabled")
 
   is(gBrowser.tabs.length, 1, "There is one tab before cmd/ctrl + t is pressed");
 
   whenTabViewIsHidden(function() { 
     is(gBrowser.tabs.length, 2, "There are two tabs after cmd/ctrl + t is pressed");
 
-    gBrowser.tabs[0].linkedBrowser.loadURI("about:robots");
+    gBrowser.tabs[0].linkedBrowser.loadURI("about:mozilla");
     gBrowser.tabs[1].linkedBrowser.loadURI("http://example.com/");
 
     afterAllTabsLoaded(function () {
       showTabView(test4);
     });
   });
   EventUtils.synthesizeKey("t", { accelKey: true }, contentWindow);
 }
--- a/browser/components/tabview/test/browser_tabview_bug610242.js
+++ b/browser/components/tabview/test/browser_tabview_bug610242.js
@@ -24,17 +24,17 @@ function onTabViewWindowLoaded(win) {
   contentWindow.UI.setActive(group);
   is(contentWindow.GroupItems.getActiveGroupItem(), group, "new group is active");
   
   // Create a bunch of tabs in the group
   let bg = {inBackground: true};
   let datatext = win.gBrowser.loadOneTab("data:text/plain,bug610242", bg);
   let datahtml = win.gBrowser.loadOneTab("data:text/html,<blink>don't blink!</blink>", bg);
   let mozilla  = win.gBrowser.loadOneTab("about:mozilla", bg);
-  let robots   = win.gBrowser.loadOneTab("about:robots", bg);
+  let synclog   = win.gBrowser.loadOneTab("about:sync-log", bg);
   let html     = win.gBrowser.loadOneTab("http://example.com", bg);
   let png      = win.gBrowser.loadOneTab("http://mochi.test:8888/browser/browser/base/content/test/moz.png", bg);
   let svg      = win.gBrowser.loadOneTab("http://mochi.test:8888/browser/browser/base/content/test/title_test.svg", bg);
   
   ok(!group.shouldStack(group._children.length), "Group should not stack.");
   
   // PREPARE FINISH:
   group.addSubscriber("close", function onClose() {
@@ -74,17 +74,17 @@ function onTabViewWindowLoaded(win) {
     children.forEach(function(tabItem) {
       tabItem.addSubscriber("iconUpdated", function onIconUpdated() {
         tabItem.removeSubscriber("iconUpdated", onIconUpdated);
 
         if (++iconUpdateCounter == len) {
           check(datatext, "datatext", false);
           check(datahtml, "datahtml", false);
           check(mozilla, "about:mozilla", false);
-          check(robots, "about:robots", true);
+          check(synclog, "about:sync-log", true);
           check(html, "html", true);
           check(png, "png", false);
           check(svg, "svg", true);
 
           // Get rid of the group and its children
           // The group close will trigger a finish().
           closeGroupItem(group);
         }
--- a/browser/components/tabview/test/browser_tabview_bug650573.js
+++ b/browser/components/tabview/test/browser_tabview_bug650573.js
@@ -74,19 +74,19 @@ function createBrowserState() {
   let bounds = {left: 20, top: 20, width: 20, height: 20};
 
   let tabViewGroups = {nextID: 99, activeGroupId: 1};
   let tabViewGroup = {
     "1st-group-id": {bounds: bounds, title: "new group 1", id: "1st-group-id"},
     "2nd-group-id": {bounds: bounds, title: "new group 2", id: "2nd-group-id"}
   };
 
-  let tab1Data = {bounds: bounds, url: "about:robots", groupID: "2nd-group-id"};
+  let tab1Data = {bounds: bounds, url: "about:rights", groupID: "2nd-group-id"};
   let tab1 = {
-    entries: [{url: "about:robots"}],
+    entries: [{url: "about:rights"}],
     extData: {"tabview-tab": JSON.stringify(tab1Data)}
   };
 
   let tab2Data = {bounds: bounds, url: "about:mozilla", groupID: "1st-group-id"};
   let tab2 = {
     entries: [{url: "about:mozilla"}],
     extData: {"tabview-tab": JSON.stringify(tab2Data)}
   };
--- a/browser/components/tabview/test/browser_tabview_privatebrowsing.js
+++ b/browser/components/tabview/test/browser_tabview_privatebrowsing.js
@@ -47,17 +47,17 @@ function onTabViewLoadedAndShown() {
   for (let a = 0; a < count; a++) {
     let gi = contentWindow.GroupItems.groupItems[a];
     groupTitles[a] = gi.getTitle();
   }
 
   contentWindow.gPrefBranch.setBoolPref("animate_zoom", false);
 
   // Create a second tab
-  gBrowser.addTab("about:robots");
+  gBrowser.addTab("about:mozilla");
   is(gBrowser.tabs.length, 2, "we now have 2 tabs");
 
   registerCleanupFunction(function() {
     gBrowser.removeTab(gBrowser.tabs[1]);
     contentWindow.gPrefBranch.clearUserPref("animate_zoom");
   });
 
   afterAllTabsLoaded(function() {
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -165,16 +165,17 @@
 @BINPATH@/components/dom_battery.xpt
 #ifdef MOZ_B2G_BT
 @BINPATH@/components/dom_bluetooth.xpt
 #endif
 @BINPATH@/components/dom_canvas.xpt
 @BINPATH@/components/dom_contacts.xpt
 @BINPATH@/components/dom_core.xpt
 @BINPATH@/components/dom_css.xpt
+@BINPATH@/components/dom_devicestorage.xpt
 @BINPATH@/components/dom_events.xpt
 @BINPATH@/components/dom_geolocation.xpt
 @BINPATH@/components/dom_network.xpt
 @BINPATH@/components/dom_notification.xpt
 @BINPATH@/components/dom_html.xpt
 @BINPATH@/components/dom_indexeddb.xpt
 @BINPATH@/components/dom_offline.xpt
 @BINPATH@/components/dom_json.xpt
--- a/browser/installer/removed-files.in
+++ b/browser/installer/removed-files.in
@@ -1174,16 +1174,17 @@ xpicleanup@BIN_SUFFIX@
   components/dom_wifi.xpt
   components/dom_system_b2g.xpt
 #endif
   components/dom_canvas.xpt
   components/dom_core.xpt
   components/dom_css.xpt
   components/dom_events.xpt
   components/dom_geolocation.xpt
+  components/dom_devicestorage.xpt
   components/dom_html.xpt
   components/dom_json.xpt
   components/dom_loadsave.xpt
   components/dom_offline.xpt
   components/dom_range.xpt
   components/dom_sidebar.xpt
   components/dom_smil.xpt
   components/dom_storage.xpt
--- a/browser/modules/WebappsInstaller.jsm
+++ b/browser/modules/WebappsInstaller.jsm
@@ -570,18 +570,16 @@ MacNativeApp.prototype = {
     <key>CFBundleIdentifier</key>\n\
     <string>' + escapeXML(this.launchURI.prePath) + '</string>\n\
     <key>CFBundleInfoDictionaryVersion</key>\n\
     <string>6.0</string>\n\
     <key>CFBundleName</key>\n\
     <string>' + escapeXML(this.appName) + '</string>\n\
     <key>CFBundlePackageType</key>\n\
     <string>APPL</string>\n\
-    <key>CFBundleSignature</key>\n\
-    <string>MOZB</string>\n\
     <key>CFBundleVersion</key>\n\
     <string>0</string>\n\
     <key>FirefoxBinary</key>\n\
 #expand     <string>__MOZ_MACBUNDLE_ID__</string>\n\
   </dict>\n\
 </plist>';
 
     let infoPListFile = this.contentsDir.clone();
--- a/build/mobile/robocop/Driver.java.in
+++ b/build/mobile/robocop/Driver.java.in
@@ -9,18 +9,17 @@ import java.util.List;
 import android.app.Activity;
 
 public interface Driver {
     /**
      * Find the first Element using the given method.
      * 
      * @param activity The activity the element belongs to
      * @param name The name of the element
-     * @return The first matching element on the current context
-     * @throws RoboCopException If no matching elements are found
+     * @return The first matching element on the current context, or null if not found.
      */
     Element findElement(Activity activity, String name);
 
     /**
      * Sets up scroll handling so that data is received from the extension.
      */
     void setupScrollHandling();
 
--- a/build/mobile/robocop/Element.java.in
+++ b/build/mobile/robocop/Element.java.in
@@ -6,20 +6,23 @@
 package @ANDROID_PACKAGE_NAME@;
 
 /** 
  *  Element provides access to a specific UI view (android.view.View). 
  *  See also Driver.findElement().
  */
 public interface Element {
 
-    /** Click on the element */
-    void click();
+    /** Click on the element's view. Returns true on success. */
+    boolean click();
 
     /** Returns true if the element is currently displayed */
     boolean isDisplayed();
 
-    /** Returns the text currently displayed on the element */
+    /** 
+     * Returns the text currently displayed on the element, or null
+     * if the text cannot be retrieved.
+     */
     String getText();
 
     /** Returns the view ID */
     Integer getId();
 }
--- a/build/mobile/robocop/FennecNativeDriver.java.in
+++ b/build/mobile/robocop/FennecNativeDriver.java.in
@@ -164,24 +164,31 @@ public class FennecNativeDriver implemen
 
     public int getGeckoWidth() {
         if (!mGeckoInfo) {
             getGeckoInfo();
         }
         return mGeckoWidth;
     }
 
+    /** Find the named element in the list of known Fennec views. 
+     *  @return An Element representing the view, or null if the view is not found.
+     */
     public Element findElement(Activity activity, String name) {
         if (name == null) {
-            throw new IllegalArgumentException("Can not findElements when passed a null");
+            FennecNativeDriver.log(FennecNativeDriver.LogLevel.ERROR,
+                "Can not findElements when passed a null");
+            return null;
         }
         if (mLocators.containsKey(name)) {
             return new FennecNativeElement(Integer.decode((String)mLocators.get(name)), activity, mSolo);
         }
-        throw new RoboCopException("Element does not exist in the list");
+        FennecNativeDriver.log(FennecNativeDriver.LogLevel.ERROR,
+            "findElement: Element '"+name+"' does not exist in the list");
+        return null;
     }
 
     public void startFrameRecording() {
         try {
             Object [] params = null;
             _startFrameRecording.invoke(null, params);
         } catch (IllegalAccessException e) {
             log(LogLevel.ERROR, e);
--- a/build/mobile/robocop/FennecNativeElement.java.in
+++ b/build/mobile/robocop/FennecNativeElement.java.in
@@ -29,44 +29,52 @@ public class FennecNativeElement impleme
         mActivity = activity;
         mSolo = solo;
     }
 
     public Integer getId() {
         return mId;
     }
 
-    public void click() {
+    private boolean mClickSuccess;
+
+    public boolean click() {
         final SynchronousQueue syncQueue = new SynchronousQueue();
+        mClickSuccess = false;
         mActivity.runOnUiThread(
             new Runnable() {
                 public void run() {
                     View view = (View)mActivity.findViewById(mId);
-                    if(view != null) {
-                        if (!view.performClick()) {
+                    if (view != null) {
+                        if (view.performClick()) {
+                            mClickSuccess = true;
+                        } else {
                             FennecNativeDriver.log(FennecNativeDriver.LogLevel.WARN,
                                 "Robocop called click on an element with no listener");
                         }
                     } else {
-                        throw new RoboCopException("click: unable to find view "+mId); 
+                        FennecNativeDriver.log(FennecNativeDriver.LogLevel.ERROR,
+                            "click: unable to find view "+mId);
                     }
                     syncQueue.offer(new Object());
                 }
             });
         try {
             syncQueue.take();
         } catch (InterruptedException e) {
             FennecNativeDriver.log(FennecNativeDriver.LogLevel.ERROR, e);
         }
+        return mClickSuccess;
     }
 
     private Object mText;
 
     public String getText() {
         final SynchronousQueue syncQueue = new SynchronousQueue();
+        mText = null;
         mActivity.runOnUiThread(
             new Runnable() {
                 public void run() {
                     View v = mActivity.findViewById(mId);
                     if (v instanceof EditText) {
                         EditText et = (EditText)v;
                         mText = et.getEditableText();
                     } else if (v instanceof TextSwitcher) {
@@ -78,32 +86,36 @@ public class FennecNativeElement impleme
                         for (int i = 0; i < vg.getChildCount(); i++) {
                             if (vg.getChildAt(i) instanceof TextView) {
                                 mText = ((TextView)vg.getChildAt(i)).getText();
                             }
                         }
                     } else if (v instanceof TextView) {
                         mText = ((TextView)v).getText(); 
                     } else if (v == null) {
-                        throw new RoboCopException("getText: unable to find view "+mId); 
+                        FennecNativeDriver.log(FennecNativeDriver.LogLevel.ERROR,
+                            "getText: unable to find view "+mId);
                     } else {
-                        throw new RoboCopException("getText: unhandled type for view "+mId); 
+                        FennecNativeDriver.log(FennecNativeDriver.LogLevel.ERROR,
+                            "getText: unhandled type for view "+mId);
                     }
                     syncQueue.offer(new Object());
                 } // end of run() method definition
             } // end of anonymous Runnable object instantiation
         );
         try {     
             // Wait for the UiThread code to finish running
             syncQueue.take();
         } catch (InterruptedException e) {
             FennecNativeDriver.log(FennecNativeDriver.LogLevel.ERROR, e);
         }
         if (mText == null) {
-            throw new RoboCopException("getText: Text is null for view "+mId);
+            FennecNativeDriver.log(FennecNativeDriver.LogLevel.WARN,
+                "getText: Text is null for view "+mId);
+            return null;
         }
         return mText.toString();
     }
 
     private boolean mDisplayed;
 
     public boolean isDisplayed() {
         final SynchronousQueue syncQueue = new SynchronousQueue();
--- a/config/Makefile.in
+++ b/config/Makefile.in
@@ -143,20 +143,22 @@ ifndef CROSS_COMPILE
 ifdef USE_ELF_DYNSTR_GC
 elf-dynstr-gc: elf-dynstr-gc.c $(GLOBAL_DEPS)
 	$(CC) $(COMPILE_CFLAGS) $(GLIB_CFLAGS) -o $@ $< $(LDFLAGS) $(GLIB_LIBS) 
 endif
 endif
 
 FORCE:
 
+ifndef COMPILER_DEPEND
 ifdef MKDEPEND_DIR
 clean clobber realclean clobber_all::
 	cd $(MKDEPEND_DIR); $(MAKE) $@
 endif
+endif
 
 PYUNITS := \
   unit-Expression.py \
   unit-Preprocessor.py \
   unit-nsinstall.py \
   unit-printprereleasesuffix.py \
   unit-JarMaker.py \
   unit-buildlist.py \
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -519,16 +519,18 @@ MOZ_ENABLE_CAIRO_FT	= @MOZ_ENABLE_CAIRO_
 MOZ_ENABLE_GTK2		= @MOZ_ENABLE_GTK2@
 MOZ_ENABLE_QT		= @MOZ_ENABLE_QT@
 MOZ_ENABLE_XREMOTE	= @MOZ_ENABLE_XREMOTE@
 MOZ_ENABLE_DWRITE_FONT	= @MOZ_ENABLE_DWRITE_FONT@
 MOZ_ENABLE_D2D_SURFACE	= @MOZ_ENABLE_D2D_SURFACE@
 MOZ_ENABLE_D3D9_LAYER	= @MOZ_ENABLE_D3D9_LAYER@
 MOZ_ENABLE_D3D10_LAYER  = @MOZ_ENABLE_D3D10_LAYER@
 MOZ_METRO	= @MOZ_METRO@
+CRTDLLVERSION	= @CRTDLLVERSION@
+CRTEXPDLLVERSION	= @CRTEXPDLLVERSION@
 
 MOZ_GTK2_CFLAGS		= @MOZ_GTK2_CFLAGS@
 MOZ_GTK2_LIBS		= @MOZ_GTK2_LIBS@
 
 MOZ_QT_CFLAGS		= @MOZ_QT_CFLAGS@
 MOZ_QT_LIBS		= @MOZ_QT_LIBS@
 MOZ_ENABLE_QTNETWORK    = @MOZ_ENABLE_QTNETWORK@
 MOZ_ENABLE_QMSYSTEM2    = @MOZ_ENABLE_QMSYSTEM2@
--- a/configure.in
+++ b/configure.in
@@ -161,51 +161,45 @@ dnl ====================================
 
 MOZ_ARG_WITH_STRING(android-ndk,
 [  --with-android-ndk=DIR
                           location where the Android NDK can be found],
     android_ndk=$withval)
 
 MOZ_ARG_WITH_STRING(android-toolchain,
 [  --with-android-toolchain=DIR
-                          location of the android toolchain, default NDK/build/prebuilt/HOST/arm-eabi-4.4.0],
+                          location of the android toolchain],
     android_toolchain=$withval)
 
 
 MOZ_ARG_WITH_STRING(android-version,
 [  --with-android-version=VER
                           android platform version, default 5],
     android_version=$withval,
     android_version=5)
 
 MOZ_ARG_WITH_STRING(android-sdk,
 [  --with-android-sdk=DIR
                           location where the Android SDK can be found (base directory, e.g. .../android/platforms/android-6)],
     android_sdk=$withval)
 
 MOZ_ARG_WITH_STRING(android-platform,
 [  --with-android-platform=DIR
-                           location of platform dir, default NDK/build/platforms/android-5/arch-arm],
+                           location of platform dir],
     android_platform=$withval)
 
-MOZ_ARG_ENABLE_BOOL(android-libstdcxx,
-[  --enable-android-libstdcxx
-                          use GNU libstdc++ instead of STLPort for NDK >= 5],
-    MOZ_ANDROID_LIBSTDCXX=1,
-    MOZ_ANDROID_LIBSTDCXX= )
-
 case "$target" in
 arm-linux*-android*|*-linuxandroid*)
     android_tool_prefix="arm-linux-androideabi"
     ;;
 i?86-*android*)
     android_tool_prefix="i686-android-linux"
     ;;
-arm-android-eabi)
-    android_tool_prefix="arm-eabi"
+mipsel-*android*)
+    android_tool_prefix="mipsel-linux-android"
     ;;
 *)
     android_tool_prefix="$target_os"
     ;;
 esac
 
 MOZ_ARG_WITH_STRING(gonk,
 [  --with-gonk=DIR
@@ -312,47 +306,52 @@ case "$target" in
         android_platform_tools="$android_sdk"/tools # SDK Tools < r8
     fi
 
     if test -z "$android_toolchain" ; then
         AC_MSG_CHECKING([for android toolchain directory])
 
         kernel_name=`uname -s | tr "[[:upper:]]" "[[:lower:]]"`
 
-        android_toolchain="$android_ndk"/build/prebuilt/$kernel_name-x86/arm-eabi-4.4.0
-
-        # With newer NDK, the toolchain path has changed.
-        if ! test -d "$android_toolchain" ; then
-            case "$target_cpu" in
-            arm)
-                target_name=arm-linux-androideabi-4.4.3
-                ;;
-            i?86)
-                target_name=x86-4.4.3
-                ;;
-            esac
-            android_toolchain="$android_ndk"/toolchains/$target_name/prebuilt/$kernel_name-x86
-        fi
+        case "$target_cpu" in
+        arm)
+            target_name=arm-linux-androideabi-4.4.3
+            ;;
+        i?86)
+            target_name=x86-4.4.3
+            ;;
+        mipsel)
+            target_name=mipsel-linux-android-4.4.3
+            ;;
+        esac
+        android_toolchain="$android_ndk"/toolchains/$target_name/prebuilt/$kernel_name-x86
 
         if test -d "$android_toolchain" ; then
             AC_MSG_RESULT([$android_toolchain])
         else
             AC_MSG_ERROR([not found. You have to specify --with-android-toolchain=/path/to/ndk/toolchain.])
         fi
     fi
 
     if test -z "$android_platform" ; then
         AC_MSG_CHECKING([for android platform directory])
 
-        android_platform="$android_ndk"/build/platforms/android-"$android_version"/arch-"$target_cpu"
-
-        # With newer NDK, the platform path has changed.
-        if ! test -d "$android_platform" ; then
-            android_platform="$android_ndk"/platforms/android-"$android_version"/arch-"$target_cpu"
-        fi
+        case "$target_cpu" in
+        arm)
+            target_name=arm
+            ;;
+        i?86)
+            target_name=x86
+            ;;
+        mipsel)
+            target_name=mips
+            ;;
+        esac
+
+        android_platform="$android_ndk"/platforms/android-"$android_version"/arch-"$target_name"
 
         if test -d "$android_platform" ; then
             AC_MSG_RESULT([$android_platform])
         else
             AC_MSG_ERROR([not found. You have to specify --with-android-platform=/path/to/ndk/platform.])
         fi
     fi
 
@@ -614,22 +613,28 @@ MOZ_ARG_ENABLE_BOOL(metro,
     MOZ_METRO=1,
     MOZ_METRO=)
 if test -n "$MOZ_METRO"; then
     AC_DEFINE(MOZ_METRO)
     # Target the Windows 8 Kit
     WINSDK_TARGETVER=602
     # Allow a higher api set
     WINVER=602
+    # toolkit/library/makefile.in needs these, see nsDllMain.
+    CRTDLLVERSION=110
+    CRTEXPDLLVERSION=1-1-0
 else
     # Target the Windows 7 SDK by default
     WINSDK_TARGETVER=601
     WINVER=502
 fi
 
+AC_SUBST(CRTDLLVERSION)
+AC_SUBST(CRTEXPDLLVERSION)
+
 if test -n "$MOZ_METRO"; then
   case "$target" in
   *-mingw*)
     ;;
   *)
     AC_MSG_ERROR([Metro builds only valid on the windows platform.]);
     ;;
   esac
@@ -1592,28 +1597,24 @@ if test "$OS_TARGET" = "Android"; then
       ANDROID_CPU_ARCH=armeabi-v7a
       ;;
     arm-*)
       ANDROID_CPU_ARCH=armeabi
       ;;
     x86-*)
       ANDROID_CPU_ARCH=x86
       ;;
+    mips-*) # When target_cpu is mipsel, CPU_ARCH is mips
+      ANDROID_CPU_ARCH=mips
+      ;;
     esac
 fi
 
 if test "$OS_TARGET" = "Android" -a -z "$gonkdir"; then
-    if test -n "$MOZ_ANDROID_LIBSTDCXX" ; then
-       if test ! -e "$android_ndk/sources/cxx-stl/gnu-libstdc++/libs/$ANDROID_CPU_ARCH/libstdc++.a" ; then
-          AC_MSG_ERROR([Cannot find path to libstdc++ (NDK version >= 5?)])
-       fi
-       STLPORT_CPPFLAGS="-I$android_ndk/sources/cxx-stl/gnu-libstdc++/include -I$android_ndk/sources/cxx-stl/gnu-libstdc++/libs/$ANDROID_CPU_ARCH/include -D_GLIBCXX_PERMIT_BACKWARD_HASH"
-       STLPORT_LDFLAGS="-L$android_ndk/sources/cxx-stl/gnu-libstdc++/libs/$ANDROID_CPU_ARCH"
-       STLPORT_LIBS="-lstdc++"
-    elif test -e "$android_ndk/sources/cxx-stl/stlport/src/iostream.cpp" ; then
+    if test -e "$android_ndk/sources/cxx-stl/stlport/src/iostream.cpp" ; then
        if test -e "$android_ndk/sources/cxx-stl/stlport/libs/$ANDROID_CPU_ARCH/libstlport_static.a"; then
           STLPORT_LDFLAGS="-L$_objdir/build/stlport -L$android_ndk/sources/cxx-stl/stlport/libs/$ANDROID_CPU_ARCH/"
        elif test -e "$android_ndk/tmp/ndk-digit/build/install/sources/cxx-stl/stlport/libs/$ANDROID_CPU_ARCH/libstlport_static.a"; then
           STLPORT_LDFLAGS="-L$_objdir/build/stlport -L$android_ndk/tmp/ndk-digit/build/install/sources/cxx-stl/stlport/libs/$ANDROID_CPU_ARCH/"
        else
           AC_MSG_ERROR([Couldn't find path to stlport in the android ndk])
        fi
        STLPORT_SOURCES="$android_ndk/sources/cxx-stl/stlport"
--- a/content/base/public/nsDOMFile.h
+++ b/content/base/public/nsDOMFile.h
@@ -127,24 +127,35 @@ public:
     NS_ASSERTION(mFile, "must have file");
     // Lazily get the content type and size
     mContentType.SetIsVoid(true);
     mFile->GetLeafName(mName);
   }
 
   // Create as a blob
   nsDOMFileFile(nsIFile *aFile, const nsAString& aContentType,
-                nsISupports *aCacheToken = nsnull)
+                nsISupports *aCacheToken)
     : nsDOMFileBase(aContentType, UINT64_MAX),
       mFile(aFile), mWholeFile(true), mStoredFile(false),
       mCacheToken(aCacheToken)
   {
     NS_ASSERTION(mFile, "must have file");
   }
 
+  // Create as a file with custom name
+  nsDOMFileFile(nsIFile *aFile, const nsAString& aName)
+    : nsDOMFileBase(EmptyString(), EmptyString(), UINT64_MAX),
+      mFile(aFile), mWholeFile(true), mStoredFile(false)
+  {
+    NS_ASSERTION(mFile, "must have file");
+    // Lazily get the content type and size
+    mContentType.SetIsVoid(true);
+    mName.Assign(aName);
+  }
+
   // Create as a stored file
   nsDOMFileFile(const nsAString& aName, const nsAString& aContentType,
                 PRUint64 aLength, nsIFile* aFile,
                 FileInfo* aFileInfo)
     : nsDOMFileBase(aName, aContentType, aLength),
       mFile(aFile), mWholeFile(true), mStoredFile(true)
   {
     NS_ASSERTION(mFile, "must have file");
--- a/content/base/public/nsDeprecatedOperationList.h
+++ b/content/base/public/nsDeprecatedOperationList.h
@@ -40,8 +40,9 @@ DEPRECATED_OPERATION(IsEqualNode)
 DEPRECATED_OPERATION(TextContent)
 DEPRECATED_OPERATION(EnablePrivilege)
 DEPRECATED_OPERATION(Position)
 DEPRECATED_OPERATION(TotalSize)
 DEPRECATED_OPERATION(InputEncoding)
 DEPRECATED_OPERATION(MozBeforePaint)
 DEPRECATED_OPERATION(MozBlobBuilder)
 DEPRECATED_OPERATION(DOMExceptionCode)
+DEPRECATED_OPERATION(MutationEvent)
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -87,18 +87,18 @@ class Loader;
 
 namespace dom {
 class Link;
 class Element;
 } // namespace dom
 } // namespace mozilla
 
 #define NS_IDOCUMENT_IID \
-{ 0x88d887da, 0xd228, 0x41c2, \
-  { 0xb8, 0x0a, 0x42, 0xec, 0xf0, 0xcb, 0xce, 0x37 } }
+{ 0x8c6a1e62, 0xd5ad, 0x4297, \
+  { 0xb9, 0x41, 0x64, 0x49, 0x22, 0x2e, 0xc4, 0xf0 } }
 
 // Flag for AddStyleSheet().
 #define NS_STYLESHEET_FROM_CATALOG                (1 << 0)
 
 // Enum for requesting a particular type of document when creating a doc
 enum DocumentFlavor {
   DocumentFlavorLegacyGuess, // compat with old code until made HTML5-compliant
   DocumentFlavorHTML, // HTMLDocument with HTMLness bit set to true
@@ -669,16 +669,22 @@ public:
   /**
    * Return the window containing the document (the outer window).
    */
   nsPIDOMWindow *GetWindow() const
   {
     return mWindow ? mWindow->GetOuterWindow() : GetWindowInternal();
   }
 
+  bool IsInBackgroundWindow() const
+  {
+    nsPIDOMWindow* outer = mWindow ? mWindow->GetOuterWindow() : nsnull;
+    return outer && outer->IsBackground();
+  }
+  
   /**
    * Return the inner window used as the script compilation scope for
    * this document. If you're not absolutely sure you need this, use
    * GetWindow().
    */
   nsPIDOMWindow* GetInnerWindow()
   {
     return mRemovedFromDocShell ? GetInnerWindowInternal() : mWindow;
--- a/content/base/src/Link.h
+++ b/content/base/src/Link.h
@@ -99,16 +99,28 @@ public:
   virtual bool HasDeferredDNSPrefetchRequest() { return true; }
 
   virtual size_t
     SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
 
 protected:
   virtual ~Link();
 
+  /**
+   * Return true if the link has associated URI.
+   */
+  bool HasURI() const
+  {
+    if (mCachedURI)
+      return true;
+
+    nsCOMPtr<nsIURI> uri(GetURI());
+    return !!uri;
+  }
+
   bool HasCachedURI() const { return !!mCachedURI; }
 
 private:
   /**
    * Unregisters from History so this node no longer gets notifications about
    * changes to visitedness.
    */
   void UnregisterFromHistory();
--- a/content/base/src/nsContentSink.cpp
+++ b/content/base/src/nsContentSink.cpp
@@ -1542,18 +1542,19 @@ nsContentSink::WillParseImpl(void)
 
   if (sEnablePerfMode == 0) {
     nsIViewManager* vm = shell->GetViewManager();
     NS_ENSURE_TRUE(vm, NS_ERROR_FAILURE);
     PRUint32 lastEventTime;
     vm->GetLastUserEventTime(lastEventTime);
 
     bool newDynLower =
-      (currentTime - mBeginLoadTime) > PRUint32(sInitialPerfTime) &&
-      (currentTime - lastEventTime) < PRUint32(sInteractiveTime);
+      mDocument->IsInBackgroundWindow() ||
+      ((currentTime - mBeginLoadTime) > PRUint32(sInitialPerfTime) &&
+       (currentTime - lastEventTime) < PRUint32(sInteractiveTime));
     
     if (mDynamicLowerValue != newDynLower) {
       FavorPerformanceHint(!newDynLower, 0);
       mDynamicLowerValue = newDynLower;
     }
   }
   
   mDeflectedCount = 0;
--- a/content/base/src/nsDOMAttributeMap.cpp
+++ b/content/base/src/nsDOMAttributeMap.cpp
@@ -22,23 +22,17 @@
 
 //----------------------------------------------------------------------
 
 nsDOMAttributeMap::nsDOMAttributeMap(Element* aContent)
   : mContent(aContent)
 {
   // We don't add a reference to our content. If it goes away,
   // we'll be told to drop our reference
-}
-
-bool
-nsDOMAttributeMap::Init()
-{
   mAttributeCache.Init();
-  return true;
 }
 
 /**
  * Clear map pointer for attributes.
  */
 PLDHashOperator
 RemoveMapRef(nsAttrHashKey::KeyType aKey, nsRefPtr<nsDOMAttribute>& aData,
              void* aUserArg)
--- a/content/base/src/nsDOMAttributeMap.h
+++ b/content/base/src/nsDOMAttributeMap.h
@@ -91,21 +91,16 @@ private:
 class nsDOMAttributeMap : public nsIDOMNamedNodeMap
 {
 public:
   typedef mozilla::dom::Element Element;
 
   nsDOMAttributeMap(Element *aContent);
   virtual ~nsDOMAttributeMap();
 
-  /**
-   * Initialize the map. Must be called before the map is used.
-   */
-  bool Init();
-
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
   // nsIDOMNamedNodeMap interface
   NS_DECL_NSIDOMNAMEDNODEMAP
 
   void DropReference();
 
   Element* GetContent()
--- a/content/base/src/nsDOMMutationObserver.cpp
+++ b/content/base/src/nsDOMMutationObserver.cpp
@@ -12,25 +12,25 @@
 #include "nsContentUtils.h"
 #include "nsThreadUtils.h"
 #include "nsIDOMMutationEvent.h"
 #include "nsTextFragment.h"
 #include "jsapi.h"
 #include "nsServiceManagerUtils.h"
 #include "DictionaryHelpers.h"
 
-nsCOMArray<nsIDOMMozMutationObserver>*
+nsCOMArray<nsIDOMMutationObserver>*
   nsDOMMutationObserver::sScheduledMutationObservers = nsnull;
 
-nsIDOMMozMutationObserver* nsDOMMutationObserver::sCurrentObserver = nsnull;
+nsIDOMMutationObserver* nsDOMMutationObserver::sCurrentObserver = nsnull;
 
 PRUint32 nsDOMMutationObserver::sMutationLevel = 0;
 PRUint64 nsDOMMutationObserver::sCount = 0;
 
-nsAutoTArray<nsCOMArray<nsIDOMMozMutationObserver>, 4>*
+nsAutoTArray<nsCOMArray<nsIDOMMutationObserver>, 4>*
 nsDOMMutationObserver::sCurrentlyHandlingObservers = nsnull;
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMMutationRecord)
 
 DOMCI_DATA(MutationRecord, nsDOMMutationRecord)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMMutationRecord)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
@@ -157,17 +157,17 @@ nsMutationReceiver::Disconnect(bool aRem
   if (mRegisterTarget) {
     mRegisterTarget->RemoveMutationObserver(this);
     mRegisterTarget = nsnull;
   }
 
   mParent = nsnull;
   nsINode* target = mTarget;
   mTarget = nsnull;
-  nsIDOMMozMutationObserver* observer = mObserver;
+  nsIDOMMutationObserver* observer = mObserver;
   mObserver = nsnull;
   RemoveClones();
 
   if (target && observer) {
     if (aRemoveFromObserver) {
       static_cast<nsDOMMutationObserver*>(observer)->RemoveReceiver(this);
     }
     // UnbindObject may delete 'this'!
@@ -390,23 +390,23 @@ void nsMutationReceiver::NodeWillBeDestr
   NS_ASSERTION(!mParent, "Shouldn't have mParent here!");
   Disconnect(true);
 }
 
 // Observer
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMMutationObserver)
 
-DOMCI_DATA(MozMutationObserver, nsDOMMutationObserver)
+DOMCI_DATA(MutationObserver, nsDOMMutationObserver)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMMutationObserver)
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMMozMutationObserver)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMMozMutationObserver)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMMutationObserver)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMMutationObserver)
   NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozMutationObserver)
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MutationObserver)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMMutationObserver)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMMutationObserver)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMMutationObserver)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mScriptContext)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOwner)
@@ -501,17 +501,17 @@ nsDOMMutationObserver::ScheduleForRun()
   mWaitingForRun = true;
   RescheduleForRun();
 }
 
 void
 nsDOMMutationObserver::RescheduleForRun()
 {
   if (!sScheduledMutationObservers) {
-    sScheduledMutationObservers = new nsCOMArray<nsIDOMMozMutationObserver>;
+    sScheduledMutationObservers = new nsCOMArray<nsIDOMMutationObserver>;
   }
 
   bool didInsert = false;
   for (PRInt32 i = 0; i < sScheduledMutationObservers->Count(); ++i) {
     if (static_cast<nsDOMMutationObserver*>((*sScheduledMutationObservers)[i])
           ->mId > mId) {
       sScheduledMutationObservers->InsertObjectAt(this, i);
       didInsert = true;
@@ -700,28 +700,28 @@ nsDOMMutationObserver::HandleMutationsIn
     // after previous mutations are handled. But in case some
     // callback calls a sync API, which spins the eventloop, we need to still
     // process other mutations happening during that sync call.
     // This does *not* catch all cases, but should work for stuff running
     // in separate tabs.
     return;
   }
 
-  nsCOMArray<nsIDOMMozMutationObserver>* suppressedObservers = nsnull;
+  nsCOMArray<nsIDOMMutationObserver>* suppressedObservers = nsnull;
 
   while (sScheduledMutationObservers) {
-    nsCOMArray<nsIDOMMozMutationObserver>* observers = sScheduledMutationObservers;
+    nsCOMArray<nsIDOMMutationObserver>* observers = sScheduledMutationObservers;
     sScheduledMutationObservers = nsnull;
     for (PRInt32 i = 0; i < observers->Count(); ++i) {
       sCurrentObserver = static_cast<nsDOMMutationObserver*>((*observers)[i]);
       if (!sCurrentObserver->Suppressed()) {
         sCurrentObserver->HandleMutation();
       } else {
         if (!suppressedObservers) {
-          suppressedObservers = new nsCOMArray<nsIDOMMozMutationObserver>;
+          suppressedObservers = new nsCOMArray<nsIDOMMutationObserver>;
         }
         if (suppressedObservers->IndexOf(sCurrentObserver) < 0) {
           suppressedObservers->AppendObject(sCurrentObserver);
         }
       }
     }
     delete observers;
   }
@@ -777,17 +777,17 @@ nsDOMMutationObserver::EnterMutationHand
 // of nested calls to the nsIMutationObserver methods).
 // The most recent mutation record is removed from mCurrentMutations, so
 // that is doesn't get modified anymore by receivers.
 void
 nsDOMMutationObserver::LeaveMutationHandling()
 {
   if (sCurrentlyHandlingObservers &&
       sCurrentlyHandlingObservers->Length() == sMutationLevel) {
-    nsCOMArray<nsIDOMMozMutationObserver>& obs =
+    nsCOMArray<nsIDOMMutationObserver>& obs =
       sCurrentlyHandlingObservers->ElementAt(sMutationLevel - 1);
     for (PRInt32 i = 0; i < obs.Count(); ++i) {
       nsDOMMutationObserver* o =
         static_cast<nsDOMMutationObserver*>(obs[i]);
       if (o->mCurrentMutations.Length() == sMutationLevel) {
         // It is already in pending mutations.
         o->mCurrentMutations.RemoveElementAt(sMutationLevel - 1);
       }
@@ -799,17 +799,17 @@ nsDOMMutationObserver::LeaveMutationHand
 
 void
 nsDOMMutationObserver::AddCurrentlyHandlingObserver(nsDOMMutationObserver* aObserver)
 {
   NS_ASSERTION(sMutationLevel > 0, "Unexpected mutation level!");
 
   if (!sCurrentlyHandlingObservers) {
     sCurrentlyHandlingObservers =
-      new nsAutoTArray<nsCOMArray<nsIDOMMozMutationObserver>, 4>;
+      new nsAutoTArray<nsCOMArray<nsIDOMMutationObserver>, 4>;
   }
 
   while (sCurrentlyHandlingObservers->Length() < sMutationLevel) {
     sCurrentlyHandlingObservers->InsertElementAt(
       sCurrentlyHandlingObservers->Length());
   }
 
   PRUint32 last = sMutationLevel - 1;
--- a/content/base/src/nsDOMMutationObserver.h
+++ b/content/base/src/nsDOMMutationObserver.h
@@ -136,17 +136,17 @@ public:
   }
 
   void RemoveClone(nsMutationReceiverBase* aClone)
   {
     mTransientReceivers.RemoveObject(aClone);
   }
   
 protected:
-  nsMutationReceiverBase(nsINode* aTarget, nsIDOMMozMutationObserver* aObserver)
+  nsMutationReceiverBase(nsINode* aTarget, nsIDOMMutationObserver* aObserver)
   : mTarget(aTarget), mObserver(aObserver), mRegisterTarget(aTarget)
   {
     mRegisterTarget->AddMutationObserver(this);
     mRegisterTarget->SetMayHaveDOMMutationObserver();
     mRegisterTarget->OwnerDoc()->SetMayHaveDOMMutationObservers();
   }
 
   nsMutationReceiverBase(nsINode* aRegisterTarget,
@@ -184,17 +184,17 @@ protected:
         return true;
       }
     }
     return false;
   }
 
   // The target for the MutationObserver.observe() method.
   nsINode*                           mTarget;
-  nsIDOMMozMutationObserver*         mObserver;
+  nsIDOMMutationObserver*            mObserver;
   nsRefPtr<nsMutationReceiverBase>   mParent; // Cleared after microtask.
   // The node to which Gecko-internal nsIMutationObserver was registered to.
   // This is different than mTarget when dealing with transient observers.
   nsINode*                           mRegisterTarget;
   nsCOMArray<nsMutationReceiverBase> mTransientReceivers;
   // While we have transient receivers, keep the original mutation receiver
   // alive so it doesn't go away and disconnect all its transient receivers.
   nsCOMPtr<nsINode>                  mKungFuDeathGrip;
@@ -213,17 +213,17 @@ private:
 
 #define NS_MUTATION_OBSERVER_IID \
 { 0xe628f313, 0x8129, 0x4f90, \
   { 0x8e, 0xc3, 0x85, 0xe8, 0x28, 0x22, 0xe7, 0xab } }
 
 class nsMutationReceiver : public nsMutationReceiverBase
 {
 public:
-  nsMutationReceiver(nsINode* aTarget, nsIDOMMozMutationObserver* aObserver)
+  nsMutationReceiver(nsINode* aTarget, nsIDOMMutationObserver* aObserver)
   : nsMutationReceiverBase(aTarget, aObserver)
   {
     mTarget->BindObject(aObserver);
   }
 
   nsMutationReceiver(nsINode* aRegisterTarget, nsMutationReceiverBase* aParent)
   : nsMutationReceiverBase(aRegisterTarget, aParent)
   {
@@ -273,29 +273,29 @@ public:
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
   NS_DECL_NSIMUTATIONOBSERVER_NODEWILLBEDESTROYED
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsMutationReceiver, NS_MUTATION_OBSERVER_IID)
 
-class nsDOMMutationObserver : public nsIDOMMozMutationObserver,
+class nsDOMMutationObserver : public nsIDOMMutationObserver,
                               public nsIJSNativeInitializer
 {
 public:
   nsDOMMutationObserver() : mWaitingForRun(false), mId(++sCount)
   {
     mTransientReceivers.Init();
   }
   virtual ~nsDOMMutationObserver();
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsDOMMutationObserver,
-                                           nsIDOMMozMutationObserver)
-  NS_DECL_NSIDOMMOZMUTATIONOBSERVER
+                                           nsIDOMMutationObserver)
+  NS_DECL_NSIDOMMUTATIONOBSERVER
 
   NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* cx, JSObject* obj,
                         PRUint32 argc, jsval* argv);
 
   void HandleMutation();
 
   // static methods
   static void HandleMutations()
@@ -303,17 +303,17 @@ public:
     if (sScheduledMutationObservers) {
       HandleMutationsInternal();
     }
   }
 
   static void EnterMutationHandling();
   static void LeaveMutationHandling();
 
-  static nsIDOMMozMutationObserver* CurrentObserver()
+  static nsIDOMMutationObserver* CurrentObserver()
   {
     return sCurrentObserver;
   }
 
   static void Shutdown();
 protected:
   friend class nsMutationReceiver;
   friend class nsAutoMutationBatch;
@@ -356,21 +356,21 @@ protected:
   nsCOMArray<nsDOMMutationRecord>                    mPendingMutations;
   nsCOMPtr<nsIMutationObserverCallback>              mCallback;
 
   bool                                               mWaitingForRun;
 
   PRUint64                                           mId;
 
   static PRUint64                                    sCount;
-  static nsCOMArray<nsIDOMMozMutationObserver>*      sScheduledMutationObservers;
-  static nsIDOMMozMutationObserver*                  sCurrentObserver;
+  static nsCOMArray<nsIDOMMutationObserver>*         sScheduledMutationObservers;
+  static nsIDOMMutationObserver*                     sCurrentObserver;
 
   static PRUint32                                    sMutationLevel;
-  static nsAutoTArray<nsCOMArray<nsIDOMMozMutationObserver>, 4>*
+  static nsAutoTArray<nsCOMArray<nsIDOMMutationObserver>, 4>*
                                                      sCurrentlyHandlingObservers;
 };
 
 class nsAutoMutationBatch
 {
 public:
   nsAutoMutationBatch()
   : mPreviousBatch(nsnull), mBatchTarget(nsnull), mRemovalDone(false),
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -2610,20 +2610,16 @@ nsGenericElement::GetAttributes(nsIDOMNa
     *aAttributes = nsnull;
     return NS_OK;
   }
 
   nsDOMSlots *slots = DOMSlots();
 
   if (!slots->mAttributeMap) {
     slots->mAttributeMap = new nsDOMAttributeMap(this);
-    if (!slots->mAttributeMap->Init()) {
-      slots->mAttributeMap = nsnull;
-      return NS_ERROR_FAILURE;
-    }
   }
 
   NS_ADDREF(*aAttributes = slots->mAttributeMap);
 
   return NS_OK;
 }
 
 nsresult
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -1522,17 +1522,16 @@ GK_ATOM(malignmark_, "malignmark")
 GK_ATOM(mathbackground_, "mathbackground")
 GK_ATOM(mathcolor_, "mathcolor")
 GK_ATOM(mathsize_, "mathsize")
 GK_ATOM(mathvariant_, "mathvariant")
 GK_ATOM(matrixrow_, "matrixrow")
 GK_ATOM(maxsize_, "maxsize")
 GK_ATOM(mean_, "mean")
 GK_ATOM(median_, "median")
-GK_ATOM(mediummathspace_, "mediummathspace")
 GK_ATOM(menclose_, "menclose")
 GK_ATOM(merror_, "merror")
 GK_ATOM(mfenced_, "mfenced")
 GK_ATOM(mfrac_, "mfrac")
 GK_ATOM(mglyph_, "mglyph")
 GK_ATOM(mi_, "mi")
 GK_ATOM(minlabelspacing_, "minlabelspacing")
 GK_ATOM(minsize_, "minsize")
@@ -1566,23 +1565,16 @@ GK_ATOM(msubsup_, "msubsup")
 GK_ATOM(msup_, "msup")
 GK_ATOM(mtable_, "mtable")
 GK_ATOM(mtd_, "mtd")
 GK_ATOM(mtext_, "mtext")
 GK_ATOM(mtr_, "mtr")
 GK_ATOM(munder_, "munder")
 GK_ATOM(munderover_, "munderover")
 GK_ATOM(naturalnumbers_, "naturalnumbers")
-GK_ATOM(negativemediummathspace_, "negativemediummathspace")
-GK_ATOM(negativethickmathspace_, "negativethickmathspace")
-GK_ATOM(negativethinmathspace_, "negativethinmathspace")
-GK_ATOM(negativeverythickmathspace_, "negativeverythickmathspace")
-GK_ATOM(negativeverythinmathspace_, "negativeverythinmathspace")
-GK_ATOM(negativeveryverythickmathspace_, "negativeveryverythickmathspace")
-GK_ATOM(negativeveryverythinmathspace_, "negativeveryverythinmathspace")
 GK_ATOM(neq_, "neq")
 GK_ATOM(notanumber_, "notanumber")
 GK_ATOM(notation_, "notation")
 GK_ATOM(note_, "note")
 GK_ATOM(notin_, "notin")
 GK_ATOM(notprsubset_, "notprsubset")
 GK_ATOM(notsubset_, "notsubset")
 GK_ATOM(numalign_, "numalign")
@@ -1634,29 +1626,23 @@ GK_ATOM(stackalign_, "stackalign")
 GK_ATOM(stretchy_, "stretchy")
 GK_ATOM(subscriptshift_, "subscriptshift")
 GK_ATOM(subset_, "subset")
 GK_ATOM(superscriptshift_, "superscriptshift")
 GK_ATOM(symmetric_, "symmetric")
 GK_ATOM(tanh_, "tanh")
 GK_ATOM(tan_, "tan")
 GK_ATOM(tendsto_, "tendsto")
-GK_ATOM(thickmathspace_, "thickmathspace")
-GK_ATOM(thinmathspace_, "thinmathspace")
 GK_ATOM(times_, "times")
 GK_ATOM(transpose_, "transpose")
 GK_ATOM(union_, "union")
 GK_ATOM(uplimit_, "uplimit")
 GK_ATOM(variance_, "variance")
 GK_ATOM(vectorproduct_, "vectorproduct")
 GK_ATOM(vector_, "vector")
-GK_ATOM(verythickmathspace_, "verythickmathspace")
-GK_ATOM(verythinmathspace_, "verythinmathspace")
-GK_ATOM(veryverythickmathspace_, "veryverythickmathspace")
-GK_ATOM(veryverythinmathspace_, "veryverythinmathspace")
 GK_ATOM(voffset_, "voffset")
 GK_ATOM(xref_, "xref")
 GK_ATOM(math, "math") // the only one without an underscore
 GK_ATOM(avg, "avg")
 GK_ATOM(booleanFromString, "boolean-from-string")
 GK_ATOM(countNonEmpty, "count-non-empty")
 GK_ATOM(daysFromDate, "days-from-date")
 GK_ATOM(init, "init")
--- a/content/base/src/nsTreeSanitizer.cpp
+++ b/content/base/src/nsTreeSanitizer.cpp
@@ -891,29 +891,21 @@ nsIAtom** const kAttributesMathML[] = {
    &nsGkAtoms::lquote_, // lquote
    &nsGkAtoms::lspace_, // lspace
    &nsGkAtoms::ltr, // ltr
    &nsGkAtoms::mathbackground_, // mathbackground
    &nsGkAtoms::mathcolor_, // mathcolor
    &nsGkAtoms::mathsize_, // mathsize
    &nsGkAtoms::mathvariant_, // mathvariant
    &nsGkAtoms::maxsize_, // maxsize
-   &nsGkAtoms::mediummathspace_, // mediummathspace
    &nsGkAtoms::minlabelspacing_, // minlabelspacing
    &nsGkAtoms::minsize_, // minsize
    &nsGkAtoms::movablelimits_, // movablelimits
    &nsGkAtoms::msgroup_, // msgroup
    &nsGkAtoms::name, // name
-   &nsGkAtoms::negativemediummathspace_, // negativemediummathspace
-   &nsGkAtoms::negativethickmathspace_, // negativethickmathspace
-   &nsGkAtoms::negativethinmathspace_, // negativethinmathspace
-   &nsGkAtoms::negativeverythickmathspace_, // negativeverythickmathspace
-   &nsGkAtoms::negativeverythinmathspace_, // negativeverythinmathspace
-   &nsGkAtoms::negativeveryverythickmathspace_, // negativeveryverythickmathspace
-   &nsGkAtoms::negativeveryverythinmathspace_, // negativeveryverythinmathspace
    &nsGkAtoms::newline, // newline
    &nsGkAtoms::notation_, // notation
    &nsGkAtoms::numalign_, // numalign
    &nsGkAtoms::number, // number
    &nsGkAtoms::open, // open
    &nsGkAtoms::order, // order
    &nsGkAtoms::other_, // other
    &nsGkAtoms::overflow, // overflow
@@ -936,23 +928,17 @@ nsIAtom** const kAttributesMathML[] = {
    &nsGkAtoms::shift_, // shift
    &nsGkAtoms::side_, // side
    &nsGkAtoms::src, // src
    &nsGkAtoms::stackalign_, // stackalign
    &nsGkAtoms::stretchy_, // stretchy
    &nsGkAtoms::subscriptshift_, // subscriptshift
    &nsGkAtoms::superscriptshift_, // superscriptshift
    &nsGkAtoms::symmetric_, // symmetric
-   &nsGkAtoms::thickmathspace_, // thickmathspace
-   &nsGkAtoms::thinmathspace_, // thinmathspace
    &nsGkAtoms::type, // type
-   &nsGkAtoms::verythickmathspace_, // verythickmathspace
-   &nsGkAtoms::verythinmathspace_, // verythinmathspace
-   &nsGkAtoms::veryverythickmathspace_, // veryverythickmathspace
-   &nsGkAtoms::veryverythinmathspace_, // veryverythinmathspace
    &nsGkAtoms::voffset_, // voffset
    &nsGkAtoms::width, // width
    &nsGkAtoms::xref_, // xref
   nsnull
 };
 
 nsIAtom** const kURLAttributesMathML[] = {
   &nsGkAtoms::href,
--- a/content/base/src/nsXMLHttpRequest.h
+++ b/content/base/src/nsXMLHttpRequest.h
@@ -172,19 +172,19 @@ public:
   {
     return mozilla::dom::XMLHttpRequestBinding::Wrap(cx, scope, this, triedToWrap);
   }
   nsISupports* GetParentObject()
   {
     return GetOwner();
   }
 
-  // The WebIDL parser converts constructors into methods called _Constructor.
+  // The WebIDL constructor.
   static already_AddRefed<nsXMLHttpRequest>
-  _Constructor(nsISupports* aGlobal, ErrorResult& aRv)
+  Constructor(nsISupports* aGlobal, ErrorResult& aRv)
   {
     nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal);
     nsCOMPtr<nsIScriptObjectPrincipal> principal = do_QueryInterface(aGlobal);
     if (!window || ! principal) {
       aRv.Throw(NS_ERROR_FAILURE);
       return NULL;
     }
 
--- a/content/base/test/test_mutationobservers.html
+++ b/content/base/test/test_mutationobservers.html
@@ -294,17 +294,17 @@ function testChildList4() {
       observer.disconnect();
       then(testChildList5);
       m = null;
     });
   m.observe(df, { childList: true, characterData: true, characterDataOldValue: true, subtree: true });
   m.observe(div, { childList: true });
   
   // Make sure transient observers aren't leaked.
-  var leakTest = new MozMutationObserver(function(){});
+  var leakTest = new M(function(){});
   leakTest.observe(div, { characterData: true, subtree: true });
   
   div.insertBefore(df, s2);
   s1.firstChild.data = "bar"; // This should *not* create a record.
   t1.data = "Hello the whole "; // This should create a record.
 }
 
 function testChildList5() {
--- a/content/events/src/nsEventListenerManager.cpp
+++ b/content/events/src/nsEventListenerManager.cpp
@@ -245,16 +245,20 @@ nsEventListenerManager::AddEventListener
 #endif // MOZ_MEDIA
   } else if (aType >= NS_MUTATION_START && aType <= NS_MUTATION_END) {
     // For mutation listeners, we need to update the global bit on the DOM window.
     // Otherwise we won't actually fire the mutation event.
     mMayHaveMutationListeners = true;
     // Go from our target to the nearest enclosing DOM window.
     nsPIDOMWindow* window = GetInnerWindowForTarget();
     if (window) {
+      nsCOMPtr<nsIDocument> doc = do_QueryInterface(window->GetExtantDocument());
+      if (doc) {
+        doc->WarnOnceAbout(nsIDocument::eMutationEvent);
+      }
       // If aType is NS_MUTATION_SUBTREEMODIFIED, we need to listen all
       // mutations. nsContentUtils::HasMutationListeners relies on this.
       window->SetMutationListeners((aType == NS_MUTATION_SUBTREEMODIFIED) ?
                                    kAllMutationBits :
                                    MutationBitForEventType(aType));
     }
   } else if (aTypeAtom == nsGkAtoms::ondeviceorientation) {
     EnableDevice(NS_DEVICE_ORIENTATION);
--- a/content/html/content/src/nsHTMLAnchorElement.cpp
+++ b/content/html/content/src/nsHTMLAnchorElement.cpp
@@ -282,18 +282,17 @@ nsHTMLAnchorElement::IsHTMLFocusable(boo
 
     *aIsFocusable = false;
 
     return true;
   }
 
   if (!HasAttr(kNameSpaceID_None, nsGkAtoms::tabindex)) {
     // check whether we're actually a link
-    nsCOMPtr<nsIURI> absURI;
-    if (!IsLink(getter_AddRefs(absURI))) {
+    if (!Link::HasURI()) {
       // Not tabbable or focusable without href (bug 17605), unless
       // forced to be via presence of nonnegative tabindex attribute
       if (aTabIndex) {
         *aTabIndex = -1;
       }
 
       *aIsFocusable = false;
 
--- a/content/media/nsBuiltinDecoderStateMachine.cpp
+++ b/content/media/nsBuiltinDecoderStateMachine.cpp
@@ -1852,16 +1852,20 @@ void nsBuiltinDecoderStateMachine::Decod
   // during the time when we didn't have the lock.
   PRInt64 seekTime = mSeekTime;
   mDecoder->StopProgressUpdates();
 
   bool currentTimeChanged = false;
   PRInt64 mediaTime = GetMediaTime();
   if (mediaTime != seekTime) {
     currentTimeChanged = true;
+    // Stop playback now to ensure that while we're outside the monitor
+    // dispatching SeekingStarted, playback doesn't advance and mess with
+    // mCurrentFrameTime that we've setting to seekTime here.
+    StopPlayback();
     UpdatePlaybackPositionInternal(seekTime);
   }
 
   // SeekingStarted will do a UpdateReadyStateForData which will
   // inform the element and its users that we have no frames
   // to display
   {
     ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor());
@@ -1869,17 +1873,16 @@ void nsBuiltinDecoderStateMachine::Decod
       NS_NewRunnableMethod(mDecoder, &nsBuiltinDecoder::SeekingStarted);
     NS_DispatchToMainThread(startEvent, NS_DISPATCH_SYNC);
   }
 
   if (currentTimeChanged) {
     // The seek target is different than the current playback position,
     // we'll need to seek the playback position, so shutdown our decode
     // and audio threads.
-    StopPlayback();
     StopAudioThread();
     ResetPlayback();
     nsresult res;
     {
       ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor());
       // Now perform the seek. We must not hold the state machine monitor
       // while we seek, since the seek reads, which could block on I/O.
       res = mReader->Seek(seekTime,
--- a/content/media/ogg/nsOggCodecState.cpp
+++ b/content/media/ogg/nsOggCodecState.cpp
@@ -813,24 +813,32 @@ bool nsOpusState::DecodeHeader(ogg_packe
   // Try parsing as the metadata header.
   if (!memcmp(aPacket->packet, "OpusTags", 8)) {
     mDoneReadingHeaders = true; // This is the last Opus header.
     mActive = true;
     return true;
   }
 
   // Otherwise, parse as the id header.
-  if (aPacket->bytes < 19 || memcmp(aPacket->packet, "OpusHead\0", 9)) {
+  if (aPacket->bytes < 19 || memcmp(aPacket->packet, "OpusHead", 8)) {
     LOG(PR_LOG_DEBUG, ("Invalid Opus file: unrecognized header"));
     mActive = false;
     return true;
   }
 
   mRate = 48000; // The Opus decoder runs at 48 kHz regardless.
 
+  int version = aPacket->packet[8];
+  // Accept file format versions 0.x.
+  if ((version & 0xf0) != 0) {
+    LOG(PR_LOG_DEBUG, ("Rejecting unknown Opus file version %d", version));
+    mActive = false;
+    return true;
+  }
+
   mChannels= aPacket->packet[9];
   mPreSkip = LEUint16(aPacket->packet + 10);
   mNominalRate = LEUint32(aPacket->packet + 12);
   mGain = (float)LEUint16(aPacket->packet + 16) / 256.0;
   mChannelMapping = aPacket->packet[18];
 
   if (mChannelMapping == 0) {
     mStreams = 1;
@@ -855,17 +863,17 @@ PRInt64 nsOpusState::Time(PRInt64 granul
   // Ogg Opus always runs at a granule rate of 48 kHz.
   CheckedInt64 t = CheckedInt64(granulepos - mPreSkip) * USECS_PER_S;
   return t.isValid() ? t.value() / mRate : -1;
 }
 
 bool nsOpusState::IsHeader(ogg_packet* aPacket)
 {
   return aPacket->bytes >= 16 &&
-         (!memcmp(aPacket->packet, "OpusHead\0", 9) ||
+         (!memcmp(aPacket->packet, "OpusHead", 8) ||
           !memcmp(aPacket->packet, "OpusTags", 8));
 }
 
 nsresult nsOpusState::PageIn(ogg_page* aPage)
 {
   if (!mActive)
     return NS_OK;
   NS_ASSERTION(static_cast<PRUint32>(ogg_page_serialno(aPage)) == mSerial,
--- a/content/smil/nsSMILTimedElement.cpp
+++ b/content/smil/nsSMILTimedElement.cpp
@@ -1307,17 +1307,23 @@ namespace
   };
 }
 
 void
 nsSMILTimedElement::ClearSpecs(TimeValueSpecList& aSpecs,
                                InstanceTimeList& aInstances,
                                RemovalTestFunction aRemove)
 {
+  AutoIntervalUpdateBatcher(*this);
+
+  for (PRUint32 i = 0; i < aSpecs.Length(); ++i) {
+    aSpecs[i]->Unlink();
+  }
   aSpecs.Clear();
+
   RemoveByFunction removeByFunction(aRemove);
   RemoveInstanceTimes(aInstances, removeByFunction);
 }
 
 void
 nsSMILTimedElement::ClearIntervals()
 {
   if (mElementState != STATE_STARTUP) {
--- a/content/xbl/src/nsXBLDocumentInfo.cpp
+++ b/content/xbl/src/nsXBLDocumentInfo.cpp
@@ -39,17 +39,17 @@ static const char kXBLCachePrefix[] = "x
 static NS_DEFINE_CID(kDOMScriptObjectFactoryCID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
 
 // An XBLDocumentInfo object has a special context associated with it which we can use to pre-compile 
 // properties and methods of XBL bindings against.
 class nsXBLDocGlobalObject : public nsIScriptGlobalObject,
                              public nsIScriptObjectPrincipal
 {
 public:
-  nsXBLDocGlobalObject(nsIScriptGlobalObjectOwner *aGlobalObjectOwner);
+  nsXBLDocGlobalObject(nsXBLDocumentInfo *aGlobalObjectOwner);
 
   // nsISupports interface
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   
   // nsIScriptGlobalObject methods
   virtual nsresult EnsureScriptEnvironment();
   void ClearScriptContext()
   {
@@ -77,17 +77,17 @@ public:
 protected:
   virtual ~nsXBLDocGlobalObject();
 
   nsIScriptContext *GetScriptContext();
 
   nsCOMPtr<nsIScriptContext> mScriptContext;
   JSObject *mJSObject;
 
-  nsIScriptGlobalObjectOwner* mGlobalObjectOwner; // weak reference
+  nsXBLDocumentInfo* mGlobalObjectOwner; // weak reference
   static JSClass gSharedGlobalClass;
 };
 
 JSBool
 nsXBLDocGlobalObject::doCheckAccess(JSContext *cx, JSObject *obj, jsid id, PRUint32 accessType)
 {
   nsIScriptSecurityManager *ssm = nsContentUtils::GetSecurityManager();
   if (!ssm) {
@@ -176,17 +176,17 @@ JSClass nsXBLDocGlobalObject::gSharedGlo
     TraceXPCGlobal
 };
 
 //----------------------------------------------------------------------
 //
 // nsXBLDocGlobalObject
 //
 
-nsXBLDocGlobalObject::nsXBLDocGlobalObject(nsIScriptGlobalObjectOwner *aGlobalObjectOwner)
+nsXBLDocGlobalObject::nsXBLDocGlobalObject(nsXBLDocumentInfo *aGlobalObjectOwner)
     : mJSObject(nsnull),
       mGlobalObjectOwner(aGlobalObjectOwner) // weak reference
 {
 }
 
 
 nsXBLDocGlobalObject::~nsXBLDocGlobalObject()
 {}
@@ -276,16 +276,21 @@ nsXBLDocGlobalObject::EnsureScriptEnviro
 
   nsIPrincipal *principal = GetPrincipal();
   JSCompartment *compartment;
 
   rv = xpc_CreateGlobalObject(cx, &gSharedGlobalClass, principal, nsnull,
                               false, &mJSObject, &compartment);
   NS_ENSURE_SUCCESS(rv, NS_OK);
 
+  // Set the location information for the new global, so that tools like
+  // about:memory may use that information
+  nsIURI *ownerURI = mGlobalObjectOwner->DocumentURI();
+  xpc::SetLocationForGlobal(mJSObject, ownerURI);
+
   ::JS_SetGlobalObject(cx, mJSObject);
 
   // Add an owning reference from JS back to us. This'll be
   // released when the JSObject is finalized.
   ::JS_SetPrivate(mJSObject, this);
   NS_ADDREF(this);
   return NS_OK;
 }
--- a/content/xul/document/src/nsXULPrototypeDocument.cpp
+++ b/content/xul/document/src/nsXULPrototypeDocument.cpp
@@ -696,16 +696,21 @@ nsXULPDGlobalObject::EnsureScriptEnviron
   ctxNew->DidInitializeContext();
 
   JSObject* global = ctxNew->GetNativeGlobal();
   NS_ASSERTION(global, "GetNativeGlobal returned NULL!");
 
   mContext = ctxNew;
   mJSObject = global;
 
+  // Set the location information for the new global, so that tools like
+  // about:memory may use that information
+  nsIURI *ownerURI = mGlobalObjectOwner->GetURI();
+  xpc::SetLocationForGlobal(mJSObject, ownerURI);
+
   return NS_OK;
 }
 
 nsIScriptContext*
 nsXULPDGlobalObject::GetScriptContext()
 {
   // This global object creates a context on demand - do that now.
   nsresult rv = EnsureScriptEnvironment();
--- a/dom/Makefile.in
+++ b/dom/Makefile.in
@@ -11,16 +11,17 @@ VPATH		= @srcdir@
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= dom
 
 DIRS = \
   interfaces/base \
   interfaces/canvas \
   interfaces/core \
+  interfaces/devicestorage \
   interfaces/html \
   interfaces/events \
   interfaces/contacts \
   interfaces/settings \
   interfaces/stylesheets \
   interfaces/sidebar \
   interfaces/css \
   interfaces/traversal \
@@ -43,16 +44,17 @@ DIRS += \
   $(NULL)
 
 DIRS += \
   apps \
   base \
   bindings \
   battery \
   contacts \
+  devicestorage \
   power \
   settings \
   sms \
   src \
   locales \
   network \
   plugins/base \
   plugins/ipc \
--- a/dom/base/BrowserElementChild.js
+++ b/dom/base/BrowserElementChild.js
@@ -56,17 +56,17 @@ BrowserElementChild.prototype = {
     //
     // Get the app manifest from the parent, if our frame has one.
     let appManifestURL = sendSyncMsg('get-mozapp-manifest-url')[0];
     let windowUtils = content.QueryInterface(Ci.nsIInterfaceRequestor)
                              .getInterface(Components.interfaces.nsIDOMWindowUtils);
 
     if (!!appManifestURL) {
       windowUtils.setIsApp(true);
-      windowUtils.setApp(mozApp);
+      windowUtils.setApp(appManifestURL);
     } else {
       windowUtils.setIsApp(false);
     }
 
     addEventListener('DOMTitleChanged',
                      this._titleChangedHandler.bind(this),
                      /* useCapture = */ true,
                      /* wantsUntrusted = */ false);
--- a/dom/base/DOMRequest.h
+++ b/dom/base/DOMRequest.h
@@ -15,21 +15,16 @@
 #include "nsCOMPtr.h"
 
 namespace mozilla {
 namespace dom {
 
 class DOMRequest : public nsDOMEventTargetHelper,
                    public nsIDOMDOMRequest
 {
-  bool mDone;
-  jsval mResult;
-  nsCOMPtr<nsIDOMDOMError> mError;
-  bool mRooted;
-
   NS_DECL_EVENT_HANDLER(success)
   NS_DECL_EVENT_HANDLER(error)
 
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMDOMREQUEST
   NS_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetHelper::)
 
@@ -41,16 +36,21 @@ public:
 
   DOMRequest(nsIDOMWindow* aWindow);
 
   virtual ~DOMRequest()
   {
     UnrootResultVal();
   }
 
+  bool mDone;
+  jsval mResult;
+  nsCOMPtr<nsIDOMDOMError> mError;
+  bool mRooted;
+
 private:
   void FireEvent(const nsAString& aType);
 
   void RootResultVal()
   {
     if (!mRooted) {
       NS_HOLD_JS_OBJECTS(this, DOMRequest);
       mRooted = true;
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -8,16 +8,17 @@
 #include "base/basictypes.h"
 
 #include "Navigator.h"
 #include "nsIXULAppInfo.h"
 #include "nsPluginArray.h"
 #include "nsMimeTypeArray.h"
 #include "nsDesktopNotification.h"
 #include "nsGeolocation.h"
+#include "nsDeviceStorage.h"
 #include "nsIHttpProtocolHandler.h"
 #include "nsICachingChannel.h"
 #include "nsIDocShell.h"
 #include "nsIWebContentHandlerRegistrar.h"
 #include "nsICookiePermission.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIJSContextStack.h"
 #include "nsCharSeparatedTokenizer.h"
@@ -84,16 +85,17 @@ Navigator::~Navigator()
 {
   Invalidate();
 }
 
 NS_INTERFACE_MAP_BEGIN(Navigator)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMNavigator)
   NS_INTERFACE_MAP_ENTRY(nsIDOMNavigator)
   NS_INTERFACE_MAP_ENTRY(nsIDOMClientInformation)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorDeviceStorage)
   NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorGeolocation)
   NS_INTERFACE_MAP_ENTRY(nsIDOMMozNavigatorBattery)
   NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorDesktopNotification)
   NS_INTERFACE_MAP_ENTRY(nsIDOMMozNavigatorSms)
 #ifdef MOZ_B2G_RIL
   NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorTelephony)
 #endif
   NS_INTERFACE_MAP_ENTRY(nsIDOMMozNavigatorNetwork)
@@ -835,16 +837,36 @@ Navigator::MozIsLocallyAvailable(const n
     return NS_OK;
   }
 
   nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(channel);
   return httpChannel->GetRequestSucceeded(aIsAvailable);
 }
 
 //*****************************************************************************
+//    Navigator::nsIDOMNavigatorDeviceStorage
+//*****************************************************************************
+
+NS_IMETHODIMP Navigator::GetDeviceStorage(const nsAString &aType, nsIVariant** _retval)
+{
+  if (!Preferences::GetBool("device.storage.enabled", false)) {
+    return NS_OK;
+  }
+
+  nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mWindow));
+
+  if (!win || !win->GetOuterWindow() || !win->GetDocShell()) {
+    return NS_ERROR_FAILURE;
+  }
+
+  nsDOMDeviceStorage::CreateDeviceStoragesFor(win, aType, _retval);
+  return NS_OK;
+}
+
+//*****************************************************************************
 //    Navigator::nsIDOMNavigatorGeolocation
 //*****************************************************************************
 
 NS_IMETHODIMP Navigator::GetGeolocation(nsIDOMGeoGeolocation** _retval)
 {
   NS_ENSURE_ARG_POINTER(_retval);
   *_retval = nsnull;
 
--- a/dom/base/Navigator.h
+++ b/dom/base/Navigator.h
@@ -4,16 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_Navigator_h
 #define mozilla_dom_Navigator_h
 
 #include "nsIDOMNavigator.h"
 #include "nsIDOMNavigatorGeolocation.h"
+#include "nsIDOMNavigatorDeviceStorage.h"
 #include "nsIDOMNavigatorDesktopNotification.h"
 #include "nsIDOMClientInformation.h"
 #include "nsIDOMNavigatorBattery.h"
 #include "nsIDOMNavigatorSms.h"
 #include "nsIDOMNavigatorNetwork.h"
 #include "nsAutoPtr.h"
 #include "nsWeakReference.h"
 
@@ -55,16 +56,17 @@ class MobileConnection;
 } // namespace Connection;
 
 namespace power {
 class PowerManager;
 } // namespace power
 
 class Navigator : public nsIDOMNavigator
                 , public nsIDOMClientInformation
+                , public nsIDOMNavigatorDeviceStorage
                 , public nsIDOMNavigatorGeolocation
                 , public nsIDOMNavigatorDesktopNotification
                 , public nsIDOMMozNavigatorBattery
                 , public nsIDOMMozNavigatorSms
 #ifdef MOZ_B2G_RIL
                 , public nsIDOMNavigatorTelephony
 #endif
                 , public nsIDOMMozNavigatorNetwork
@@ -74,16 +76,17 @@ class Navigator : public nsIDOMNavigator
 {
 public:
   Navigator(nsPIDOMWindow *aInnerWindow);
   virtual ~Navigator();
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDOMNAVIGATOR
   NS_DECL_NSIDOMCLIENTINFORMATION
+  NS_DECL_NSIDOMNAVIGATORDEVICESTORAGE
   NS_DECL_NSIDOMNAVIGATORGEOLOCATION
   NS_DECL_NSIDOMNAVIGATORDESKTOPNOTIFICATION
   NS_DECL_NSIDOMMOZNAVIGATORBATTERY
   NS_DECL_NSIDOMMOZNAVIGATORSMS
 #ifdef MOZ_B2G_RIL
   NS_DECL_NSIDOMNAVIGATORTELEPHONY
 #endif
   NS_DECL_NSIDOMMOZNAVIGATORNETWORK
--- a/dom/base/Webapps.jsm
+++ b/dom/base/Webapps.jsm
@@ -182,17 +182,17 @@ let DOMApplicationRegistry = {
 
     let appObject = this._cloneAppObject(app);
     appObject.installTime = (new Date()).getTime();
     let appNote = JSON.stringify(appObject);
     appNote.id = id;
 
     let dir = FileUtils.getDir(DIRECTORY_NAME, ["webapps", id], true, true);
     let manFile = dir.clone();
-    manFile.append("manifest.json");
+    manFile.append("manifest.webapp");
     this._writeFile(manFile, JSON.stringify(app.manifest));
     this.webapps[id] = appObject;
 
     if (!aFromSync)
       this._saveApps((function() {
         ppmm.sendAsyncMessage("Webapps:Install:Return:OK", aData);
         Services.obs.notifyObservers(this, "webapps-sync-install", appNote);
       }).bind(this));
@@ -224,17 +224,23 @@ let DOMApplicationRegistry = {
   _readManifests: function(aData, aFinalCallback, aIndex) {
     if (!aData.length) {
       aFinalCallback(aData);
       return;
     }
 
     let index = aIndex || 0;
     let id = aData[index].id;
-    let file = FileUtils.getFile(DIRECTORY_NAME, ["webapps", id, "manifest.json"], true);
+
+    // the manifest file used to be named manifest.json, so fallback on this.
+    let file = FileUtils.getFile(DIRECTORY_NAME, ["webapps", id, "manifest.webapp"], true);
+    if (!file.exists()) {
+      file = FileUtils.getFile(DIRECTORY_NAME, ["webapps", id, "manifest.json"], true);
+    }
+
     this._loadJSONAsync(file, (function(aJSON) {
       aData[index].manifest = aJSON;
       if (index == aData.length - 1)
         aFinalCallback(aData);
       else
         this._readManifests(aData, aFinalCallback, index + 1);
     }).bind(this));
   },
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -409,16 +409,20 @@
 #include "nsIDOMCanvasRenderingContext2D.h"
 #include "nsIDOMWebGLRenderingContext.h"
 
 #include "nsIImageDocument.h"
 
 // Storage includes
 #include "nsDOMStorage.h"
 
+// Device Storage
+#include "nsIDOMDeviceStorage.h"
+#include "nsIDOMDeviceStorageCursor.h"
+
 // Drag and drop
 #include "nsIDOMDataTransfer.h"
 
 // Geolocation
 #include "nsIDOMGeoGeolocation.h"
 #include "nsIDOMGeoPosition.h"
 #include "nsIDOMGeoPositionCoords.h"
 #include "nsIDOMGeoPositionError.h"
@@ -429,16 +433,17 @@
 #include "nsDOMFile.h"
 #include "nsDOMFileReader.h"
 #include "nsIDOMFormData.h"
 
 #include "nsIDOMDOMStringMap.h"
 
 #include "nsIDOMDesktopNotification.h"
 #include "nsIDOMNavigatorDesktopNotification.h"
+#include "nsIDOMNavigatorDeviceStorage.h"
 #include "nsIDOMNavigatorGeolocation.h"
 #include "Navigator.h"
 
 #include "nsPluginArray.h"
 #include "nsMimeTypeArray.h"
 
 // Simple gestures include
 #include "nsIDOMSimpleGestureEvent.h"
@@ -1389,16 +1394,22 @@ static nsDOMClassInfoData sClassInfoData
                            WINDOW_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(DataContainerEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(MessageEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
+  NS_DEFINE_CLASSINFO_DATA(DeviceStorage, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+
+  NS_DEFINE_CLASSINFO_DATA(DeviceStorageCursor, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+
   NS_DEFINE_CLASSINFO_DATA(GeoGeolocation, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   
   NS_DEFINE_CLASSINFO_DATA(GeoPosition, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS) 
   
   NS_DEFINE_CLASSINFO_DATA(GeoPositionCoords, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
@@ -1591,17 +1602,17 @@ static nsDOMClassInfoData sClassInfoData
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(MozCSSKeyframesRule, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(MediaQueryList, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(CustomEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CLASSINFO_DATA(MozMutationObserver, nsDOMGenericSH,
+  NS_DEFINE_CLASSINFO_DATA(MutationObserver, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(MutationRecord, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(MozSettingsEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
 #ifdef MOZ_B2G_RIL
   NS_DEFINE_CLASSINFO_DATA(Telephony, nsEventTargetSH,
@@ -1641,17 +1652,17 @@ static const nsContractIDMapData kConstr
   NS_DEFINE_CONSTRUCTOR_DATA(FormData, NS_FORMDATA_CONTRACTID)
   NS_DEFINE_CONSTRUCTOR_DATA(XMLSerializer, NS_XMLSERIALIZER_CONTRACTID)
   NS_DEFINE_CONSTRUCTOR_DATA(XMLHttpRequest, NS_XMLHTTPREQUEST_CONTRACTID)
   NS_DEFINE_CONSTRUCTOR_DATA(WebSocket, NS_WEBSOCKET_CONTRACTID)
   NS_DEFINE_CONSTRUCTOR_DATA(XPathEvaluator, NS_XPATH_EVALUATOR_CONTRACTID)
   NS_DEFINE_CONSTRUCTOR_DATA(XSLTProcessor,
                              "@mozilla.org/document-transformer;1?type=xslt")
   NS_DEFINE_CONSTRUCTOR_DATA(EventSource, NS_EVENTSOURCE_CONTRACTID)
-  NS_DEFINE_CONSTRUCTOR_DATA(MozMutationObserver, NS_DOMMUTATIONOBSERVER_CONTRACTID)
+  NS_DEFINE_CONSTRUCTOR_DATA(MutationObserver, NS_DOMMUTATIONOBSERVER_CONTRACTID)
 };
 
 #define NS_DEFINE_EVENT_CTOR(_class)                        \
   nsresult                                                  \
   NS_DOM##_class##Ctor(nsISupports** aInstancePtrResult)    \
   {                                                         \
     nsIDOMEvent* e = nsnull;                                \
     nsresult rv = NS_NewDOM##_class(&e, nsnull, nsnull);    \
@@ -2426,16 +2437,17 @@ nsDOMClassInfo::Init()
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(Location, nsIDOMLocation)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMLocation)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(Navigator, nsIDOMNavigator)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNavigator)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMNavigatorDeviceStorage)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNavigatorGeolocation)
     DOM_CLASSINFO_MAP_CONDITIONAL_ENTRY(nsIDOMNavigatorDesktopNotification,
                                         Navigator::HasDesktopNotificationSupport())
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMClientInformation)
     DOM_CLASSINFO_MAP_CONDITIONAL_ENTRY(nsIDOMMozNavigatorBattery,
                                         battery::BatteryManager::HasSupport())
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozNavigatorSms)
 #ifdef MOZ_B2G_RIL
@@ -4029,16 +4041,26 @@ nsDOMClassInfo::Init()
     DOM_CLASSINFO_EVENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(MessageEvent, nsIDOMMessageEvent)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMMessageEvent)
     DOM_CLASSINFO_EVENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
+  DOM_CLASSINFO_MAP_BEGIN(DeviceStorage, nsIDOMDeviceStorage)
+     DOM_CLASSINFO_MAP_ENTRY(nsIDOMDeviceStorage)
+  DOM_CLASSINFO_MAP_END
+
+  DOM_CLASSINFO_MAP_BEGIN(DeviceStorageCursor, nsIDOMDeviceStorageCursor)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMDeviceStorageCursor)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMDOMRequest)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
+  DOM_CLASSINFO_MAP_END
+
   DOM_CLASSINFO_MAP_BEGIN(GeoGeolocation, nsIDOMGeoGeolocation)
      DOM_CLASSINFO_MAP_ENTRY(nsIDOMGeoGeolocation)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(GeoPosition, nsIDOMGeoPosition)
      DOM_CLASSINFO_MAP_ENTRY(nsIDOMGeoPosition)
   DOM_CLASSINFO_MAP_END
 
@@ -4378,18 +4400,18 @@ nsDOMClassInfo::Init()
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMMediaQueryList)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(CustomEvent, nsIDOMCustomEvent)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMCustomEvent)
     DOM_CLASSINFO_EVENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
-  DOM_CLASSINFO_MAP_BEGIN(MozMutationObserver, nsIDOMMozMutationObserver)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozMutationObserver)
+  DOM_CLASSINFO_MAP_BEGIN(MutationObserver, nsIDOMMutationObserver)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMMutationObserver)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(MutationRecord, nsIDOMMutationRecord)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMMutationRecord)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(MozSettingsEvent, nsIDOMMozSettingsEvent)
      DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozSettingsEvent)
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -382,16 +382,19 @@ DOMCI_CLASS(ModalContentWindow)
 
 // Data Events
 DOMCI_CLASS(DataContainerEvent)
 
 // event used for cross-domain message-passing and for server-sent events in
 // HTML5
 DOMCI_CLASS(MessageEvent)
 
+DOMCI_CLASS(DeviceStorage)
+DOMCI_CLASS(DeviceStorageCursor)
+
 // Geolocation
 DOMCI_CLASS(GeoGeolocation)
 DOMCI_CLASS(GeoPosition)
 DOMCI_CLASS(GeoPositionCoords)
 DOMCI_CLASS(GeoPositionError)
 
 DOMCI_CLASS(MozBatteryManager)
 
@@ -500,17 +503,17 @@ DOMCI_CLASS(TouchList)
 DOMCI_CLASS(TouchEvent)
 
 DOMCI_CLASS(MozCSSKeyframeRule)
 DOMCI_CLASS(MozCSSKeyframesRule)
 
 DOMCI_CLASS(MediaQueryList)
 DOMCI_CLASS(CustomEvent)
 
-DOMCI_CLASS(MozMutationObserver)
+DOMCI_CLASS(MutationObserver)
 DOMCI_CLASS(MutationRecord)
 
 DOMCI_CLASS(MozSettingsEvent)
 
 #ifdef MOZ_B2G_RIL
 DOMCI_CLASS(Telephony)
 DOMCI_CLASS(TelephonyCall)
 DOMCI_CLASS(CallEvent)
--- a/dom/base/nsFocusManager.h
+++ b/dom/base/nsFocusManager.h
@@ -58,16 +58,26 @@ public:
   /**
    * A faster version of nsIFocusManager::GetFocusedElement, returning a
    * raw nsIContent pointer (instead of having AddRef-ed nsIDOMElement
    * pointer filled in to an out-parameter).
    */
   nsIContent* GetFocusedContent() { return mFocusedContent; }
 
   /**
+   * Return a focused window. Version of nsIFocusManager::GetFocusedWindow.
+   */
+  nsPIDOMWindow* GetFocusedWindow() const { return mFocusedWindow; }
+
+  /**
+   * Return an active window. Version of nsIFocusManager::GetActiveWindow.
+   */
+  nsPIDOMWindow* GetActiveWindow() const { return mActiveWindow; }
+
+  /**
    * Called when content has been removed.
    */
   nsresult ContentRemoved(nsIDocument* aDocument, nsIContent* aContent);
 
   /**
    * Called when mouse button down event handling is started and finished.
    */
   void SetMouseButtonDownHandlingDocument(nsIDocument* aDocument)
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -1817,17 +1817,19 @@ nsGlobalWindow::SetNewDocument(nsIDocume
 
       mInnerWindow = nsnull;
 
       Freeze();
       mCreatingInnerWindow = true;
       // Every script context we are initialized with must create a
       // new global.
       nsCOMPtr<nsIXPConnectJSObjectHolder> &holder = mInnerWindowHolder;
-      rv = mContext->CreateNativeGlobalForInner(sgo, isChrome,
+      rv = mContext->CreateNativeGlobalForInner(sgo,
+                                                aDocument->GetDocumentURI(),
+                                                isChrome,
                                                 aDocument->NodePrincipal(),
                                                 &newInnerWindow->mJSObject,
                                                 getter_AddRefs(holder));
       NS_ASSERTION(NS_SUCCEEDED(rv) && newInnerWindow->mJSObject && holder,
                    "Failed to get script global and holder");
 
       mCreatingInnerWindow = false;
       createdInnerWindow = true;
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -908,17 +908,16 @@ protected:
   nsTimeout*                    mTimeoutInsertionPoint;
   PRUint32                      mTimeoutPublicIdCounter;
   PRUint32                      mTimeoutFiringDepth;
   nsRefPtr<nsLocation>          mLocation;
   nsRefPtr<nsHistory>           mHistory;
 
   // These member variables are used on both inner and the outer windows.
   nsCOMPtr<nsIPrincipal> mDocumentPrincipal;
-  nsCOMPtr<nsIDocument> mDoc;  // For fast access to principals
   JSObject* mJSObject;
 
   typedef nsCOMArray<nsIDOMStorageEvent> nsDOMStorageEventArray;
   nsDOMStorageEventArray mPendingStorageEvents;
 
   PRUint32 mTimeoutsSuspendDepth;
 
   // the method that was used to focus mFocusedNode
--- a/dom/base/nsIScriptContext.h
+++ b/dom/base/nsIScriptContext.h
@@ -20,16 +20,17 @@ class nsIPrincipal;
 class nsIAtom;
 class nsIArray;
 class nsIVariant;
 class nsIObjectInputStream;
 class nsIObjectOutputStream;
 template<class> class nsScriptObjectHolder;
 class nsIScriptObjectPrincipal;
 class nsIDOMWindow;
+class nsIURI;
 
 typedef void (*nsScriptTerminationFunc)(nsISupports* aRef);
 
 #define NS_ISCRIPTCONTEXTPRINCIPAL_IID \
   { 0xd012cdb3, 0x8f1e, 0x4440, \
     { 0x8c, 0xbd, 0x32, 0x7f, 0x98, 0x1d, 0x37, 0xb4 } }
 
 class nsIScriptContextPrincipal : public nsISupports
@@ -39,18 +40,18 @@ public:
 
   virtual nsIScriptObjectPrincipal* GetObjectPrincipal() = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIScriptContextPrincipal,
                               NS_ISCRIPTCONTEXTPRINCIPAL_IID)
 
 #define NS_ISCRIPTCONTEXT_IID \
-{ 0xf1c8c13e, 0xc23b, 0x434e, \
-  { 0xa4, 0x77, 0xe0, 0x2f, 0xc3, 0x73, 0xf8, 0x71 } }
+  { 0xec47ccd4, 0x5f6a, 0x40d6, \
+    { 0xbc, 0x2f, 0x5a, 0x1e, 0xd3, 0xe4, 0xb4, 0xff } }
 
 /* This MUST match JSVERSION_DEFAULT.  This version stuff if we don't
    know what language we have is a little silly... */
 #define SCRIPTVERSION_DEFAULT JSVERSION_DEFAULT
 
 /**
  * It is used by the application to initialize a runtime and run scripts.
  * A script runtime would implement this interface.
@@ -260,16 +261,17 @@ public:
 
   /**
    * Create a new global object that will be used for an inner window.
    * Return the native global and an nsISupports 'holder' that can be used
    * to manage the lifetime of it.
    */
   virtual nsresult CreateNativeGlobalForInner(
                                       nsIScriptGlobalObject *aNewInner,
+                                      nsIURI *aURI,
                                       bool aIsChrome,
                                       nsIPrincipal *aPrincipal,
                                       JSObject** aNativeGlobal,
                                       nsISupports **aHolder) = 0;
 
   /**
    * Initialize the context generally. Does not create a global object.
    **/
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -2072,16 +2072,17 @@ JSObject*
 nsJSContext::GetNativeGlobal()
 {
     return JS_GetGlobalObject(mContext);
 }
 
 nsresult
 nsJSContext::CreateNativeGlobalForInner(
                                 nsIScriptGlobalObject *aNewInner,
+                                nsIURI *aURI,
                                 bool aIsChrome,
                                 nsIPrincipal *aPrincipal,
                                 JSObject** aNativeGlobal, nsISupports **aHolder)
 {
   nsIXPConnect *xpc = nsContentUtils::XPConnect();
   PRUint32 flags = aIsChrome? nsIXPConnect::FLAG_SYSTEM_GLOBAL_OBJECT : 0;
 
   nsCOMPtr<nsIPrincipal> systemPrincipal;
@@ -2095,16 +2096,22 @@ nsJSContext::CreateNativeGlobalForInner(
           InitClassesWithNewWrappedGlobal(mContext, aNewInner,
                                           aIsChrome ? systemPrincipal.get() : aPrincipal,
                                           flags, getter_AddRefs(jsholder));
   if (NS_FAILED(rv)) {
     return rv;
   }
   jsholder->GetJSObject(aNativeGlobal);
   jsholder.forget(aHolder);
+
+  // Set the location information for the new global, so that tools like
+  // about:memory may use that information
+  MOZ_ASSERT(aNativeGlobal && *aNativeGlobal);
+  xpc::SetLocationForGlobal(*aNativeGlobal, aURI);
+
   return NS_OK;
 }
 
 JSContext*
 nsJSContext::GetNativeContext()
 {
   return xpc_UnmarkGrayContext(mContext);
 }
@@ -3048,33 +3055,33 @@ nsJSContext::CycleCollectNow(nsICycleCol
   if (sPostGCEventsToConsole) {
     PRTime delta = 0;
     if (sFirstCollectionTime) {
       delta = now - sFirstCollectionTime;
     } else {
       sFirstCollectionTime = now;
     }
 
-    nsString gcmsg;
+    nsCString gcMsg;
     if (ccResults.mForcedGC) {
-      gcmsg.AssignLiteral(", forced a GC");
+      gcMsg.AssignLiteral(", forced a GC");
     }
 
     NS_NAMED_MULTILINE_LITERAL_STRING(kFmt,
       NS_LL("CC(T+%.1f) duration: %llums, suspected: %lu, visited: %lu RCed and %lu GCed, collected: %lu RCed and %lu GCed (%lu waiting for GC)%s\n")
       NS_LL("ForgetSkippable %lu times before CC, min: %lu ms, max: %lu ms, avg: %lu ms, total: %lu ms, removed: %lu"));
     nsString msg;
     PRUint32 cleanups = sForgetSkippableBeforeCC ? sForgetSkippableBeforeCC : 1;
     sMinForgetSkippableTime = (sMinForgetSkippableTime == PR_UINT32_MAX)
       ? 0 : sMinForgetSkippableTime;
     msg.Adopt(nsTextFormatter::smprintf(kFmt.get(), double(delta) / PR_USEC_PER_SEC,
                                         (now - start) / PR_USEC_PER_MSEC, suspected,
                                         ccResults.mVisitedRefCounted, ccResults.mVisitedGCed,
                                         ccResults.mFreedRefCounted, ccResults.mFreedGCed,
-                                        sCCollectedWaitingForGC, gcmsg.get(),
+                                        sCCollectedWaitingForGC, gcMsg.get(),
                                         sForgetSkippableBeforeCC,
                                         sMinForgetSkippableTime / PR_USEC_PER_MSEC,
                                         sMaxForgetSkippableTime / PR_USEC_PER_MSEC,
                                         (sTotalForgetSkippableTime / cleanups) /
                                           PR_USEC_PER_MSEC,
                                         sTotalForgetSkippableTime / PR_USEC_PER_MSEC,
                                         sRemovedPurples));
     nsCOMPtr<nsIConsoleService> cs =
--- a/dom/base/nsJSEnvironment.h
+++ b/dom/base/nsJSEnvironment.h
@@ -104,16 +104,17 @@ public:
 
   virtual nsIScriptGlobalObject *GetGlobalObject();
   inline nsIScriptGlobalObject *GetGlobalObjectRef() { return mGlobalObjectRef; };
 
   virtual JSContext* GetNativeContext();
   virtual JSObject* GetNativeGlobal();
   virtual nsresult CreateNativeGlobalForInner(
                                       nsIScriptGlobalObject *aGlobal,
+                                      nsIURI *aURI,
                                       bool aIsChrome,
                                       nsIPrincipal *aPrincipal,
                                       JSObject** aNativeGlobal,
                                       nsISupports **aHolder);
   virtual nsresult InitContext();
   virtual nsresult InitOuterWindow();
   virtual bool IsContextInitialized();
 
--- a/dom/base/nsPIDOMWindow.h
+++ b/dom/base/nsPIDOMWindow.h
@@ -43,18 +43,18 @@ class nsIDocument;
 class nsIScriptTimeoutHandler;
 struct nsTimeout;
 template <class> class nsScriptObjectHolder;
 class nsXBLPrototypeHandler;
 class nsIArray;
 class nsPIWindowRoot;
 
 #define NS_PIDOMWINDOW_IID \
-{ 0x7a6238d4, 0x7cbc, 0x43b2, \
-  { 0x86, 0x68, 0x92, 0xeb, 0x9e, 0xb0, 0x49, 0xaf } }
+{ 0xf0bafbe6, 0xe45c, 0x490e, \
+  { 0xa2, 0x1c, 0xfe, 0x14, 0x2f, 0xb6, 0x34, 0xba } }
 
 class nsPIDOMWindow : public nsIDOMWindowInternal
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_PIDOMWINDOW_IID)
 
   virtual nsPIDOMWindow* GetPrivateRoot() = 0;
 
@@ -159,16 +159,20 @@ public:
   virtual void MaybeUpdateTouchState() {}
   virtual void UpdateTouchState() {}
 
   // GetExtantDocument provides a backdoor to the DOM GetDocument accessor
   nsIDOMDocument* GetExtantDocument() const
   {
     return mDocument;
   }
+  nsIDocument* GetExtantDoc() const
+  {
+    return mDoc;
+  }
 
   // Internal getter/setter for the frame element, this version of the
   // getter crosses chrome boundaries whereas the public scriptable
   // one doesn't for security reasons.
   nsIDOMElement* GetFrameElementInternal() const
   {
     if (mOuterWindow) {
       return mOuterWindow->GetFrameElementInternal();
@@ -591,16 +595,17 @@ protected:
 
   virtual void UpdateParentTarget() = 0;
 
   // These two variables are special in that they're set to the same
   // value on both the outer window and the current inner window. Make
   // sure you keep them in sync!
   nsCOMPtr<nsIDOMEventTarget> mChromeEventHandler; // strong
   nsCOMPtr<nsIDOMDocument> mDocument; // strong
+  nsCOMPtr<nsIDocument> mDoc; // strong, for fast access
 
   nsCOMPtr<nsIDOMEventTarget> mParentTarget; // strong
 
   // These members are only used on outer windows.
   nsCOMPtr<nsIDOMElement> mFrameElement;
   nsIDocShell           *mDocShell;  // Weak Reference
 
   PRUint32               mModalStateDepth;
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -664,12 +664,64 @@ protected:
   }
 
   nsRefPtr<T> ptr;
 #ifdef DEBUG
   bool inited;
 #endif
 };
 
+enum StringificationBehavior {
+  eStringify,
+  eEmpty,
+  eNull
+};
+
+static inline bool
+ConvertJSValueToString(JSContext* cx, const JS::Value& v, JS::Value* pval,
+                       StringificationBehavior nullBehavior,
+                       StringificationBehavior undefinedBehavior,
+                       nsDependentString& result)
+{
+  JSString *s;
+  if (v.isString()) {
+    s = v.toString();
+  } else {
+    StringificationBehavior behavior;
+    if (v.isNull()) {
+      behavior = nullBehavior;
+    } else if (v.isUndefined()) {
+      behavior = undefinedBehavior;
+    } else {
+      behavior = eStringify;
+    }
+
+    // If pval is null, that means the argument was optional and
+    // not passed; turn those into void strings if they're
+    // supposed to be stringified.
+    if (behavior != eStringify || !pval) {
+      // Here behavior == eStringify implies !pval, so both eNull and
+      // eStringify should end up with void strings.
+      result.SetIsVoid(behavior != eEmpty);
+      return true;
+    }
+
+    s = JS_ValueToString(cx, v);
+    if (!s) {
+      return false;
+    }
+    pval->setString(s);  // Root the new string.
+  }
+
+  size_t len;
+  const jschar *chars = JS_GetStringCharsZAndLength(cx, s, &len);
+  if (!chars) {
+    return false;
+  }
+
+  result.Rebind(chars, len);
+  return true;
+}
+
 } // namespace dom
 } // namespace mozilla
 
 #endif /* mozilla_dom_BindingUtils_h__ */
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -6,21 +6,21 @@
 
 import os
 import string
 
 from WebIDL import *
 
 AUTOGENERATED_WARNING_COMMENT = \
     "/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n\n"
-ADDPROPERTY_HOOK_NAME = '_AddProperty'
-FINALIZE_HOOK_NAME = '_Finalize'
-TRACE_HOOK_NAME = '_Trace'
-CONSTRUCT_HOOK_NAME = '_Construct'
-HASINSTANCE_HOOK_NAME = '_HasInstance'
+ADDPROPERTY_HOOK_NAME = '_addProperty'
+FINALIZE_HOOK_NAME = '_finalize'
+TRACE_HOOK_NAME = '_trace'
+CONSTRUCT_HOOK_NAME = '_constructor'
+HASINSTANCE_HOOK_NAME = '_hasInstance'
 
 def replaceFileIfChanged(filename, newContents):
     """
     Read a copy of the old file, so that we don't touch it if it hasn't changed.
     Returns True if the file was updated, false otherwise.
     """
     oldFileContents = ""
     try:
@@ -283,20 +283,19 @@ class CGNamespace(CGWrapper):
         CGWrapper.__init__(self, child, pre=pre, post=post,
                            declareOnly=declareOnly)
     @staticmethod
     def build(namespaces, child, declareOnly=False):
         """
         Static helper method to build multiple wrapped namespaces.
         """
         if not namespaces:
-            return child
-        return CGNamespace(namespaces[0], CGNamespace.build(namespaces[1:],
-                                                            child),
-                           declareOnly=declareOnly)
+            return CGWrapper(child, declareOnly=declareOnly)
+        inner = CGNamespace.build(namespaces[1:], child, declareOnly=declareOnly)
+        return CGNamespace(namespaces[0], inner, declareOnly=declareOnly)
 
 class CGIncludeGuard(CGWrapper):
     """
     Generates include guards for a header.
     """
     def __init__(self, prefix, child):
         """|prefix| is the filename without the extension."""
         define = 'mozilla_dom_%s_h__' % prefix
@@ -505,17 +504,17 @@ class CGClassFinalizeHook(CGAbstractClas
   }""" % (self.name, self.args[0].name)
         if self.descriptor.workers:
             release = "self->Release();"
         else:
             assert self.descriptor.nativeIsISupports
             release = """
   XPCJSRuntime *rt = nsXPConnect::GetRuntimeInstance();
   if (rt) {
-    rt->DeferredRelease(NativeToSupports(self));
+    rt->DeferredRelease(reinterpret_cast<nsISupports*>(self));
   } else {
     NS_RELEASE(self);
   }"""
         return """
   self->ClearWrapper();
   %s""" % (release)
 
 class CGClassTraceHook(CGAbstractClassHook):
@@ -549,39 +548,37 @@ class CGClassConstructHook(CGAbstractSta
 
     def definition_body(self):
         return self.generate_code()
 
     def generate_code(self):
         preamble = """
   JSObject* obj = JS_GetGlobalForObject(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)));
 """
-        preArgs = ""
         if self.descriptor.workers:
-            preArgs = "cx, obj, "
+            preArgs = ["cx", "obj"]
         else:
             preamble += """
   nsISupports* global;
   xpc_qsSelfRef globalRef;
   {
     nsresult rv;
     JS::Value val = OBJECT_TO_JSVAL(obj);
     rv = xpc_qsUnwrapArg<nsISupports>(cx, val, &global, &globalRef.ptr, &val);
     if (NS_FAILED(rv)) {
       return Throw<true>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);
     }
   }
 """
-            preArgs = "global, "
-
-        name = "_" + self._ctor.identifier.name
-        nativeName = "_" + MakeNativeName(self._ctor.identifier.name)
-        nativeName = self.descriptor.binaryNames.get(name, nativeName)
+            preArgs = ["global"]
+
+        name = MakeNativeName(self._ctor.identifier.name)
+        nativeName = self.descriptor.binaryNames.get(name, name)
         callGenerator = CGMethodCall(preArgs, nativeName, True,
-                                     self.descriptor, self._ctor, {})
+                                     self.descriptor, self._ctor)
         return preamble + callGenerator.define();
 
 class CGClassHasInstanceHook(CGAbstractStaticMethod):
     def __init__(self, descriptor):
         args = [Argument('JSContext*', 'cx'), Argument('JSHandleObject', 'obj'),
                 Argument('const jsval*', 'v'), Argument('JSBool*', 'bp')]
         CGAbstractStaticMethod.__init__(self, descriptor, HASINSTANCE_HOOK_NAME,
                                         'JSBool', args)
@@ -1011,34 +1008,16 @@ class CGDefineDOMInterfaceMethod(CGAbstr
             getter = "GetConstructorObject"
 
         return ("  JSObject* global = JS_GetGlobalForObject(aCx, aReceiver);\n" +
                 CheckPref(self.descriptor, "global", "*aEnabled", "false") + 
                 """
   *aEnabled = true;
   return !!%s(aCx, global, aReceiver);""" % (getter))
 
-class CGNativeToSupportsMethod(CGAbstractStaticMethod):
-    """
-    A method to cast our native to an nsISupports.  We do it by casting up the
-    interface chain in hopes of getting to something that singly-inherits from
-    nsISupports.
-    """
-    def __init__(self, descriptor):
-        args = [Argument(descriptor.nativeType + '*', 'aNative')]
-        CGAbstractStaticMethod.__init__(self, descriptor, 'NativeToSupports', 'nsISupports*', args)
-
-    def definition_body(self):
-        cur = CGGeneric("aNative")
-        for proto in reversed(self.descriptor.prototypeChain[:-1]):
-            d = self.descriptor.getDescriptor(proto)
-            cast = "static_cast<%s*>(\n" % d.nativeType;
-            cur = CGWrapper(CGIndenter(cur), pre=cast, post=")")
-        return CGIndenter(CGWrapper(cur, pre="return ", post=";")).define();
-
 class CGWrapMethod(CGAbstractMethod):
     def __init__(self, descriptor):
         # XXX can we wrap if we don't have an interface prototype object?
         assert descriptor.interface.hasInterfacePrototypeObject()
         args = [Argument('JSContext*', 'aCx'), Argument('JSObject*', 'aScope'),
                 Argument(descriptor.nativeType + '*', 'aObject'),
                 Argument('bool*', 'aTriedToWrap')]
         CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'JSObject*', args)
@@ -1212,34 +1191,42 @@ def getJSToNativeConversionTemplate(type
         or None if no such holder is needed.
 
     ${declName} must be in scope before the generated code is entered.
 
     If holderType is not None then ${holderName} must be in scope
     before the generated code is entered.
     """
 
+    # A helper function for dealing with failures due to the JS value being the
+    # wrong type of value
+    def onFailure(failureCode, isWorker):
+        return CGWrapper(CGGeneric(
+                failureCode or
+                "return Throw<%s>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);"
+                % toStringBool(isWorker)), post="\n")
+
     # A helper function for wrapping up the template body for
     # possibly-nullable objecty stuff
     def wrapObjectTemplate(templateBody, isDefinitelyObject, type,
-                           codeToSetNull, isWorker):
+                           codeToSetNull, isWorker, failureCode=None):
         if not isDefinitelyObject:
             # Handle the non-object cases by wrapping up the whole
             # thing in an if cascade.
             templateBody = (
                 "if (${val}.isObject()) {\n" +
                 CGIndenter(CGGeneric(templateBody)).define() + "\n")
             if type.nullable():
                 templateBody += (
                     "} else if (${val}.isNullOrUndefined()) {\n"
                     "  %s;\n" % codeToSetNull)
             templateBody += (
-                "} else {\n"
-                "  return Throw<%s>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);\n"
-                "}" % toStringBool(not isWorker))
+                "} else {\n" +
+                CGIndenter(onFailure(failureCode, isWorker)).define() +
+                "}")
         return templateBody
 
     if type.isArray():
         raise TypeError("Can't handle array arguments yet")
 
     if type.isSequence():
         if isSequenceMember:
             raise TypeError("Can't handle sequences of sequences")
@@ -1383,22 +1370,18 @@ for (uint32_t i = 0; i < length; ++i) {
                 # will just own stuff.
                 templateBody += "nsCOMPtr<" + typeName + "> ${holderName};"
             else:
                 holderType = "nsCOMPtr<" + typeName + ">"
             templateBody += (
                 "jsval tmpVal = ${val};\n" +
                 typePtr + " tmp;\n"
                 "if (NS_FAILED(xpc_qsUnwrapArg<" + typeName + ">(cx, ${val}, &tmp, getter_AddRefs(${holderName}), &tmpVal))) {\n")
-            if failureCode is not None:
-                templateBody += "  " + failureCode + "\n"
-            else:
-                templateBody += (
-                    "  return Throw<%s>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);\n"
-                    % toStringBool(not descriptor.workers))
+            templateBody += CGIndenter(onFailure(failureCode,
+                                                 descriptor.workers)).define()
             templateBody += ("}\n"
                 "MOZ_ASSERT(tmp);\n")
 
             if not isDefinitelyObject:
                 # Our tmpVal will go out of scope, so we can't rely on it
                 # for rooting
                 templateBody += (
                     "if (tmpVal != ${val} && !${holderName}) {\n"
@@ -1429,19 +1412,19 @@ for (uint32_t i = 0; i < length; ++i) {
             "}")
         if type.nullable():
             template += (
                 " else if (${val}.isNullOrUndefined()) {\n"
                 "  ${declName} = NULL;\n"
                 "}")
 
         template += (
-            # XXXbz We don't know whether we're on workers, so play it safe
-            " else {\n"
-            "  return Throw<false>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);\n"
+            " else {\n" +
+            CGIndenter(onFailure(failureCode,
+                                 descriptorProvider.workers)).define() +
             "}")
 
         return (template, CGGeneric(declType), None)
 
     if type.isString():
         if isSequenceMember:
             raise TypeError("Can't handle sequences of strings")
         # XXXbz Need to figure out string behavior based on extended args?  Also, how to
@@ -1452,22 +1435,21 @@ for (uint32_t i = 0; i < length; ++i) {
         if type.nullable():
             nullBehavior = "eNull"
             undefinedBehavior = "eNull"
         else:
             nullBehavior = "eStringify"
             undefinedBehavior = "eStringify"
 
         return (
-            "const xpc_qsDOMString ${declName}(cx, ${val}, ${valPtr},\n"
-            "                           xpc_qsDOMString::%s,\n"
-            "                           xpc_qsDOMString::%s);\n"
-            "if (!${declName}.IsValid()) {\n"
+            "if (!ConvertJSValueToString(cx, ${val}, ${valPtr}, %s, %s, ${holderName})) {\n"
             "  return false;\n"
-            "}" % (nullBehavior, undefinedBehavior), None, None)
+            "}\n"
+            "${declName} = &${holderName};" % (nullBehavior, undefinedBehavior),
+            CGGeneric("NonNull<const nsAString>"), CGGeneric("nsDependentString"))
 
     if type.isEnum():
         if type.nullable():
             raise TypeError("We don't support nullable enumerated arguments "
                             "yet")
         enum = type.inner.identifier.name
         return (
             "{\n"
@@ -1492,16 +1474,29 @@ for (uint32_t i = 0; i < length; ++i) {
             "  ${declName} = NULL;\n"
             "}", CGGeneric("JSObject*"), None)
 
     if type.isAny():
         if isSequenceMember:
             raise TypeError("Can't handle sequences of 'any'")
         return ("${declName} = ${val};", CGGeneric("JS::Value"), None)
 
+    if type.isObject():
+        if isSequenceMember:
+            raise TypeError("Can't handle sequences of 'object'")
+        template = wrapObjectTemplate("${declName} = &${val}.toObject();",
+                                      isDefinitelyObject, type,
+                                      "${declName} = NULL",
+                                      descriptorProvider.workers, failureCode)
+        if type.nullable():
+            declType = CGGeneric("JSObject*")
+        else:
+            declType = CGGeneric("NonNull<JSObject>")
+        return (template, declType, None)
+
     if not type.isPrimitive():
         raise TypeError("Need conversion for argument type '%s'" % type)
 
     # XXXbz need to add support for [EnforceRange] and [Clamp]
     typeName = builtinNames[type.tag()]
     if type.nullable():
         return ("if (${val}.isNullOrUndefined()) {\n"
                 "  ${declName}.SetNull();\n"
@@ -1750,16 +1745,25 @@ if (!%(resultStr)s) {
         # to wrap here.
         return setValue("JS::ObjectOrNullValue(%s)" % result, True)
 
     if type.tag() == IDLType.Tags.any:
         # See comments in WrapNewBindingObject explaining why we need
         # to wrap here.
         return setValue(result, True)
 
+    if type.isObject():
+        # See comments in WrapNewBindingObject explaining why we need
+        # to wrap here.
+        if type.nullable():
+            toValue = "JS::ObjectOrNullValue(%s)"
+        else:
+            toValue = "JS::ObjectValue(*%s)"
+        return setValue(toValue % result, True)
+
     if not type.isPrimitive():
         raise TypeError("Need to learn to wrap %s" % type)
 
     if type.nullable():
         return ("if (%s.IsNull()) {\n" % result +
                 CGIndenter(CGGeneric(setValue("JSVAL_NULL"))).define() + "\n" +
                 "}\n" +
                 getWrapTemplateForType(type.inner, descriptorProvider,
@@ -1807,94 +1811,121 @@ def wrapForType(type, descriptorProvider
     """
     wrap = getWrapTemplateForType(type, descriptorProvider,
                                   templateValues.get('result', 'result'),
                                   templateValues.get('successCode', None))
 
     defaultValues = {'obj': 'obj'}
     return string.Template(wrap).substitute(defaultValues, **templateValues)
 
+# Returns a tuple consisting of a CGThing containing the type of the return
+# value and a boolean signalling whether we need to pass a JSContext as the
+# first argument of the call.
 def getRetvalDeclarationForType(returnType, descriptorProvider,
                                 resultAlreadyAddRefed):
     if returnType is None or returnType.isVoid():
         # Nothing to declare
-        result = None
-    elif returnType.isPrimitive() and returnType.tag() in builtinNames:
+        return None, False
+    if returnType.isPrimitive() and returnType.tag() in builtinNames:
         result = CGGeneric(builtinNames[returnType.tag()])
         if returnType.nullable():
             result = CGWrapper(result, pre="Nullable<", post=">")
-    elif returnType.isString():
-        result = CGGeneric("nsString")
-    elif returnType.isEnum():
+        return result, False
+    if returnType.isString():
+        return CGGeneric("nsString"), False
+    if returnType.isEnum():
         if returnType.nullable():
             raise TypeError("We don't support nullable enum return values")
-        result = CGGeneric(returnType.inner.identifier.name)
-    elif returnType.isInterface() and not returnType.isArrayBuffer():
+        return CGGeneric(returnType.inner.identifier.name), False
+    if returnType.isInterface() and not returnType.isArrayBuffer():
         result = CGGeneric(descriptorProvider.getDescriptor(
             returnType.unroll().inner.identifier.name).nativeType)
         if resultAlreadyAddRefed:
             result = CGWrapper(result, pre="nsRefPtr<", post=">")
         else:
             result = CGWrapper(result, post="*")
-    elif returnType.isCallback():
+        return result, False
+    if returnType.isCallback():
         # XXXbz we're going to assume that callback types are always
         # nullable for now.
-        result = CGGeneric("JSObject*")
-    elif returnType.tag() is IDLType.Tags.any:
-        result = CGGeneric("JS::Value")
-    elif returnType.isSequence():
+        return CGGeneric("JSObject*"), False
+    if returnType.tag() is IDLType.Tags.any:
+        return CGGeneric("JS::Value"), False
+    if returnType.isObject():
+        return CGGeneric("JSObject*"), True
+    if returnType.isSequence():
         nullable = returnType.nullable()
         if nullable:
             returnType = returnType.inner
         # Assume no need to addref for now
-        result = CGWrapper(getRetvalDeclarationForType(returnType.inner,
-                                                       descriptorProvider,
-                                                       False),
-                           pre="nsTArray< ", post=" >")
+        (result, needsCx) = getRetvalDeclarationForType(returnType.inner,
+                                                        descriptorProvider,
+                                                        False)
+        result = CGWrapper(result, pre="nsTArray< ", post=" >")
         if nullable:
             result = CGWrapper(result, pre="Nullable< ", post=" >")
-    else:
-        raise TypeError("Don't know how to declare return value for %s" %
-                        returnType)
-    return result
-
+        return result, needsCx
+    raise TypeError("Don't know how to declare return value for %s" %
+                    returnType)
+
+
+
+def isResultAlreadyAddRefed(descriptor, extendedAttributes):
+    # Default to already_AddRefed on the main thread, raw pointer in workers
+    return not descriptor.workers and not 'resultNotAddRefed' in extendedAttributes
 
 class CGCallGenerator(CGThing):
     """
     A class to generate an actual call to a C++ object.  Assumes that the C++
     object is stored in a variable named "self".
     """
-    def __init__(self, errorReport, argCount, argsPre, returnType,
-                 resultAlreadyAddRefed, descriptorProvider, nativeMethodName, static):
+    def __init__(self, errorReport, arguments, argsPre, returnType,
+                 extendedAttributes, descriptorProvider, nativeMethodName, static):
         CGThing.__init__(self)
 
         isFallible = errorReport is not None
 
-        args = CGList([CGGeneric("arg" + str(i)) for i in range(argCount)], ", ")
+        args = CGList([CGGeneric(arg) for arg in argsPre], ", ")
+        for (i, a) in enumerate(arguments):
+            arg = "arg" + str(i)
+            # This is a workaround for a bug in Apple's clang.
+            if a.type.isObject() and not a.type.nullable():
+                arg = "(JSObject&)" + arg
+            args.append(CGGeneric(arg))
         resultOutParam = (returnType is not None and
                           (returnType.isString() or returnType.isSequence()))
         # Return values that go in outparams go here
         if resultOutParam:
             args.append(CGGeneric("result"))
         if isFallible:
             args.append(CGGeneric("rv"))
 
-        result = getRetvalDeclarationForType(returnType, descriptorProvider,
-                                             resultAlreadyAddRefed)
+        resultAlreadyAddRefed = isResultAlreadyAddRefed(descriptorProvider,
+                                                        extendedAttributes)
+        (result, needsCx) = getRetvalDeclarationForType(returnType,
+                                                        descriptorProvider,
+                                                        resultAlreadyAddRefed)
+
+        if not needsCx:
+            needsCx = reduce(lambda b, a: b or a.type.isObject(), arguments,
+                             False)
+
+        if not "cx" in argsPre and (needsCx or 'implicitJSContext' in extendedAttributes):
+            args.prepend(CGGeneric("cx"))
 
         # Build up our actual call
         self.cgRoot = CGList([], "\n")
 
         call = CGGeneric(nativeMethodName)
         if static:
             call = CGWrapper(call, pre="%s::" % (descriptorProvider.getDescriptor(
                 returnType.unroll().inner.identifier.name).nativeType))
         else: 
             call = CGWrapper(call, pre="self->")
-        call = CGList([call, CGWrapper(args, pre="(" + argsPre, post=");")])
+        call = CGList([call, CGWrapper(args, pre="(", post=");")])
         if result is not None:
             result = CGWrapper(result, post=" result;")
             self.cgRoot.prepend(result)
             if not resultOutParam:
                 call = CGWrapper(call, pre="result = ")
 
         call = CGWrapper(call)
         self.cgRoot.append(call)
@@ -1927,40 +1958,41 @@ class CGPerSignatureCall(CGThing):
     |idlNode.identifier| in both cases, so we can be agnostic between the two.
     """
     # XXXbz For now each entry in the argument list is either an
     # IDLArgument or a FakeArgument, but longer-term we may want to
     # have ways of flagging things like JSContext* or optional_argc in
     # there.
 
     def __init__(self, returnType, argsPre, arguments, nativeMethodName, static,
-                 descriptor, idlNode, extendedAttributes, argConversionStartsAt=0):
+                 descriptor, idlNode, argConversionStartsAt=0,
+                 getter=False, setter=False):
         CGThing.__init__(self)
         self.returnType = returnType
         self.descriptor = descriptor
         self.idlNode = idlNode
-        self.extendedAttributes = extendedAttributes
-        # Default to already_AddRefed on the main thread, raw pointer in workers
-        self.resultAlreadyAddRefed = not descriptor.workers and not 'resultNotAddRefed' in self.extendedAttributes
-        self.argsPre = "cx, " if 'implicitJSContext' in self.extendedAttributes else ""
-        self.argsPre += argsPre
+        self.extendedAttributes = descriptor.getExtendedAttributes(idlNode,
+                                                                   getter=getter,
+                                                                   setter=setter)
+        self.argsPre = argsPre
+        self.arguments = arguments
         self.argCount = len(arguments)
         if self.argCount > argConversionStartsAt:
             # Insert our argv in there
             cgThings = [CGGeneric(self.getArgvDecl())]
         else:
             cgThings = []
         cgThings.extend([CGArgumentConverter(arguments[i], i, self.getArgv(),
                                              self.getArgc(), self.descriptor) for
                          i in range(argConversionStartsAt, self.argCount)])
 
         cgThings.append(CGCallGenerator(
                     self.getErrorReport() if self.isFallible() else None,
-                    self.argCount, self.argsPre, returnType,
-                    self.resultAlreadyAddRefed, descriptor, nativeMethodName,
+                    self.arguments, self.argsPre, returnType,
+                    self.extendedAttributes, descriptor, nativeMethodName,
                     static))
         self.cgRoot = CGList(cgThings, "\n")
 
     def getArgv(self):
         return "argv" if self.argCount > 0 else ""
     def getArgvDecl(self):
         return "\nJS::Value* argv = JS_ARGV(cx, vp);\n"
     def getArgc(self):
@@ -2029,18 +2061,17 @@ class CGCase(CGList):
         self.append(CGIndenter(bodyList));
         self.append(CGGeneric("}"))
 
 class CGMethodCall(CGThing):
     """
     A class to generate selection of a method signature from a set of
     signatures and generation of a call to that signature.
     """
-    def __init__(self, argsPre, nativeMethodName, static, descriptor, method,
-                 extendedAttributes):
+    def __init__(self, argsPre, nativeMethodName, static, descriptor, method):
         CGThing.__init__(self)
 
         def requiredArgCount(signature):
             arguments = signature[1]
             if len(arguments) == 0:
                 return 0
             requiredArgs = len(arguments)
             while requiredArgs and arguments[requiredArgs-1].optional:
@@ -2068,18 +2099,17 @@ class CGMethodCall(CGThing):
             for idx in range(0, argCount):
                 if isValidDistinguishingIndex(idx, signatures):
                     return idx
             return -1
 
         def getPerSignatureCall(signature, argConversionStartsAt=0):
             return CGPerSignatureCall(signature[0], argsPre, signature[1],
                                       nativeMethodName, static, descriptor,
-                                      method, extendedAttributes,
-                                      argConversionStartsAt)
+                                      method, argConversionStartsAt)
             
 
         signatures = method.signatures()
         if len(signatures) == 1:
             # Special case: we can just do a per-signature method call
             # here for our one signature and not worry about switching
             # on anything.
             signature = signatures[0]
@@ -2297,34 +2327,34 @@ class CGMethodCall(CGThing):
         return self.cgRoot.define()
 
 class CGGetterSetterCall(CGPerSignatureCall):
     """
     A class to generate a native object getter or setter call for a
     particular IDL getter or setter.
     """
     def __init__(self, returnType, arguments, nativeMethodName, descriptor,
-                 attr, extendedAttributes):
-        CGPerSignatureCall.__init__(self, returnType, "", arguments,
+                 attr, getter=False, setter=False):
+        assert bool(getter) != bool(setter)
+        CGPerSignatureCall.__init__(self, returnType, [], arguments,
                                     nativeMethodName, False, descriptor, attr,
-                                    extendedAttributes)
+                                    getter=getter, setter=setter)
     def getArgv(self):
         if generateNativeAccessors:
             return CGPerSignatureCall.getArgv(self)
         return "vp"
 
 class CGGetterCall(CGGetterSetterCall):
     """
     A class to generate a native object getter call for a particular IDL
     getter.
     """
-    def __init__(self, returnType, nativeMethodName, descriptor, attr,
-                 extendedAttributes):
+    def __init__(self, returnType, nativeMethodName, descriptor, attr):
         CGGetterSetterCall.__init__(self, returnType, [], nativeMethodName,
-                                    descriptor, attr, extendedAttributes)
+                                    descriptor, attr, getter=True)
     def getArgc(self):
         if generateNativeAccessors:
             return CGGetterSetterCall.getArgc()
         return "0"
     def getArgvDecl(self):
         if generateNativeAccessors:
             return CGPerSignatureCall.getArgvDecl(self)
         # We just get our stuff from vp
@@ -2335,21 +2365,20 @@ class FakeArgument():
         self.type = type
         self.optional = False
 
 class CGSetterCall(CGGetterSetterCall):
     """
     A class to generate a native object setter call for a particular IDL
     setter.
     """
-    def __init__(self, argType, nativeMethodName, descriptor, attr,
-                 extendedAttributes):
+    def __init__(self, argType, nativeMethodName, descriptor, attr):
         CGGetterSetterCall.__init__(self, None, [FakeArgument(argType)],
                                     nativeMethodName, descriptor, attr,
-                                    extendedAttributes)
+                                    setter=True)
     def wrap_return_value(self):
         if generateNativeAccessors:
             return CGGetterSetterCall.wrap_return_value(self)
         # We have no return value
         return "\nreturn true;"
     def getArgc(self):
         if generateNativeAccessors:
             return CGGetterSetterCall.getArgc(self)
@@ -2368,18 +2397,17 @@ class CGSetterCall(CGGetterSetterCall):
 class CGAbstractBindingMethod(CGAbstractStaticMethod):
     """
     Common class to generate the JSNatives for all our methods, getters, and
     setters.  This will generate the function declaration and unwrap the
     |this| object.  Subclasses are expected to override the generate_code
     function to do the rest of the work.  This function should return a
     CGThing which is already properly indented.
     """
-    def __init__(self, descriptor, name, args, extendedAttributes):
-        self.extendedAttributes = extendedAttributes
+    def __init__(self, descriptor, name, args):
         CGAbstractStaticMethod.__init__(self, descriptor, name, "JSBool", args)
 
     def definition_body(self):
         unwrapThis = CGIndenter(CGGeneric(
             str(FailureFatalCastableObjectUnwrapper(self.descriptor,
                                                     "obj", "&self"))))
         return CGList([ self.getThis(), unwrapThis,
                         self.generate_code() ], "\n").define()
@@ -2403,81 +2431,77 @@ class CGNativeMethod(CGAbstractBindingMe
     """
     A class for generating the C++ code for an IDL method..
     """
     def __init__(self, descriptor, method):
         self.method = method
         baseName = method.identifier.name
         args = [Argument('JSContext*', 'cx'), Argument('unsigned', 'argc'),
                 Argument('JS::Value*', 'vp')]
-        CGAbstractBindingMethod.__init__(self, descriptor, baseName, args,
-                                         descriptor.getExtendedAttributes(method))
+        CGAbstractBindingMethod.__init__(self, descriptor, baseName, args)
     def generate_code(self):
         name = self.method.identifier.name
         nativeName = self.descriptor.binaryNames.get(name, MakeNativeName(name))
-        return CGMethodCall("", nativeName, self.method.isStatic(),
-                            self.descriptor, self.method,
-                            self.extendedAttributes)
+        return CGMethodCall([], nativeName, self.method.isStatic(),
+                            self.descriptor, self.method)
 
 class CGNativeGetter(CGAbstractBindingMethod):
     """
     A class for generating the C++ code for an IDL attribute getter.
     """
     def __init__(self, descriptor, attr):
         self.attr = attr
         name = 'get_' + attr.identifier.name
         if generateNativeAccessors:
             args = [Argument('JSContext*', 'cx'), Argument('unsigned', 'argc'),
                     Argument('JS::Value*', 'vp')]
         else:
             args = [Argument('JSContext*', 'cx'), Argument('JSHandleObject', 'obj'),
                     Argument('JSHandleId', 'id'), Argument('JS::Value*', 'vp')]
-        CGAbstractBindingMethod.__init__(self, descriptor, name, args,
-                                         descriptor.getExtendedAttributes(self.attr, getter=True))
+        CGAbstractBindingMethod.__init__(self, descriptor, name, args)
 
     def getThis(self):
         if generateNativeAccessors:
             return CGAbstractBindingMethod.getThis(self)
         return CGIndenter(
             CGGeneric("%s* self;" % self.descriptor.nativeType))
 
     def generate_code(self):
 
         nativeMethodName = "Get" + MakeNativeName(self.attr.identifier.name)
         return CGIndenter(CGGetterCall(self.attr.type, nativeMethodName, self.descriptor,
-                                       self.attr, self.extendedAttributes))
+                                       self.attr))
 
 class CGNativeSetter(CGAbstractBindingMethod):
     """
     A class for generating the C++ code for an IDL attribute setter.
     """
     def __init__(self, descriptor, attr):
         self.attr = attr
         baseName = attr.identifier.name
         name = 'set_' + attr.identifier.name
         if generateNativeAccessors:
             args = [Argument('JSContext*', 'cx'), Argument('unsigned', 'argc'),
                     Argument('JS::Value*', 'vp')]
         else:
             args = [Argument('JSContext*', 'cx'), Argument('JSHandleObject', 'obj'),
                     Argument('JSHandleId', 'id'), Argument('JSBool', 'strict'),
                     Argument('JS::Value*', 'vp')]
-        CGAbstractBindingMethod.__init__(self, descriptor, name, args,
-                                         descriptor.getExtendedAttributes(self.attr, setter=True))
+        CGAbstractBindingMethod.__init__(self, descriptor, name, args)
 
     def getThis(self):
         if generateNativeAccessors:
             return CGAbstractBindingMethod.getThis(self)
         return CGIndenter(
             CGGeneric("%s* self;" % self.descriptor.nativeType))
 
     def generate_code(self):
         nativeMethodName = "Set" + MakeNativeName(self.attr.identifier.name)
         return CGIndenter(CGSetterCall(self.attr.type, nativeMethodName, self.descriptor,
-                                       self.attr, self.extendedAttributes))
+                                       self.attr))
 
 def getEnumValueName(value):
     # Some enum values can be empty strings.  Others might have weird
     # characters in them.  Deal with the former by returning "_empty",
     # deal with possible name collisions from that by throwing if the
     # enum value is actually "_empty", and throw on any value
     # containing chars other than [a-z] or '-' for now. Replace '-' with '_'.
     value = value.replace('-', '_')
@@ -2941,18 +2965,16 @@ class CGDescriptor(CGThing):
                              a.isAttr() and not a.readonly])
 
         if descriptor.concrete:
             if not descriptor.workers:
                 cgThings.append(CGAddPropertyHook(descriptor))
 
             # Always have a finalize hook, regardless of whether the class wants a
             # custom hook.
-            if descriptor.nativeIsISupports:
-                cgThings.append(CGNativeToSupportsMethod(descriptor))
             cgThings.append(CGClassFinalizeHook(descriptor))
 
             # Only generate a trace hook if the class wants a custom hook.
             if (descriptor.customTrace):
                 cgThings.append(CGClassTraceHook(descriptor))
 
         if descriptor.concrete or descriptor.interface.hasInterfacePrototypeObject():
             cgThings.append(CGNativePropertyHooks(descriptor))
new file mode 100644
--- /dev/null
+++ b/dom/devicestorage/Makefile.in
@@ -0,0 +1,40 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this file,
+# You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DEPTH            = ../..
+topsrcdir        = @top_srcdir@
+srcdir           = @srcdir@
+VPATH            = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE           = dom
+LIBRARY_NAME     = domdevicestorage_s
+XPIDL_MODULE     = dom_devicestorage
+LIBXUL_LIBRARY   = 1
+FORCE_STATIC_LIB = 1
+
+include $(topsrcdir)/dom/dom-config.mk
+
+CPPSRCS		= \
+		nsDeviceStorage.cpp \
+		$(NULL)
+
+EXPORTS         = \
+		nsDeviceStorage.h \
+		$(NULL)
+
+LOCAL_INCLUDES = \
+		-I$(topsrcdir)/dom/base \
+		-I$(topsrcdir)/dom/ipc \
+		-I$(topsrcdir)/content/base/src \
+		-I$(topsrcdir)/content/events/src \
+		$(NULL)
+
+include $(topsrcdir)/config/config.mk
+include $(topsrcdir)/ipc/chromium/chromium-config.mk
+include $(topsrcdir)/config/rules.mk
+
+DEFINES += -D_IMPL_NS_LAYOUT
+
new file mode 100644
--- /dev/null
+++ b/dom/devicestorage/nsDeviceStorage.cpp
@@ -0,0 +1,1186 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsDeviceStorage.h"
+#include "DOMRequest.h"
+#include "nsServiceManagerUtils.h"
+#include "nsILocalFile.h"
+#include "nsIDirectoryEnumerator.h"
+#include "nsAppDirectoryServiceDefs.h"
+#include "nsIDOMFile.h"
+#include "nsDOMBlobBuilder.h"
+#include "nsNetUtil.h"
+#include "nsCycleCollectionParticipant.h"
+#include "nsIContentPermissionPrompt.h"
+#include "nsIPrincipal.h"
+#include "mozilla/Preferences.h"
+#include "nsJSUtils.h"
+
+using namespace mozilla::dom;
+
+#include "nsDirectoryServiceDefs.h"
+
+class DeviceStorageFile : public nsISupports {
+public:
+  DeviceStorageFile(nsIFile* aFile, const nsAString& aPath)
+    : mFile(aFile)
+    , mPath(aPath)
+    {
+      NS_ASSERTION(aFile, "Must not create a DeviceStorageFile with a null nsIFile");
+      NormalizeFilePath();
+    }
+  DeviceStorageFile(nsIFile* aFile)
+    : mFile(aFile)
+    {
+      NS_ASSERTION(aFile, "Must not create a DeviceStorageFile with a null nsIFile");
+    }
+    nsCOMPtr<nsIFile> mFile;
+    nsString mPath;
+
+    NS_DECL_ISUPPORTS
+
+private:
+  void NormalizeFilePath() {
+#if defined(XP_WIN)
+    PRUnichar* cur = mPath.BeginWriting();
+    PRUnichar* end = mPath.EndWriting();
+    for (; cur < end; ++cur) {
+      if (PRUnichar('\\') == *cur)
+	*cur = PRUnichar('/');
+    }
+#endif
+  }
+
+};
+
+NS_IMPL_THREADSAFE_ISUPPORTS0(DeviceStorageFile)
+
+// we want to make sure that the names of file can't reach
+// outside of the type of storage the user asked for.
+bool
+isSafePath(const nsAString& aPath)
+{
+  nsAString::const_iterator start, end;
+  aPath.BeginReading(start);
+  aPath.EndReading(end);
+
+  // if the path has a ~ or \ in it, return false.
+  NS_NAMED_LITERAL_STRING(tilde, "~");
+  NS_NAMED_LITERAL_STRING(bslash, "\\");
+  if (FindInReadable(tilde, start, end) ||
+      FindInReadable(bslash, start, end)) {
+    return false;
+  }
+
+  // split on /.  if any token is "", ., or .., return false.
+  NS_ConvertUTF16toUTF8 cname(aPath);
+  char* buffer = cname.BeginWriting();
+  const char* token;
+
+  while ((token = nsCRT::strtok(buffer, "/", &buffer))) {
+    if (PL_strcmp(token, "") == 0 ||
+        PL_strcmp(token, ".") == 0 ||
+        PL_strcmp(token, "..") == 0 ) {
+          return false;
+    }
+  }
+  return true;
+}
+
+static void AppendRelativePath(nsIFile* file, const nsAString& aPath) {
+
+#if defined(XP_WIN)
+  // replace forward slashes with backslashes,
+  // since nsLocalFileWin chokes on them
+  nsString temp;
+  temp.Assign(aPath);
+
+  PRUnichar* cur = temp.BeginWriting();
+  PRUnichar* end = temp.EndWriting();
+
+  for (; cur < end; ++cur) {
+    if (PRUnichar('/') == *cur)
+      *cur = PRUnichar('\\');
+  }
+  file->AppendRelativePath(temp);
+#else
+  file->AppendRelativePath(aPath);
+#endif
+}
+
+// TODO - eventually, we will want to factor this method
+// out into different system specific subclasses (or
+// something)
+PRInt32
+nsDOMDeviceStorage::SetRootFileForType(const nsAString& aType, const PRInt32 aIndex)
+{
+  PRInt32 typeResult = DEVICE_STORAGE_TYPE_DEFAULT;
+
+  nsCOMPtr<nsILocalFile> f;
+  nsCOMPtr<nsIProperties> dirService = do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID);
+  NS_ASSERTION(dirService, "Must have directory service");
+
+  // Picture directory
+  if (aType.Equals(NS_LITERAL_STRING("pictures"))) {
+#ifdef MOZ_WIDGET_GONK
+    if (aIndex == 0) {
+      NS_NewLocalFile(NS_LITERAL_STRING("/data/pictures"), false, getter_AddRefs(f));
+    }
+    else if (aIndex == 1) {
+      NS_NewLocalFile(NS_LITERAL_STRING("/sdcard/DCIM"), false, getter_AddRefs(f));
+      typeResult = DEVICE_STORAGE_TYPE_EXTERNAL;
+    }
+#elif defined (MOZ_WIDGET_COCOA)
+    if (aIndex == 0) {
+      dirService->Get(NS_OSX_PICTURE_DOCUMENTS_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(f));
+    }
+#elif defined (XP_UNIX)
+    if (aIndex == 0) {
+      dirService->Get(NS_UNIX_XDG_PICTURES_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(f));
+    }
+#endif
+  }
+
+  // in testing, we have access to a few more directory locations
+  if (mozilla::Preferences::GetBool("device.storage.testing", false)) {
+
+    // Temp directory
+    if (aType.Equals(NS_LITERAL_STRING("temp")) && aIndex == 0) {
+      dirService->Get(NS_OS_TEMP_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(f));
+    }
+
+    // Profile directory
+    else if (aType.Equals(NS_LITERAL_STRING("profile")) && aIndex == 0) {
+      dirService->Get(NS_APP_USER_PROFILE_50_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(f));
+    }
+  } 
+
+  mFile = f;
+  return typeResult;
+}
+
+static jsval nsIFileToJsval(nsPIDOMWindow* aWindow, DeviceStorageFile* aFile, bool aEditable)
+{
+  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+  NS_ASSERTION(aWindow, "Null Window");
+
+  if (aEditable) {
+    // TODO - needs janv's file handle support.
+    return JSVAL_NULL;
+  }
+
+  if (aFile == nsnull) {
+    return JSVAL_NULL;
+  }
+
+  nsCOMPtr<nsIDOMBlob> blob = new nsDOMFileFile(aFile->mFile, aFile->mPath);
+
+  nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aWindow);
+  if (!sgo) {
+    return JSVAL_NULL;
+  }
+    
+  nsIScriptContext *scriptContext = sgo->GetScriptContext();
+  if (!scriptContext) {
+    return JSVAL_NULL;
+  }
+
+  JSContext *cx = scriptContext->GetNativeContext();
+  if (!cx) {
+    return JSVAL_NULL;
+  }
+
+  jsval wrappedFile;
+  nsresult rv = nsContentUtils::WrapNative(cx,
+                                           JS_GetGlobalObject(cx),
+                                           blob,
+                                           &NS_GET_IID(nsIDOMFile),
+                                           &wrappedFile);
+  if (NS_FAILED(rv)) {
+    return JSVAL_NULL;
+  }
+
+  return wrappedFile;
+}
+
+
+static jsval StringToJsval(nsPIDOMWindow* aWindow, nsAString& aString)
+{
+  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+  NS_ASSERTION(aWindow, "Null Window");
+
+  nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aWindow);
+  if (!sgo) {
+    return JSVAL_NULL;
+  }
+    
+  nsIScriptContext *scriptContext = sgo->GetScriptContext();
+  if (!scriptContext) {
+    return JSVAL_NULL;
+  }
+
+  JSContext *cx = scriptContext->GetNativeContext();
+  if (!cx) {
+    return JSVAL_NULL;
+  }
+
+  JSAutoRequest ar(cx);
+
+  jsval result = JSVAL_NULL;
+  if (!xpc::StringToJsval(cx, aString, &result)) {
+    return JSVAL_NULL;
+  }
+
+  return result;
+}
+
+
+class nsDOMDeviceStorageCursor
+  : public nsIDOMDeviceStorageCursor
+  , public DOMRequest
+  , public nsIContentPermissionRequest
+{
+public:
+  NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_NSICONTENTPERMISSIONREQUEST
+  NS_DECL_NSIDOMDEVICESTORAGECURSOR
+
+  nsDOMDeviceStorageCursor(nsIDOMWindow* aWindow,
+                           nsIURI* aURI,
+                           DeviceStorageFile* aFile,
+                           bool aEditable);
+
+private:
+  ~nsDOMDeviceStorageCursor();
+
+protected:
+  nsTArray<nsRefPtr<DeviceStorageFile> > mFiles;
+
+  bool mOkToCallContinue;
+  nsRefPtr<DeviceStorageFile> mFile;
+  nsCOMPtr<nsIURI> mURI;
+  bool mEditable;
+
+  // to access mFiles
+  friend class InitCursorEvent;
+  friend class ContinueCursorEvent;
+};
+
+#define POST_ERROR_EVENT_FILE_DOES_NOT_EXIST         "File location doesn't exists"
+#define POST_ERROR_EVENT_FILE_NOT_ENUMERABLE         "File location is not enumerable"
+#define POST_ERROR_EVENT_PERMISSION_DENIED           "Permission Denied"
+#define POST_ERROR_EVENT_ILLEGAL_FILE_NAME           "Illegal file name"
+#define POST_ERROR_EVENT_UNKNOWN                     "Unknown"
+#define POST_ERROR_EVENT_NON_STRING_TYPE_UNSUPPORTED "Non-string type unsupported"
+
+class PostErrorEvent : public nsRunnable
+{
+public:
+  PostErrorEvent(nsRefPtr<DOMRequest>& aRequest, const char* aMessage, DeviceStorageFile* aFile)
+  {
+    mRequest.swap(aRequest);
+    BuildErrorString(aMessage, aFile);
+  }
+
+  PostErrorEvent(DOMRequest* aRequest, const char* aMessage, DeviceStorageFile* aFile)
+    : mRequest(aRequest)
+  {
+    BuildErrorString(aMessage, aFile);
+  }
+
+  ~PostErrorEvent() {}
+
+  void BuildErrorString(const char* aMessage, DeviceStorageFile* aFile)
+  {
+    nsAutoString fullPath;
+
+    if (aFile && aFile->mFile) {
+      aFile->mFile->GetPath(fullPath);
+    }
+    else {
+      fullPath.Assign(NS_LITERAL_STRING("null file"));
+    }
+      
+    mError = NS_ConvertASCIItoUTF16(aMessage);
+    mError.Append(NS_LITERAL_STRING(" file path = "));
+    mError.Append(fullPath.get());
+    mError.Append(NS_LITERAL_STRING(" path = "));
+
+    if (aFile) {
+      mError.Append(aFile->mPath);
+    }
+    else {
+      mError.Append(NS_LITERAL_STRING("null path"));
+    }
+  }
+
+  NS_IMETHOD Run() {
+    NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+
+    mRequest->FireError(mError);
+    mRequest = nsnull;
+    return NS_OK;
+  }
+
+private:
+  nsRefPtr<DOMRequest> mRequest;
+  nsString mError;
+};
+
+class ContinueCursorEvent : public nsRunnable
+{
+public:
+
+  ContinueCursorEvent(nsRefPtr<DOMRequest>& aRequest)
+  {
+    mRequest.swap(aRequest);
+  }
+
+  ContinueCursorEvent(DOMRequest* aRequest)
+    : mRequest(aRequest)
+  {
+  }
+
+  ~ContinueCursorEvent() {}
+
+  NS_IMETHOD Run() {
+    NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+
+    jsval val;
+
+    nsDOMDeviceStorageCursor* cursor = static_cast<nsDOMDeviceStorageCursor*>(mRequest.get());
+    if (cursor->mFiles.Length() == 0) {
+      val = JSVAL_NULL;
+    }
+    else {
+      nsRefPtr<DeviceStorageFile> file = cursor->mFiles[0];
+      cursor->mFiles.RemoveElementAt(0);
+      val = nsIFileToJsval(cursor->GetOwner(), file, cursor->mEditable);
+      cursor->mOkToCallContinue = true;
+    }
+
+    mRequest->FireSuccess(val);
+    mRequest = nsnull;
+    return NS_OK;
+  }
+
+private:
+  nsRefPtr<DOMRequest> mRequest;
+};
+
+
+class InitCursorEvent : public nsRunnable
+{
+public:
+    InitCursorEvent(DOMRequest* aRequest, DeviceStorageFile* aFile)
+    : mFile(aFile)
+    , mRequest(aRequest)
+  {
+  }
+
+  ~InitCursorEvent() {}
+
+  NS_IMETHOD Run() {
+    NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
+
+    bool check;
+    mFile->mFile->IsDirectory(&check);
+    if (!check) {
+      nsCOMPtr<PostErrorEvent> event = new PostErrorEvent(mRequest,
+                                                          POST_ERROR_EVENT_FILE_NOT_ENUMERABLE,
+                                                          mFile);
+      NS_DispatchToMainThread(event);
+      return NS_OK;
+    }
+
+    nsString fullpath;
+    mFile->mFile->GetPath(fullpath);
+    collectFiles(fullpath, mFile);
+
+    nsCOMPtr<ContinueCursorEvent> event = new ContinueCursorEvent(mRequest);
+    NS_DispatchToMainThread(event);
+
+    return NS_OK;
+  }
+
+  void collectFiles(const nsString& aInitialFullPath, DeviceStorageFile* aFile)
+  {
+      // TODO - we may want to do this incrementally.
+    if (!aFile)
+      return;
+
+    nsCOMPtr<nsISimpleEnumerator> e;
+    aFile->mFile->GetDirectoryEntries(getter_AddRefs(e));
+
+    nsCOMPtr<nsIDirectoryEnumerator> files = do_QueryInterface(e);
+    nsCOMPtr<nsIFile> f;
+
+    while (NS_SUCCEEDED(files->GetNextFile(getter_AddRefs(f))) && f) {
+      bool isDir;
+      f->IsDirectory(&isDir);
+
+      bool isFile;
+      f->IsFile(&isFile);
+
+      nsString fullpath;
+      f->GetPath(fullpath);
+
+      nsAString::size_type len = aInitialFullPath.Length() + 1; // +1 for the trailing /
+      nsDependentSubstring newPath = Substring(fullpath, len);
+
+      if (!StringBeginsWith(fullpath, aInitialFullPath)) {
+	NS_WARNING("collectFiles returned a path that does not belong!");
+	continue;
+      }
+
+      nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(f, newPath);
+      if (isDir) {
+	 collectFiles(aInitialFullPath, dsf);
+      }
+      else if (isFile) {
+        nsDOMDeviceStorageCursor* cursor = static_cast<nsDOMDeviceStorageCursor*>(mRequest.get());
+        cursor->mFiles.AppendElement(dsf);
+      }
+    }
+  }
+
+private:
+  nsRefPtr<DeviceStorageFile> mFile;
+  nsRefPtr<DOMRequest> mRequest;
+};
+
+DOMCI_DATA(DeviceStorageCursor, nsDOMDeviceStorageCursor)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMDeviceStorageCursor)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMDeviceStorageCursor)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMDeviceStorageCursor)
+  NS_INTERFACE_MAP_ENTRY(nsIContentPermissionRequest)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMDOMRequest)
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DeviceStorageCursor)
+NS_INTERFACE_MAP_END_INHERITING(DOMRequest)
+
+NS_IMPL_ADDREF_INHERITED(nsDOMDeviceStorageCursor, DOMRequest)
+NS_IMPL_RELEASE_INHERITED(nsDOMDeviceStorageCursor, DOMRequest)
+
+nsDOMDeviceStorageCursor::nsDOMDeviceStorageCursor(nsIDOMWindow* aWindow,
+                                                   nsIURI* aURI,
+                                                   DeviceStorageFile* aFile,
+                                                   bool aEditable)
+  : DOMRequest(aWindow)
+  , mOkToCallContinue(false)
+  , mFile(aFile)
+  , mURI(aURI)
+  , mEditable(aEditable)
+{
+  if (mozilla::Preferences::GetBool("device.storage.prompt.testing", false)) {
+    Allow();
+    return;
+  }
+
+  nsCOMPtr<nsIContentPermissionPrompt> prompt = do_GetService(NS_CONTENT_PERMISSION_PROMPT_CONTRACTID);
+  if (prompt) {
+    prompt->Prompt(this);
+  }
+}
+
+nsDOMDeviceStorageCursor::~nsDOMDeviceStorageCursor()
+{
+}
+
+NS_IMETHODIMP
+nsDOMDeviceStorageCursor::GetType(nsACString & aType)
+{
+  aType = "device-storage";
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMDeviceStorageCursor::GetUri(nsIURI * *aRequestingURI)
+{
+  mURI.forget(aRequestingURI);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMDeviceStorageCursor::GetWindow(nsIDOMWindow * *aRequestingWindow)
+{
+  NS_IF_ADDREF(*aRequestingWindow = GetOwner());
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMDeviceStorageCursor::GetElement(nsIDOMElement * *aRequestingElement)
+{
+  *aRequestingElement = nsnull;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMDeviceStorageCursor::Cancel()
+{
+  nsCOMPtr<PostErrorEvent> event = new PostErrorEvent(this,
+                                                      POST_ERROR_EVENT_PERMISSION_DENIED,
+                                                      mFile);
+  NS_DispatchToMainThread(event);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMDeviceStorageCursor::Allow()
+{
+  if (!isSafePath(mFile->mPath)) {
+    nsCOMPtr<nsIRunnable> r = new PostErrorEvent(this,
+                                                 POST_ERROR_EVENT_ILLEGAL_FILE_NAME,
+                                                 mFile);
+    NS_DispatchToMainThread(r);
+    return NS_OK;
+  }
+
+  AppendRelativePath(mFile->mFile, mFile->mPath);
+
+  nsCOMPtr<nsIEventTarget> target = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
+  NS_ASSERTION(target, "Must have stream transport service");
+
+  nsCOMPtr<InitCursorEvent> event = new InitCursorEvent(this, mFile);
+  target->Dispatch(event, NS_DISPATCH_NORMAL);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMDeviceStorageCursor::Continue()
+{
+  if (!mOkToCallContinue) {
+    return NS_ERROR_UNEXPECTED;
+  }
+
+  if (mRooted) {
+    // We call onsuccess multiple times. clear the last
+    // rooted result.
+    NS_DROP_JS_OBJECTS(this, nsDOMDeviceStorageCursor);
+    mResult = JSVAL_VOID;
+    mDone = false;
+    mRooted = false;
+  }
+
+  nsCOMPtr<ContinueCursorEvent> event = new ContinueCursorEvent(this);
+  NS_DispatchToMainThread(event);
+
+  mOkToCallContinue = false;
+  return NS_OK;
+}
+
+
+class PostResultEvent : public nsRunnable
+{
+public:
+  PostResultEvent(nsRefPtr<DOMRequest>& aRequest, bool aEditable, DeviceStorageFile* aFile)
+    : mEditable(aEditable)
+    , mFile(aFile)
+    {
+      mRequest.swap(aRequest);
+    }
+
+  PostResultEvent(nsRefPtr<DOMRequest>& aRequest, const nsAString & aPath)
+    : mPath(aPath)
+    {
+      mRequest.swap(aRequest);
+    }
+
+  ~PostResultEvent() {}
+
+  NS_IMETHOD Run() 
+  {
+    NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
+
+    jsval result = JSVAL_NULL;
+    if (mFile) {
+      result = nsIFileToJsval(mRequest->GetOwner(), mFile, mEditable);
+    } else {
+      result = StringToJsval(mRequest->GetOwner(), mPath);
+    }
+
+    mRequest->FireSuccess(result);
+    mRequest = nsnull;
+    return NS_OK;
+  }
+
+private:
+  bool mEditable;
+  nsRefPtr<DeviceStorageFile> mFile;
+  nsString mPath;
+  nsRefPtr<DOMRequest> mRequest;
+};
+
+class WriteFileEvent : public nsRunnable
+{
+public:
+  WriteFileEvent(nsIDOMBlob *aBlob,
+                 DeviceStorageFile *aFile,
+                 nsRefPtr<DOMRequest>& aRequest)
+  : mBlob(aBlob)
+  , mFile(aFile)
+    {
+      mRequest.swap(aRequest);
+    }
+
+  ~WriteFileEvent() {}
+
+  void CleanupOnFail(const char* error)
+  {
+    if (mFile) {
+      mFile->mFile->Remove(false);
+    }
+
+    nsCOMPtr<PostErrorEvent> event = new PostErrorEvent(mRequest,
+                                                        error,
+                                                        mFile);
+    NS_DispatchToMainThread(event);
+  }
+
+  NS_IMETHOD Run() 
+  {
+    NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
+
+    //TODO - this might be faster if we check to see if
+    //these are backed by OS-files, and if so, then just do
+    //a copy()
+
+    nsCOMPtr<nsIFile> f = mFile->mFile;
+
+    // This also creates all ancestors
+    nsresult rv = f->Create(nsIFile::NORMAL_FILE_TYPE, 00600);
+    if (NS_FAILED(rv)) {
+      CleanupOnFail(POST_ERROR_EVENT_UNKNOWN " 1 ");
+      return NS_OK;
+    }
+    
+    nsCOMPtr<nsIInputStream> stream;
+    mBlob->GetInternalStream(getter_AddRefs(stream));
+
+    if (!stream) {
+      CleanupOnFail(POST_ERROR_EVENT_UNKNOWN " 2 ");
+      return NS_OK;
+    }
+
+    PRUint32 bufSize;
+    stream->Available(&bufSize);
+
+    nsCOMPtr<nsIOutputStream> outputStream;
+    NS_NewLocalFileOutputStream(getter_AddRefs(outputStream), f);
+
+    if (!outputStream) {
+      CleanupOnFail(POST_ERROR_EVENT_UNKNOWN " 3 ");
+      return NS_OK;
+    }
+
+    nsCOMPtr<nsIOutputStream> bufferedOutputStream;
+    NS_NewBufferedOutputStream(getter_AddRefs(bufferedOutputStream),
+                               outputStream,
+                               4096*4);
+
+    if (!bufferedOutputStream) {
+      CleanupOnFail(POST_ERROR_EVENT_UNKNOWN " 4" );
+      return NS_OK;
+    }
+
+    PRUint32 wrote;
+    bufferedOutputStream->WriteFrom(stream, bufSize, &wrote);
+    bufferedOutputStream->Close();
+    outputStream->Close();
+
+    if (bufSize != wrote) {
+      CleanupOnFail(POST_ERROR_EVENT_UNKNOWN " 5 " );
+      return NS_OK;
+    }
+
+    nsCOMPtr<PostResultEvent> event = new PostResultEvent(mRequest, mFile->mPath);
+    NS_DispatchToMainThread(event);
+
+    return NS_OK;
+  }
+
+private:
+  nsCOMPtr<nsIDOMBlob> mBlob;
+  nsRefPtr<DeviceStorageFile> mFile;
+  nsRefPtr<DOMRequest> mRequest;
+};
+
+
+class ReadFileEvent : public nsRunnable
+{
+public:
+    ReadFileEvent(DeviceStorageFile* aFile,
+                  bool aEditable,
+                  nsRefPtr<DOMRequest>& aRequest)
+  : mFile(aFile)
+  , mEditable(aEditable)
+    {
+      mRequest.swap(aRequest);
+    }
+
+  ~ReadFileEvent() {}
+
+  NS_IMETHOD Run() 
+  {
+    NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
+
+    nsRefPtr<nsRunnable> r;
+
+    if (!mEditable) {
+      bool check = false;
+      mFile->mFile->Exists(&check);
+      if (!check) {
+        r = new PostErrorEvent(mRequest, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST, mFile);
+      }
+    }
+
+    if (!r) {
+      r = new PostResultEvent(mRequest, mEditable, mFile);
+    }
+    NS_DispatchToMainThread(r);
+    return NS_OK;
+  }
+
+private:
+  nsRefPtr<DeviceStorageFile> mFile;
+  bool mEditable;
+  nsRefPtr<DOMRequest> mRequest;
+};
+
+class DeleteFileEvent : public nsRunnable
+{
+public:
+  DeleteFileEvent(DeviceStorageFile* aFile,
+                  nsRefPtr<DOMRequest>& aRequest)
+  : mFile(aFile)
+    {
+      mRequest.swap(aRequest);
+    }
+
+  ~DeleteFileEvent() {}
+    
+  NS_IMETHOD Run() 
+  {
+    NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
+
+    mFile->mFile->Remove(true);
+    nsCOMPtr<PostResultEvent> event = new PostResultEvent(mRequest, mFile->mPath);
+    NS_DispatchToMainThread(event);
+    return NS_OK;
+  }
+
+private:
+  nsRefPtr<DeviceStorageFile> mFile;
+  nsRefPtr<DOMRequest> mRequest;
+};
+
+class DeviceStorageRequest : public nsIContentPermissionRequest, public nsIRunnable
+{
+public:
+
+    enum {
+        DEVICE_STORAGE_REQUEST_READ,
+        DEVICE_STORAGE_REQUEST_WRITE,
+        DEVICE_STORAGE_REQUEST_DELETE
+    };
+    DeviceStorageRequest(const PRInt32 aRequestType,
+                         nsPIDOMWindow *aWindow,
+                         nsIURI *aURI,
+                         DeviceStorageFile *aFile,
+                         DOMRequest* aRequest,
+                         bool aEditable,
+                         nsIDOMBlob *aBlob = nsnull)
+        : mRequestType(aRequestType)
+        , mWindow(aWindow)
+        , mURI(aURI)
+        , mFile(aFile)
+        , mRequest(aRequest)
+        , mEditable(aEditable)
+        , mBlob(aBlob) {}
+
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(DeviceStorageRequest, nsIContentPermissionRequest)
+
+  NS_IMETHOD Run() {
+
+    if (mozilla::Preferences::GetBool("device.storage.prompt.testing", false)) {
+      Allow();
+      return NS_OK;
+    }
+
+    nsCOMPtr<nsIContentPermissionPrompt> prompt = do_GetService(NS_CONTENT_PERMISSION_PROMPT_CONTRACTID);
+    if (prompt) {
+      prompt->Prompt(this);
+    }
+    return NS_OK;
+  }
+
+  NS_IMETHOD GetType(nsACString & aType)
+  {
+    aType = "device-storage";
+    return NS_OK;
+  }
+
+  NS_IMETHOD GetUri(nsIURI * *aRequestingURI)
+  {
+    NS_ADDREF(*aRequestingURI = mURI);
+    return NS_OK;
+  }
+
+  NS_IMETHOD GetWindow(nsIDOMWindow * *aRequestingWindow)
+  {
+    NS_IF_ADDREF(*aRequestingWindow = mWindow);
+    return NS_OK;
+  }
+
+  NS_IMETHOD GetElement(nsIDOMElement * *aRequestingElement)
+  {
+    *aRequestingElement = nsnull;
+    return NS_OK;
+  }
+
+  NS_IMETHOD Cancel()
+  {
+    nsCOMPtr<PostErrorEvent> event = new PostErrorEvent(mRequest,
+                                                        POST_ERROR_EVENT_PERMISSION_DENIED,
+                                                        mFile);
+    NS_DispatchToMainThread(event);
+    return NS_OK;
+  }
+
+  NS_IMETHOD Allow()
+  {
+    nsCOMPtr<nsIRunnable> r;
+
+    if (!mRequest) {
+      return NS_ERROR_FAILURE;
+    }
+
+    switch(mRequestType) {
+      case DEVICE_STORAGE_REQUEST_WRITE:
+      {
+        if (!mBlob) {
+          return NS_ERROR_FAILURE;
+        }
+
+        r = new WriteFileEvent(mBlob, mFile, mRequest);
+        break;
+      }
+      case DEVICE_STORAGE_REQUEST_READ:
+      {
+        r = new ReadFileEvent(mFile, mEditable, mRequest);
+        break;
+      }
+      case DEVICE_STORAGE_REQUEST_DELETE:
+      {
+        r = new DeleteFileEvent(mFile, mRequest);
+        break;
+      }
+    }
+    
+    if (r) {
+      nsCOMPtr<nsIEventTarget> target = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
+      NS_ASSERTION(target, "Must have stream transport service");
+      target->Dispatch(r, NS_DISPATCH_NORMAL);
+    }
+    return NS_OK;
+  }
+
+private:
+  PRInt32 mRequestType;
+  nsCOMPtr<nsPIDOMWindow> mWindow;
+  nsCOMPtr<nsIURI> mURI;
+  nsRefPtr<DeviceStorageFile> mFile;
+
+  nsRefPtr<DOMRequest> mRequest;
+  bool mEditable;
+  nsCOMPtr<nsIDOMBlob> mBlob;
+};
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DeviceStorageRequest)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContentPermissionRequest)
+  NS_INTERFACE_MAP_ENTRY(nsIContentPermissionRequest)
+  NS_INTERFACE_MAP_ENTRY(nsIRunnable)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(DeviceStorageRequest)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(DeviceStorageRequest)
+NS_IMPL_CYCLE_COLLECTION_CLASS(DeviceStorageRequest)
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DeviceStorageRequest)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mRequest)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mWindow)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mBlob)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DeviceStorageRequest)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mRequest, nsIDOMDOMRequest)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mWindow, nsPIDOMWindow)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mBlob, nsIDOMBlob)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+DOMCI_DATA(DeviceStorage, nsDOMDeviceStorage)
+
+NS_INTERFACE_MAP_BEGIN(nsDOMDeviceStorage)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMDeviceStorage)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMDeviceStorage)
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DeviceStorage)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_THREADSAFE_ADDREF(nsDOMDeviceStorage)
+NS_IMPL_THREADSAFE_RELEASE(nsDOMDeviceStorage)
+
+nsDOMDeviceStorage::nsDOMDeviceStorage()
+ : mStorageType(DEVICE_STORAGE_TYPE_DEFAULT)
+{
+}
+
+nsresult
+nsDOMDeviceStorage::Init(nsPIDOMWindow* aWindow, const nsAString &aType, const PRInt32 aIndex)
+{
+  NS_ASSERTION(aWindow, "Must have a content dom");
+
+  mStorageType = SetRootFileForType(aType, aIndex);
+  if (!mFile) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+
+  mOwner = do_GetWeakReference(aWindow);
+  if (!mOwner) {
+    return NS_ERROR_FAILURE;
+  }
+
+  // Grab the uri of the document
+  nsCOMPtr<nsIDOMDocument> domdoc;
+  aWindow->GetDocument(getter_AddRefs(domdoc));
+  nsCOMPtr<nsIDocument> doc = do_QueryInterface(domdoc);
+  if (!doc) {
+    return NS_ERROR_FAILURE;
+  }
+  doc->NodePrincipal()->GetURI(getter_AddRefs(mURI));
+
+  return NS_OK;
+}
+
+nsDOMDeviceStorage::~nsDOMDeviceStorage()
+{
+}
+
+void
+nsDOMDeviceStorage::CreateDeviceStoragesFor(nsPIDOMWindow* aWin,
+                                            const nsAString &aType,
+                                            nsIVariant** _retval)
+{
+  nsTArray<nsRefPtr<nsIDOMDeviceStorage> > stores;
+
+  PRInt32 index = 0;
+  while (1) {
+    nsresult rv;
+    nsRefPtr<nsDOMDeviceStorage> storage = new nsDOMDeviceStorage();
+    rv = storage->Init(aWin, aType, index++);
+    if (NS_FAILED(rv))
+      break;
+    stores.AppendElement(storage);
+  }
+
+  nsCOMPtr<nsIWritableVariant> result = do_CreateInstance("@mozilla.org/variant;1");
+  if (!result) {
+    return;
+  }
+
+  result->SetAsArray(nsIDataType::VTYPE_INTERFACE,
+                     &NS_GET_IID(nsIDOMDeviceStorage),
+                     stores.Length(),
+                     const_cast<void*>(static_cast<const void*>(stores.Elements())));
+  NS_ADDREF(*_retval = result);
+}
+
+NS_IMETHODIMP
+nsDOMDeviceStorage::GetType(nsAString & aType)
+{
+  switch(mStorageType) {
+    case DEVICE_STORAGE_TYPE_EXTERNAL:
+      aType.AssignLiteral("external");
+      break;
+    case DEVICE_STORAGE_TYPE_SHARED:
+      aType.AssignLiteral("shared");
+      break;
+    case DEVICE_STORAGE_TYPE_DEFAULT:
+    default:
+      aType.AssignLiteral("default");
+      break;
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMDeviceStorage::Add(nsIDOMBlob *aBlob, nsIDOMDOMRequest * *_retval NS_OUTPARAM)
+{
+  char buffer[128];
+  NS_MakeRandomString(buffer, 128);
+
+  nsString path;
+  path.AssignWithConversion(nsDependentCString(buffer));
+
+  return AddNamed(aBlob, path, _retval);
+}
+
+NS_IMETHODIMP
+nsDOMDeviceStorage::AddNamed(nsIDOMBlob *aBlob,
+                             const nsAString & aPath,
+                             nsIDOMDOMRequest * *_retval NS_OUTPARAM)
+{
+  // if the blob is null here, bail
+  if (aBlob == nsnull)
+    return NS_OK;
+
+  nsCOMPtr<nsPIDOMWindow> win = do_QueryReferent(mOwner);
+  if (!win) {
+    return NS_ERROR_UNEXPECTED;
+  }
+  
+  nsRefPtr<DOMRequest> request = new DOMRequest(win);
+  NS_ADDREF(*_retval = request);
+
+  nsCOMPtr<nsIRunnable> r;
+
+  nsCOMPtr<nsIFile> file;
+  mFile->Clone(getter_AddRefs(file));
+  AppendRelativePath(file, aPath);
+
+  nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(file, aPath);
+
+  if (!isSafePath(aPath)) {
+    r = new PostErrorEvent(request, POST_ERROR_EVENT_ILLEGAL_FILE_NAME, dsf);
+  }
+  else {
+    r = new DeviceStorageRequest(DeviceStorageRequest::DEVICE_STORAGE_REQUEST_WRITE,
+                                 win, mURI, dsf, request, true, aBlob);
+  }
+  NS_DispatchToMainThread(r);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMDeviceStorage::Get(const JS::Value & aPath,
+                        JSContext* aCx,
+                        nsIDOMDOMRequest * *_retval NS_OUTPARAM)
+{
+  return GetInternal(aPath, aCx, _retval, false);
+}
+
+NS_IMETHODIMP
+nsDOMDeviceStorage::GetEditable(const JS::Value & aPath,
+                                JSContext* aCx,
+                                nsIDOMDOMRequest * *_retval NS_OUTPARAM)
+{
+  return GetInternal(aPath, aCx, _retval, true);
+}
+
+nsresult
+nsDOMDeviceStorage::GetInternal(const JS::Value & aPath,
+                                JSContext* aCx,
+                                nsIDOMDOMRequest * *_retval NS_OUTPARAM,
+                                bool aEditable)
+{
+  nsCOMPtr<nsPIDOMWindow> win = do_QueryReferent(mOwner);
+  if (!win) {
+    return NS_ERROR_UNEXPECTED;
+  }
+
+  nsRefPtr<DOMRequest> request = new DOMRequest(win);
+  NS_ADDREF(*_retval = request);
+
+  nsCOMPtr<nsIRunnable> r;
+
+  JSString* jsstr = JS_ValueToString(aCx, aPath);
+  nsDependentJSString path;
+  if (!path.init(aCx, jsstr)) {
+    nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mFile);
+    r = new PostErrorEvent(request,
+                           POST_ERROR_EVENT_NON_STRING_TYPE_UNSUPPORTED,
+                           dsf);
+  } else if (!isSafePath(path)) {
+    nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mFile, path);
+    r = new PostErrorEvent(request, POST_ERROR_EVENT_ILLEGAL_FILE_NAME, dsf);
+  } else {
+
+    nsCOMPtr<nsIFile> file;
+    mFile->Clone(getter_AddRefs(file));
+    AppendRelativePath(file, path);
+
+    nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(file, path);
+
+    r = new DeviceStorageRequest(DeviceStorageRequest::DEVICE_STORAGE_REQUEST_READ,
+                                 win, mURI, dsf, request, aEditable);
+  }
+  NS_DispatchToMainThread(r);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMDeviceStorage::Delete(const JS::Value & aPath, JSContext* aCx, nsIDOMDOMRequest * *_retval NS_OUTPARAM)
+{
+  nsCOMPtr<nsIRunnable> r;
+
+  nsCOMPtr<nsPIDOMWindow> win = do_QueryReferent(mOwner);
+  if (!win) {
+    return NS_ERROR_UNEXPECTED;
+  }
+
+  nsRefPtr<DOMRequest> request = new DOMRequest(win);
+  NS_ADDREF(*_retval = request);
+
+  JSString* jsstr = JS_ValueToString(aCx, aPath);
+  nsDependentJSString path;
+  if (!path.init(aCx, jsstr)) {
+    nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mFile);
+    r = new PostErrorEvent(request, POST_ERROR_EVENT_NON_STRING_TYPE_UNSUPPORTED, dsf);
+  } else if (!isSafePath(path)) {
+    nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mFile, path);
+    r = new PostErrorEvent(request, POST_ERROR_EVENT_ILLEGAL_FILE_NAME, dsf);
+  }
+  else {
+    nsCOMPtr<nsIFile> file;
+    mFile->Clone(getter_AddRefs(file));
+    AppendRelativePath(file, path);
+
+    nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(file, path);
+    r = new DeviceStorageRequest(DeviceStorageRequest::DEVICE_STORAGE_REQUEST_DELETE,
+                                 win, mURI, dsf, request, true);
+  }
+  NS_DispatchToMainThread(r);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMDeviceStorage::Enumerate(const nsAString & aPath,
+                              nsIDOMDeviceStorageCursor * *_retval NS_OUTPARAM)
+{
+  return EnumerateInternal(aPath, _retval, false);
+}
+
+NS_IMETHODIMP
+nsDOMDeviceStorage::EnumerateEditable(const nsAString & aPath,
+                                      nsIDOMDeviceStorageCursor * *_retval NS_OUTPARAM)
+{
+  return EnumerateInternal(aPath, _retval, true);
+}
+
+nsresult
+nsDOMDeviceStorage::EnumerateInternal(const nsAString & aPath,
+                                      nsIDOMDeviceStorageCursor * *_retval NS_OUTPARAM,
+                                      bool aEditable)
+{
+  nsCOMPtr<nsPIDOMWindow> win = do_QueryReferent(mOwner);
+  if (!win)
+    return NS_ERROR_UNEXPECTED;
+
+  nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mFile, aPath);
+
+  nsDOMDeviceStorageCursor* cursor = new nsDOMDeviceStorageCursor(win, mURI, dsf, aEditable);
+  NS_ADDREF(*_retval = cursor);
+
+  return NS_OK;
+}
new file mode 100644
--- /dev/null
+++ b/dom/devicestorage/nsDeviceStorage.h
@@ -0,0 +1,58 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsDeviceStorage_h
+#define nsDeviceStorage_h
+
+class nsPIDOMWindow;
+
+#include "nsIClassInfo.h"
+#include "nsIDOMDeviceStorage.h"
+#include "nsIDOMDeviceStorageCursor.h"
+#include "nsIDOMWindow.h"
+#include "nsIURI.h"
+
+#include "nsAutoPtr.h"
+#include "nsCycleCollectionParticipant.h"
+#include "nsDOMClassInfoID.h"
+#include "nsString.h"
+#include "nsWeakPtr.h"
+#include "nsInterfaceHashtable.h"
+
+class nsDOMDeviceStorage : public nsIDOMDeviceStorage
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIDOMDEVICESTORAGE
+
+  nsDOMDeviceStorage();
+
+  nsresult Init(nsPIDOMWindow* aWindow, const nsAString &aType, const PRInt32 aIndex);
+
+  PRInt32 SetRootFileForType(const nsAString& aType, const PRInt32 aIndex);
+
+  static void CreateDeviceStoragesFor(nsPIDOMWindow* aWin, const nsAString &aType, nsIVariant** _retval);
+
+private:
+  ~nsDOMDeviceStorage();
+
+
+  nsresult GetInternal(const JS::Value & aName, JSContext* aCx, nsIDOMDOMRequest * *_retval NS_OUTPARAM, bool aEditable);
+  nsresult EnumerateInternal(const nsAString & aName, nsIDOMDeviceStorageCursor * *_retval NS_OUTPARAM, bool aEditable);
+
+  PRInt32 mStorageType;
+  nsCOMPtr<nsIFile> mFile;
+
+  nsWeakPtr mOwner;
+  nsCOMPtr<nsIURI> mURI;
+
+  // nsIDOMDeviceStorage.type
+  enum {
+      DEVICE_STORAGE_TYPE_DEFAULT = 0,
+      DEVICE_STORAGE_TYPE_SHARED,
+      DEVICE_STORAGE_TYPE_EXTERNAL,
+  };
+};
+
+#endif
--- a/dom/interfaces/core/nsIDOMMutationObserver.idl
+++ b/dom/interfaces/core/nsIDOMMutationObserver.idl
@@ -51,22 +51,22 @@ dictionary MutationObserverInit
   boolean characterData;
   boolean subtree;
   boolean attributeOldValue;
   boolean characterDataOldValue;
   jsval   attributeFilter; // DOMString[]
 };
 
 //[Constructor(in nsIMutationCallback aDoneCallback)]
-[scriptable, builtinclass, uuid(156e2ce4-e44a-45f3-92c2-e6611f391dae)]
-interface nsIDOMMozMutationObserver : nsISupports
+[scriptable, builtinclass, uuid(573105b5-d64e-468f-959f-87eebf93913e)]
+interface nsIDOMMutationObserver : nsISupports
 {
   [implicit_jscontext]
   void observe(in nsIDOMNode aTarget, in jsval aOptions);
   void disconnect();
   nsIVariant takeRecords();
 };
 
-[scriptable, function, uuid(fb539590-b088-4d07-96ff-2cefbc90a198)]
+[scriptable, function, uuid(5b52ce60-2210-42f0-842b-7f9f03d62f85)]
 interface nsIMutationObserverCallback : nsISupports
 {
-  void handleMutations(in nsIVariant aRecords, in nsIDOMMozMutationObserver aObserver);
+  void handleMutations(in nsIVariant aRecords, in nsIDOMMutationObserver aObserver);
 };
new file mode 100644
--- /dev/null
+++ b/dom/interfaces/devicestorage/Makefile.in
@@ -0,0 +1,26 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this file,
+# You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DEPTH            = ../../..
+topsrcdir        = @top_srcdir@
+srcdir           = @srcdir@
+VPATH            = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE           = dom
+LIBRARY_NAME     = domdevicestorage_s
+XPIDL_MODULE     = dom_devicestorage
+LIBXUL_LIBRARY   = 1
+FORCE_STATIC_LIB = 1
+
+include $(topsrcdir)/dom/dom-config.mk
+
+XPIDLSRCS = \
+	nsIDOMDeviceStorage.idl \
+	nsIDOMDeviceStorageCursor.idl \
+	nsIDOMNavigatorDeviceStorage.idl
+
+include $(topsrcdir)/config/rules.mk
+
new file mode 100644
--- /dev/null
+++ b/dom/interfaces/devicestorage/nsIDOMDeviceStorage.idl
@@ -0,0 +1,35 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "domstubs.idl"
+interface nsIDOMBlob;
+interface nsIDOMDOMRequest;
+interface nsIDOMDeviceStorageCursor;
+
+[scriptable, uuid(05C0D0C8-D698-4CCD-899C-7198A33BD7EC)]
+interface nsIDOMDeviceStorage : nsISupports
+{
+    /*
+     * Hint as to what kind of storage this object is.
+     * May be "external", "shared", or "default".
+     */
+    readonly attribute DOMString type;
+
+    nsIDOMDOMRequest add(in nsIDOMBlob aBlob);
+    nsIDOMDOMRequest addNamed(in nsIDOMBlob aBlob, in DOMString aName);
+
+    [implicit_jscontext]
+    nsIDOMDOMRequest get(in jsval aName);
+
+    [implicit_jscontext]
+    nsIDOMDOMRequest getEditable(in jsval aName);
+    
+    [implicit_jscontext]
+    nsIDOMDOMRequest delete(in jsval aName);
+
+    nsIDOMDeviceStorageCursor enumerate([optional] in DOMString directory);
+
+    nsIDOMDeviceStorageCursor enumerateEditable([optional] in DOMString directory);
+};
+
new file mode 100644
--- /dev/null
+++ b/dom/interfaces/devicestorage/nsIDOMDeviceStorageCursor.idl
@@ -0,0 +1,11 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "domstubs.idl"
+
+[scriptable, uuid(995DFF99-ED70-4780-AC9A-4B58CD491186)]
+interface nsIDOMDeviceStorageCursor : nsISupports
+{
+    void continue();
+};
new file mode 100644
--- /dev/null
+++ b/dom/interfaces/devicestorage/nsIDOMNavigatorDeviceStorage.idl
@@ -0,0 +1,17 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "domstubs.idl"
+interface nsIVariant;
+
+/**
+ * Property that extends the navigator object.
+ */
+[scriptable, uuid(A4B2831D-6065-472F-8A6D-2C9085C74C15)]
+interface nsIDOMNavigatorDeviceStorage : nsISupports
+{
+    // returns an array of nsIDOMDeviceStorage
+    nsIVariant getDeviceStorage(in DOMString type);
+};
+
--- a/dom/ipc/Makefile.in
+++ b/dom/ipc/Makefile.in
@@ -75,13 +75,17 @@ LOCAL_INCLUDES += \
 	-I$(topsrcdir)/dom/base \
 	-I$(topsrcdir)/toolkit/xre \
 	-I$(topsrcdir)/hal/sandbox \
 	-I$(topsrcdir)/dom/sms/src/ipc \
 	$(NULL)
 
 DEFINES += -DBIN_SUFFIX='"$(BIN_SUFFIX)"'
 
+ifeq ($(MOZ_WIDGET_TOOLKIT),$(findstring $(MOZ_WIDGET_TOOLKIT),android gtk2 gonk qt))
+DEFINES += -DMOZ_ENABLE_FREETYPE
+endif
+
 ifdef MOZ_PERMISSIONS
 DEFINES += -DMOZ_PERMISSIONS
 endif
 
 CXXFLAGS += $(TK_CFLAGS)
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -905,29 +905,31 @@ TabChild::InitWidget(const nsIntSize& si
     if (!remoteFrame) {
       NS_WARNING("failed to construct RenderFrame");
       return false;
     }
 
     NS_ABORT_IF_FALSE(0 == remoteFrame->ManagedPLayersChild().Length(),
                       "shouldn't have a shadow manager yet");
     LayerManager::LayersBackend be;
-    PLayersChild* shadowManager = remoteFrame->SendPLayersConstructor(&be);
+    PRInt32 maxTextureSize;
+    PLayersChild* shadowManager = remoteFrame->SendPLayersConstructor(&be, &maxTextureSize);
     if (!shadowManager) {
       NS_WARNING("failed to construct LayersChild");
       // This results in |remoteFrame| being deleted.
       PRenderFrameChild::Send__delete__(remoteFrame);
       return false;
     }
 
     ShadowLayerForwarder* lf =
         mWidget->GetLayerManager(shadowManager, be)->AsShadowForwarder();
     NS_ABORT_IF_FALSE(lf && lf->HasShadowManager(),
                       "PuppetWidget should have shadow manager");
     lf->SetParentBackendType(be);
+    lf->SetMaxTextureSize(maxTextureSize);
 
     mRemoteFrame = remoteFrame;
     return true;
 }
 
 void
 TabChild::SetBackgroundColor(const nscolor& aColor)
 {
--- a/dom/locales/en-US/chrome/dom/dom.properties
+++ b/dom/locales/en-US/chrome/dom/dom.properties
@@ -115,8 +115,10 @@ MediaLoadSourceMediaNotMatched=Specified
 # LOCALIZATION NOTE: %1$S is the MIME type HTTP header being sent by the web server, %2$S is the URL of the media resource which failed to load.
 MediaLoadUnsupportedMimeType=HTTP "Content-Type" of "%1$S" is not supported. Load of media resource %2$S failed.
 # LOCALIZATION NOTE: %S is the URL of the media resource which failed to load because of error in decoding.
 MediaLoadDecodeError=Media resource %S could not be decoded.
 # LOCALIZATION NOTE: Do not translate "MozBlobBuilder" and "Blob"
 MozBlobBuilderWarning=Use of MozBlobBuilder is deprecated. Use Blob constructor instead.
 # LOCALIZATION NOTE: Do not translate "DOMException", "code" and "name"
 DOMExceptionCodeWarning=Use of DOMException's code attribute is deprecated. Use name instead.
+# LOCALIZATION NOTE: Do not translate "Mutation Event" and "MutationObserver"
+MutationEventWarning=Use of Mutation Events is deprecated. Use MutationObserver instead.
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -3411,17 +3411,16 @@ NS_IMETHODIMP nsPluginInstanceOwner::Cre
 // Mac specific code to fix up the port location and clipping region
 #ifdef XP_MACOSX
 
 void* nsPluginInstanceOwner::FixUpPluginWindow(PRInt32 inPaintState)
 {
   if (!mWidget || !mPluginWindow || !mInstance || !mObjectFrame)
     return nsnull;
 
-  NPDrawingModel drawingModel = GetDrawingModel();
   NPEventModel eventModel = GetEventModel();
 
   nsCOMPtr<nsIPluginWidget> pluginWidget = do_QueryInterface(mWidget);
   if (!pluginWidget)
     return nsnull;
 
   // If we've already set up a CGContext in nsObjectFrame::PaintPlugin(), we
   // don't want calls to SetPluginPortAndDetectChange() to step on our work.
@@ -3453,16 +3452,17 @@ void* nsPluginInstanceOwner::FixUpPlugin
   bool widgetVisible;
   pluginWidget->GetPluginClipRect(widgetClip, pluginOrigin, widgetVisible);
   mWidgetVisible = widgetVisible;
 
   // printf("GetPluginClipRect returning visible %d\n", widgetVisible);
 
 #ifndef NP_NO_QUICKDRAW
   // set the port coordinates
+  NPDrawingModel drawingModel = GetDrawingModel();
   if (drawingModel == NPDrawingModelQuickDraw) {
     mPluginWindow->x = -static_cast<NP_Port*>(pluginPort)->portx;
     mPluginWindow->y = -static_cast<NP_Port*>(pluginPort)->porty;
   }
   else if (drawingModel == NPDrawingModelCoreGraphics || 
            drawingModel == NPDrawingModelCoreAnimation ||
            drawingModel == NPDrawingModelInvalidatingCoreAnimation)
 #endif
--- a/dom/plugins/test/mochitest/test_crash_notify.xul
+++ b/dom/plugins/test/mochitest/test_crash_notify.xul
@@ -10,16 +10,22 @@
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
 <body xmlns="http://www.w3.org/1999/xhtml" onload="runTests()">
 <embed id="plugin1" type="application/x-test" width="200" height="200"></embed>
 </body>
 <script class="testbody" type="application/javascript">
 <![CDATA[
 SimpleTest.waitForExplicitFinish();
 
+const isOSXLion = navigator.userAgent.indexOf("Mac OS X 10.7") != -1;
+if (isOSXLion) {
+  todo(false, "Can't test plugin crash notification on OS X 10.7, see bug 705047");
+  SimpleTest.finish();
+}
+
 var success = false;
 
 var observerFired = false;
 
 var testObserver = {
   observe: function(subject, topic, data) {
     observerFired = true;
     ok(true, "Observer fired");
--- a/dom/plugins/test/mochitest/test_crash_notify_no_report.xul
+++ b/dom/plugins/test/mochitest/test_crash_notify_no_report.xul
@@ -10,16 +10,22 @@
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
 <body xmlns="http://www.w3.org/1999/xhtml" onload="runTests()">
 <embed id="plugin1" type="application/x-test" width="200" height="200"></embed>
 </body>
 <script class="testbody" type="application/javascript">
 <![CDATA[
 SimpleTest.waitForExplicitFinish();
 
+const isOSXLion = navigator.userAgent.indexOf("Mac OS X 10.7") != -1;
+if (isOSXLion) {
+  todo(false, "Can't test plugin crash notification on OS X 10.7, see bug 705047");
+  SimpleTest.finish();
+}
+
 var success = false;
 
 var observerFired = false;
 
 var testObserver = {
   observe: function(subject, topic, data) {
     observerFired = true;
     ok(true, "Observer fired");
--- a/dom/plugins/test/mochitest/test_crash_submit.xul
+++ b/dom/plugins/test/mochitest/test_crash_submit.xul
@@ -13,16 +13,22 @@
 <body xmlns="http://www.w3.org/1999/xhtml" onload="runTests()">
 <embed id="plugin1" type="application/x-test" width="200" height="200"></embed>
 </body>
 <script class="testbody" type="application/javascript">
 <![CDATA[
 SimpleTest.waitForExplicitFinish();
 SimpleTest.ignoreAllUncaughtExceptions();
 
+const isOSXLion = navigator.userAgent.indexOf("Mac OS X 10.7") != -1;
+if (isOSXLion) {
+  todo(false, "Can't test plugin crash notification on OS X 10.7, see bug 705047");
+  SimpleTest.finish();
+}
+
 Components.utils.import("resource://gre/modules/NetUtil.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 var crashReporter =
   Components.classes["@mozilla.org/toolkit/crash-reporter;1"]
     .getService(Components.interfaces.nsICrashReporter);
 var oldServerURL = crashReporter.serverURL;
 
--- a/dom/plugins/test/mochitest/test_crashing.html
+++ b/dom/plugins/test/mochitest/test_crashing.html
@@ -1,16 +1,22 @@
 <head>
   <title>Plugin crashing</title>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
 
 <body>
   <script class="testbody" type="application/javascript">
   SimpleTest.waitForExplicitFinish();
 
+  const isOSXLion = navigator.userAgent.indexOf("Mac OS X 10.7") != -1;
+  if (isOSXLion) {
+    todo(false, "Can't test plugin crash notification on OS X 10.7, see bug 705047");
+    SimpleTest.finish();
+  }
+
   window.frameLoaded = function frameLoaded_toCrash() {
     if (!SimpleTest.testPluginIsOOP()) {
       ok(true, "Skipping this test when test plugin is not OOP.");
       SimpleTest.finish();
       return;
     }
 
     SimpleTest.expectChildProcessCrash();
--- a/dom/plugins/test/mochitest/test_hanging.html
+++ b/dom/plugins/test/mochitest/test_hanging.html
@@ -1,16 +1,22 @@
 <head>
   <title>Plugin hanging</title>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
 
 <body>
   <script class="testbody" type="application/javascript">
   SimpleTest.waitForExplicitFinish();
 
+  const isOSXLion = navigator.userAgent.indexOf("Mac OS X 10.7") != -1;
+  if (isOSXLion) {
+    todo(false, "Can't test plugin crash notification on OS X 10.7, see bug 705047");
+    SimpleTest.finish();
+  }
+
   window.frameLoaded = function frameLoaded_toCrash() {
     if (!SimpleTest.testPluginIsOOP()) {
       ok(true, "Skipping this test when test plugin is not OOP.");
       SimpleTest.finish();
       return;
     }
 
     SimpleTest.expectChildProcessCrash();
--- a/dom/settings/SettingsManager.js
+++ b/dom/settings/SettingsManager.js
@@ -112,49 +112,55 @@ SettingsLock.prototype = {
         lock.process();
       }
       if (!this._requests.isEmpty())
         this.process();
     }
   },
 
   get: function get(aName) {
-    if (!this._open)
+    if (!this._open) {
+      dump("Settings lock not open!\n");
       throw Components.results.NS_ERROR_ABORT;
+    }
 
     if (this._settingsManager.hasReadPrivileges || this._settingsManager.hasReadWritePrivileges) {
       let req = Services.DOMRequest.createRequest(this._settingsManager._window);
       this._requests.enqueue({ request: req, intent:"get", name: aName });
       this.createTransactionAndProcess();
       return req;
     } else {
       debug("get not allowed");
       throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
     }
   },
 
   set: function set(aSettings) {
-    if (!this._open)
+    if (!this._open) {
+      dump("Settings lock not open!\n");
       throw Components.results.NS_ERROR_ABORT;
+    }
 
     if (this._settingsManager.hasReadWritePrivileges) {
       let req = Services.DOMRequest.createRequest(this._settingsManager._window);
       debug("send: " + JSON.stringify(aSettings));
       this._requests.enqueue({request: req, intent: "set", settings: aSettings});
       this.createTransactionAndProcess();
       return req;
     } else {
       debug("set not allowed");
       throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
     }
   },
 
   clear: function clear() {
-    if (!this._open)
+    if (!this._open) {
+      dump("Settings lock not open!\n");
       throw Components.results.NS_ERROR_ABORT;
+    }
 
     if (this._settingsManager.hasReadWritePrivileges) {
       let req = Services.DOMRequest.createRequest(this._settingsManager._window);
       this._requests.enqueue({ request: req, intent: "clear"});
       this.createTransactionAndProcess();
       return req;
     } else {
       debug("clear not allowed");
--- a/dom/settings/tests/test_settings_basics.html
+++ b/dom/settings/tests/test_settings_basics.html
@@ -471,16 +471,32 @@ var steps = [
     var lock = mozSettings.getLock();
     req = lock.set(wifiNetworks0);
     req.onsuccess = function () {
       ok(true, "Set Done");
       next();
     };
     req.onerror = onFailure;
   },
+  function () {
+    ok(true, "Test set after lock closed");
+    var lockx = mozSettings.getLock();
+    var cb = function() {
+      var reqx = null;
+      try {
+        reqx = lockx.set(wifiNetworks0);
+        ok(false, "should have thrown");
+      } catch (ex) {
+        ok(reqx == null, "request is still null");
+        ok(true, "Caught Exception");
+        next();
+      }
+    }
+    SimpleTest.executeSoon(cb);
+  },
   function() {
     ok(true, "Clear DB");
     var lock = mozSettings.getLock();
     req = lock.clear();
     req.onsuccess = function () {
       ok(true, "Deleted the database");
       next();
     };
--- a/dom/tests/mochitest/Makefile.in
+++ b/dom/tests/mochitest/Makefile.in
@@ -13,16 +13,17 @@ include $(DEPTH)/config/autoconf.mk
 DIRS	+= \
 	dom-level0 \
 	dom-level1-core \
 	dom-level2-core \
 	dom-level2-html \
 	ajax \
 	bugs \
 	chrome \
+	devicestorage \
 	general \
 	whatwg \
 	geolocation \
 	localstorage \
 	orientation \
 	sessionstorage \
 	storageevent \
 	pointerlock \
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/devicestorage/Makefile.in
@@ -0,0 +1,27 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this file,
+# You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DEPTH		= ../../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+relativesrcdir	= dom/tests/mochitest/devicestorage
+
+include $(DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/rules.mk
+
+_TEST_FILES	= \
+		test_sanity.html \
+		test_basic.html \
+		test_enumerate.html \
+		test_enumerateMultipleContinue.html \
+		test_overwrite.html \
+		test_dotdot.html \
+		devicestorage_common.js \
+		$(NULL)
+
+libs:: 	$(_TEST_FILES)
+	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
+
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/devicestorage/devicestorage_common.js
@@ -0,0 +1,48 @@
+/**
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+var oldVal = false;
+  
+function devicestorage_setup() {
+  SimpleTest.waitForExplicitFinish();
+  try {
+    oldVal = SpecialPowers.getBoolPref("device.storage.enabled");
+  } catch(e) {}
+  SpecialPowers.setBoolPref("device.storage.enabled", true);
+  SpecialPowers.setBoolPref("device.storage.testing", true);
+  SpecialPowers.setBoolPref("device.storage.prompt.testing", true);
+}
+
+function devicestorage_cleanup() {
+  SpecialPowers.setBoolPref("device.storage.enabled", oldVal);
+  SpecialPowers.setBoolPref("device.storage.testing", false);
+  SpecialPowers.setBoolPref("device.storage.prompt.testing", false);
+  SimpleTest.finish();
+}
+
+function getRandomBuffer() {
+  var size = 1024;
+  var buffer = new ArrayBuffer(size);
+  var view = new Uint8Array(buffer);
+  for (var i = 0; i < size; i++) {
+    view[i] = parseInt(Math.random() * 255);
+  }
+  return buffer;
+}
+
+function createRandomBlob() {
+ return blob = new Blob([getRandomBuffer()], {type: 'binary/random'});
+}
+
+function randomFilename(l) {
+    var set = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZ";
+    var result = "";
+    for (var i=0; i<l; i++) {
+	var r = Math.floor(set.length * Math.random());
+	result += set.substring(r, r + 1);
+    }
+    return result;
+}
+
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/devicestorage/test_basic.html
@@ -0,0 +1,102 @@
+<!--
+  Any copyright is dedicated to the Public Domain.
+  http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!DOCTYPE HTML>
+<html> <!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=717103
+-->
+<head>
+  <title>Test for the device storage API </title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="devicestorage_common.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=717103">Mozilla Bug 717103</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+devicestorage_setup();
+
+var gFileName = "devicestorage/hi";
+
+function getAfterDeleteSuccess(e) {
+  ok(false, "file was deleted not successfully");
+  devicestorage_cleanup();
+}
+
+function getAfterDeleteError(e) {
+  ok(true, "file was deleted successfully");
+  devicestorage_cleanup();
+}
+
+function deleteSuccess(e) {
+
+  ok(e.target.result == gFileName, "File name should match");
+
+  var storage = navigator.getDeviceStorage("profile");
+  request = storage[0].get(e.target.result);
+  request.onsuccess = getAfterDeleteSuccess;
+  request.onerror = getAfterDeleteError;
+
+}
+
+function deleteError(e) {
+  ok(false, "deleteError was called : " + e.target.error.name);
+  devicestorage_cleanup();
+}
+
+function getSuccess(e) {
+  var storage = navigator.getDeviceStorage("profile");
+  ok(navigator.getDeviceStorage, "Should have getDeviceStorage");
+
+  ok(e.target.result.name == gFileName, "File name should match");
+
+  request = storage[0].delete(e.target.result.name)
+  request.onsuccess = deleteSuccess;
+  request.onerror = deleteError;
+}
+
+function getError(e) {
+  ok(false, "getError was called : " + e.target.error.name);
+  SpecialPowers.setBoolPref("device.storage.enabled", oldVal);
+  SimpleTest.finish();
+}
+
+function addSuccess(e) {
+
+  ok(e.target.result == gFileName, "File name should match");
+
+  var storage = navigator.getDeviceStorage("profile");
+  request = storage[0].get(gFileName);
+  request.onsuccess = getSuccess;
+  request.onerror = getError;
+
+  ok(true, "addSuccess was called");
+}
+
+function addError(e) {
+  ok(false, "addError was called : " + e.target.error.name);
+  devicestorage_cleanup();
+}
+
+var storage = navigator.getDeviceStorage("profile");
+ok(navigator.getDeviceStorage, "Should have getDeviceStorage");
+
+request = storage[0].addNamed(createRandomBlob(), "devicestorage/hi");
+ok(request, "Should have a non-null request");
+
+request.onsuccess = addSuccess;
+request.onerror = addError;
+
+</script>
+</pre>
+</body>
+</html>
+
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/devicestorage/test_dotdot.html
@@ -0,0 +1,71 @@
+<!--
+  Any copyright is dedicated to the Public Domain.
+  http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!DOCTYPE HTML>
+<html> <!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=717103
+-->
+<head>
+  <title>Test for the device storage API </title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="devicestorage_common.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=717103">Mozilla Bug 717103</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+devicestorage_setup();
+
+function profileStorage() {
+  return navigator.getDeviceStorage("profile")[0];
+}
+
+var tests = [
+  function () { return profileStorage().addNamed(createRandomBlob(), gFileName); },
+  function () { return profileStorage().delete(gFileName); },
+  function () { return profileStorage().get(gFileName); },
+  function () { var r = profileStorage().enumerate("../"); return r; }
+];
+
+var gFileName = "../owned";
+
+function fail(e) {
+  ok(false, "addSuccess was called");
+  dump(request);
+  devicestorage_cleanup();
+}
+
+function next(e) {
+
+  if (e != undefined)
+    ok(true, "addError was called");
+  
+  var f = tests.pop();
+
+  if (f == undefined) {
+    devicestorage_cleanup();
+    return;
+  }
+
+  request = f();
+  request.onsuccess = fail;
+  request.onerror = next;
+}
+
+next();
+
+
+
+</script>
+</pre>
+</body>
+</html>
+
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/devicestorage/test_enumerate.html
@@ -0,0 +1,101 @@
+<!--
+  Any copyright is dedicated to the Public Domain.
+  http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!DOCTYPE HTML>
+<html> <!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=717103
+-->
+<head>
+  <title>Test for the device storage API </title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="devicestorage_common.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=717103">Mozilla Bug 717103</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+// Array Remove - By John Resig (MIT Licensed)
+Array.prototype.remove = function(from, to) {
+  var rest = this.slice((to || from) + 1 || this.length);
+  this.length = from < 0 ? this.length + from : from;
+  return this.push.apply(this, rest);
+};
+
+devicestorage_setup();
+
+function enumerateSuccess(e) {
+
+  if (e.target.result == null) {
+    ok(files.length == 0, "when the enumeration is done, we shouldn't have any files in this array")
+    dump("We still have length = " + files.length);
+    devicestorage_cleanup();
+    return;
+  }
+  
+  dump("asdfasdf"+ e.target.result + "\n");
+  dump("asdfasdf"+ e.target.result.name + "\n");
+
+  var filename = e.target.result.name;
+
+  var index = files.indexOf(filename);
+  files.remove(index);
+
+  ok(index > -1, "filename should be in the enumeration : " + e.target.result.name);
+
+  // clean up
+  var cleanup = storage[0].delete(prefix + "/" + filename);
+  cleanup.onsuccess = function(e) {}  // todo - can i remove this?
+
+  e.target.continue();
+}
+
+function handleError(e) {
+  ok(false, "handleError was called : " + e.target.error.name);
+  devicestorage_cleanup();
+}
+
+function addSuccess(e) {
+  addedSoFar = addedSoFar + 1;
+  if (addedSoFar == files.length) {
+
+    var cursor = storage[0].enumerate(prefix);
+    cursor.onsuccess = enumerateSuccess;
+    cursor.onerror = handleError;
+  }
+}
+
+function addError(e) {
+  ok(false, "addError was called : " + e.target.error.name);
+  devicestorage_cleanup();
+}
+
+var storage = navigator.getDeviceStorage("profile");
+ok(navigator.getDeviceStorage, "Should have getDeviceStorage");
+var prefix = "devicestorage/" + randomFilename(12)
+
+var files = [ "a", "b", "c", "d/a", "d/b", "d/c", "d/d", "The/quick/brown/fox/jumps/over/the/lazy/dog"]
+var addedSoFar = 0;
+
+
+for (var i=0; i<files.length; i++) {
+
+ request = storage[0].addNamed(createRandomBlob(), prefix + '/' + files[i]);
+
+ ok(request, "Should have a non-null request");
+ request.onsuccess = addSuccess;
+ request.onerror = addError;
+}
+
+</script>
+</pre>
+</body>
+</html>
+
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/devicestorage/test_enumerateMultipleContinue.html
@@ -0,0 +1,50 @@
+<!--
+  Any copyright is dedicated to the Public Domain.
+  http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!DOCTYPE HTML>
+<html> <!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=717103
+-->
+<head>
+  <title>Test for the device storage API </title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="devicestorage_common.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=717103">Mozilla Bug 717103</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+devicestorage_setup();
+
+function enumerateSuccess(e) {
+}
+
+function enumerateFailure(e) {
+}
+
+var cursor = navigator.getDeviceStorage("profile")[0].enumerate();
+cursor.onsuccess = enumerateSuccess;
+cursor.onerror = enumerateFailure;
+
+try {
+ cursor.continue();
+}
+catch (e) {
+  ok(true, "Calling continue before enumerateSuccess fires should throw");
+  devicestorage_cleanup();
+}
+
+
+</script>
+</pre>
+</body>
+</html>
+
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/devicestorage/test_enumerateNoParam.html
@@ -0,0 +1,95 @@
+<!--
+  Any copyright is dedicated to the Public Domain.
+  http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!DOCTYPE HTML>
+<html> <!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=717103
+-->
+<head>
+  <title>Test for the device storage API </title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="devicestorage_common.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=717103">Mozilla Bug 717103</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+// Array Remove - By John Resig (MIT Licensed)
+Array.prototype.remove = function(from, to) {
+  var rest = this.slice((to || from) + 1 || this.length);
+  this.length = from < 0 ? this.length + from : from;
+  return this.push.apply(this, rest);
+};
+
+devicestorage_setup();
+
+function enumerateSuccess(e) {
+
+  if (e.target.result == null) {
+    ok(files.length == 0, "when the enumeration is done, we shouldn't have any files in this array")
+    devicestorage_cleanup();
+  }
+  
+  var filename = e.target.result.name;
+  var index = files.indexOf(filename);
+  files.remove(index);
+
+  ok(index > -1, "filename should be in the enumeration : " + e.target.result.name);
+
+  // clean up
+  var cleanup = storage[0].delete(prefix + "/" + filename);
+  cleanup.onsuccess = function(e) {}  // todo - can i remove this?
+
+  e.target.continue();
+}
+
+function handleError(e) {
+  ok(false, "handleError was called : " + e.target.error.name);
+  devicestorage_cleanup();
+}
+
+function addSuccess(e) {
+  addedSoFar = addedSoFar + 1;
+  if (addedSoFar == files.length) {
+
+    var cursor = storage[0].enumerate();
+    cursor.onsuccess = enumerateSuccess;
+    cursor.onerror = handleError;
+  }
+}
+
+function addError(e) {
+  ok(false, "addError was called : " + e.target.error.name);
+  devicestorage_cleanup();
+}
+
+var storage = navigator.getDeviceStorage("profile");
+ok(navigator.getDeviceStorage, "Should have getDeviceStorage");
+var prefix = "devicestorage/" + randomFilename(12)
+
+var files = [ "a", "b", "c" ]
+var addedSoFar = 0;
+
+
+for (var i=0; i<files.length; i++) {
+
+ request = storage[0].addNamed(createRandomBlob(), prefix + '/' + files[i]);
+
+ ok(request, "Should have a non-null request");
+ request.onsuccess = addSuccess;
+ request.onerror = addError;
+}
+
+</script>
+</pre>
+</body>
+</html>
+
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/devicestorage/test_overwrite.html
@@ -0,0 +1,90 @@
+<!--
+  Any copyright is dedicated to the Public Domain.
+  http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=717103
+-->
+<head>
+  <title>Test for basic sanity of the device storage API </title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="devicestorage_common.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=717103">Mozilla Bug 717103</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+var filename = "devicestorage/aaaa"
+
+devicestorage_setup();
+
+
+function deleteSuccess(e) {
+  devicestorage_cleanup();
+}
+
+function deleteError(e) {
+  ok(false, "deleteError was called : " + e.target.error.name);
+  devicestorage_cleanup();
+}
+
+function addOverwritingSuccess(e) {
+  ok(false, "addOverwritingSuccess was called.");
+}
+
+function addOverwritingError(e) {
+  ok(true, "Adding to the same location should fail");
+
+  var storage = navigator.getDeviceStorage("profile");
+  request = storage[0].delete(filename)
+  request.onsuccess = deleteSuccess;
+  request.onerror = deleteError;
+}
+
+function addSuccess(e) {
+  ok(true, "addSuccess was called");
+
+  var storage = navigator.getDeviceStorage("profile");
+  ok(navigator.getDeviceStorage, "Should have getDeviceStorage");
+
+  request = storage[0].addNamed(createRandomBlob(), filename);
+  ok(request, "Should have a non-null request");
+
+  request.onsuccess = addOverwritingSuccess;
+  request.onerror = addOverwritingError;
+}
+
+function addError(e) {
+  // test file is already exists.  clean it up and try again..
+  var storage = navigator.getDeviceStorage("profile");
+  request = storage[0].delete(filename)
+  request.onsuccess = runtest;
+}
+
+function runtest() {
+  var storage = navigator.getDeviceStorage("profile");
+  ok(navigator.getDeviceStorage, "Should have getDeviceStorage");
+
+  request = storage[0].addNamed(createRandomBlob(), filename);
+  ok(request, "Should have a non-null request");
+
+  request.onsuccess = addSuccess;
+  request.onerror = addError;
+}
+
+runtest();
+
+</script>
+</pre>
+</body>
+</html>
+
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/devicestorage/test_sanity.html
@@ -0,0 +1,72 @@
+<!--
+  Any copyright is dedicated to the Public Domain.
+  http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=717103
+-->
+<head>
+  <title>Test for basic sanity of the device storage API </title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="devicestorage_common.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=717103">Mozilla Bug 717103</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+devicestorage_setup()
+
+ok(navigator.getDeviceStorage, "Should have getDeviceStorage");
+
+var storage;
+
+var throws = false;
+try {
+ storage = navigator.getDeviceStorage();
+} catch(e) {throws = true}
+ok(throws, "getDeviceStorage takes one arg");
+
+storage = navigator.getDeviceStorage("kilimanjaro");
+ok(!storage, "kilimanjaro - Should not have this type of storage");
+
+storage = navigator.getDeviceStorage("temp");
+ok(storage, "temp - Should have getDeviceStorage");
+
+storage = navigator.getDeviceStorage("profile");
+ok(storage, "profile - Should have getDeviceStorage");
+
+var cursor = storage[0].enumerate();
+ok(cursor, "Should have a non-null cursor");
+
+var i = 4;
+cursor.onsuccess = function(e) {
+  i = i - 1;
+  if (i > 0) {
+    ok(true, "onsuccess was called");
+    e.target.continue();
+  }
+  else {
+    ok(true, "onsuccess was called 4 times");
+    devicestorage_cleanup();
+  }
+}
+
+cursor.onerror = function(e) {
+  ok(false, "onerror was called : " + e.target.error.name);
+  devicestorage_cleanup();
+}
+
+</script>
+</pre>
+</body>
+</html>
+
--- a/dom/workers/DOMBindingBase.cpp
+++ b/dom/workers/DOMBindingBase.cpp
@@ -25,26 +25,26 @@ DOMBindingBase::DOMBindingBase(JSContext
 DOMBindingBase::~DOMBindingBase()
 {
   if (!mJSContext) {
     AssertIsOnMainThread();
   }
 }
 
 void
-DOMBindingBase::_Trace(JSTracer* aTrc)
+DOMBindingBase::_trace(JSTracer* aTrc)
 {
   JSObject* obj = GetJSObject();
   if (obj) {
     JS_CALL_OBJECT_TRACER(aTrc, obj, "cached wrapper");
   }
 }
 
 void
-DOMBindingBase::_Finalize(JSFreeOp* aFop)
+DOMBindingBase::_finalize(JSFreeOp* aFop)
 {
   ClearWrapper();
   NS_RELEASE_THIS();
 }
 
 JSContext*
 DOMBindingBase::GetJSContextFromContextStack() const
 {
--- a/dom/workers/DOMBindingBase.h
+++ b/dom/workers/DOMBindingBase.h
@@ -32,20 +32,20 @@ class DOMBindingBase : public nsWrapperC
   JSContext* mJSContext;
   mutable nsCOMPtr<nsIThreadJSContextStack> mContextStack;
 
 protected:
   DOMBindingBase(JSContext* aCx);
   virtual ~DOMBindingBase();
 
   virtual void
-  _Trace(JSTracer* aTrc);
+  _trace(JSTracer* aTrc);
 
   virtual void
-  _Finalize(JSFreeOp* aFop);
+  _finalize(JSFreeOp* aFop);
 
   JSContext*
   GetJSContextFromContextStack() const;
 
 public:
   NS_INLINE_DECL_REFCOUNTING(DOMBindingBase)
 
   JSContext*
--- a/dom/workers/EventListenerManager.h
+++ b/dom/workers/EventListenerManager.h
@@ -28,25 +28,25 @@ public:
     PR_INIT_CLIST(&mCollectionHead);
   }
 
 #ifdef DEBUG
   ~EventListenerManager();
 #endif
 
   void
-  _Trace(JSTracer* aTrc) const
+  _trace(JSTracer* aTrc) const
   {
     if (!PR_CLIST_IS_EMPTY(&mCollectionHead)) {
       TraceInternal(aTrc);
     }
   }
 
   void
-  _Finalize(JSFreeOp* aFop)
+  _finalize(JSFreeOp* aFop)
   {
     if (!PR_CLIST_IS_EMPTY(&mCollectionHead)) {
       FinalizeInternal(aFop);
     }
   }
 
   enum Phase
   {
--- a/dom/workers/EventTarget.cpp
+++ b/dom/workers/EventTarget.cpp
@@ -4,27 +4,27 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "EventTarget.h"
 
 USING_WORKERS_NAMESPACE
 using mozilla::ErrorResult;
 
 void
-EventTarget::_Trace(JSTracer* aTrc)
+EventTarget::_trace(JSTracer* aTrc)
 {
-  mListenerManager._Trace(aTrc);
-  DOMBindingBase::_Trace(aTrc);
+  mListenerManager._trace(aTrc);
+  DOMBindingBase::_trace(aTrc);
 }
 
 void
-EventTarget::_Finalize(JSFreeOp* aFop)
+EventTarget::_finalize(JSFreeOp* aFop)
 {
-  mListenerManager._Finalize(aFop);
-  DOMBindingBase::_Finalize(aFop);
+  mListenerManager._finalize(aFop);
+  DOMBindingBase::_finalize(aFop);
 }
 
 JSObject*
 EventTarget::GetEventListener(const nsAString& aType, ErrorResult& aRv) const
 {
   JSContext* cx = GetJSContext();
 
   JSString* type =
--- a/dom/workers/EventTarget.h
+++ b/dom/workers/EventTarget.h
@@ -27,20 +27,20 @@ protected:
   : DOMBindingBase(aCx)
   { }
 
   virtual ~EventTarget()
   { }
 
 public:
   virtual void
-  _Trace(JSTracer* aTrc) MOZ_OVERRIDE;
+  _trace(JSTracer* aTrc) MOZ_OVERRIDE;
 
   virtual void
-  _Finalize(JSFreeOp* aFop) MOZ_OVERRIDE;
+  _finalize(JSFreeOp* aFop) MOZ_OVERRIDE;
 
   void
   AddEventListener(const nsAString& aType, JSObject* aListener,
                    bool aCapture, Nullable<bool> aWantsUntrusted,
                    ErrorResult& aRv);
 
   void
   RemoveEventListener(const nsAString& aType, JSObject* aListener,
--- a/dom/workers/Worker.cpp
+++ b/dom/workers/Worker.cpp
@@ -214,27 +214,27 @@ private:
   }
 
   static void
   Finalize(JSFreeOp* aFop, JSObject* aObj)
   {
     JS_ASSERT(JS_GetClass(aObj) == Class());
     WorkerPrivate* worker = UnwrapDOMObject<WorkerPrivate>(aObj, Class());
     if (worker) {
-      worker->_Finalize(aFop);
+      worker->_finalize(aFop);
     }
   }
 
   static void
   Trace(JSTracer* aTrc, JSObject* aObj)
   {
     JS_ASSERT(JS_GetClass(aObj) == Class());
     WorkerPrivate* worker = UnwrapDOMObject<WorkerPrivate>(aObj, Class());
     if (worker) {
-      worker->_Trace(aTrc);
+      worker->_trace(aTrc);
     }
   }
 
   static JSBool
   Terminate(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
@@ -372,27 +372,27 @@ private:
   }
 
   static void
   Finalize(JSFreeOp* aFop, JSObject* aObj)
   {
     JS_ASSERT(JS_GetClass(aObj) == Class());
     WorkerPrivate* worker = UnwrapDOMObject<WorkerPrivate>(aObj, Class());
     if (worker) {
-      worker->_Finalize(aFop);
+      worker->_finalize(aFop);
     }
   }
 
   static void
   Trace(JSTracer* aTrc, JSObject* aObj)
   {
     JS_ASSERT(JS_GetClass(aObj) == Class());
     WorkerPrivate* worker = UnwrapDOMObject<WorkerPrivate>(aObj, Class());
     if (worker) {
-      worker->_Trace(aTrc);
+      worker->_trace(aTrc);
     }
   }
 };
 
 MOZ_STATIC_ASSERT(prototypes::MaxProtoChainLength == 3,
                   "The MaxProtoChainLength must match our manual DOMJSClasses");
 
 DOMJSClass ChromeWorker::sClass = {
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -2042,27 +2042,27 @@ WorkerPrivateParent<Derived>::Resume(JSC
     return false;
   }
 
   return true;
 }
 
 template <class Derived>
 void
-WorkerPrivateParent<Derived>::_Trace(JSTracer* aTrc)
+WorkerPrivateParent<Derived>::_trace(JSTracer* aTrc)
 {
   // This should only happen on the parent thread but we can't assert that
   // because it can also happen on the cycle collector thread when this is a
   // top-level worker.
-  EventTarget::_Trace(aTrc);
+  EventTarget::_trace(aTrc);
 }
 
 template <class Derived>
 void
-WorkerPrivateParent<Derived>::_Finalize(JSFreeOp* aFop)
+WorkerPrivateParent<Derived>::_finalize(JSFreeOp* aFop)
 {
   AssertIsOnParentThread();
 
   MOZ_ASSERT(mJSObject);
   MOZ_ASSERT(!mJSObjectRooted);
 
   // Clear the JS object.
   mJSObject = nsnull;
@@ -2078,17 +2078,17 @@ WorkerPrivateParent<Derived>::_Finalize(
   // this mess...
   WorkerPrivateParent<Derived>* extraSelfRef = NULL;
 
   if (!mParent && !mMainThreadObjectsForgotten) {
     AssertIsOnMainThread();
     NS_ADDREF(extraSelfRef = this);
   }
 
-  EventTarget::_Finalize(aFop);
+  EventTarget::_finalize(aFop);
 
   if (extraSelfRef) {
     nsCOMPtr<nsIRunnable> runnable =
       NS_NewNonOwningRunnableMethod(extraSelfRef,
                                     &WorkerPrivateParent<Derived>::Release);
     if (NS_FAILED(NS_DispatchToCurrentThread(runnable))) {
       NS_WARNING("Failed to proxy release, this will leak!");
     }
--- a/dom/workers/WorkerPrivate.h
+++ b/dom/workers/WorkerPrivate.h
@@ -253,20 +253,20 @@ public:
 
   bool
   Suspend(JSContext* aCx);
 
   bool
   Resume(JSContext* aCx);
 
   virtual void
-  _Trace(JSTracer* aTrc) MOZ_OVERRIDE;
+  _trace(JSTracer* aTrc) MOZ_OVERRIDE;
 
   virtual void
-  _Finalize(JSFreeOp* aFop) MOZ_OVERRIDE;
+  _finalize(JSFreeOp* aFop) MOZ_OVERRIDE;
 
   void
   Finish(JSContext* aCx)
   {
     RootJSObject(aCx, false);
   }
 
   bool
--- a/dom/workers/WorkerScope.cpp
+++ b/dom/workers/WorkerScope.cpp
@@ -96,50 +96,53 @@ public:
 
   static JSObject*
   InitClass(JSContext* aCx, JSObject* aObj, JSObject* aParentProto)
   {
     return JS_InitClass(aCx, aObj, aParentProto, Class(), Construct, 0,
                         sProperties, sFunctions, NULL, NULL);
   }
 
+  using EventTarget::GetEventListener;
+  using EventTarget::SetEventListener;
+
 protected:
   WorkerGlobalScope(JSContext* aCx, WorkerPrivate* aWorker)
   : EventTarget(aCx), mWorker(aWorker)
   {
     MOZ_COUNT_CTOR(mozilla::dom::workers::WorkerGlobalScope);
     for (int32 i = 0; i < SLOT_COUNT; i++) {
       mSlots[i] = JSVAL_VOID;
     }
   }
 
   ~WorkerGlobalScope()
   {
     MOZ_COUNT_DTOR(mozilla::dom::workers::WorkerGlobalScope);
   }
 
   virtual void
-  _Trace(JSTracer* aTrc) MOZ_OVERRIDE
+  _trace(JSTracer* aTrc) MOZ_OVERRIDE
   {
     for (int32 i = 0; i < SLOT_COUNT; i++) {
       JS_CALL_VALUE_TRACER(aTrc, mSlots[i], "WorkerGlobalScope instance slot");
     }
     mWorker->TraceInternal(aTrc);
-    EventTarget::_Trace(aTrc);
+    EventTarget::_trace(aTrc);
   }
 
   virtual void
-  _Finalize(JSFreeOp* aFop) MOZ_OVERRIDE
+  _finalize(JSFreeOp* aFop) MOZ_OVERRIDE
   {
-    EventTarget::_Finalize(aFop);
+    EventTarget::_finalize(aFop);
   }
 
 private:
   static JSBool
-  _GetEventListener(JSContext* aCx, JSHandleObject aObj, JSHandleId aIdval, jsval* aVp)
+  GetEventListener(JSContext* aCx, JSHandleObject aObj, JSHandleId aIdval, jsval* aVp)
   {
     JS_ASSERT(JSID_IS_INT(aIdval));
     JS_ASSERT(JSID_TO_INT(aIdval) >= 0 && JSID_TO_INT(aIdval) < STRING_COUNT);
 
     const char* name = sEventStrings[JSID_TO_INT(aIdval)];
     WorkerGlobalScope* scope = GetInstancePrivate(aCx, aObj, name);
     if (!scope) {
       return false;
@@ -155,17 +158,17 @@ private:
       return false;
     }
 
     *aVp = listener ? OBJECT_TO_JSVAL(listener) : JSVAL_NULL;
     return true;
   }
 
   static JSBool
-  _SetEventListener(JSContext* aCx, JSHandleObject aObj, JSHandleId aIdval, JSBool aStrict,
+  SetEventListener(JSContext* aCx, JSHandleObject aObj, JSHandleId aIdval, JSBool aStrict,
                    jsval* aVp)
   {
     JS_ASSERT(JSID_IS_INT(aIdval));
     JS_ASSERT(JSID_TO_INT(aIdval) >= 0 && JSID_TO_INT(aIdval) < STRING_COUNT);
 
     const char* name = sEventStrings[JSID_TO_INT(aIdval)];
     WorkerGlobalScope* scope = GetInstancePrivate(aCx, aObj, name);
     if (!scope) {
@@ -609,17 +612,17 @@ JSClass WorkerGlobalScope::sClass = {
 };
 
 JSPropertySpec WorkerGlobalScope::sProperties[] = {
   { "location", SLOT_location, PROPERTY_FLAGS, GetLocation, 
     js_GetterOnlyPropertyStub },
   { sEventStrings[STRING_onerror], STRING_onerror, PROPERTY_FLAGS,
     GetOnErrorListener, SetOnErrorListener },
   { sEventStrings[STRING_onclose], STRING_onclose, PROPERTY_FLAGS,
-    _GetEventListener, _SetEventListener },
+    GetEventListener, SetEventListener },
   { "navigator", SLOT_navigator, PROPERTY_FLAGS, GetNavigator, 
     js_GetterOnlyPropertyStub },
   { "self", 0, PROPERTY_FLAGS, GetSelf, js_GetterOnlyPropertyStub },
   { 0, 0, 0, NULL, NULL }
 };
 
 JSFunctionSpec WorkerGlobalScope::sFunctions[] = {
   JS_FN("close", Close, 0, FUNCTION_FLAGS),
@@ -695,18 +698,21 @@ protected:
   }
 
   ~DedicatedWorkerGlobalScope()
   {
     MOZ_COUNT_DTOR(mozilla::dom::workers::DedicatedWorkerGlobalScope);
   }
 
 private:
+  using EventTarget::GetEventListener;
+  using EventTarget::SetEventListener;
+
   static JSBool
-  _GetEventListener(JSContext* aCx, JSHandleObject aObj, JSHandleId aIdval, jsval* aVp)
+  GetEventListener(JSContext* aCx, JSHandleObject aObj, JSHandleId aIdval, jsval* aVp)
   {
     JS_ASSERT(JSID_IS_INT(aIdval));
     JS_ASSERT(JSID_TO_INT(aIdval) >= 0 && JSID_TO_INT(aIdval) < STRING_COUNT);
 
     const char* name = sEventStrings[JSID_TO_INT(aIdval)];
     DedicatedWorkerGlobalScope* scope = GetInstancePrivate(aCx, aObj, name);
     if (!scope) {
       return false;
@@ -722,18 +728,18 @@ private:
       return false;
     }
 
     *aVp = listener ? OBJECT_TO_JSVAL(listener) : JSVAL_NULL;
     return true;
   }
 
   static JSBool
-  _SetEventListener(JSContext* aCx, JSHandleObject aObj, JSHandleId aIdval, JSBool aStrict,
-                    jsval* aVp)
+  SetEventListener(JSContext* aCx, JSHandleObject aObj, JSHandleId aIdval, JSBool aStrict,
+                   jsval* aVp)
   {
     JS_ASSERT(JSID_IS_INT(aIdval));
     JS_ASSERT(JSID_TO_INT(aIdval) >= 0 && JSID_TO_INT(aIdval) < STRING_COUNT);
 
     const char* name = sEventStrings[JSID_TO_INT(aIdval)];
     DedicatedWorkerGlobalScope* scope = GetInstancePrivate(aCx, aObj, name);
     if (!scope) {
       return false;
@@ -795,29 +801,29 @@ private:
   static void
   Finalize(JSFreeOp* aFop, JSObject* aObj)
   {
     JS_ASSERT(JS_GetClass(aObj) == Class());
     DedicatedWorkerGlobalScope* scope =
       UnwrapDOMObject<DedicatedWorkerGlobalScope>(aObj, Class());
     if (scope) {
       DestroyProtoOrIfaceCache(aObj);
-      scope->_Finalize(aFop);
+      scope->_finalize(aFop);
     }
   }
 
   static void
   Trace(JSTracer* aTrc, JSObject* aObj)
   {
     JS_ASSERT(JS_GetClass(aObj) == Class());
     DedicatedWorkerGlobalScope* scope =
       UnwrapDOMObject<DedicatedWorkerGlobalScope>(aObj, Class());
     if (scope) {
       mozilla::dom::TraceProtoOrIfaceCache(aTrc, aObj);
-      scope->_Trace(aTrc);
+      scope->_trace(aTrc);
     }
   }
 
   static JSBool
   PostMessage(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
@@ -853,17 +859,17 @@ DOMJSClass DedicatedWorkerGlobalScope::s
   },
   { prototypes::id::EventTarget_workers, prototypes::id::_ID_Count,
     prototypes::id::_ID_Count },
   -1, false, DOM_GLOBAL_OBJECT_SLOT
 };
 
 JSPropertySpec DedicatedWorkerGlobalScope::sProperties[] = {
   { sEventStrings[STRING_onmessage], STRING_onmessage, PROPERTY_FLAGS,
-    _GetEventListener, _SetEventListener },
+    GetEventListener, SetEventListener },
   { 0, 0, 0, NULL, NULL }
 };
 
 JSFunctionSpec DedicatedWorkerGlobalScope::sFunctions[] = {
   JS_FN("postMessage", PostMessage, 1, FUNCTION_FLAGS),
   JS_FS_END
 };
 
--- a/dom/workers/XMLHttpRequest.cpp
+++ b/dom/workers/XMLHttpRequest.cpp
@@ -1425,35 +1425,35 @@ XMLHttpRequest::XMLHttpRequest(JSContext
 
 XMLHttpRequest::~XMLHttpRequest()
 {
   mWorkerPrivate->AssertIsOnWorkerThread();
   MOZ_ASSERT(!mJSObjectRooted);
 }
 
 void
-XMLHttpRequest::_Trace(JSTracer* aTrc)
+XMLHttpRequest::_trace(JSTracer* aTrc)
 {
   if (mUpload) {
     JS_CALL_OBJECT_TRACER(aTrc, mUpload->GetJSObject(), "mUpload");
   }
   JS_CALL_VALUE_TRACER(aTrc, mStateData.mResponse, "mResponse");
-  XMLHttpRequestEventTarget::_Trace(aTrc);
+  XMLHttpRequestEventTarget::_trace(aTrc);
 }
 
 void
-XMLHttpRequest::_Finalize(JSFreeOp* aFop)
+XMLHttpRequest::_finalize(JSFreeOp* aFop)
 {
   ReleaseProxy(XHRIsGoingAway);
-  XMLHttpRequestEventTarget::_Finalize(aFop);
+  XMLHttpRequestEventTarget::_finalize(aFop);
 }
 
 // static
 XMLHttpRequest*
-XMLHttpRequest::_Constructor(JSContext* aCx, JSObject* aGlobal, ErrorResult& aRv)
+XMLHttpRequest::Constructor(JSContext* aCx, JSObject* aGlobal, ErrorResult& aRv)
 {
   WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(aCx);
   MOZ_ASSERT(workerPrivate);
 
   nsRefPtr<XMLHttpRequest> xhr = new XMLHttpRequest(aCx, workerPrivate);
 
   if (!Wrap(aCx, aGlobal, xhr)) {
     aRv.Throw(NS_ERROR_FAILURE);
--- a/dom/workers/XMLHttpRequest.h
+++ b/dom/workers/XMLHttpRequest.h
@@ -57,23 +57,23 @@ private:
   bool mCanceled;
 
 protected:
   XMLHttpRequest(JSContext* aCx, WorkerPrivate* aWorkerPrivate);
   virtual ~XMLHttpRequest();
 
 public:
   virtual void
-  _Trace(JSTracer* aTrc) MOZ_OVERRIDE;
+  _trace(JSTracer* aTrc) MOZ_OVERRIDE;
 
   virtual void
-  _Finalize(JSFreeOp* aFop) MOZ_OVERRIDE;
+  _finalize(JSFreeOp* aFop) MOZ_OVERRIDE;
 
   static XMLHttpRequest*
-  _Constructor(JSContext* aCx, JSObject* aGlobal, ErrorResult& aRv);
+  Constructor(JSContext* aCx, JSObject* aGlobal, ErrorResult& aRv);
 
   void
   Unpin();
 
   bool
   Notify(JSContext* aCx, Status aStatus) MOZ_OVERRIDE;
 
 #define IMPL_GETTER_AND_SETTER(_type)                                          \
--- a/dom/workers/XMLHttpRequestEventTarget.cpp
+++ b/dom/workers/XMLHttpRequestEventTarget.cpp
@@ -3,18 +3,18 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "XMLHttpRequestEventTarget.h"
 
 USING_WORKERS_NAMESPACE
 
 void
-XMLHttpRequestEventTarget::_Trace(JSTracer* aTrc)
+XMLHttpRequestEventTarget::_trace(JSTracer* aTrc)
 {
-  EventTarget::_Trace(aTrc);
+  EventTarget::_trace(aTrc);
 }
 
 void
-XMLHttpRequestEventTarget::_Finalize(JSFreeOp* aFop)
+XMLHttpRequestEventTarget::_finalize(JSFreeOp* aFop)
 {
-  EventTarget::_Finalize(aFop);
+  EventTarget::_finalize(aFop);
 }
--- a/dom/workers/XMLHttpRequestEventTarget.h
+++ b/dom/workers/XMLHttpRequestEventTarget.h
@@ -17,20 +17,20 @@ protected:
   : EventTarget(aCx)
   { }
 
   virtual ~XMLHttpRequestEventTarget()
   { }
 
 public:
   virtual void
-  _Trace(JSTracer* aTrc) MOZ_OVERRIDE;
+  _trace(JSTracer* aTrc) MOZ_OVERRIDE;
 
   virtual void
-  _Finalize(JSFreeOp* aFop) MOZ_OVERRIDE;
+  _finalize(JSFreeOp* aFop) MOZ_OVERRIDE;
 
 #define IMPL_GETTER_AND_SETTER(_type)                                          \
   JSObject*                                                                    \
   GetOn##_type(ErrorResult& aRv)                                               \
   {                                                                            \
     return GetEventListener(NS_LITERAL_STRING(#_type), aRv);                   \
   }                                                                            \
                                                                                \
--- a/dom/workers/XMLHttpRequestUpload.cpp
+++ b/dom/workers/XMLHttpRequestUpload.cpp
@@ -15,21 +15,21 @@ USING_WORKERS_NAMESPACE
 XMLHttpRequestUpload*
 XMLHttpRequestUpload::Create(JSContext* aCx, XMLHttpRequest* aXHR)
 {
   nsRefPtr<XMLHttpRequestUpload> upload = new XMLHttpRequestUpload(aCx, aXHR);
   return Wrap(aCx, NULL, upload) ? upload : NULL;
 }
 
 void
-XMLHttpRequestUpload::_Trace(JSTracer* aTrc)
+XMLHttpRequestUpload::_trace(JSTracer* aTrc)
 {
   if (mXHR) {
     JS_CALL_OBJECT_TRACER(aTrc, mXHR->GetJSObject(), "mXHR");
   }
-  XMLHttpRequestEventTarget::_Trace(aTrc);
+  XMLHttpRequestEventTarget::_trace(aTrc);
 }
 
 void
-XMLHttpRequestUpload::_Finalize(JSFreeOp* aFop)
+XMLHttpRequestUpload::_finalize(JSFreeOp* aFop)
 {
-  XMLHttpRequestEventTarget::_Finalize(aFop);
+  XMLHttpRequestEventTarget::_finalize(aFop);
 }
--- a/dom/workers/XMLHttpRequestUpload.h
+++ b/dom/workers/XMLHttpRequestUpload.h
@@ -24,17 +24,17 @@ protected:
   virtual ~XMLHttpRequestUpload()
   { }
 
 public:
   static XMLHttpRequestUpload*
   Create(JSContext* aCx, XMLHttpRequest* aXHR);
 
   virtual void
-  _Trace(JSTracer* aTrc) MOZ_OVERRIDE;
+  _trace(JSTracer* aTrc) MOZ_OVERRIDE;
 
   virtual void
-  _Finalize(JSFreeOp* aFop) MOZ_OVERRIDE;
+  _finalize(JSFreeOp* aFop) MOZ_OVERRIDE;
 };
 
 END_WORKERS_NAMESPACE
 
 #endif // mozilla_dom_workers_xmlhttprequestupload_h__
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -10,16 +10,20 @@
 #include "Rect.h"
 #include "Matrix.h"
 #include "UserData.h"
 // This RefPtr class isn't ideal for usage in Azure, as it doesn't allow T**
 // outparams using the &-operator. But it will have to do as there's no easy
 // solution.
 #include "mozilla/RefPtr.h"
 
+#ifdef MOZ_ENABLE_FREETYPE
+#include <string>
+#endif
+
 struct _cairo_surface;
 typedef _cairo_surface cairo_surface_t;
 
 struct _cairo_scaled_font;
 typedef _cairo_scaled_font cairo_scaled_font_t;
 
 struct ID3D10Device1;
 struct ID3D10Texture2D;
@@ -306,17 +310,17 @@ public:
   virtual TemporaryRef<DataSourceSurface> GetDataSurface() = 0;
 };
 
 class DataSourceSurface : public SourceSurface
 {
 public:
   virtual SurfaceType GetType() const { return SURFACE_DATA; }
   /* Get the raw bitmap data of the surface */
-  virtual unsigned char *GetData() = 0;
+  virtual uint8_t *GetData() = 0;
   /*
    * Stride of the surface, distance in bytes between the start of the image
    * data belonging to row y and row y+1. This may be negative.
    */
   virtual int32_t Stride() = 0;
 
   /*
    * This function is called after modifying the data on the source surface
@@ -459,16 +463,30 @@ public:
    * others.
    */
   virtual void CopyGlyphsToBuilder(const GlyphBuffer &aBuffer, PathBuilder *aBuilder) = 0;
 
 protected:
   ScaledFont() {}
 };
 
+#ifdef MOZ_ENABLE_FREETYPE
+/**
+ * Describes a font
+ * Used to pass the key informatin from a gfxFont into Azure
+ * XXX Should be replaced by a more long term solution, perhaps Bug 738014
+ */
+struct FontOptions
+{
+  std::string mName;
+  FontStyle mStyle;
+};
+#endif
+
+
 /* This class is designed to allow passing additional glyph rendering
  * parameters to the glyph drawing functions. This is an empty wrapper class
  * merely used to allow holding on to and passing around platform specific
  * parameters. This is because different platforms have unique rendering
  * parameters.
  */
 class GlyphRenderingOptions : public RefCounted<GlyphRenderingOptions>
 {
@@ -805,25 +823,25 @@ public:
 
   /*
    * This creates a simple data source surface for a certain size. It allocates
    * new memory for the surface. This memory is freed when the surface is
    * destroyed.
    */
   static TemporaryRef<DataSourceSurface>
     CreateDataSourceSurface(const IntSize &aSize, SurfaceFormat aFormat);
-  
+
   /*
    * This creates a simple data source surface for some existing data. It will
    * wrap this data and the data for this source surface. The caller is
    * responsible for deallocating the memory only after destruction of the
    * surface.
    */
   static TemporaryRef<DataSourceSurface>
-    CreateDataSourceSurfaceFromData(unsigned char *aData, int32_t aStride,
+    CreateWrappingDataSourceSurface(uint8_t *aData, int32_t aStride,
                                     const IntSize &aSize, SurfaceFormat aFormat);
 
 #ifdef WIN32
   static TemporaryRef<DrawTarget> CreateDrawTargetForD3D10Texture(ID3D10Texture2D *aTexture, SurfaceFormat aFormat);
   static TemporaryRef<DrawTarget>
     CreateDualDrawTargetForD3D10Textures(ID3D10Texture2D *aTextureA,
                                          ID3D10Texture2D *aTextureB,
                                          SurfaceFormat aFormat);
--- a/gfx/2d/DrawTargetD2D.cpp
+++ b/gfx/2d/DrawTargetD2D.cpp
@@ -253,45 +253,51 @@ DrawTargetD2D::DrawSurface(SourceSurface
   switch (aSurface->GetType()) {
 
   case SURFACE_D2D1_BITMAP:
     {
       SourceSurfaceD2D *srcSurf = static_cast<SourceSurfaceD2D*>(aSurface);
       bitmap = srcSurf->GetBitmap();
 
       if (!bitmap) {
-        if (aSource.width > rt->GetMaximumBitmapSize() ||
-            aSource.height > rt->GetMaximumBitmapSize()) {
-          gfxDebug() << "Bitmap source larger than texture size specified. DrawBitmap will silently fail.";
-          // Don't know how to deal with this yet.
-          return;
-        }
-
-        int stride = srcSurf->GetSize().width * BytesPerPixel(srcSurf->GetFormat());
-
-        unsigned char *data = srcSurf->mRawData +
-                              (uint32_t)aSource.y * stride +
-                              (uint32_t)aSource.x * BytesPerPixel(srcSurf->GetFormat());
-
-        D2D1_BITMAP_PROPERTIES props =
-          D2D1::BitmapProperties(D2D1::PixelFormat(DXGIFormat(srcSurf->GetFormat()), AlphaMode(srcSurf->GetFormat())));
-        mRT->CreateBitmap(D2D1::SizeU(UINT32(aSource.width), UINT32(aSource.height)), data, stride, props, byRef(bitmap));
-
-        srcRect.x -= (uint32_t)aSource.x;
-        srcRect.y -= (uint32_t)aSource.y;
+        return;
       }
     }
     break;
   case SURFACE_D2D1_DRAWTARGET:
     {
       SourceSurfaceD2DTarget *srcSurf = static_cast<SourceSurfaceD2DTarget*>(aSurface);
       bitmap = srcSurf->GetBitmap(mRT);
       AddDependencyOnSource(srcSurf);
     }
     break;
+  case SURFACE_DATA:
+    {
+      DataSourceSurface *srcSurf = static_cast<DataSourceSurface*>(aSurface);
+      if (aSource.width > rt->GetMaximumBitmapSize() ||
+          aSource.height > rt->GetMaximumBitmapSize()) {
+        gfxDebug() << "Bitmap source larger than texture size specified. DrawBitmap will silently fail.";
+        // Don't know how to deal with this yet.
+        return;
+      }
+
+      int stride = srcSurf->Stride();
+
+      unsigned char *data = srcSurf->GetData() +
+                            (uint32_t)aSource.y * stride +
+                            (uint32_t)aSource.x * BytesPerPixel(srcSurf->GetFormat());
+
+      D2D1_BITMAP_PROPERTIES props =
+        D2D1::BitmapProperties(D2D1::PixelFormat(DXGIFormat(srcSurf->GetFormat()), AlphaMode(srcSurf->GetFormat())));
+      mRT->CreateBitmap(D2D1::SizeU(UINT32(aSource.width), UINT32(aSource.height)), data, stride, props, byRef(bitmap));
+
+      srcRect.x -= (uint32_t)aSource.x;
+      srcRect.y -= (uint32_t)aSource.y;
+    }
+    break;
   }
 
   rt->DrawBitmap(bitmap, D2DRect(aDest), aOptions.mAlpha, D2DFilter(aSurfOptions.mFilter), D2DRect(srcRect));
 
   FinalizeRTForOperation(aOptions.mCompositionOp, ColorPattern(Color()), aDest);
 }
 
 void
@@ -1650,17 +1656,16 @@ DrawTargetD2D::PopAllClips()
   }
 }
 
 void
 DrawTargetD2D::PushClipsToRT(ID2D1RenderTarget *aRT)
 {
   for (std::vector<PushedClip>::iterator iter = mPushedClips.begin();
         iter != mPushedClips.end(); iter++) {
-    D2D1_LAYER_OPTIONS options = D2D1_LAYER_OPTIONS_NONE;
     if (iter->mLayer) {
       D2D1_LAYER_OPTIONS options = D2D1_LAYER_OPTIONS_NONE;
 
       if (mFormat == FORMAT_B8G8R8X8) {
         options = D2D1_LAYER_OPTIONS_INITIALIZE_FOR_CLEARTYPE;
       }
 
       aRT->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(), iter->mPath->mGeometry,
@@ -1883,16 +1888,17 @@ DrawTargetD2D::FillGlyphsManual(ScaledFo
   RefPtr<ID3D10RenderTargetView> rtView;
   ID3D10RenderTargetView *rtViews;
   mDevice->CreateRenderTargetView(mTexture, NULL, byRef(rtView));
 
   rtViews = rtView;
   mDevice->OMSetRenderTargets(1, &rtViews, NULL);
 
   mDevice->Draw(4, 0);
+  return true;
 }
 
 TemporaryRef<ID2D1Brush>
 DrawTargetD2D::CreateBrushForPattern(const Pattern &aPattern, Float aAlpha)
 {
   if (IsPatternSupportedByD2D(aPattern)) {
     RefPtr<ID2D1SolidColorBrush> colBrush;
     mRT->CreateSolidColorBrush(D2D1::ColorF(1.0f, 1.0f, 1.0f, 1.0f), byRef(colBrush));
@@ -1975,32 +1981,39 @@ DrawTargetD2D::CreateBrushForPattern(con
     switch (pat->mSurface->GetType()) {
     case SURFACE_D2D1_BITMAP:
       {
         SourceSurfaceD2D *surf = static_cast<SourceSurfaceD2D*>(pat->mSurface.get());
 
         bitmap = surf->mBitmap;
 
         if (!bitmap) {
-          bitmap = CreatePartialBitmapForSurface(surf, mat);
-
-          if (!bitmap) {
-            return NULL;
-          }
+          return NULL;
         }
       }
       break;
     case SURFACE_D2D1_DRAWTARGET:
       {
         SourceSurfaceD2DTarget *surf =
           static_cast<SourceSurfaceD2DTarget*>(pat->mSurface.get());
         bitmap = surf->GetBitmap(mRT);
         AddDependencyOnSource(surf);
       }
       break;
+    case SURFACE_DATA:
+      {
+        DataSourceSurface *dataSurf =
+          static_cast<DataSourceSurface*>(pat->mSurface.get());
+        bitmap = CreatePartialBitmapForSurface(dataSurf, mat);
+        
+        if (!bitmap) {
+          return NULL;
+        }
+      }
+      break;
     }
     
     mRT->CreateBitmapBrush(bitmap,
                            D2D1::BitmapBrushProperties(D2DExtend(pat->mExtendMode),
                                                        D2DExtend(pat->mExtendMode),
                                                        D2DFilter(pat->mFilter)),
                            D2D1::BrushProperties(aAlpha, D2DMatrix(mat)),
                            byRef(bmBrush));
@@ -2081,20 +2094,20 @@ DrawTargetD2D::CreateStrokeStyleForOptio
 
   if (FAILED(hr)) {
     gfxWarning() << "Failed to create Direct2D stroke style.";
   }
 
   return style;
 }
 
-TemporaryRef<ID3D10Texture1D>
+TemporaryRef<ID3D10Texture2D>
 DrawTargetD2D::CreateGradientTexture(const GradientStopsD2D *aStops)
 {
-  CD3D10_TEXTURE1D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, 4096, 1, 1);
+  CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, 4096, 1, 1, 1);
 
   std::vector<D2D1_GRADIENT_STOP> rawStops;
   rawStops.resize(aStops->mStopCollection->GetGradientStopCount());
   aStops->mStopCollection->GetGradientStops(&rawStops.front(), rawStops.size());
 
   std::vector<unsigned char> textureData;
   textureData.resize(4096 * 4);
   unsigned char *texData = &textureData.front();
@@ -2139,19 +2152,20 @@ DrawTargetD2D::CreateGradientTexture(con
     texData[i * 4] = (char)(255.0f * newColor.b);
     texData[i * 4 + 1] = (char)(255.0f * newColor.g);
     texData[i * 4 + 2] = (char)(255.0f * newColor.r);
     texData[i * 4 + 3] = (char)(255.0f * newColor.a);
   }
 
   D3D10_SUBRESOURCE_DATA data;
   data.pSysMem = &textureData.front();
-
-  RefPtr<ID3D10Texture1D> tex;
-  mDevice->CreateTexture1D(&desc, &data, byRef(tex));
+  data.SysMemPitch = 4096 * 4;
+
+  RefPtr<ID3D10Texture2D> tex;
+  mDevice->CreateTexture2D(&desc, &data, byRef(tex));
 
   return tex;
 }
 
 TemporaryRef<ID3D10Texture2D>
 DrawTargetD2D::CreateTextureForAnalysis(IDWriteGlyphRunAnalysis *aAnalysis, const IntRect &aBounds)
 {
   HRESULT hr;
@@ -2211,17 +2225,17 @@ DrawTargetD2D::CreateTextureForAnalysis(
 
   if (FAILED(hr)) {
     return NULL;
   }
 
   return tex;
 }
 TemporaryRef<ID2D1Bitmap>
-DrawTargetD2D::CreatePartialBitmapForSurface(SourceSurfaceD2D *aSurface, Matrix &aMatrix)
+DrawTargetD2D::CreatePartialBitmapForSurface(DataSourceSurface *aSurface, Matrix &aMatrix)
 {
   RefPtr<ID2D1Bitmap> bitmap;
 
   // This is where things get complicated. The source surface was
   // created for a surface that was too large to fit in a texture.
   // We'll need to figure out if we can work with a partial upload
   // or downsample in software.
 
@@ -2233,62 +2247,63 @@ DrawTargetD2D::CreatePartialBitmapForSur
   }
 
   Rect rect(0, 0, mSize.width, mSize.height);
 
   // Calculate the rectangle of the source mapped to our surface.
   rect = invTransform.TransformBounds(rect);
   rect.RoundOut();
 
-  Rect uploadRect(0, 0, aSurface->mSize.width, aSurface->mSize.height);
+  IntSize size = aSurface->GetSize();
+
+  Rect uploadRect(0, 0, size.width, size.height);
 
   // Calculate the rectangle on the source bitmap that touches our
   // surface.
   uploadRect = uploadRect.Intersect(rect);
 
   if (uploadRect.IsEmpty()) {
     // This bitmap does not cover anything on the screen. XXX -
     // we need to deal with EXTEND modes here!
     return NULL;
   }
 
+  int stride = aSurface->Stride();
+
   if (uploadRect.width <= mRT->GetMaximumBitmapSize() &&
       uploadRect.height <= mRT->GetMaximumBitmapSize()) {
             
-    int Bpp = BytesPerPixel(aSurface->mFormat);
-    int stride = Bpp * aSurface->mSize.width;
+    int Bpp = BytesPerPixel(aSurface->GetFormat());
 
     // A partial upload will suffice.
     mRT->CreateBitmap(D2D1::SizeU(uint32_t(uploadRect.width), uint32_t(uploadRect.height)),
-                      aSurface->mRawData + int(uploadRect.x) * 4 + int(uploadRect.y) * stride,
+                      aSurface->GetData() + int(uploadRect.x) * 4 + int(uploadRect.y) * stride,
                       stride,
-                      D2D1::BitmapProperties(D2DPixelFormat(aSurface->mFormat)),
+                      D2D1::BitmapProperties(D2DPixelFormat(aSurface->GetFormat())),
                       byRef(bitmap));
 
     aMatrix.Translate(uploadRect.x, uploadRect.y);
 
     return bitmap;
   } else {
-    int Bpp = BytesPerPixel(aSurface->mFormat);
+    int Bpp = BytesPerPixel(aSurface->GetFormat());
 
     if (Bpp != 4) {
       // This shouldn't actually happen in practice!
       MOZ_ASSERT(false);
       return NULL;
     }
 
-    int stride = Bpp * aSurface->mSize.width;
-
-    ImageHalfScaler scaler(aSurface->mRawData, stride, IntSize(aSurface->mSize));
+    ImageHalfScaler scaler(aSurface->GetData(), stride, size);
 
     // Calculate the maximum width/height of the image post transform.
-    Point topRight = transform * Point(aSurface->mSize.width, 0);
+    Point topRight = transform * Point(size.width, 0);
     Point topLeft = transform * Point(0, 0);
-    Point bottomRight = transform * Point(aSurface->mSize.width, aSurface->mSize.height);
-    Point bottomLeft = transform * Point(0, aSurface->mSize.height);
+    Point bottomRight = transform * Point(size.width, size.height);
+    Point bottomLeft = transform * Point(0, size.height);
     
     IntSize scaleSize;
 
     scaleSize.width = max(Distance(topRight, topLeft), Distance(bottomRight, bottomLeft));
     scaleSize.height = max(Distance(topRight, bottomRight), Distance(topLeft, bottomLeft));
 
     if (scaleSize.width > mRT->GetMaximumBitmapSize()) {
       // Ok, in this case we'd really want a downscale of a part of the bitmap,
@@ -2301,20 +2316,20 @@ DrawTargetD2D::CreatePartialBitmapForSur
     }
 
     scaler.ScaleForSize(scaleSize);
 
     IntSize newSize = scaler.GetSize();
     
     mRT->CreateBitmap(D2D1::SizeU(newSize.width, newSize.height),
                       scaler.GetScaledData(), scaler.GetStride(),
-                      D2D1::BitmapProperties(D2DPixelFormat(aSurface->mFormat)),
+                      D2D1::BitmapProperties(D2DPixelFormat(aSurface->GetFormat())),
                       byRef(bitmap));
 
-    aMatrix.Scale(aSurface->mSize.width / newSize.width, aSurface->mSize.height / newSize.height);
+    aMatrix.Scale(size.width / newSize.width, size.height / newSize.height);
     return bitmap;
   }
 }
 
 void
 DrawTargetD2D::SetupEffectForRadialGradient(const RadialGradientPattern *aPattern)
 {
   mPrivateData->mEffect->GetTechniqueByName("SampleRadialGradient")->GetPassByIndex(0)->Apply(0);
@@ -2323,17 +2338,17 @@ DrawTargetD2D::SetupEffectForRadialGradi
 
   float dimensions[] = { float(mSize.width), float(mSize.height), 0, 0 };
   mPrivateData->mEffect->GetVariableByName("dimensions")->AsVector()->
     SetFloatVector(dimensions);
 
   const GradientStopsD2D *stops =
     static_cast<const GradientStopsD2D*>(aPattern->mStops.get());
 
-  RefPtr<ID3D10Texture1D> tex = CreateGradientTexture(stops);
+  RefPtr<ID3D10Texture2D> tex = CreateGradientTexture(stops);
 
   RefPtr<ID3D10ShaderResourceView> srView;
   mDevice->CreateShaderResourceView(tex, NULL, byRef(srView));
 
   mPrivateData->mEffect->GetVariableByName("tex")->AsShaderResource()->SetResource(srView);
 
   Point dc = aPattern->mCenter2 - aPattern->mCenter1;
   float dr = aPattern->mRadius2 - aPattern->mRadius1;
--- a/gfx/2d/DrawTargetD2D.h
+++ b/gfx/2d/DrawTargetD2D.h
@@ -172,23 +172,23 @@ private:
                         IDWriteRenderingParams *aParams,
                         const DrawOptions &aOptions = DrawOptions());
 
   TemporaryRef<ID2D1RenderTarget> CreateRTForTexture(ID3D10Texture2D *aTexture, SurfaceFormat aFormat);
   TemporaryRef<ID2D1Geometry> GetClippedGeometry();
 
   TemporaryRef<ID2D1Brush> CreateBrushForPattern(const Pattern &aPattern, Float aAlpha = 1.0f);
 
-  TemporaryRef<ID3D10Texture1D> CreateGradientTexture(const GradientStopsD2D *aStops);
+  TemporaryRef<ID3D10Texture2D> CreateGradientTexture(const GradientStopsD2D *aStops);
   TemporaryRef<ID3D10Texture2D> CreateTextureForAnalysis(IDWriteGlyphRunAnalysis *aAnalysis, const IntRect &aBounds);
 
-  // This creates a partially uploaded bitmap for a SourceSurfaceD2D that is
-  // too big to fit in a bitmap. It adjusts the passed Matrix to accomodate the
-  // partial upload.
-  TemporaryRef<ID2D1Bitmap> CreatePartialBitmapForSurface(SourceSurfaceD2D *aSurface, Matrix &aMatrix);
+  // This creates a (partially) uploaded bitmap for a DataSourceSurface. It
+  // uploads the minimum requirement and possibly downscales. It adjusts the
+  // input Matrix to compensate.
+  TemporaryRef<ID2D1Bitmap> CreatePartialBitmapForSurface(DataSourceSurface *aSurface, Matrix &aMatrix);
 
   void SetupEffectForRadialGradient(const RadialGradientPattern *aPattern);
   void SetupStateForRendering();
 
   static const uint32_t test = 4;
 
   IntSize mSize;
 
--- a/gfx/2d/Factory.cpp
+++ b/gfx/2d/Factory.cpp
@@ -8,18 +8,20 @@
 #ifdef USE_CAIRO
 #include "DrawTargetCairo.h"
 #include "ScaledFontBase.h"
 #endif
 
 #ifdef USE_SKIA
 #include "DrawTargetSkia.h"
 #include "ScaledFontBase.h"
+#ifdef MOZ_ENABLE_FREETYPE
 #include "ScaledFontFreetype.h"
 #endif
+#endif
 
 #if defined(WIN32) && defined(USE_SKIA)
 #include "ScaledFontWin.h"
 #endif
 
 #ifdef XP_MACOSX
 #include "ScaledFontMac.h"
 #endif
@@ -32,16 +34,18 @@
 #ifdef WIN32
 #include "DrawTargetD2D.h"
 #include "ScaledFontDWrite.h"
 #include <d3d10_1.h>
 #endif
 
 #include "DrawTargetDual.h"
 
+#include "SourceSurfaceRawData.h"
+
 #include "Logging.h"
 
 #ifdef PR_LOGGING
 PRLogModuleInfo *sGFX2DLog = PR_NewLogModule("gfx2d");
 #endif
 
 // The following code was largely taken from xpcom/glue/SSE.cpp and
 // made a little simpler.
@@ -244,21 +248,23 @@ Factory::CreateScaledFontForNativeFont(c
 #endif
 #ifdef USE_SKIA
 #ifdef WIN32
   case NATIVE_FONT_GDI_FONT_FACE:
     {
       return new ScaledFontWin(static_cast<LOGFONT*>(aNativeFont.mFont), aSize);
     }
 #endif
+#ifdef MOZ_ENABLE_FREETYPE
   case NATIVE_FONT_SKIA_FONT_FACE:
     {
-      return new ScaledFontFreetype(static_cast<gfxFont*>(aNativeFont.mFont), aSize);
+      return new ScaledFontFreetype(static_cast<FontOptions*>(aNativeFont.mFont), aSize);
     }
 #endif
+#endif
 #ifdef USE_CAIRO
   case NATIVE_FONT_CAIRO_FONT_FACE:
     {
       return new ScaledFontBase(aSize);
     }
 #endif
   default:
     gfxWarning() << "Invalid native font type specified.";
@@ -356,10 +362,24 @@ Factory::CreateDrawTargetForCairoSurface
   if (newTarget->Init(aSurface)) {
     return newTarget;
   }
 
 #endif
   return NULL;
 }
 
+TemporaryRef<DataSourceSurface>
+Factory::CreateWrappingDataSourceSurface(uint8_t *aData, int32_t aStride,
+                                         const IntSize &aSize,
+                                         SurfaceFormat aFormat)
+{
+  RefPtr<SourceSurfaceRawData> newSurf = new SourceSurfaceRawData();
+
+  if (newSurf->InitWrappingData(aData, aSize, aStride, aFormat, false)) {
+    return newSurf;
+  }
+
+  return NULL;
+}
+
 }
 }
--- a/gfx/2d/HelpersD2D.h
+++ b/gfx/2d/HelpersD2D.h
@@ -127,26 +127,16 @@ static inline D2D1_ALPHA_MODE AlphaMode(
   return D2D1_ALPHA_MODE_PREMULTIPLIED;
 }
 
 static inline D2D1_PIXEL_FORMAT D2DPixelFormat(SurfaceFormat aFormat)
 {
   return D2D1::PixelFormat(DXGIFormat(aFormat), AlphaMode(aFormat));
 }
 
-static inline int BytesPerPixel(SurfaceFormat aFormat)
-{
-  switch (aFormat) {
-  case FORMAT_A8:
-    return 1;
-  default:
-    return 4;
-  }
-}
-
 static bool IsPatternSupportedByD2D(const Pattern &aPattern)
 {
   if (aPattern.GetType() != PATTERN_RADIAL_GRADIENT) {
     return false;
   }
 
   const RadialGradientPattern *pat =
     static_cast<const RadialGradientPattern*>(&aPattern);
--- a/gfx/2d/Makefile.in
+++ b/gfx/2d/Makefile.in
@@ -38,16 +38,17 @@ CPPSRCS	= \
         Matrix.cpp \
         DrawTargetCairo.cpp \
         SourceSurfaceCairo.cpp \
         PathCairo.cpp \
         Blur.cpp \
         ScaledFontBase.cpp \
         DrawTargetDual.cpp \
         ImageScaling.cpp \
+        SourceSurfaceRawData.cpp \
         $(NULL)
 
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 CPPSRCS	+= \
 	   SourceSurfaceCG.cpp \
 	   DrawTargetCG.cpp \
 	   PathCG.cpp \
 	   $(NULL)
@@ -55,32 +56,38 @@ endif
 
 DEFINES += -DMOZ_GFX -DUSE_CAIRO -DGFX2D_INTERNAL
 
 ifdef MOZ_ENABLE_SKIA
 CPPSRCS	+= \
         SourceSurfaceSkia.cpp \
         DrawTargetSkia.cpp \
         PathSkia.cpp \
-        ScaledFontFreetype.cpp
         $(NULL)
 
 DEFINES += -DUSE_SKIA
 
 endif
 
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 ifdef MOZ_ENABLE_SKIA
 CPPSRCS += \
         ScaledFontMac.cpp \
         $(NULL)
 
 endif
 endif
 
+ifeq ($(MOZ_WIDGET_TOOLKIT),$(findstring $(MOZ_WIDGET_TOOLKIT),android gtk2 gonk qt))
+CPPSRCS	+= \
+        ScaledFontFreetype.cpp \
+        $(NULL)
+DEFINES += -DMOZ_ENABLE_FREETYPE
+endif
+
 ifeq (android,$(MOZ_WIDGET_TOOLKIT))
 DEFINES += -DSK_BUILD_FOR_ANDROID_NDK
 endif
 
 DEFINES += -DSK_A32_SHIFT=24 -DSK_R32_SHIFT=16 -DSK_G32_SHIFT=8 -DSK_B32_SHIFT=0
 
 ifdef MOZ_DEBUG
 DEFINES += -DGFX_LOG_DEBUG -DGFX_LOG_WARNING
--- a/gfx/2d/Matrix.h
+++ b/gfx/2d/Matrix.h
@@ -135,17 +135,17 @@ public:
   bool operator!=(const Matrix& other) const
   {
     return !(*this == other);
   }
 
   /* Returns true if the matrix is a rectilinear transformation (i.e.
    * grid-aligned rectangles are transformed to grid-aligned rectangles)
    */
-  bool IsRectilinear() {
+  bool IsRectilinear() const {
     if (FuzzyEqual(_12, 0) && FuzzyEqual(_21, 0)) {
       return true;
     } else if (FuzzyEqual(_22, 0) && FuzzyEqual(_11, 0)) {
       return true;
     }
 
     return false;
   }
--- a/gfx/2d/ScaledFontFreetype.cpp
+++ b/gfx/2d/ScaledFontFreetype.cpp
@@ -1,48 +1,53 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ScaledFontFreetype.h"
+#include "Logging.h"
 
 #include "gfxFont.h"
 
 #ifdef USE_SKIA
 #include "skia/SkTypeface.h"
 #endif
 
+#include <string>
+
 using namespace std;
 
 namespace mozilla {
 namespace gfx {
 
 #ifdef USE_SKIA
 static SkTypeface::Style
-gfxFontStyleToSkia(const gfxFontStyle* aStyle)
+fontStyleToSkia(FontStyle aStyle)
 {
-  if (aStyle->style == NS_FONT_STYLE_ITALIC) {
-    if (aStyle->weight == NS_FONT_WEIGHT_BOLD) {
-      return SkTypeface::kBoldItalic;
-    }
+  switch (aStyle) {
+  case FONT_STYLE_NORMAL:
+    return SkTypeface::kNormal;
+  case FONT_STYLE_ITALIC:
     return SkTypeface::kItalic;
-  }
-  if (aStyle->weight == NS_FONT_WEIGHT_BOLD) {
+  case FONT_STYLE_BOLD:
     return SkTypeface::kBold;
-  }
+  case FONT_STYLE_BOLD_ITALIC:
+    return SkTypeface::kBoldItalic;
+   }
+
+  gfxWarning() << "Unknown font style";
   return SkTypeface::kNormal;
 }
 #endif
 
 // Ideally we want to use FT_Face here but as there is currently no way to get
 // an SkTypeface from an FT_Face we do this.
-ScaledFontFreetype::ScaledFontFreetype(gfxFont* aFont, Float aSize)
+ScaledFontFreetype::ScaledFontFreetype(FontOptions* aFont, Float aSize)
   : ScaledFontBase(aSize)
 {
 #ifdef USE_SKIA
-  NS_LossyConvertUTF16toASCII name(aFont->GetName());
-  mTypeface = SkTypeface::CreateFromName(name.get(), gfxFontStyleToSkia(aFont->GetStyle()));
+  mTypeface = SkTypeface::CreateFromName(aFont->mName.c_str(), fontStyleToSkia(aFont->mStyle));
 #endif
 }
 
 }
 }
--- a/gfx/2d/ScaledFontFreetype.h
+++ b/gfx/2d/ScaledFontFreetype.h
@@ -10,15 +10,15 @@
 
 namespace mozilla {
 namespace gfx {
 
 class ScaledFontFreetype : public ScaledFontBase
 {
 public:
 
-  ScaledFontFreetype(gfxFont* aFont, Float aSize);
+  ScaledFontFreetype(FontOptions* aFont, Float aSize);
 };
 
 }
 }
 
 #endif /* MOZILLA_GFX_SCALEDFONTFREETYPE_H_ */
--- a/gfx/2d/ShadersD2D.fx
+++ b/gfx/2d/ShadersD2D.fx
@@ -416,22 +416,24 @@ technique10 SampleTextureWithShadow
         SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleMaskShadowVPS()));
     }
 }
 
 technique10 SampleTextTexture
 {
     pass Unmasked
     {
+        SetRasterizerState(TextureRast);
         SetBlendState(bTextBlend, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
         SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleTextureVS()));
         SetGeometryShader(NULL);
         SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleTextTexturePS()));
     }
     pass Masked
     {
+        SetRasterizerState(TextureRast);
         SetBlendState(bTextBlend, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
         SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleTextureVS()));
         SetGeometryShader(NULL);
         SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleTextTexturePSMasked()));
     }
 }
 
--- a/gfx/2d/ShadersD2D.h
+++ b/gfx/2d/ShadersD2D.h
@@ -1,11202 +1,11205 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#if 0
-//
-// FX Version: fx_4_0
-// Child effect (requires effect pool): false
-//
-// 3 local buffer(s)
-//
-cbuffer cb0
-{
-    float4  QuadDesc;                   // Offset:    0, size:   16
-    float4  TexCoords;                  // Offset:   16, size:   16
-    float4  MaskTexCoords;              // Offset:   32, size:   16
-    float4  TextColor;                  // Offset:   48, size:   16
-}
-
-cbuffer cb1
-{
-    float4  BlurOffsetsH[3];            // Offset:    0, size:   48
-    float4  BlurOffsetsV[3];            // Offset:   48, size:   48
-    float4  BlurWeights[3];             // Offset:   96, size:   48
-    float4  ShadowColor;                // Offset:  144, size:   16
-}
-
-cbuffer cb2
-{
-    float3x3 DeviceSpaceToUserSpace;    // Offset:    0, size:   44
-    float2  dimensions;                 // Offset:   48, size:    8
-    float3  diff;                       // Offset:   64, size:   12
-    float2  center1;                    // Offset:   80, size:    8
-    float   A;                          // Offset:   88, size:    4
-    float   radius1;                    // Offset:   92, size:    4
-    float   sq_radius1;                 // Offset:   96, size:    4
-}
-
-//
-// 11 local object(s)
-//
-Texture2D tex;
-Texture2D mask;
-SamplerState sSampler
-{
-    Filter   = uint(MIN_MAG_MIP_LINEAR /* 21 */);
-    Texture  = tex;
-    AddressU = uint(CLAMP /* 3 */);
-    AddressV = uint(CLAMP /* 3 */);
-};
-SamplerState sWrapSampler
-{
-    Filter   = uint(MIN_MAG_MIP_LINEAR /* 21 */);
-    Texture  = tex;
-    AddressU = uint(WRAP /* 1 */);
-    AddressV = uint(WRAP /* 1 */);
-};
-SamplerState sMirrorSampler
-{
-    Filter   = uint(MIN_MAG_MIP_LINEAR /* 21 */);
-    Texture  = tex;
-    AddressU = uint(MIRROR /* 2 */);
-    AddressV = uint(MIRROR /* 2 */);
-};
-SamplerState sMaskSampler
-{
-    Filter   = uint(MIN_MAG_MIP_LINEAR /* 21 */);
-    Texture  = mask;
-    AddressU = uint(CLAMP /* 3 */);
-    AddressV = uint(CLAMP /* 3 */);
-};
-SamplerState sShadowSampler
-{
-    Filter   = uint(MIN_MAG_MIP_LINEAR /* 21 */);
-    Texture  = tex;
-    AddressU = uint(BORDER /* 4 */);
-    AddressV = uint(BORDER /* 4 */);
-    BorderColor = float4(0, 0, 0, 0);
-};
-RasterizerState TextureRast
-{
-    ScissorEnable = bool(FALSE /* 0 */);
-    CullMode = uint(NONE /* 1 */);
-};
-BlendState ShadowBlendH
-{
-    BlendEnable[0] = bool(FALSE /* 0 */);
-    RenderTargetWriteMask[0] = byte(0x0f);
-};
-BlendState ShadowBlendV
-{
-    BlendEnable[0] = bool(TRUE /* 1 */);
-    SrcBlend[0] = uint(ONE /* 2 */);
-    DestBlend[0] = uint(INV_SRC_ALPHA /* 6 */);
-    BlendOp[0] = uint(ADD /* 1 */);
-    SrcBlendAlpha[0] = uint(ONE /* 2 */);
-    DestBlendAlpha[0] = uint(INV_SRC_ALPHA /* 6 */);
-    BlendOpAlpha[0] = uint(ADD /* 1 */);
-    RenderTargetWriteMask[0] = byte(0x0f);
-};
-BlendState bTextBlend
-{
-    AlphaToCoverageEnable = bool(FALSE /* 0 */);
-    BlendEnable[0] = bool(TRUE /* 1 */);
-    SrcBlend[0] = uint(SRC1_COLOR /* 16 */);
-    DestBlend[0] = uint(INV_SRC1_COLOR /* 17 */);
-    BlendOp[0] = uint(ADD /* 1 */);
-    SrcBlendAlpha[0] = uint(SRC1_ALPHA /* 18 */);
-    DestBlendAlpha[0] = uint(INV_SRC1_ALPHA /* 19 */);
-    BlendOpAlpha[0] = uint(ADD /* 1 */);
-    RenderTargetWriteMask[0] = byte(0x0f);
-};
-
-//
-// 5 technique(s)
-//
-technique10 SampleTexture
-{
-    pass P0
-    {
-        RasterizerState = TextureRast;
-        VertexShader = asm {
-            //
-            // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
-            //
-            //
-            // Buffer Definitions: 
-            //
-            // cbuffer cb0
-            // {
-            //
-            //   float4 QuadDesc;                   // Offset:    0 Size:    16
-            //   float4 TexCoords;                  // Offset:   16 Size:    16
-            //   float4 MaskTexCoords;              // Offset:   32 Size:    16
-            //   float4 TextColor;                  // Offset:   48 Size:    16 [unused]
-            //
-            // }
-            //
-            //
-            // Resource Bindings:
-            //
-            // Name                                 Type  Format         Dim Slot Elements
-            // ------------------------------ ---------- ------- ----------- ---- --------
-            // cb0                               cbuffer      NA          NA    0        1
-            //
-            //
-            //
-            // Input signature:
-            //
-            // Name                 Index   Mask Register SysValue Format   Used
-            // -------------------- ----- ------ -------- -------- ------ ------
-            // POSITION                 0   xyz         0     NONE  float   xy  
-            //
-            //
-            // Output signature:
-            //
-            // Name                 Index   Mask Register SysValue Format   Used
-            // -------------------- ----- ------ -------- -------- ------ ------
-            // SV_Position              0   xyzw        0      POS  float   xyzw
-            // TEXCOORD                 0   xy          1     NONE  float   xy  
-            // TEXCOORD                 1     zw        1     NONE  float     zw
-            //
-            //
-            // Constant buffer to DX9 shader constant mappings:
-            //
-            // Target Reg Buffer  Start Reg # of Regs        Data Conversion
-            // ---------- ------- --------- --------- ----------------------
-            // c1         cb0             0         3  ( FLT, FLT, FLT, FLT)
-            //
-            //
-            // Runtime generated constant mappings:
-            //
-            // Target Reg                               Constant Description
-            // ---------- --------------------------------------------------
-            // c0                              Vertex Shader position offset
-            //
-            //
-            // Level9 shader bytecode:
-            //
-                vs_2_x
-                def c4, 0, 1, 0, 0
-                dcl_texcoord v0
-                mad oT0.xy, v0, c2.zwzw, c2
-                mad oT0.zw, v0.xyyx, c3.xywz, c3.xyyx
-                mad r0.xy, v0, c1.zwzw, c1
-                add oPos.xy, r0, c0
-                mov oPos.zw, c4.xyxy
-            
-            // approximately 5 instruction slots used
-            vs_4_0
-            dcl_constantbuffer cb0[3], immediateIndexed
-            dcl_input v0.xy
-            dcl_output_siv o0.xyzw, position
-            dcl_output o1.xy
-            dcl_output o1.zw
-            mad o0.xy, v0.xyxx, cb0[0].zwzz, cb0[0].xyxx
-            mov o0.zw, l(0,0,0,1.000000)
-            mad o1.xy, v0.xyxx, cb0[1].zwzz, cb0[1].xyxx
-            mad o1.zw, v0.xxxy, cb0[2].zzzw, cb0[2].xxxy
-            ret 
-            // Approximately 5 instruction slots used
-                    
-        };
-        GeometryShader = NULL;
-        PixelShader = asm {
-            //
-            // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
-            //
-            //
-            // Resource Bindings:
-            //
-            // Name                                 Type  Format         Dim Slot Elements
-            // ------------------------------ ---------- ------- ----------- ---- --------
-            // sSampler                          sampler      NA          NA    0        1
-            // tex                               texture  float4          2d    0        1
-            //
-            //
-            //
-            // Input signature:
-            //
-            // Name                 Index   Mask Register SysValue Format   Used
-            // -------------------- ----- ------ -------- -------- ------ ------
-            // SV_Position              0   xyzw        0      POS  float       
-            // TEXCOORD                 0   xy          1     NONE  float   xy  
-            // TEXCOORD                 1     zw        1     NONE  float       
-            //
-            //
-            // Output signature:
-            //
-            // Name                 Index   Mask Register SysValue Format   Used
-            // -------------------- ----- ------ -------- -------- ------ ------
-            // SV_Target                0   xyzw        0   TARGET  float   xyzw
-            //
-            //
-            // Sampler/Resource to DX9 shader sampler mappings:
-            //
-            // Target Sampler Source Sampler  Source Resource
-            // -------------- --------------- ----------------
-            // s0             s0              t0               
-            //
-            //
-            // Level9 shader bytecode:
-            //
-                ps_2_x
-                dcl t0
-                dcl_2d s0
-                texld r0, t0, s0
-                mov oC0, r0
-            
-            // approximately 2 instruction slots used (1 texture, 1 arithmetic)
-            ps_4_0
-            dcl_sampler s0, mode_default
-            dcl_resource_texture2d (float,float,float,float) t0
-            dcl_input_ps linear v1.xy
-            dcl_output o0.xyzw
-            sample o0.xyzw, v1.xyxx, t0.xyzw, s0
-            ret 
-            // Approximately 2 instruction slots used
-                    
-        };
-    }
-
-}
-
-technique10 SampleRadialGradient
-{
-    pass APos
-    {
-        RasterizerState = TextureRast;
-        VertexShader = asm {
-            //
-            // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
-            //
-            //
-            // Buffer Definitions: 
-            //
-            // cbuffer cb0
-            // {
-            //
-            //   float4 QuadDesc;                   // Offset:    0 Size:    16
-            //   float4 TexCoords;                  // Offset:   16 Size:    16 [unused]
-            //   float4 MaskTexCoords;              // Offset:   32 Size:    16
-            //   float4 TextColor;                  // Offset:   48 Size:    16 [unused]
-            //
-            // }
-            //
-            // cbuffer cb2
-            // {
-            //
-            //   float3x3 DeviceSpaceToUserSpace;   // Offset:    0 Size:    44
-            //   float2 dimensions;                 // Offset:   48 Size:     8
-            //   float3 diff;                       // Offset:   64 Size:    12 [unused]
-            //   float2 center1;                    // Offset:   80 Size:     8 [unused]
-            //   float A;                           // Offset:   88 Size:     4 [unused]
-            //   float radius1;                     // Offset:   92 Size:     4 [unused]
-            //   float sq_radius1;                  // Offset:   96 Size:     4 [unused]
-            //
-            // }
-            //
-            //
-            // Resource Bindings:
-            //
-            // Name                                 Type  Format         Dim Slot Elements
-            // ------------------------------ ---------- ------- ----------- ---- --------
-            // cb0                               cbuffer      NA          NA    0        1
-            // cb2                               cbuffer      NA          NA    1        1
-            //
-            //
-            //
-            // Input signature:
-            //
-            // Name                 Index   Mask Register SysValue Format   Used
-            // -------------------- ----- ------ -------- -------- ------ ------
-            // POSITION                 0   xyz         0     NONE  float   xy  
-            //
-            //
-            // Output signature:
-            //
-            // Name                 Index   Mask Register SysValue Format   Used
-            // -------------------- ----- ------ -------- -------- ------ ------
-            // SV_Position              0   xyzw        0      POS  float   xyzw
-            // TEXCOORD                 0   xy          1     NONE  float   xy  
-            // TEXCOORD                 1     zw        1     NONE  float     zw
-            //
-            //
-            // Constant buffer to DX9 shader constant mappings:
-            //
-            // Target Reg Buffer  Start Reg # of Regs        Data Conversion
-            // ---------- ------- --------- --------- ----------------------
-            // c1         cb0             0         1  ( FLT, FLT, FLT, FLT)
-            // c2         cb0             2         1  ( FLT, FLT, FLT, FLT)
-            // c3         cb1             0         2  ( FLT, FLT, FLT, FLT)
-            // c5         cb1             3         1  ( FLT, FLT, FLT, FLT)
-            //
-            //
-            // Runtime generated constant mappings:
-            //
-            // Target Reg                               Constant Description
-            // ---------- --------------------------------------------------
-            // c0                              Vertex Shader position offset
-            //
-            //
-            // Level9 shader bytecode:
-            //
-                vs_2_x
-                def c6, 1, 0.5, 0, 0
-                dcl_texcoord v0
-                mad oT0.xy, v0, c2.zwzw, c2
-                mad r0.xy, v0, c1.zwzw, c1
-                add r0.z, r0.x, c6.x
-                mul r0.z, r0.z, c5.x
-                mul r1.x, r0.z, c6.y
-                add r0.z, -r0.y, c6.x
-                add oPos.xy, r0, c0
-                mul r0.x, r0.z, c5.y
-                mul r1.y, r0.x, c6.y
-                mov r1.z, c6.x
-                dp3 oT0.w, r1, c3
-                dp3 oT0.z, r1, c4
-                mov oPos.zw, c6.xyzx
-            
-            // approximately 13 instruction slots used
-            vs_4_0
-            dcl_constantbuffer cb0[3], immediateIndexed
-            dcl_constantbuffer cb1[4], immediateIndexed
-            dcl_input v0.xy
-            dcl_output_siv o0.xyzw, position
-            dcl_output o1.xy
-            dcl_output o1.zw
-            dcl_temps 2
-            mov o0.zw, l(0,0,0,1.000000)
-            mad r0.xy, v0.xyxx, cb0[0].zwzz, cb0[0].xyxx
-            mov o0.xy, r0.xyxx
-            add r0.x, r0.x, l(1.000000)
-            add r0.y, -r0.y, l(1.000000)
-            mul r0.xy, r0.xyxx, cb1[3].xyxx
-            mul r1.xy, r0.xyxx, l(0.500000, 0.500000, 0.000000, 0.000000)
-            mov r1.z, l(1.000000)
-            dp3 o1.z, r1.xyzx, cb1[0].xyzx
-            dp3 o1.w, r1.xyzx, cb1[1].xyzx
-            mad o1.xy, v0.xyxx, cb0[2].zwzz, cb0[2].xyxx
-            ret 
-            // Approximately 12 instruction slots used
-                    
-        };
-        GeometryShader = NULL;
-        PixelShader = asm {
-            //
-            // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
-            //
-            //
-            // Buffer Definitions: 
-            //
-            // cbuffer cb2
-            // {
-            //
-            //   float3x3 DeviceSpaceToUserSpace;   // Offset:    0 Size:    44 [unused]
-            //   float2 dimensions;                 // Offset:   48 Size:     8 [unused]
-            //   float3 diff;                       // Offset:   64 Size:    12
-            //   float2 center1;                    // Offset:   80 Size:     8
-            //   float A;                           // Offset:   88 Size:     4
-            //   float radius1;                     // Offset:   92 Size:     4
-            //   float sq_radius1;                  // Offset:   96 Size:     4
-            //
-            // }
-            //
-            //
-            // Resource Bindings:
-            //
-            // Name                                 Type  Format         Dim Slot Elements
-            // ------------------------------ ---------- ------- ----------- ---- --------
-            // sSampler                          sampler      NA          NA    0        1
-            // sMaskSampler                      sampler      NA          NA    1        1
-            // tex                               texture  float4          2d    0        1
-            // mask                              texture  float4          2d    1        1
-            // cb2                               cbuffer      NA          NA    0        1
-            //
-            //
-            //
-            // Input signature:
-            //
-            // Name                 Index   Mask Register SysValue Format   Used
-            // -------------------- ----- ------ -------- -------- ------ ------
-            // SV_Position              0   xyzw        0      POS  float       
-            // TEXCOORD                 0   xy          1     NONE  float   xy  
-            // TEXCOORD                 1     zw        1     NONE  float     zw
-            //
-            //
-            // Output signature:
-            //
-            // Name                 Index   Mask Register SysValue Format   Used
-            // -------------------- ----- ------ -------- -------- ------ ------
-            // SV_Target                0   xyzw        0   TARGET  float   xyzw
-            //
-            //
-            // Constant buffer to DX9 shader constant mappings:
-            //
-            // Target Reg Buffer  Start Reg # of Regs        Data Conversion
-            // ---------- ------- --------- --------- ----------------------
-            // c0         cb0             4         3  ( FLT, FLT, FLT, FLT)
-            //
-            //
-            // Sampler/Resource to DX9 shader sampler mappings:
-            //
-            // Target Sampler Source Sampler  Source Resource
-            // -------------- --------------- ----------------
-            // s0             s0              t0               
-            // s1             s1              t1               
-            //
-            //
-            // Level9 shader bytecode:
-            //
-                ps_2_x
-                def c3, 0.5, 0, 0, 0
-                def c4, 1, -1, 0, -0
-                dcl t0
-                dcl_2d s0
-                dcl_2d s1
-                add r0.xy, t0.wzzw, -c1
-                dp2add r0.w, r0, r0, -c2.x
-                mul r0.w, r0.w, c1.z
-                mov r0.z, c1.w
-                dp3 r0.x, r0, c0
-                mad r0.y, r0.x, r0.x, -r0.w
-                abs r0.z, r0.y
-                rsq r0.z, r0.z
-                rcp r1.x, r0.z
-                mov r1.yz, -r1.x
-                add r0.xzw, r0.x, r1.xyyz
-                rcp r1.x, c1.z
-                mul r0.xzw, r0, r1.x
-                mov r1.w, c1.w
-                mad r1.xyz, r0.xzww, c0.z, r1.w
-                cmp r2.x, r1.x, r0.x, r0.w
-                cmp r0.xzw, r1.xyyz, c4.xyxy, c4.zyzw
-                mov r2.y, c3.x
-                texld r1, t0, s1
-                texld r2, r2, s0
-                mul r2.xyz, r2.w, r2
-                mul r1, r1.w, r2
-                add r0.w, r0.w, r0.x
-                cmp r0.x, r0.w, r0.x, r0.z
-                cmp r1, -r0.x, c4.z, r1
-                cmp r0, r0.y, r1, c4.z
-                mov oC0, r0
-            
-            // approximately 28 instruction slots used (2 texture, 26 arithmetic)
-            ps_4_0
-            dcl_constantbuffer cb0[7], immediateIndexed
-            dcl_sampler s0, mode_default
-            dcl_sampler s1, mode_default
-            dcl_resource_texture2d (float,float,float,float) t0
-            dcl_resource_texture2d (float,float,float,float) t1
-            dcl_input_ps linear v1.xy
-            dcl_input_ps linear v1.zw
-            dcl_output o0.xyzw
-            dcl_temps 3
-            add r0.xy, v1.zwzz, -cb0[5].xyxx
-            mov r0.z, cb0[5].w
-            dp3 r0.z, r0.xyzx, cb0[4].xyzx
-            dp2 r0.x, r0.xyxx, r0.xyxx
-            add r0.x, r0.x, -cb0[6].x
-            mul r0.x, r0.x, cb0[5].z
-            mad r0.x, r0.z, r0.z, -r0.x
-            lt r0.y, r0.x, l(0.000000)
-            sqrt r1.x, |r0.x|
-            mov r1.y, -r1.x
-            add r0.xz, r0.zzzz, r1.xxyx
-            div r0.xz, r0.xxzx, cb0[5].zzzz
-            mul r1.xy, r0.xzxx, cb0[4].zzzz
-            ge r1.xy, r1.xyxx, -cb0[5].wwww
-            and r1.xy, r1.xyxx, l(0x3f800000, 0x3f800000, 0, 0)
-            add r0.x, -r0.z, r0.x
-            mad r2.x, r1.x, r0.x, r0.z
-            mov r2.y, l(0.500000)
-            sample r2.xyzw, r2.xyxx, t0.xyzw, s0
-            if_nz r0.y
-              mov o0.xyzw, l(0,0,0,0)
-              ret 
-            endif 
-            max r0.x, r1.y, r1.x
-            ge r0.x, l(0.000000), r0.x
-            if_nz r0.x
-              mov o0.xyzw, l(0,0,0,0)
-              ret 
-            endif 
-            mul r2.xyz, r2.wwww, r2.xyzx
-            sample r0.xyzw, v1.xyxx, t1.xyzw, s1
-            mul o0.xyzw, r0.wwww, r2.xyzw
-            ret 
-            // Approximately 33 instruction slots used
-                    
-        };
-    }
-
-    pass A0
-    {
-        RasterizerState = TextureRast;
-        VertexShader = asm {
-            //
-            // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
-            //
-            //
-            // Buffer Definitions: 
-            //
-            // cbuffer cb0
-            // {
-            //
-            //   float4 QuadDesc;                   // Offset:    0 Size:    16
-            //   float4 TexCoords;                  // Offset:   16 Size:    16 [unused]
-            //   float4 MaskTexCoords;              // Offset:   32 Size:    16
-            //   float4 TextColor;                  // Offset:   48 Size:    16 [unused]
-            //
-            // }
-            //
-            // cbuffer cb2
-            // {
-            //
-            //   float3x3 DeviceSpaceToUserSpace;   // Offset:    0 Size:    44
-            //   float2 dimensions;                 // Offset:   48 Size:     8
-            //   float3 diff;                       // Offset:   64 Size:    12 [unused]
-            //   float2 center1;                    // Offset:   80 Size:     8 [unused]
-            //   float A;                           // Offset:   88 Size:     4 [unused]
-            //   float radius1;                     // Offset:   92 Size:     4 [unused]
-            //   float sq_radius1;                  // Offset:   96 Size:     4 [unused]
-            //
-            // }
-            //
-            //
-            // Resource Bindings:
-            //
-            // Name                                 Type  Format         Dim Slot Elements
-            // ------------------------------ ---------- ------- ----------- ---- --------
-            // cb0                               cbuffer      NA          NA    0        1
-            // cb2                               cbuffer      NA          NA    1        1
-            //
-            //
-            //
-            // Input signature:
-            //
-            // Name                 Index   Mask Register SysValue Format   Used
-            // -------------------- ----- ------ -------- -------- ------ ------
-            // POSITION                 0   xyz         0     NONE  float   xy  
-            //
-            //
-            // Output signature:
-            //
-            // Name                 Index   Mask Register SysValue Format   Used
-            // -------------------- ----- ------ -------- -------- ------ ------
-            // SV_Position              0   xyzw        0      POS  float   xyzw
-            // TEXCOORD                 0   xy          1     NONE  float   xy  
-            // TEXCOORD                 1     zw        1     NONE  float     zw
-            //
-            //
-            // Constant buffer to DX9 shader constant mappings:
-            //
-            // Target Reg Buffer  Start Reg # of Regs        Data Conversion
-            // ---------- ------- --------- --------- ----------------------
-            // c1         cb0             0         1  ( FLT, FLT, FLT, FLT)
-            // c2         cb0             2         1  ( FLT, FLT, FLT, FLT)
-            // c3         cb1             0         2  ( FLT, FLT, FLT, FLT)
-            // c5         cb1             3         1  ( FLT, FLT, FLT, FLT)
-            //
-            //
-            // Runtime generated constant mappings:
-            //
-            // Target Reg                               Constant Description
-            // ---------- --------------------------------------------------
-            // c0                              Vertex Shader position offset
-            //
-            //
-            // Level9 shader bytecode:
-            //
-                vs_2_x
-                def c6, 1, 0.5, 0, 0
-                dcl_texcoord v0
-                mad oT0.xy, v0, c2.zwzw, c2
-                mad r0.xy, v0, c1.zwzw, c1
-                add r0.z, r0.x, c6.x
-                mul r0.z, r0.z, c5.x
-                mul r1.x, r0.z, c6.y
-                add r0.z, -r0.y, c6.x
-                add oPos.xy, r0, c0
-                mul r0.x, r0.z, c5.y
-                mul r1.y, r0.x, c6.y
-                mov r1.z, c6.x
-                dp3 oT0.w, r1, c3
-                dp3 oT0.z, r1, c4
-                mov oPos.zw, c6.xyzx
-            
-            // approximately 13 instruction slots used
-            vs_4_0
-            dcl_constantbuffer cb0[3], immediateIndexed
-            dcl_constantbuffer cb1[4], immediateIndexed
-            dcl_input v0.xy
-            dcl_output_siv o0.xyzw, position
-            dcl_output o1.xy
-            dcl_output o1.zw
-            dcl_temps 2
-            mov o0.zw, l(0,0,0,1.000000)
-            mad r0.xy, v0.xyxx, cb0[0].zwzz, cb0[0].xyxx
-            mov o0.xy, r0.xyxx
-            add r0.x, r0.x, l(1.000000)
-            add r0.y, -r0.y, l(1.000000)
-            mul r0.xy, r0.xyxx, cb1[3].xyxx
-            mul r1.xy, r0.xyxx, l(0.500000, 0.500000, 0.000000, 0.000000)
-            mov r1.z, l(1.000000)
-            dp3 o1.z, r1.xyzx, cb1[0].xyzx
-            dp3 o1.w, r1.xyzx, cb1[1].xyzx
-            mad o1.xy, v0.xyxx, cb0[2].zwzz, cb0[2].xyxx
-            ret 
-            // Approximately 12 instruction slots used
-                    
-        };
-        GeometryShader = NULL;
-        PixelShader = asm {
-            //
-            // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
-            //
-            //
-            // Buffer Definitions: 
-            //
-            // cbuffer cb2
-            // {
-            //
-            //   float3x3 DeviceSpaceToUserSpace;   // Offset:    0 Size:    44 [unused]
-            //   float2 dimensions;                 // Offset:   48 Size:     8 [unused]
-            //   float3 diff;                       // Offset:   64 Size:    12
-            //   float2 center1;                    // Offset:   80 Size:     8
-            //   float A;                           // Offset:   88 Size:     4 [unused]
-            //   float radius1;                     // Offset:   92 Size:     4
-            //   float sq_radius1;                  // Offset:   96 Size:     4 [unused]
-            //
-            // }
-            //
-            //
-            // Resource Bindings:
-            //
-            // Name                                 Type  Format         Dim Slot Elements
-            // ------------------------------ ---------- ------- ----------- ---- --------
-            // sSampler                          sampler      NA          NA    0        1
-            // sMaskSampler                      sampler      NA          NA    1        1
-            // tex                               texture  float4          2d    0        1
-            // mask                              texture  float4          2d    1        1
-            // cb2                               cbuffer      NA          NA    0        1
-            //
-            //
-            //
-            // Input signature:
-            //
-            // Name                 Index   Mask Register SysValue Format   Used
-            // -------------------- ----- ------ -------- -------- ------ ------
-            // SV_Position              0   xyzw        0      POS  float       
-            // TEXCOORD                 0   xy          1     NONE  float   xy  
-            // TEXCOORD                 1     zw        1     NONE  float     zw
-            //
-            //
-            // Output signature:
-            //
-            // Name                 Index   Mask Register SysValue Format   Used
-            // -------------------- ----- ------ -------- -------- ------ ------
-            // SV_Target                0   xyzw        0   TARGET  float   xyzw
-            //
-            //
-            // Constant buffer to DX9 shader constant mappings:
-            //
-            // Target Reg Buffer  Start Reg # of Regs        Data Conversion
-            // ---------- ------- --------- --------- ----------------------
-            // c0         cb0             4         2  ( FLT, FLT, FLT, FLT)
-            //
-            //
-            // Sampler/Resource to DX9 shader sampler mappings:
-            //
-            // Target Sampler Source Sampler  Source Resource
-            // -------------- --------------- ----------------
-            // s0             s0              t0               
-            // s1             s1              t1               
-            //
-            //
-            // Level9 shader bytecode:
-            //
-                ps_2_x
-                def c2, 0.5, 0, 0, 0
-                dcl t0
-                dcl_2d s0
-                dcl_2d s1
-                mul r0.w, c1.w, c1.w
-                add r0.xy, t0.wzzw, -c1
-                dp2add r0.w, r0, r0, -r0.w
-                mul r0.w, r0.w, c2.x
-                mov r0.z, c1.w
-                dp3 r0.x, r0, c0
-                rcp r0.x, r0.x
-                mul r0.x, r0.x, r0.w
-                mov r0.y, c2.x
-                texld r1, t0, s1
-                texld r2, r0, s0
-                mov r0.w, c1.w
-                mad r0.x, r0.x, -c0.z, -r0.w
-                mul r2.xyz, r2.w, r2
-                mul r1, r1.w, r2
-                cmp r0, r0.x, c2.y, r1
-                mov oC0, r0
-            
-            // approximately 18 instruction slots used (2 texture, 16 arithmetic)
-            ps_4_0
-            dcl_constantbuffer cb0[6], immediateIndexed
-            dcl_sampler s0, mode_default
-            dcl_sampler s1, mode_default
-            dcl_resource_texture2d (float,float,float,float) t0
-            dcl_resource_texture2d (float,float,float,float) t1
-            dcl_input_ps linear v1.xy
-            dcl_input_ps linear v1.zw
-            dcl_output o0.xyzw
-            dcl_temps 2
-            add r0.xy, v1.zwzz, -cb0[5].xyxx
-            mov r0.z, cb0[5].w
-            dp3 r0.z, r0.xyzx, cb0[4].xyzx
-            dp2 r0.x, r0.xyxx, r0.xyxx
-            mad r0.x, -cb0[5].w, cb0[5].w, r0.x
-            mul r0.x, r0.x, l(0.500000)
-            div r0.x, r0.x, r0.z
-            mul r0.z, r0.x, cb0[4].z
-            ge r0.z, -cb0[5].w, r0.z
-            mov r0.y, l(0.500000)
-            sample r1.xyzw, r0.xyxx, t0.xyzw, s0
-            if_nz r0.z
-              mov o0.xyzw, l(0,0,0,0)
-              ret 
-            endif 
-            mul r1.xyz, r1.wwww, r1.xyzx
-            sample r0.xyzw, v1.xyxx, t1.xyzw, s1
-            mul o0.xyzw, r0.wwww, r1.xyzw
-            ret 
-            // Approximately 19 instruction slots used
-                    
-        };
-    }
-
-    pass APosWrap
-    {
-        RasterizerState = TextureRast;
-        VertexShader = asm {
-            //
-            // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
-            //
-            //
-            // Buffer Definitions: 
-            //
-            // cbuffer cb0
-            // {
-            //
-            //   float4 QuadDesc;                   // Offset:    0 Size:    16
-            //   float4 TexCoords;                  // Offset:   16 Size:    16 [unused]
-            //   float4 MaskTexCoords;              // Offset:   32 Size:    16
-            //   float4 TextColor;                  // Offset:   48 Size:    16 [unused]
-            //
-            // }
-            //
-            // cbuffer cb2
-            // {
-            //
-            //   float3x3 DeviceSpaceToUserSpace;   // Offset:    0 Size:    44
-            //   float2 dimensions;                 // Offset:   48 Size:     8
-            //   float3 diff;                       // Offset:   64 Size:    12 [unused]
-            //   float2 center1;                    // Offset:   80 Size:     8 [unused]
-            //   float A;                           // Offset:   88 Size:     4 [unused]
-            //   float radius1;                     // Offset:   92 Size:     4 [unused]
-            //   float sq_radius1;                  // Offset:   96 Size:     4 [unused]
-            //
-            // }
-            //
-            //
-            // Resource Bindings:
-            //
-            // Name                                 Type  Format         Dim Slot Elements
-            // ------------------------------ ---------- ------- ----------- ---- --------
-            // cb0                               cbuffer      NA          NA    0        1
-            // cb2                               cbuffer      NA          NA    1        1
-            //
-            //
-            //
-            // Input signature:
-            //
-            // Name                 Index   Mask Register SysValue Format   Used
-            // -------------------- ----- ------ -------- -------- ------ ------
-            // POSITION                 0   xyz         0     NONE  float   xy  
-            //
-            //
-            // Output signature:
-            //
-            // Name                 Index   Mask Register SysValue Format   Used
-            // -------------------- ----- ------ -------- -------- ------ ------
-            // SV_Position              0   xyzw        0      POS  float   xyzw
-            // TEXCOORD                 0   xy          1     NONE  float   xy  
-            // TEXCOORD                 1     zw        1     NONE  float     zw
-            //
-            //
-            // Constant buffer to DX9 shader constant mappings:
-            //
-            // Target Reg Buffer  Start Reg # of Regs        Data Conversion
-            // ---------- ------- --------- --------- ----------------------
-            // c1         cb0             0         1  ( FLT, FLT, FLT, FLT)
-            // c2         cb0             2         1  ( FLT, FLT, FLT, FLT)
-            // c3         cb1             0         2  ( FLT, FLT, FLT, FLT)
-            // c5         cb1             3         1  ( FLT, FLT, FLT, FLT)
-            //
-            //
-            // Runtime generated constant mappings:
-            //
-            // Target Reg                               Constant Description
-            // ---------- --------------------------------------------------
-            // c0                              Vertex Shader position offset
-            //
-            //
-            // Level9 shader bytecode:
-            //
-                vs_2_x
-                def c6, 1, 0.5, 0, 0
-                dcl_texcoord v0
-                mad oT0.xy, v0, c2.zwzw, c2
-                mad r0.xy, v0, c1.zwzw, c1
-                add r0.z, r0.x, c6.x
-                mul r0.z, r0.z, c5.x
-                mul r1.x, r0.z, c6.y
-                add r0.z, -r0.y, c6.x
-                add oPos.xy, r0, c0
-                mul r0.x, r0.z, c5.y
-                mul r1.y, r0.x, c6.y
-                mov r1.z, c6.x
-                dp3 oT0.w, r1, c3
-                dp3 oT0.z, r1, c4
-                mov oPos.zw, c6.xyzx
-            
-            // approximately 13 instruction slots used
-            vs_4_0
-            dcl_constantbuffer cb0[3], immediateIndexed
-            dcl_constantbuffer cb1[4], immediateIndexed
-            dcl_input v0.xy
-            dcl_output_siv o0.xyzw, position
-            dcl_output o1.xy
-            dcl_output o1.zw
-            dcl_temps 2
-            mov o0.zw, l(0,0,0,1.000000)
-            mad r0.xy, v0.xyxx, cb0[0].zwzz, cb0[0].xyxx
-            mov o0.xy, r0.xyxx
-            add r0.x, r0.x, l(1.000000)
-            add r0.y, -r0.y, l(1.000000)
-            mul r0.xy, r0.xyxx, cb1[3].xyxx
-            mul r1.xy, r0.xyxx, l(0.500000, 0.500000, 0.000000, 0.000000)
-            mov r1.z, l(1.000000)
-            dp3 o1.z, r1.xyzx, cb1[0].xyzx
-            dp3 o1.w, r1.xyzx, cb1[1].xyzx
-            mad o1.xy, v0.xyxx, cb0[2].zwzz, cb0[2].xyxx
-            ret 
-            // Approximately 12 instruction slots used
-                    
-        };
-        GeometryShader = NULL;
-        PixelShader = asm {
-            //
-            // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
-            //
-            //
-            // Buffer Definitions: 
-            //
-            // cbuffer cb2
-            // {
-            //
-            //   float3x3 DeviceSpaceToUserSpace;   // Offset:    0 Size:    44 [unused]
-            //   float2 dimensions;                 // Offset:   48 Size:     8 [unused]
-            //   float3 diff;                       // Offset:   64 Size:    12
-            //   float2 center1;                    // Offset:   80 Size:     8
-            //   float A;                           // Offset:   88 Size:     4
-            //   float radius1;                     // Offset:   92 Size:     4
-            //   float sq_radius1;                  // Offset:   96 Size:     4
-            //
-            // }
-            //
-            //
-            // Resource Bindings:
-            //
-            // Name                                 Type  Format         Dim Slot Elements
-            // ------------------------------ ---------- ------- ----------- ---- --------
-            // sWrapSampler                      sampler      NA          NA    0        1
-            // sMaskSampler                      sampler      NA          NA    1        1
-            // tex                               texture  float4          2d    0        1
-            // mask                              texture  float4          2d    1        1
-            // cb2                               cbuffer      NA          NA    0        1
-            //
-            //
-            //
-            // Input signature:
-            //
-            // Name                 Index   Mask Register SysValue Format   Used
-            // -------------------- ----- ------ -------- -------- ------ ------
-            // SV_Position              0   xyzw        0      POS  float       
-            // TEXCOORD                 0   xy          1     NONE  float   xy  
-            // TEXCOORD                 1     zw        1     NONE  float     zw
-            //
-            //
-            // Output signature: