Merge from mozilla-central.
authorDavid Anderson <danderson@mozilla.com>
Wed, 23 May 2012 14:33:15 -0700
changeset 106253 a15a3a3b4647fa24609d08706ea35e9cd5998c52
parent 106252 abe401869582dd4746162d6dbafb54c505c197c7 (current diff)
parent 94665 320b16daa7c077157b3e51e03a11fff06d395c84 (diff)
child 106254 bc9132845c4d7480999363308b0dd3bcd3eadf99
push id1075
push uservporof@mozilla.com
push dateThu, 13 Sep 2012 10:46:49 +0000
treeherderfx-team@f39786e8364d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone15.0a1
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:
-            //
-            // 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)