Merge m-c to s-c.
authorRichard Newman <rnewman@mozilla.com>
Sun, 01 Jul 2012 11:06:36 -0700
changeset 98698 c73c500bd6e7c119aa7f2c25f81895fa63559a98
parent 98697 ea8c4810d3d5a5a2d60452143024ded37bc318fa (current diff)
parent 98091 3be950fe9e1e01703601d8da182612871cde3ebd (diff)
child 98699 d07cb07160dd75a9dd7a678dbeeb439dafd24790
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
milestone16.0a1
Merge m-c to s-c.
browser/components/nsBrowserGlue.js
dom/apps/src/Webapps.jsm
dom/browser-element/BrowserElementChild.js.orig
dom/browser-element/BrowserElementParent.js.orig
gfx/layers/basic/BasicLayers.cpp
js/src/jit-test/tests/basic/testStackIter.js
js/src/jit-test/tests/basic/testStackIterDebug.js
testing/testsuite-targets.mk
--- a/accessible/src/base/States.h
+++ b/accessible/src/base/States.h
@@ -1,10 +1,10 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:expandtab:shiftwidth=2:tabstop=2: */
+/* vim: set 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/. */
 
 #ifndef _states_h_
 #define _states_h_
 
 #include <prtypes.h>
--- a/accessible/src/base/StyleInfo.cpp
+++ b/accessible/src/base/StyleInfo.cpp
@@ -1,10 +1,10 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:expandtab:shiftwidth=2:tabstop=2: */
+/* vim: set 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 "StyleInfo.h"
 
 #include "mozilla/dom/Element.h"
 #include "nsComputedDOMStyle.h"
--- a/accessible/src/base/StyleInfo.h
+++ b/accessible/src/base/StyleInfo.h
@@ -1,10 +1,10 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:expandtab:shiftwidth=2:tabstop=2: */
+/* vim: set 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/. */
 
 #ifndef _mozilla_a11y_style_h_
 #define _mozilla_a11y_style_h_
 
 #include "mozilla/gfx/Types.h"
--- a/accessible/src/generic/ARIAGridAccessible.cpp
+++ b/accessible/src/generic/ARIAGridAccessible.cpp
@@ -233,52 +233,38 @@ ARIAGridAccessible::SelectedRowCount()
 
     if (isRowSelected)
       count++;
   }
 
   return count;
 }
 
-NS_IMETHODIMP
-ARIAGridAccessible::GetSelectedCells(nsIArray** aCells)
+void
+ARIAGridAccessible::SelectedCells(nsTArray<Accessible*>* aCells)
 {
-  NS_ENSURE_ARG_POINTER(aCells);
-  *aCells = nsnull;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  nsresult rv = NS_OK;
-  nsCOMPtr<nsIMutableArray> selCells =
-    do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
-
   AccIterator rowIter(this, filters::GetRow);
 
   Accessible* row = nsnull;
   while ((row = rowIter.Next())) {
     AccIterator cellIter(row, filters::GetCell);
     Accessible* cell = nsnull;
 
     if (nsAccUtils::IsARIASelected(row)) {
       while ((cell = cellIter.Next()))
-        selCells->AppendElement(static_cast<nsIAccessible *>(cell), false);
+        aCells->AppendElement(cell);
 
       continue;
     }
 
     while ((cell = cellIter.Next())) {
       if (nsAccUtils::IsARIASelected(cell))
-        selCells->AppendElement(static_cast<nsIAccessible *>(cell), false);
+        aCells->AppendElement(cell);
     }
   }
-
-  NS_ADDREF(*aCells = selCells);
-  return NS_OK;
 }
 
 void
 ARIAGridAccessible::SelectedCellIndices(nsTArray<PRUint32>* aCells)
 {
   PRUint32 rowCount = RowCount(), colCount = ColCount();
 
   AccIterator rowIter(this, filters::GetRow);
--- a/accessible/src/generic/ARIAGridAccessible.h
+++ b/accessible/src/generic/ARIAGridAccessible.h
@@ -43,16 +43,17 @@ public:
   virtual PRUint32 RowCount();
   virtual Accessible* CellAt(PRUint32 aRowIndex, PRUint32 aColumnIndex);
   virtual bool IsColSelected(PRUint32 aColIdx);
   virtual bool IsRowSelected(PRUint32 aRowIdx);
   virtual bool IsCellSelected(PRUint32 aRowIdx, PRUint32 aColIdx);
   virtual PRUint32 SelectedCellCount();
   virtual PRUint32 SelectedColCount();
   virtual PRUint32 SelectedRowCount();
+  virtual void SelectedCells(nsTArray<Accessible*>* aCells);
   virtual void SelectedCellIndices(nsTArray<PRUint32>* aCells);
   virtual void SelectedColIndices(nsTArray<PRUint32>* aCols);
   virtual void SelectedRowIndices(nsTArray<PRUint32>* aRows);
   virtual void SelectCol(PRUint32 aColIdx);
   virtual void SelectRow(PRUint32 aRowIdx);
   virtual void UnselectCol(PRUint32 aColIdx);
   virtual void UnselectRow(PRUint32 aRowIdx);
 
--- a/accessible/src/generic/TableAccessible.h
+++ b/accessible/src/generic/TableAccessible.h
@@ -129,17 +129,17 @@ public:
   /**
    * Return the number of selected rows.
    */
   virtual PRUint32 SelectedRowCount() { return 0; }
 
   /**
    * Get the set of selected cells.
    */
-  virtual void SelectedCells(nsTArray<Accessible*>* aCells) {}
+  virtual void SelectedCells(nsTArray<Accessible*>* aCells) = 0;
 
   /**
    * Get the set of selected cell indices.
    */
   virtual void SelectedCellIndices(nsTArray<PRUint32>* aCells) = 0;
 
   /**
    * Get the set of selected column indices.
--- a/accessible/src/html/HTMLTableAccessible.cpp
+++ b/accessible/src/html/HTMLTableAccessible.cpp
@@ -605,64 +605,47 @@ HTMLTableAccessible::SelectedRowCount()
 
   for (PRUint32 rowIdx = 0; rowIdx < rowCount; rowIdx++)
     if (IsRowSelected(rowIdx))
       count++;
 
   return count;
 }
 
-NS_IMETHODIMP
-HTMLTableAccessible::GetSelectedCells(nsIArray** aCells)
+void
+HTMLTableAccessible::SelectedCells(nsTArray<Accessible*>* aCells)
 {
-  NS_ENSURE_ARG_POINTER(aCells);
-  *aCells = nsnull;
-
-  PRInt32 rowCount = 0;
-  nsresult rv = GetRowCount(&rowCount);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  PRInt32 columnCount = 0;
-  rv = GetColumnCount(&columnCount);
-  NS_ENSURE_SUCCESS(rv, rv);
+  PRUint32 rowCount = RowCount(), colCount = ColCount();
 
   nsITableLayout *tableLayout = GetTableLayout();
-  NS_ENSURE_STATE(tableLayout);
-
-  nsCOMPtr<nsIMutableArray> selCells =
-    do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
+  if (!tableLayout) 
+    return;
 
   nsCOMPtr<nsIDOMElement> cellElement;
   PRInt32 startRowIndex = 0, startColIndex = 0,
     rowSpan, colSpan, actualRowSpan, actualColSpan;
   bool isSelected = false;
 
-  PRInt32 rowIndex, index;
-  for (rowIndex = 0, index = 0; rowIndex < rowCount; rowIndex++) {
-    PRInt32 columnIndex;
-    for (columnIndex = 0; columnIndex < columnCount; columnIndex++, index++) {
-      rv = tableLayout->GetCellDataAt(rowIndex, columnIndex,
+  for (PRUint32 rowIdx = 0; rowIdx < rowCount; rowIdx++) {
+    for (PRUint32 colIdx = 0; colIdx < colCount; colIdx++) {
+      nsresult rv = tableLayout->GetCellDataAt(rowIdx, colIdx,
                                       *getter_AddRefs(cellElement),
                                       startRowIndex, startColIndex,
                                       rowSpan, colSpan,
                                       actualRowSpan, actualColSpan,
                                       isSelected);
 
-      if (NS_SUCCEEDED(rv) && startRowIndex == rowIndex &&
-          startColIndex == columnIndex && isSelected) {
+      if (NS_SUCCEEDED(rv) && startRowIndex == rowIdx &&
+          startColIndex == colIdx && isSelected) {
         nsCOMPtr<nsIContent> cellContent(do_QueryInterface(cellElement));
         Accessible* cell = mDoc->GetAccessible(cellContent);
-        selCells->AppendElement(static_cast<nsIAccessible*>(cell), false);
+        aCells->AppendElement(cell);
       }
     }
   }
-
-  NS_ADDREF(*aCells = selCells);
-  return NS_OK;
 }
 
 void
 HTMLTableAccessible::SelectedCellIndices(nsTArray<PRUint32>* aCells)
 {
   nsITableLayout *tableLayout = GetTableLayout();
   if (!tableLayout)
     return;
--- a/accessible/src/html/HTMLTableAccessible.h
+++ b/accessible/src/html/HTMLTableAccessible.h
@@ -111,16 +111,17 @@ public:
   virtual PRUint32 ColExtentAt(PRUint32 aRowIdx, PRUint32 aColIdx);
   virtual PRUint32 RowExtentAt(PRUint32 aRowIdx, PRUint32 aColIdx);
   virtual bool IsColSelected(PRUint32 aColIdx);
   virtual bool IsRowSelected(PRUint32 aRowIdx);
   virtual bool IsCellSelected(PRUint32 aRowIdx, PRUint32 aColIdx);
   virtual PRUint32 SelectedCellCount();
   virtual PRUint32 SelectedColCount();
   virtual PRUint32 SelectedRowCount();
+  virtual void SelectedCells(nsTArray<Accessible*>* aCells);
   virtual void SelectedCellIndices(nsTArray<PRUint32>* aCells);
   virtual void SelectedColIndices(nsTArray<PRUint32>* aCols);
   virtual void SelectedRowIndices(nsTArray<PRUint32>* aRows);
   virtual void SelectCol(PRUint32 aColIdx);
   virtual void SelectRow(PRUint32 aRowIdx);
   virtual void UnselectCol(PRUint32 aColIdx);
   virtual void UnselectRow(PRUint32 aRowIdx);
   virtual bool IsProbablyLayoutTable();
--- a/accessible/src/jsat/Presenters.jsm
+++ b/accessible/src/jsat/Presenters.jsm
@@ -255,34 +255,21 @@ AndroidPresenter.prototype = {
            eventType: this.ANDROID_VIEW_HOVER_EXIT,
            text: []
          }
       });
     }
 
     let output = [];
 
-    if (isExploreByTouch) {
-      // Just provide the parent for some context, no need to utter the entire
-      // ancestry change since it doesn't make sense in spatial navigation.
-      for (var i = aContext.newAncestry.length - 1; i >= 0; i--) {
-        let utter = UtteranceGenerator.genForObject(aContext.newAncestry[i]);
-        if (utter.length) {
-          output.push.apply(output, utter);
-          break;
-        }
+    aContext.newAncestry.forEach(
+      function(acc) {
+        output.push.apply(output, UtteranceGenerator.genForObject(acc));
       }
-    } else {
-      // Utter the entire context change in linear navigation.
-      aContext.newAncestry.forEach(
-        function(acc) {
-          output.push.apply(output, UtteranceGenerator.genForObject(acc));
-        }
-      );
-    }
+    );
 
     output.push.apply(output,
                       UtteranceGenerator.genForObject(aContext.accessible));
 
     aContext.subtreePreorder.forEach(
       function(acc) {
         output.push.apply(output, UtteranceGenerator.genForObject(acc));
       }
--- a/accessible/src/jsat/UtteranceGenerator.jsm
+++ b/accessible/src/jsat/UtteranceGenerator.jsm
@@ -132,17 +132,16 @@ var UtteranceGenerator = {
     'menuitem': INCLUDE_DESC,
     'tooltip': INCLUDE_DESC,
     'application': INCLUDE_NAME,
     'document': INCLUDE_NAME,
     'grouping': INCLUDE_DESC | INCLUDE_NAME,
     'toolbar': INCLUDE_DESC,
     'table': INCLUDE_DESC | INCLUDE_NAME,
     'link': INCLUDE_DESC,
-    'list': INCLUDE_DESC,
     'listitem': INCLUDE_DESC,
     'outline': INCLUDE_DESC,
     'outlineitem': INCLUDE_DESC,
     'pagetab': INCLUDE_DESC,
     'graphic': INCLUDE_DESC,
     'pushbutton': INCLUDE_DESC,
     'checkbutton': INCLUDE_DESC,
     'radiobutton': INCLUDE_DESC,
--- a/accessible/src/xpcom/xpcAccessibleTable.cpp
+++ b/accessible/src/xpcom/xpcAccessibleTable.cpp
@@ -4,16 +4,19 @@
  * 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 "xpcAccessibleTable.h"
 
 #include "Accessible.h"
 #include "TableAccessible.h"
 
+#include "nsIMutableArray.h"
+#include "nsComponentManagerUtils.h"
+
 static const PRUint32 XPC_TABLE_DEFAULT_SIZE = 40;
 
 nsresult
 xpcAccessibleTable::GetCaption(nsIAccessible** aCaption)
 {
   NS_ENSURE_ARG_POINTER(aCaption);
   *aCaption = nsnull;
   if (!mTable)
@@ -239,16 +242,43 @@ xpcAccessibleTable::GetSelectedRowCount(
   if (!mTable)
     return NS_ERROR_FAILURE;
 
   *aSelectedRowCount = mTable->SelectedRowCount();
   return NS_OK;
 }
 
 nsresult
+xpcAccessibleTable::GetSelectedCells(nsIArray** aSelectedCells)
+{
+  NS_ENSURE_ARG_POINTER(aSelectedCells);
+  *aSelectedCells = nsnull;
+
+  if (!mTable)
+    return NS_ERROR_FAILURE;
+
+  nsresult rv = NS_OK;
+  nsCOMPtr<nsIMutableArray> selCells = 
+    do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsAutoTArray<Accessible*, XPC_TABLE_DEFAULT_SIZE> cellsArray;
+  mTable->SelectedCells(&cellsArray);
+
+  PRUint32 totalCount = cellsArray.Length();
+  for (PRUint32 idx = 0; idx < totalCount; idx++) {
+    Accessible* cell = cellsArray.ElementAt(idx);
+    selCells -> AppendElement(static_cast<nsIAccessible*>(cell), false);
+  }
+
+  NS_ADDREF(*aSelectedCells = selCells);
+  return NS_OK;
+}
+
+nsresult
 xpcAccessibleTable::GetSelectedCellIndices(PRUint32* aCellsArraySize,
                                            PRInt32** aCellsArray)
 {
   NS_ENSURE_ARG_POINTER(aCellsArraySize);
   *aCellsArraySize = 0;
 
   NS_ENSURE_ARG_POINTER(aCellsArray);
   *aCellsArray = 0;
--- a/accessible/src/xpcom/xpcAccessibleTable.h
+++ b/accessible/src/xpcom/xpcAccessibleTable.h
@@ -5,17 +5,19 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_A11Y_XPCOM_XPACCESSIBLETABLE_H_
 #define MOZILLA_A11Y_XPCOM_XPACCESSIBLETABLE_H_
 
 #include "nsAString.h"
 #include "nscore.h"
 
+
 class nsIAccessible;
+class nsIArray;
 namespace mozilla {
 namespace a11y {
 class TableAccessible;
 }
 }
 
 class xpcAccessibleTable
 {
@@ -41,16 +43,17 @@ public:
   nsresult GetColumnDescription(PRInt32 aColIdx, nsAString& aDescription);
   nsresult GetRowDescription(PRInt32 aRowIdx, nsAString& aDescription);
   nsresult IsColumnSelected(PRInt32 aColIdx, bool* _retval);
   nsresult IsRowSelected(PRInt32 aRowIdx, bool* _retval);
   nsresult IsCellSelected(PRInt32 aRowIdx, PRInt32 aColIdx, bool* _retval);
   nsresult GetSelectedCellCount(PRUint32* aSelectedCellCount);
   nsresult GetSelectedColumnCount(PRUint32* aSelectedColumnCount);
   nsresult GetSelectedRowCount(PRUint32* aSelectedRowCount);
+  nsresult GetSelectedCells(nsIArray** aSelectedCell);
   nsresult GetSelectedCellIndices(PRUint32* aCellsArraySize,
                                   PRInt32** aCellsArray);
   nsresult GetSelectedColumnIndices(PRUint32* aColsArraySize,
                                     PRInt32** aColsArray);
   nsresult GetSelectedRowIndices(PRUint32* aRowsArraySize,
                                  PRInt32** aRowsArray);
   nsresult SelectColumn(PRInt32 aColIdx);
   nsresult SelectRow(PRInt32 aRowIdx);
@@ -96,17 +99,18 @@ protected:
   NS_SCRIPTABLE NS_IMETHOD IsCellSelected(PRInt32 rowIdx, PRInt32 colIdx, bool* _retval NS_OUTPARAM) \
     { return xpcAccessibleTable::IsCellSelected(rowIdx, colIdx, _retval); } \
   NS_SCRIPTABLE NS_IMETHOD GetSelectedCellCount(PRUint32* aSelectedCellCount) \
     { return xpcAccessibleTable::GetSelectedCellCount(aSelectedCellCount); } \
   NS_SCRIPTABLE NS_IMETHOD GetSelectedColumnCount(PRUint32* aSelectedColumnCount) \
     { return xpcAccessibleTable::GetSelectedColumnCount(aSelectedColumnCount); } \
   NS_SCRIPTABLE NS_IMETHOD GetSelectedRowCount(PRUint32* aSelectedRowCount) \
     { return xpcAccessibleTable::GetSelectedRowCount(aSelectedRowCount); } \
-  NS_SCRIPTABLE NS_IMETHOD GetSelectedCells(nsIArray * *aSelectedCells); \
+  NS_SCRIPTABLE NS_IMETHOD GetSelectedCells(nsIArray** aSelectedCells) \
+    { return xpcAccessibleTable::GetSelectedCells(aSelectedCells); } \
   NS_SCRIPTABLE NS_IMETHOD GetSelectedCellIndices(PRUint32* cellsArraySize NS_OUTPARAM, \
                                                   PRInt32** cellsArray NS_OUTPARAM) \
     { return xpcAccessibleTable::GetSelectedCellIndices(cellsArraySize, cellsArray); } \
   NS_SCRIPTABLE NS_IMETHOD GetSelectedColumnIndices(PRUint32* colsArraySize NS_OUTPARAM, \
                                                     PRInt32** colsArray NS_OUTPARAM) \
     { return xpcAccessibleTable::GetSelectedColumnIndices(colsArraySize, colsArray); } \
   NS_SCRIPTABLE NS_IMETHOD GetSelectedRowIndices(PRUint32* rowsArraySize NS_OUTPARAM, \
                                                  PRInt32** rowsArray NS_OUTPARAM) \
--- a/accessible/src/xul/XULListboxAccessible.cpp
+++ b/accessible/src/xul/XULListboxAccessible.cpp
@@ -349,64 +349,48 @@ XULListboxAccessible::SelectedRowCount()
 
   PRInt32 selectedRowCount = 0;
   nsresult rv = control->GetSelectedCount(&selectedRowCount);
   NS_ENSURE_SUCCESS(rv, 0);
 
   return selectedRowCount >= 0 ? selectedRowCount : 0;
 }
 
-NS_IMETHODIMP
-XULListboxAccessible::GetSelectedCells(nsIArray** aCells)
+void
+XULListboxAccessible::SelectedCells(nsTArray<Accessible*>* aCells)
 {
-  NS_ENSURE_ARG_POINTER(aCells);
-  *aCells = nsnull;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  nsresult rv = NS_OK;
-  nsCOMPtr<nsIMutableArray> selCells =
-    do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
-
   nsCOMPtr<nsIDOMXULMultiSelectControlElement> control =
     do_QueryInterface(mContent);
   NS_ASSERTION(control,
                "Doesn't implement nsIDOMXULMultiSelectControlElement.");
 
   nsCOMPtr<nsIDOMNodeList> selectedItems;
   control->GetSelectedItems(getter_AddRefs(selectedItems));
   if (!selectedItems)
-    return NS_OK;
+    return;
 
   PRUint32 selectedItemsCount = 0;
-  rv = selectedItems->GetLength(&selectedItemsCount);
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsresult rv = selectedItems->GetLength(&selectedItemsCount);
+  NS_ASSERTION(NS_SUCCEEDED(rv), "GetLength() Shouldn't fail!");
 
-  NS_ENSURE_TRUE(mDoc, NS_ERROR_FAILURE);
-  PRUint32 index = 0;
-  for (; index < selectedItemsCount; index++) {
+  for (PRUint32 index = 0; index < selectedItemsCount; index++) {
     nsCOMPtr<nsIDOMNode> itemNode;
     selectedItems->Item(index, getter_AddRefs(itemNode));
     nsCOMPtr<nsIContent> itemContent(do_QueryInterface(itemNode));
     Accessible* item = mDoc->GetAccessible(itemContent);
 
     if (item) {
       PRUint32 cellCount = item->ChildCount();
       for (PRUint32 cellIdx = 0; cellIdx < cellCount; cellIdx++) {
         Accessible* cell = mChildren[cellIdx];
         if (cell->Role() == roles::CELL)
-          selCells->AppendElement(static_cast<nsIAccessible*>(cell), false);
+          aCells->AppendElement(cell);
       }
     }
   }
-
-  NS_ADDREF(*aCells = selCells);
-  return NS_OK;
 }
 
 void
 XULListboxAccessible::SelectedCellIndices(nsTArray<PRUint32>* aCells)
 {
   nsCOMPtr<nsIDOMXULMultiSelectControlElement> control =
     do_QueryInterface(mContent);
   NS_ASSERTION(control,
--- a/accessible/src/xul/XULListboxAccessible.h
+++ b/accessible/src/xul/XULListboxAccessible.h
@@ -77,16 +77,17 @@ public:
   virtual PRUint32 RowCount();
   virtual Accessible* CellAt(PRUint32 aRowIndex, PRUint32 aColumnIndex);
   virtual bool IsColSelected(PRUint32 aColIdx);
   virtual bool IsRowSelected(PRUint32 aRowIdx);
   virtual bool IsCellSelected(PRUint32 aRowIdx, PRUint32 aColIdx);
   virtual PRUint32 SelectedCellCount();
   virtual PRUint32 SelectedColCount();
   virtual PRUint32 SelectedRowCount();
+  virtual void SelectedCells(nsTArray<Accessible*>* aCells);
   virtual void SelectedCellIndices(nsTArray<PRUint32>* aCells);
   virtual void SelectedColIndices(nsTArray<PRUint32>* aCols);
   virtual void SelectedRowIndices(nsTArray<PRUint32>* aRows);
   virtual void SelectRow(PRUint32 aRowIdx);
   virtual void UnselectRow(PRUint32 aRowIdx);
 
   // nsAccessNode
   virtual void Shutdown();
--- a/accessible/src/xul/XULTreeGridAccessible.cpp
+++ b/accessible/src/xul/XULTreeGridAccessible.cpp
@@ -80,58 +80,29 @@ XULTreeGridAccessible::SelectedRowCount(
 {
   PRInt32 selectedRowCount = 0;
   nsresult rv = GetSelectionCount(&selectedRowCount);
   NS_ENSURE_SUCCESS(rv, 0);
 
   return selectedRowCount >= 0 ? selectedRowCount : 0;
 }
 
-NS_IMETHODIMP
-XULTreeGridAccessible::GetSelectedCells(nsIArray** aCells)
+void
+XULTreeGridAccessible::SelectedCells(nsTArray<Accessible*>* aCells)
 {
-  NS_ENSURE_ARG_POINTER(aCells);
-  *aCells = nsnull;
-
-  if (!mTreeView)
-    return NS_OK;
-
-  nsCOMPtr<nsIMutableArray> selCells = do_CreateInstance(NS_ARRAY_CONTRACTID);
-  NS_ENSURE_TRUE(selCells, NS_ERROR_FAILURE);
-
-  PRInt32 selectedrowCount = 0;
-  nsresult rv = GetSelectionCount(&selectedrowCount);
-  NS_ENSURE_SUCCESS(rv, rv);
+  PRUint32 colCount = ColCount(), rowCount = RowCount();
 
-  PRInt32 columnCount = 0;
-  rv = GetColumnCount(&columnCount);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<nsITreeSelection> selection;
-  rv = mTreeView->GetSelection(getter_AddRefs(selection));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  PRInt32 rowCount = 0;
-  rv = GetRowCount(&rowCount);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  bool isSelected;
-  for (PRInt32 rowIdx = 0; rowIdx < rowCount; rowIdx++) {
-    selection->IsSelected(rowIdx, &isSelected);
-    if (isSelected) {
-      for (PRInt32 colIdx = 0; colIdx < columnCount; colIdx++) {
-        nsCOMPtr<nsIAccessible> cell;
-        GetCellAt(rowIdx, colIdx, getter_AddRefs(cell));
-        selCells->AppendElement(cell, false);
+  for (PRUint32 rowIdx = 0; rowIdx < rowCount; rowIdx++) {
+    if (IsRowSelected(rowIdx)) {
+      for (PRUint32 colIdx = 0; colIdx < colCount; colIdx++) {
+        Accessible* cell = CellAt(rowIdx, colIdx);
+        aCells->AppendElement(cell);
       }
     }
   }
-
-  NS_ADDREF(*aCells = selCells);
-  return NS_OK;
 }
 
 void
 XULTreeGridAccessible::SelectedCellIndices(nsTArray<PRUint32>* aCells)
 {
   PRUint32 colCount = ColCount(), rowCount = RowCount();
 
   for (PRUint32 rowIdx = 0; rowIdx < rowCount; rowIdx++)
--- a/accessible/src/xul/XULTreeGridAccessible.h
+++ b/accessible/src/xul/XULTreeGridAccessible.h
@@ -36,16 +36,17 @@ public:
   virtual Accessible* CellAt(PRUint32 aRowIndex, PRUint32 aColumnIndex);
   virtual void ColDescription(PRUint32 aColIdx, nsString& aDescription);
   virtual bool IsColSelected(PRUint32 aColIdx);
   virtual bool IsRowSelected(PRUint32 aRowIdx);
   virtual bool IsCellSelected(PRUint32 aRowIdx, PRUint32 aColIdx);
   virtual PRUint32 SelectedCellCount();
   virtual PRUint32 SelectedColCount();
   virtual PRUint32 SelectedRowCount();
+  virtual void SelectedCells(nsTArray<Accessible*>* aCells);
   virtual void SelectedCellIndices(nsTArray<PRUint32>* aCells);
   virtual void SelectedColIndices(nsTArray<PRUint32>* aCols);
   virtual void SelectedRowIndices(nsTArray<PRUint32>* aRows);
   virtual void SelectRow(PRUint32 aRowIdx);
   virtual void UnselectRow(PRUint32 aRowIdx);
 
   // nsAccessNode
   virtual void Shutdown();
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -18,20 +18,16 @@ Cu.import('resource://gre/modules/Webapp
 XPCOMUtils.defineLazyServiceGetter(Services, 'env',
                                    '@mozilla.org/process/environment;1',
                                    'nsIEnvironment');
 
 XPCOMUtils.defineLazyServiceGetter(Services, 'ss',
                                    '@mozilla.org/content/style-sheet-service;1',
                                    'nsIStyleSheetService');
 
-XPCOMUtils.defineLazyServiceGetter(Services, 'idle',
-                                   '@mozilla.org/widget/idleservice;1',
-                                   'nsIIdleService');
-
 #ifdef MOZ_WIDGET_GONK
 XPCOMUtils.defineLazyServiceGetter(Services, 'audioManager',
                                    '@mozilla.org/telephony/audiomanager;1',
                                    'nsIAudioManager');
 #else
 Services.audioManager = {
   'masterVolume': 0
 };
@@ -169,17 +165,17 @@ var shell = {
     window.removeEventListener('mozfullscreenchange', this);
     window.removeEventListener('sizemodechange', this);
     this.contentBrowser.removeEventListener('mozbrowserloadstart', this, true);
 
 #ifndef MOZ_WIDGET_GONK
     delete Services.audioManager;
 #endif
   },
- 
+
   changeVolume: function shell_changeVolume(delta) {
     let steps = 10;
     try {
       steps = Services.prefs.getIntPref("media.volume.steps");
       if (steps <= 0)
         steps = 1;
     } catch(e) {}
 
@@ -430,32 +426,33 @@ var AlertsHelper = {
   },
 
   registerListener: function alert_registerListener(cookie, alertListener) {
     let id = "alert" + this._count++;
     this._listeners[id] = { observer: alertListener, cookie: cookie };
     return id;
   },
 
-  showAlertNotification: function alert_showAlertNotification(imageUrl, title, text, textClickable, 
+  showAlertNotification: function alert_showAlertNotification(imageUrl, title, text, textClickable,
                                                               cookie, alertListener, name) {
     let id = this.registerListener(cookie, alertListener);
     let content = shell.contentBrowser.contentWindow;
-    shell.sendEvent(content, "mozChromeEvent", { type: "desktop-notification", id: id, icon: imageUrl, 
+    shell.sendEvent(content, "mozChromeEvent", { type: "desktop-notification", id: id, icon: imageUrl,
                                                  title: title, text: text } );
   }
 }
 
 var WebappsHelper = {
   _installers: {},
   _count: 0,
 
   init: function webapps_init() {
     Services.obs.addObserver(this, "webapps-launch", false);
     Services.obs.addObserver(this, "webapps-ask-install", false);
+    DOMApplicationRegistry.allAppsLaunchable = true;
   },
 
   registerInstaller: function webapps_registerInstaller(data) {
     let id = "installer" + this._count++;
     this._installers[id] = data;
     return id;
   },
 
@@ -516,86 +513,16 @@ function startDebugger() {
 }
 
 window.addEventListener('ContentStart', function(evt) {
   if (Services.prefs.getBoolPref('devtools.debugger.remote-enabled')) {
     startDebugger();
   }
 });
 
-(function PowerManager() {
-  // This will eventually be moved to content, so use content API as
-  // much as possible here. TODO: Bug 738530
-  let power = navigator.mozPower;
-  let idleHandler = function idleHandler(subject, topic, time) {
-    if (topic !== 'idle')
-      return;
-
-    if (power.getWakeLockState("screen") != "locked-foreground") {
-      navigator.mozPower.screenEnabled = false;
-    }
-  }
-
-  let wakeLockHandler = function(topic, state) {
-    // Turn off the screen when no one needs the it or all of them are
-    // invisible, otherwise turn the screen on. Note that the CPU
-    // might go to sleep as soon as the screen is turned off and
-    // acquiring wake lock will not bring it back (actually the code
-    // is not executed at all).
-    if (topic === 'screen') {
-      if (state != "locked-foreground") {
-        if (Services.idle.idleTime > idleTimeout*1000) {
-          navigator.mozPower.screenEnabled = false;
-        }
-      } else {
-        navigator.mozPower.screenEnabled = true;
-      }
-    } else if (topic == 'cpu') {
-      navigator.mozPower.cpuSleepAllowed = (state != 'locked-foreground' &&
-                                            state != 'locked-background');
-    }
-  }
-
-  let idleTimeout = Services.prefs.getIntPref('power.screen.timeout');
-  if (!('mozSettings' in navigator))
-    return;
-
-  let request = navigator.mozSettings.getLock().get('power.screen.timeout');
-  request.onsuccess = function onSuccess() {
-    idleTimeout = request.result['power.screen.timeout'] || idleTimeout;
-    if (!idleTimeout)
-      return;
-
-    Services.idle.addIdleObserver(idleHandler, idleTimeout);
-    power.addWakeLockListener(wakeLockHandler);
-  };
-
-  request.onerror = function onError() {
-    if (!idleTimeout)
-      return;
-
-    Services.idle.addIdleObserver(idleHandler, idleTimeout);
-    power.addWakeLockListener(wakeLockHandler);
-  };
-
-  SettingsListener.observe('power.screen.timeout', idleTimeout, function(value) {
-    if (!value)
-      return;
-
-    Services.idle.removeIdleObserver(idleHandler, idleTimeout);
-    idleTimeout = value;
-    Services.idle.addIdleObserver(idleHandler, idleTimeout);
-  });
-
-  window.addEventListener('unload', function removeIdleObjects() {
-    Services.idle.removeIdleObserver(idleHandler, idleTimeout);
-    power.removeWakeLockListener(wakeLockHandler);
-  });
-})();
-
 // This is the backend for Gaia's screenshot feature.  Gaia requests a
 // screenshot by sending a mozContentEvent with detail.type set to
 // 'take-screenshot'.  Then we take a screenshot and send a
 // mozChromeEvent with detail.type set to 'take-screenshot-success'
 // and detail.file set to the an image/png blob
 window.addEventListener('ContentStart', function ss_onContentStart() {
   let content = shell.contentBrowser.contentWindow;
   content.addEventListener('mozContentEvent', function ss_onMozContentEvent(e) {
--- a/browser/app/blocklist.xml
+++ b/browser/app/blocklist.xml
@@ -1,10 +1,10 @@
 <?xml version="1.0"?>
-<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1340295852000">
+<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1341001222000">
   <emItems>
       <emItem  blockID="i58" id="webmaster@buzzzzvideos.info">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i86" id="{45147e67-4020-47e2-8f7a-55464fb535aa}">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
@@ -202,16 +202,20 @@
       <emItem  blockID="i42" id="{D19CA586-DD6C-4a0a-96F8-14644F340D60}">
                         <versionRange  minVersion="0.1" maxVersion="14.4.0" severity="1">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i67" id="youtube2@youtube2.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
+      <emItem  blockID="i109" id="{392e123b-b691-4a5e-b52f-c4c1027e749c}">
+                        <versionRange  minVersion="0" maxVersion="*">
+                    </versionRange>
+                  </emItem>
       <emItem  blockID="i60" id="youtb3@youtb3.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                   </emItem>
       <emItem  blockID="i38" id="{B7082FAA-CB62-4872-9106-E42DD88EDE45}">
                         <versionRange  minVersion="0.1" maxVersion="3.3.0.*">
                       <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="3.7a1" maxVersion="*" />
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1093,17 +1093,17 @@ pref("devtools.gcli.allowSet", false);
 // Console will use the default height next time it shows.
 // Change to -1 if you do not want the Web Console to remember its last height.
 pref("devtools.hud.height", 0);
 
 // Remember the Web Console position. Possible values:
 //   above - above the web page,
 //   below - below the web page,
 //   window - in a separate window/popup panel.
-pref("devtools.webconsole.position", "above");
+pref("devtools.webconsole.position", "below");
 
 // Remember the Web Console filters
 pref("devtools.webconsole.filter.network", true);
 pref("devtools.webconsole.filter.networkinfo", true);
 pref("devtools.webconsole.filter.csserror", true);
 pref("devtools.webconsole.filter.cssparser", true);
 pref("devtools.webconsole.filter.exception", true);
 pref("devtools.webconsole.filter.jswarn", true);
--- a/browser/base/content/browser-tabview.js
+++ b/browser/base/content/browser-tabview.js
@@ -287,17 +287,18 @@ let TabView = {
     this._initFrame(function() {
       let activeGroup = tab._tabViewTabItem.parent;
       let groupItems = self._window.GroupItems.groupItems;
 
       groupItems.forEach(function(groupItem) {
         // if group has title, it's not hidden and there is no active group or
         // the active group id doesn't match the group id, a group menu item
         // would be added.
-        if (!groupItem.hidden && groupItem.getChildren().length &&
+        if (!groupItem.hidden &&
+            (groupItem.getTitle().trim() || groupItem.getChildren().length) &&
             (!activeGroup || activeGroup.id != groupItem.id)) {
           let menuItem = self._createGroupMenuItem(groupItem);
           popup.insertBefore(menuItem, separator);
           isEmpty = false;
         }
       });
       separator.hidden = isEmpty;
     });
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -459,17 +459,16 @@
                  autocompletesearch="urlinline history"
                  autocompletesearchparam="enable-actions"
                  autocompletepopup="PopupAutoCompleteRichResult"
                  completeselectedindex="true"
                  tabscrolling="true"
                  showcommentcolumn="true"
                  showimagecolumn="true"
                  enablehistory="true"
-                 maxrows="6"
                  newlines="stripsurroundingwhitespace"
                  oninput="gBrowser.userTypedValue = this.value;"
                  ontextentered="this.handleCommand(param);"
                  ontextreverted="return this.handleRevert();"
                  pageproxystate="invalid"
                  onfocus="document.getElementById('identity-box').style.MozUserFocus= 'normal'"
                  onblur="setTimeout(function() document.getElementById('identity-box').style.MozUserFocus = '', 0);">
           <box id="notification-popup-box" hidden="true" align="center">
--- a/browser/base/content/pageinfo/pageInfo.xul
+++ b/browser/base/content/pageinfo/pageInfo.xul
@@ -349,27 +349,32 @@
               <radio id="geo#2" command="cmd_geoToggle" label="&permBlock;"/>
             </radiogroup>
           </hbox>
         </vbox>
         <vbox class="permission">
           <label class="permissionLabel" id="permIndexedDBLabel"
                  value="&permIndexedDB;" control="indexedDBRadioGroup"/>
           <hbox role="group" aria-labelledby="permIndexedDBLabel">
-            <checkbox id="indexedDBDef" command="cmd_indexedDBDef" label="&permAskAlways;"/>
+            <checkbox id="indexedDBDef" command="cmd_indexedDBDef" label="&permUseDefault;"/>
+            <spacer flex="1"/>
+            <radiogroup id="indexedDBRadioGroup" orient="horizontal">
+              <!-- Ask and Allow are purposefully reversed here! -->
+              <radio id="indexedDB#1" command="cmd_indexedDBToggle" label="&permAskAlways;"/>
+              <radio id="indexedDB#0" command="cmd_indexedDBToggle" label="&permAllow;"/>
+              <radio id="indexedDB#2" command="cmd_indexedDBToggle" label="&permBlock;"/>
+            </radiogroup>
+          </hbox>
+          <hbox>
             <spacer flex="1"/>
             <vbox pack="center">
-              <label id="indexedDBStatus" control="indexedDBClear"/>
+              <label id="indexedDBStatus" control="indexedDBClear" hidden="true"/>
             </vbox>
-            <button id="indexedDBClear" label="&permClearStorage;"
+            <button id="indexedDBClear" label="&permClearStorage;" hidden="true"
                     accesskey="&permClearStorage.accesskey;" onclick="onIndexedDBClear();"/>
-            <radiogroup id="indexedDBRadioGroup" orient="horizontal">
-              <radio id="indexedDB#1" command="cmd_indexedDBToggle" label="&permAllow;"/>
-              <radio id="indexedDB#2" command="cmd_indexedDBToggle" label="&permBlock;"/>
-            </radiogroup>
           </hbox>
         </vbox>
         <vbox class="permission" id="permPluginsRow">
           <label class="permissionLabel" id="permPluginsLabel"
                  value="&permPlugins;" control="pluginsRadioGroup"/>
           <hbox role="group" aria-labelledby="permPluginsLabel">
             <checkbox id="pluginsDef" command="cmd_pluginsDef" label="&permAskAlways;"/>
             <spacer flex="1"/>
--- a/browser/base/content/pageinfo/permissions.js
+++ b/browser/base/content/pageinfo/permissions.js
@@ -46,17 +46,17 @@ var gPermObj = {
     return BLOCK;
   },
   geo: function getGeoDefaultPermissions()
   {
     return BLOCK;
   },
   indexedDB: function getIndexedDBDefaultPermissions()
   {
-    return BLOCK;
+    return UNKNOWN;
   },
   plugins: function getPluginsDefaultPermissions()
   {
     if (gPrefs.getBoolPref("plugins.click_to_play"))
       return BLOCK;
     return ALLOW;
   },
   fullscreen: function getFullscreenDefaultPermissions()
@@ -144,19 +144,16 @@ function onCheckboxClick(aPartId)
 {
   var permissionManager = Components.classes[PERMISSION_CONTRACTID]
                                     .getService(nsIPermissionManager);
 
   var command  = document.getElementById("cmd_" + aPartId + "Toggle");
   var checkbox = document.getElementById(aPartId + "Def");
   if (checkbox.checked) {
     permissionManager.remove(gPermURI.host, aPartId);
-    if (aPartId == "indexedDB") {
-      permissionManager.remove(gPermURI.host, "indexedDB-unlimited");
-    }
     command.setAttribute("disabled", "true");
     var perm = gPermObj[aPartId]();
     setRadioState(aPartId, perm);
   }
   else {
     onRadioClick(aPartId);
     command.removeAttribute("disabled");
   }
@@ -166,17 +163,18 @@ function onRadioClick(aPartId)
 {
   var permissionManager = Components.classes[PERMISSION_CONTRACTID]
                                     .getService(nsIPermissionManager);
 
   var radioGroup = document.getElementById(aPartId + "RadioGroup");
   var id = radioGroup.selectedItem.id;
   var permission = id.split('#')[1];
   permissionManager.add(gPermURI, aPartId, permission);
-  if (aPartId == "indexedDB" && permission == BLOCK) {
+  if (aPartId == "indexedDB" &&
+      (permission == ALLOW || permission == BLOCK)) {
     permissionManager.remove(gPermURI.host, "indexedDB-unlimited");
   }
   if (aPartId == "fullscreen" && permission == UNKNOWN) {
     permissionManager.remove(gPermURI.host, "fullscreen");
   }  
 }
 
 function setRadioState(aPartId, aValue)
@@ -202,17 +200,16 @@ function initIndexedDBRow()
 function onIndexedDBClear()
 {
   Components.classes["@mozilla.org/dom/indexeddb/manager;1"]
             .getService(nsIIndexedDatabaseManager)
             .clearDatabasesForURI(gPermURI);
 
   var permissionManager = Components.classes[PERMISSION_CONTRACTID]
                                     .getService(nsIPermissionManager);
-  permissionManager.remove(gPermURI.host, "indexedDB");
   permissionManager.remove(gPermURI.host, "indexedDB-unlimited");
   initIndexedDBRow();
 }
 
 function onIndexedDBUsageCallback(uri, usage, fileUsage)
 {
   if (!uri.equals(gPermURI)) {
     throw new Error("Callback received for bad URI: " + uri);
--- a/browser/base/content/test/newtab/browser_newtab_bug735987.js
+++ b/browser/base/content/test/newtab/browser_newtab_bug735987.js
@@ -12,11 +12,15 @@ function runTests() {
   checkGrid("0,99p,1,2,3,4,5,6,7");
 
   yield blockCell(1);
   checkGrid("0,1,2,3,4,5,6,7,8");
 
   yield simulateDrop(1);
   checkGrid("0,99p,1,2,3,4,5,6,7");
 
+  NewTabUtils.blockedLinks.resetCache();
+  yield addNewTabPageTab();
+  checkGrid("0,99p,1,2,3,4,5,6,7");
+
   yield blockCell(1);
   checkGrid("0,1,2,3,4,5,6,7,8");
 }
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -620,16 +620,18 @@
             case "underflow":
               this._contentIsCropped = false;
               this._hideURLTooltip();
               break;
           }
         ]]></body>
       </method>
 
+      <property name="maxRows" onget="return this.popup.maxResults;"/>
+
       <property name="textValue"
                 onget="return this.value;">
         <setter>
           <![CDATA[
           try {
             val = losslessDecodeURI(makeURI(val));
           } catch (ex) { }
 
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -1590,17 +1590,17 @@ ContentPermissionPrompt.prototype = {
       return chromeWin;
     }
 
     var browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
 
     var mainAction = {
       label: browserBundle.GetStringFromName("geolocation.shareLocation"),
       accessKey: browserBundle.GetStringFromName("geolocation.shareLocation.accesskey"),
-      callback: function(notification) {
+      callback: function() {
         request.allow();
       },
     };
 
     var message;
     var secondaryActions = [];
     var requestingWindow = request.window.top;
     var chromeWin = getChromeWindow(requestingWindow).wrappedJSObject;
--- a/browser/components/tabview/content.js
+++ b/browser/components/tabview/content.js
@@ -36,17 +36,19 @@ let WindowEventHandler = {
     sendSyncMessage("Panorama:DOMWillOpenModalDialog");
   },
 
   // ----------
   // Function: onMozAfterPaint
   // Sends an asynchronous message when the "onMozAfterPaint" event
   // is fired.
   onMozAfterPaint: function WEH_onMozAfterPaint(event) {
-    sendAsyncMessage("Panorama:MozAfterPaint");
+    if (event.clientRects.length > 0) {
+      sendAsyncMessage("Panorama:MozAfterPaint");
+    }
   }
 };
 
 // add event listeners
 addEventListener("DOMWillOpenModalDialog", WindowEventHandler.onDOMWillOpenModalDialog, false);
 addEventListener("MozAfterPaint", WindowEventHandler.onMozAfterPaint, false);
 
 // ----------
--- a/browser/components/tabview/tabview.js
+++ b/browser/components/tabview/tabview.js
@@ -24,19 +24,16 @@ XPCOMUtils.defineLazyGetter(this, "tabbr
 
 function tabviewString(name) tabviewBundle.GetStringFromName('tabview.' + name);
 function tabbrowserString(name) tabbrowserBundle.GetStringFromName(name);
 
 XPCOMUtils.defineLazyGetter(this, "gPrefBranch", function() {
   return Services.prefs.getBranch("browser.panorama.");
 });
 
-XPCOMUtils.defineLazyServiceGetter(this, "gPrivateBrowsing",
-  "@mozilla.org/privatebrowsing;1", "nsIPrivateBrowsingService");
-
 XPCOMUtils.defineLazyModuleGetter(this, "gPageThumbnails",
   "resource:///modules/PageThumbs.jsm", "PageThumbs");
 
 var gWindow = window.parent;
 var gBrowser = gWindow.gBrowser;
 var gTabView = gWindow.TabView;
 var gTabViewDeck = gWindow.document.getElementById("tab-view-deck");
 var gBrowserPanel = gWindow.document.getElementById("browser-panel");
--- a/browser/components/tabview/telemetry.js
+++ b/browser/components/tabview/telemetry.js
@@ -51,13 +51,13 @@ let Telemetry = {
     addTelemetryValue("STACKED_GROUPS_COUNT", stackedGroupsCount);
     addTelemetryValue("MEDIAN_TABS_IN_GROUPS_COUNT", median(childCounts));
   },
 
   /**
    * Observes for gather telemetry topic.
    */
   observe: function Telemetry_observe(aSubject, aTopic, aData) {
-    if (!gPrivateBrowsing.privateBrowsingEnabled)
+    if (!("gPrivateBrowsingUI" in gWindow) || !gWindow.gPrivateBrowsingUI.privateWindow)
       this._collect();
   }
 }
 
--- a/browser/components/tabview/test/Makefile.in
+++ b/browser/components/tabview/test/Makefile.in
@@ -137,16 +137,17 @@ include $(topsrcdir)/config/rules.mk
                  browser_tabview_bug706736.js \
                  browser_tabview_bug707466.js \
                  browser_tabview_bug712203.js \
                  browser_tabview_bug715454.js \
                  browser_tabview_bug716880.js \
                  browser_tabview_bug728887.js \
                  browser_tabview_bug733115.js \
                  browser_tabview_bug749658.js \
+                 browser_tabview_bug766597.js \
                  browser_tabview_click_group.js \
                  browser_tabview_dragdrop.js \
                  browser_tabview_exit_button.js \
                  browser_tabview_expander.js \
                  browser_tabview_firstrun_pref.js \
                  browser_tabview_group.js \
                  browser_tabview_launch.js \
                  browser_tabview_multiwindow_search.js \
new file mode 100644
--- /dev/null
+++ b/browser/components/tabview/test/browser_tabview_bug766597.js
@@ -0,0 +1,61 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function test() {
+  waitForExplicitFinish();
+
+  let tContextMenu = document.getElementById("tabContextMenu");
+  let tvMenuPopup = document.getElementById("context_tabViewMenuPopup");
+  let group1;
+  let group2;
+
+  function openMoveToGroupPopup() {
+    let tab = gBrowser.selectedTab;
+    let tvMenu = document.getElementById("context_tabViewMenu");
+    let tvMenuPopup = document.getElementById("context_tabViewMenuPopup");
+    let tvEvent = new Event("");
+
+    tab.dispatchEvent(tvEvent);
+    tContextMenu.openPopup(tab, "end_after", 0, 0, true, false, tvEvent);
+    tvMenuPopup.openPopup(tvMenu, "end_after", 0, 0, true, false);
+  }
+
+  function hideMoveToGroupPopup() {
+    tvMenuPopup.hidePopup();
+    tContextMenu.hidePopup();
+  }
+
+  function createGroups() {
+    let cw = TabView.getContentWindow();
+
+    group1 = createGroupItemWithTabs(window, 200, 200, 20, ["about:blank"]);
+    group1.setTitle("group with items and title");
+    group2 = createEmptyGroupItem(cw, 200, 200, 20);
+    cw.UI.setActive(cw.GroupItems.groupItems[0]);
+
+    // Check the group count.
+    is(cw.GroupItems.groupItems.length, 3, "Validate group count in tab view.");
+
+    hideTabView(checkGroupMenuItems);
+  }
+
+  // The group count includes the separator and the 'new group' menu item.
+  function checkGroupMenuItems() {
+    // First test with an empty untitled group.
+    openMoveToGroupPopup();
+    is(tvMenuPopup.childNodes.length, 3, "Validate group item count in move to group popup.");
+    hideMoveToGroupPopup();
+
+    // Then test with an empty but titled group.
+    group2.setTitle("empty group with title");
+    openMoveToGroupPopup();
+    is(tvMenuPopup.childNodes.length, 4, "Validate group item count in move to group popup.");
+    hideMoveToGroupPopup();
+
+    // Clean 
+    closeGroupItem(group1, function() { closeGroupItem(group2, finish); });
+  }
+
+  showTabView(createGroups);
+}
+
--- a/browser/config/tooltool-manifests/linux32/clang.manifest
+++ b/browser/config/tooltool-manifests/linux32/clang.manifest
@@ -1,15 +1,15 @@
 [
-{"clang_version": "r159219"},
+{"clang_version": "r159409"},
 {
 "size": 47,
 "digest": "2005a41fe97a5e00997063705f39d42b6a43b1cf7ba306cbc7b1513de34cdcd050fc6326efa2107f19ba0cc67914745dbf13154fa748010a93cf072481ef4aaa",
 "algorithm": "sha512",
 "filename": "setup.sh"
 },
 {
-"size": 73555568,
-"digest": "29102005216bfd719561ce1920f4cddd3c34c5581ed4cebc3abdc30d8d3f2b4705344cd4a2571ac05b11ff35fc1e0a9584568de89cc19ba6599311adccf5397b",
+"size": 74004324,
+"digest": "c5bb558a5958458b11da385d57897a1f7e57a7be2f452438f6813cf1e9f2a4ce93769c36e304126f97dbd753732b70446c7fa3c779267e80152d7ac0175057fc",
 "algorithm": "sha512",
 "filename": "clang.tar.bz2"
 }
 ]
--- a/browser/config/tooltool-manifests/linux64/clang.manifest
+++ b/browser/config/tooltool-manifests/linux64/clang.manifest
@@ -1,15 +1,15 @@
 [
-{"clang_version": "r159219"},
+{"clang_version": "r159409"},
 {
 "size": 47,
 "digest": "2005a41fe97a5e00997063705f39d42b6a43b1cf7ba306cbc7b1513de34cdcd050fc6326efa2107f19ba0cc67914745dbf13154fa748010a93cf072481ef4aaa",
 "algorithm": "sha512",
 "filename": "setup.sh"
 },
 {
-"size": 72267837,
-"digest": "15d0f9e3f1c897d06a7808edb931cdd23d82b38d271454e52740e23bd890338e204857bc87bfe3dde242fa62b38e01f15c19b814cab55e84874f0c6c5b4187e8",
+"size": 72533541,
+"digest": "f092080caed28db1ed7d9f0612aef1d885d2587b4e069d3662af5c241950ee772b6bc249d766a47b4fe2c170a46cfe05010269a3cbc1123d1f4126bc182b7b40",
 "algorithm": "sha512",
 "filename": "clang.tar.bz2"
 }
 ]
--- a/browser/config/tooltool-manifests/macosx64/clang.manifest
+++ b/browser/config/tooltool-manifests/macosx64/clang.manifest
@@ -1,15 +1,15 @@
 [
-{"clang_version": "r159219"},
+{"clang_version": "r159409"},
 {
 "size": 47,
 "digest": "2005a41fe97a5e00997063705f39d42b6a43b1cf7ba306cbc7b1513de34cdcd050fc6326efa2107f19ba0cc67914745dbf13154fa748010a93cf072481ef4aaa",
 "algorithm": "sha512",
 "filename": "setup.sh"
 },
 {
-"size": 63318129,
-"digest": "cf1dbc9221ff5f751ef9b8a3b93106585eb0955e648429359feb14a02892774538f7a19d0cf949b26549dae933a9a56dbb138e3cb2d1a883e6bfc47de27c16bb",
+"size": 63604770,
+"digest": "c664beadb01a4e8ba7f32698b3ef694ade9044a9117d90d57f1475f2cefea82d74d1b0f3da89dcb9932ba90e048ae3d908bff05ab09d0ce2c82731e949e62a47",
 "algorithm": "sha512",
 "filename": "clang.tar.bz2"
 }
 ]
--- a/browser/devtools/commandline/gcli.jsm
+++ b/browser/devtools/commandline/gcli.jsm
@@ -1,12 +1,22 @@
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 "use strict";
 
 /**
  * DO NOT MODIFY THIS FILE DIRECTLY.
  * This file is generated from separate files stored in the GCLI project.
  * Please modify the files there and use the import script so the 2 projects
@@ -16,19 +26,29 @@
 
 var EXPORTED_SYMBOLS = [ "gcli" ];
 
 Components.utils.import("resource:///modules/devtools/Require.jsm");
 Components.utils.import("resource:///modules/devtools/Console.jsm");
 Components.utils.import("resource:///modules/devtools/Browser.jsm");
 
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 var mozl10n = {};
 
 (function(aMozl10n) {
   var temp = {};
   Components.utils.import("resource://gre/modules/Services.jsm", temp);
   var stringBundle = temp.Services.strings.createBundle(
@@ -108,19 +128,29 @@ define('gcli/index', ['require', 'export
    */
   exports.createDisplay = function(opts) {
     var FFDisplay = require('gcli/ui/ffdisplay').FFDisplay;
     return new FFDisplay(opts);
   };
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gcli/types/basic', ['require', 'exports', 'module' , 'gcli/l10n', 'gcli/types', 'gcli/types/spell', 'gcli/types/selection', 'gcli/argument'], function(require, exports, module) {
 
 
 var l10n = require('gcli/l10n');
 var types = require('gcli/types');
 var Type = require('gcli/types').Type;
@@ -468,19 +498,29 @@ ArrayType.prototype.getBlank = function(
 
 ArrayType.prototype.name = 'array';
 
 exports.ArrayType = ArrayType;
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gcli/l10n', ['require', 'exports', 'module' ], function(require, exports, module) {
 
 Components.utils.import('resource://gre/modules/XPCOMUtils.jsm');
 Components.utils.import('resource://gre/modules/Services.jsm');
 
 var imports = {};
@@ -548,19 +588,29 @@ exports.lookupFormat = function(key, swa
     console.error('Failed to format ', key, ex);
     return key;
   }
 };
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gcli/types', ['require', 'exports', 'module' , 'gcli/argument'], function(require, exports, module) {
 var types = exports;
 
 
 var Argument = require('gcli/argument').Argument;
 
@@ -1050,19 +1100,29 @@ types.getType = function(typeSpec) {
   }
 
   throw new Error('Can\'t extract type from ' + typeSpec);
 };
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gcli/argument', ['require', 'exports', 'module' ], function(require, exports, module) {
 var argument = exports;
 
 
 /**
  * We record where in the input string an argument comes so we can report
@@ -1662,19 +1722,29 @@ Speller.prototype._edits = function(word
   return results;
 };
 
 exports.Speller = Speller;
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gcli/types/selection', ['require', 'exports', 'module' , 'gcli/l10n', 'gcli/types', 'gcli/types/spell'], function(require, exports, module) {
 
 
 var l10n = require('gcli/l10n');
 var types = require('gcli/types');
 var Type = require('gcli/types').Type;
@@ -1955,19 +2025,29 @@ SelectionType.prototype._findValue = fun
 
 SelectionType.prototype.name = 'selection';
 
 exports.SelectionType = SelectionType;
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gcli/types/command', ['require', 'exports', 'module' , 'gcli/canon', 'gcli/l10n', 'gcli/types', 'gcli/types/selection'], function(require, exports, module) {
 
 
 var canon = require('gcli/canon');
 var l10n = require('gcli/l10n');
 var types = require('gcli/types');
@@ -2060,19 +2140,29 @@ CommandType.prototype.parse = function(a
   }
 
   return new Conversion(undefined, arg, Status.INCOMPLETE, '', predictFunc);
 };
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gcli/canon', ['require', 'exports', 'module' , 'gcli/util', 'gcli/l10n', 'gcli/types', 'gcli/types/basic'], function(require, exports, module) {
 var canon = exports;
 
 
 var util = require('gcli/util');
 var l10n = require('gcli/l10n');
@@ -2457,19 +2547,29 @@ canon.CommandOutputManager = CommandOutp
  * We maintain a global command output manager for the majority case where
  * there is only one important set of outputs.
  */
 canon.commandOutputManager = new CommandOutputManager();
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gcli/util', ['require', 'exports', 'module' ], function(require, exports, module) {
 
 /*
  * A number of DOM manipulation and event handling utilities.
  */
 
@@ -3151,19 +3251,29 @@ else {
     DOM_VK_QUOTE: 222,
     DOM_VK_META: 224
   };
 }
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gcli/types/javascript', ['require', 'exports', 'module' , 'gcli/l10n', 'gcli/types'], function(require, exports, module) {
 
 
 var l10n = require('gcli/l10n');
 var types = require('gcli/types');
 
@@ -3702,19 +3812,29 @@ JavascriptType.prototype._isSafeProperty
 
 JavascriptType.prototype.name = 'javascript';
 
 exports.JavascriptType = JavascriptType;
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gcli/types/node', ['require', 'exports', 'module' , 'gcli/host', 'gcli/l10n', 'gcli/types'], function(require, exports, module) {
 
 
 var host = require('gcli/host');
 var l10n = require('gcli/l10n');
 var types = require('gcli/types');
@@ -3815,19 +3935,29 @@ NodeType.prototype.parse = function(arg)
           l10n.lookupFormat('nodeParseMultiple', [ nodes.length ]));
 };
 
 NodeType.prototype.name = 'node';
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gcli/host', ['require', 'exports', 'module' ], function(require, exports, module) {
 
 
   /**
    * The chromeWindow as as required by Highlighter, so it knows where to
    * create temporary highlight nodes.
@@ -3851,19 +3981,29 @@ define('gcli/host', ['require', 'exports
 
     imports.Highlighter.flashNodes(nodes, exports.chromeWindow, match);
     */
   };
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gcli/types/resource', ['require', 'exports', 'module' , 'gcli/types', 'gcli/types/selection'], function(require, exports, module) {
 
 
 var types = require('gcli/types');
 var SelectionType = require('gcli/types/selection').SelectionType;
 
@@ -4156,19 +4296,29 @@ var ResourceCache = {
   clear: function() {
     ResourceCache._cached = [];
   }
 };
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gcli/types/setting', ['require', 'exports', 'module' , 'gcli/settings', 'gcli/types', 'gcli/types/selection', 'gcli/types/basic'], function(require, exports, module) {
 
 
 var settings = require('gcli/settings');
 var types = require('gcli/types');
 var SelectionType = require('gcli/types/selection').SelectionType;
@@ -4252,19 +4402,29 @@ SettingValueType.prototype.defer = funct
   }
 };
 
 SettingValueType.prototype.name = 'settingValue';
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gcli/settings', ['require', 'exports', 'module' , 'gcli/util', 'gcli/types'], function(require, exports, module) {
 
 var imports = {};
 
 Components.utils.import('resource://gre/modules/XPCOMUtils.jsm', imports);
 
@@ -4478,19 +4638,29 @@ exports.onChange = util.createEvent('Set
  * Remove a setting. A no-op in this case
  */
 exports.removeSetting = function(nameOrSpec) {
 };
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gcli/ui/intro', ['require', 'exports', 'module' , 'gcli/settings', 'gcli/l10n', 'gcli/util', 'gcli/ui/view', 'gcli/cli', 'text!gcli/ui/intro.html'], function(require, exports, module) {
 
   var settings = require('gcli/settings');
   var l10n = require('gcli/l10n');
   var util = require('gcli/util');
   var view = require('gcli/ui/view');
@@ -4555,19 +4725,29 @@ define('gcli/ui/intro', ['require', 'exp
           hideIntro.value = true;
           output.onClose();
         }
       }
     });
   };
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gcli/ui/view', ['require', 'exports', 'module' , 'gcli/util', 'gcli/ui/domtemplate'], function(require, exports, module) {
 
 
 var util = require('gcli/util');
 var domtemplate = require('gcli/ui/domtemplate');
 
@@ -4635,32 +4815,52 @@ exports.createView = function(options) {
       return child;
     }
   };
 };
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gcli/ui/domtemplate', ['require', 'exports', 'module' ], function(require, exports, module) {
 
   var obj = {};
   Components.utils.import('resource:///modules/devtools/Templater.jsm', obj);
   exports.template = obj.template;
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gcli/cli', ['require', 'exports', 'module' , 'gcli/util', 'gcli/ui/view', 'gcli/canon', 'gcli/promise', 'gcli/types', 'gcli/types/basic', 'gcli/argument'], function(require, exports, module) {
 
 
 var util = require('gcli/util');
 var view = require('gcli/ui/view');
 
@@ -6259,19 +6459,29 @@ exports.createExecutionContext = functio
       return new Promise();
     }
   };
 };
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gcli/promise', ['require', 'exports', 'module' ], function(require, exports, module) {
 
   Components.utils.import("resource:///modules/devtools/Promise.jsm");
   exports.Promise = Promise;
 
 });
@@ -6286,19 +6496,29 @@ define("text!gcli/ui/intro.html", [], "\
   "    ${l10n.introTextKeys} <code>${l10n.introTextF1Escape}</code>.\n" +
   "  </p>\n" +
   "\n" +
   "  <button onclick=\"${onGotIt}\" if=\"${showHideButton}\">${l10n.introTextGo}</button>\n" +
   "</div>\n" +
   "");
 
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gcli/ui/focus', ['require', 'exports', 'module' , 'gcli/util', 'gcli/settings', 'gcli/l10n', 'gcli/canon'], function(require, exports, module) {
 
 
 var util = require('gcli/util');
 var settings = require('gcli/settings');
 var l10n = require('gcli/l10n');
@@ -6683,19 +6903,29 @@ FocusManager.prototype._shouldShowOutput
   return { visible: false, reason: 'default' };
 };
 
 exports.FocusManager = FocusManager;
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gcli/ui/fields/basic', ['require', 'exports', 'module' , 'gcli/util', 'gcli/l10n', 'gcli/argument', 'gcli/types', 'gcli/types/basic', 'gcli/ui/fields'], function(require, exports, module) {
 
 
 var util = require('gcli/util');
 var l10n = require('gcli/l10n');
 
@@ -7053,19 +7283,29 @@ ArrayField.prototype._onAdd = function(e
   delButton.addEventListener('click', member.onDelete, false);
 
   this.members.push(member);
 };
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gcli/ui/fields', ['require', 'exports', 'module' , 'gcli/util', 'gcli/types/basic'], function(require, exports, module) {
 
 
 var util = require('gcli/util');
 var KeyEvent = require('gcli/util').KeyEvent;
 
@@ -7291,19 +7531,29 @@ BlankField.prototype.getConversion = fun
   return this.type.parse(new Argument());
 };
 
 exports.addField(BlankField);
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gcli/ui/fields/javascript', ['require', 'exports', 'module' , 'gcli/util', 'gcli/argument', 'gcli/types/javascript', 'gcli/ui/fields/menu', 'gcli/ui/fields'], function(require, exports, module) {
 
 
 var util = require('gcli/util');
 
 var Argument = require('gcli/argument').Argument;
@@ -7425,19 +7675,29 @@ JavascriptField.prototype.getConversion 
   return this.type.parse(this.arg);
 };
 
 JavascriptField.DEFAULT_VALUE = '__JavascriptField.DEFAULT_VALUE';
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gcli/ui/fields/menu', ['require', 'exports', 'module' , 'gcli/util', 'gcli/argument', 'gcli/canon', 'gcli/ui/domtemplate', 'text!gcli/ui/fields/menu.css', 'text!gcli/ui/fields/menu.html'], function(require, exports, module) {
 
 
 var util = require('gcli/util');
 
 var Argument = require('gcli/argument').Argument;
@@ -7640,19 +7900,29 @@ define("text!gcli/ui/fields/menu.html", 
   "      onclick=\"${onItemClickInternal}\" title=\"${item.manual}\">\n" +
   "    <td class=\"gcli-menu-name\">${item.name}</td>\n" +
   "    <td class=\"gcli-menu-desc\">${item.description}</td>\n" +
   "  </tr>\n" +
   "</table>\n" +
   "");
 
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gcli/ui/fields/selection', ['require', 'exports', 'module' , 'gcli/util', 'gcli/l10n', 'gcli/argument', 'gcli/types', 'gcli/types/basic', 'gcli/types/selection', 'gcli/ui/fields/menu', 'gcli/ui/fields'], function(require, exports, module) {
 
 
 var util = require('gcli/util');
 var l10n = require('gcli/l10n');
 
@@ -7840,19 +8110,29 @@ Object.defineProperty(SelectionTooltipFi
   enumerable: true
 });
 
 SelectionTooltipField.DEFAULT_VALUE = '__SelectionTooltipField.DEFAULT_VALUE';
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gcli/commands/help', ['require', 'exports', 'module' , 'gcli/canon', 'gcli/l10n', 'gcli/util', 'gcli/ui/view', 'text!gcli/commands/help_man.html', 'text!gcli/commands/help_list.html', 'text!gcli/commands/help.css'], function(require, exports, module) {
 var help = exports;
 
 
 var canon = require('gcli/canon');
 var l10n = require('gcli/l10n');
@@ -8084,19 +8364,29 @@ define("text!gcli/commands/help_list.htm
   "    </tr>\n" +
   "  </table>\n" +
   "</div>\n" +
   "");
 
 define("text!gcli/commands/help.css", [], "");
 
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gcli/commands/pref', ['require', 'exports', 'module' , 'gcli/canon', 'gcli/l10n', 'gcli/settings', 'text!gcli/commands/pref_set_check.html'], function(require, exports, module) {
 
 
 var canon = require('gcli/canon');
 var l10n = require('gcli/l10n');
 var settings = require('gcli/settings');
@@ -8229,19 +8519,29 @@ exports.shutdown = function() {
 define("text!gcli/commands/pref_set_check.html", [], "<div>\n" +
   "  <p><strong>${l10n.prefSetCheckHeading}</strong></p>\n" +
   "  <p>${l10n.prefSetCheckBody}</p>\n" +
   "  <button onclick=\"${activate}\">${l10n.prefSetCheckGo}</button>\n" +
   "</div>\n" +
   "");
 
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gcli/ui/ffdisplay', ['require', 'exports', 'module' , 'gcli/ui/inputter', 'gcli/ui/completer', 'gcli/ui/tooltip', 'gcli/ui/focus', 'gcli/cli', 'gcli/types/javascript', 'gcli/types/node', 'gcli/types/resource', 'gcli/host', 'gcli/ui/intro', 'gcli/canon'], function(require, exports, module) {
 
 var Inputter = require('gcli/ui/inputter').Inputter;
 var Completer = require('gcli/ui/completer').Completer;
 var Tooltip = require('gcli/ui/tooltip').Tooltip;
 var FocusManager = require('gcli/ui/focus').FocusManager;
@@ -8471,19 +8771,29 @@ FFDisplay.prototype.resizer = function()
     }
   }
 };
 
 exports.FFDisplay = FFDisplay;
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gcli/ui/inputter', ['require', 'exports', 'module' , 'gcli/util', 'gcli/types', 'gcli/history', 'text!gcli/ui/inputter.css'], function(require, exports, module) {
 
 
 var util = require('gcli/util');
 var KeyEvent = require('gcli/util').KeyEvent;
 
@@ -9021,19 +9331,29 @@ Inputter.prototype.getInputState = funct
   return input;
 };
 
 exports.Inputter = Inputter;
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gcli/history', ['require', 'exports', 'module' ], function(require, exports, module) {
 
 /**
  * A History object remembers commands that have been entered in the past and
  * provides an API for accessing them again.
  * See Bug 681340: Search through history (like C-r in bash)?
@@ -9086,19 +9406,29 @@ History.prototype.backward = function() 
 };
 
 exports.History = History;
 
 });
 define("text!gcli/ui/inputter.css", [], "");
 
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gcli/ui/completer', ['require', 'exports', 'module' , 'gcli/util', 'gcli/ui/domtemplate', 'text!gcli/ui/completer.html'], function(require, exports, module) {
 
 
 var util = require('gcli/util');
 var domtemplate = require('gcli/ui/domtemplate');
 
@@ -9359,19 +9689,29 @@ define("text!gcli/ui/completer.html", []
   "  <label class=\"gcli-in-ontab\">${directTabText}</label>\n" +
   "  <label class=\"gcli-in-todo\" foreach=\"param in ${emptyParameters}\">${param}</label>\n" +
   "  <label class=\"gcli-in-ontab\">${arrowTabText}</label>\n" +
   "  <label class=\"gcli-in-closebrace\" if=\"${unclosedJs}\">}</label>\n" +
   "</description>\n" +
   "");
 
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gcli/ui/tooltip', ['require', 'exports', 'module' , 'gcli/util', 'gcli/cli', 'gcli/ui/fields', 'gcli/ui/domtemplate', 'text!gcli/ui/tooltip.css', 'text!gcli/ui/tooltip.html'], function(require, exports, module) {
 
 
 var util = require('gcli/util');
 var CommandAssignment = require('gcli/cli').CommandAssignment;
 
--- a/browser/devtools/commandline/test/browser_gcli_web.js
+++ b/browser/devtools/commandline/test/browser_gcli_web.js
@@ -1,12 +1,22 @@
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 /*
  *
  *
  *
  *
  *
@@ -55,19 +65,29 @@ let console = (function() {
 })();
 
 registerCleanupFunction(function tearDown() {
   define = undefined;
   require = undefined;
   console = undefined;
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gclitest/index', ['require', 'exports', 'module' , 'gclitest/suite'], function(require, exports, module) {
 
   var examiner = require('gclitest/suite').examiner;
 
   // A minimum fake dom to get us through the JS tests
   var fakeWindow = {
@@ -106,19 +126,29 @@ define('gclitest/index', ['require', 'ex
       window: options.window,
       display: options.display,
       hideExec: options.hideExec
     };
   };
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gclitest/suite', ['require', 'exports', 'module' , 'gcli/index', 'test/examiner', 'gclitest/testCanon', 'gclitest/testCli', 'gclitest/testCompletion', 'gclitest/testExec', 'gclitest/testHelp', 'gclitest/testHistory', 'gclitest/testInputter', 'gclitest/testIntro', 'gclitest/testJs', 'gclitest/testKeyboard', 'gclitest/testPref', 'gclitest/testRequire', 'gclitest/testResource', 'gclitest/testScratchpad', 'gclitest/testSettings', 'gclitest/testSpell', 'gclitest/testSplit', 'gclitest/testTokenize', 'gclitest/testTooltip', 'gclitest/testTypes', 'gclitest/testUtil'], function(require, exports, module) {
 
   // We need to make sure GCLI is initialized before we begin testing it
   require('gcli/index');
 
   var examiner = require('test/examiner');
@@ -146,19 +176,29 @@ define('gclitest/suite', ['require', 'ex
   examiner.addSuite('gclitest/testTokenize', require('gclitest/testTokenize'));
   examiner.addSuite('gclitest/testTooltip', require('gclitest/testTooltip'));
   examiner.addSuite('gclitest/testTypes', require('gclitest/testTypes'));
   examiner.addSuite('gclitest/testUtil', require('gclitest/testUtil'));
 
   exports.examiner = examiner;
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('test/examiner', ['require', 'exports', 'module' , 'test/assert', 'test/status'], function(require, exports, module) {
 var examiner = exports;
 
 var assert = require('test/assert');
 var stati = require('test/status').stati;
 
@@ -550,32 +590,52 @@ Test.prototype.toRemote = function() {
     failures: this.failures,
     checks: this.checks
   };
 };
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('test/assert', ['require', 'exports', 'module' ], function(require, exports, module) {
 
   exports.ok = ok;
   exports.is = is;
   exports.log = info;
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('test/status', ['require', 'exports', 'module' ], function(require, exports, module) {
 
   /**
    * This should really be inside assert.js, however that is over-ridden by
    * a custom assert.js for mozilla, so we keep it separate to avoid
    * duplicating it in 2 places.
@@ -585,19 +645,29 @@ define('test/status', ['require', 'expor
     executing: { index: 1, name: 'Executing' },
     asynchronous: { index: 2, name: 'Waiting' },
     pass: { index: 3, name: 'Pass' },
     fail: { index: 4, name: 'Fail' }
   };
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gclitest/testCanon', ['require', 'exports', 'module' , 'gclitest/helpers', 'gcli/canon', 'test/assert'], function(require, exports, module) {
 
   var helpers = require('gclitest/helpers');
   var canon = require('gcli/canon');
   var test = require('test/assert');
 
@@ -680,19 +750,29 @@ define('gclitest/testCanon', ['require',
     test.is(canon.getCommands().length, startCount, 'nonexistant2 command success');
     test.is(events, 5, 'nonexistant2 event');
 
     canon.onCanonChange.remove(canonChange);
   };
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gclitest/helpers', ['require', 'exports', 'module' , 'test/assert'], function(require, exports, module) {
 
 
 var test = require('test/assert');
 
 /**
@@ -865,19 +945,29 @@ exports.exec = function(options, tests) 
       console.log(displayed);
     }
   }
 };
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gclitest/testCli', ['require', 'exports', 'module' , 'gcli/cli', 'gcli/types', 'gclitest/mockCommands', 'test/assert'], function(require, exports, module) {
 
 
 var Requisition = require('gcli/cli').Requisition;
 var Status = require('gcli/types').Status;
 var mockCommands = require('gclitest/mockCommands');
@@ -1320,19 +1410,29 @@ exports.testDeeplyNested = function() {
   test.is(Status.ERROR, status);
   test.is('tsn deep down nested', requ.commandAssignment.value.name);
   test.is(undefined, assign1);
 };
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gclitest/mockCommands', ['require', 'exports', 'module' , 'gcli/canon', 'gcli/util', 'gcli/types/selection', 'gcli/types/basic', 'gcli/types'], function(require, exports, module) {
 
 
 var canon = require('gcli/canon');
 var util = require('gcli/util');
 
@@ -1589,19 +1689,29 @@ exports.tsg = {
     }
   ],
   exec: createExec('tsg')
 };
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gclitest/testCompletion', ['require', 'exports', 'module' , 'test/assert', 'gclitest/mockCommands'], function(require, exports, module) {
 
 
 var test = require('test/assert');
 var mockCommands = require('gclitest/mockCommands');
 
@@ -1794,19 +1904,29 @@ exports.testActivate = function(options)
     cursor: 5,
     arrowTabText: 'tselarr'
   }, options);
 };
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gclitest/testExec', ['require', 'exports', 'module' , 'gcli/cli', 'gcli/canon', 'gclitest/mockCommands', 'gcli/types/node', 'test/assert'], function(require, exports, module) {
 
 
 var Requisition = require('gcli/cli').Requisition;
 var canon = require('gcli/canon');
 var mockCommands = require('gclitest/mockCommands');
@@ -1952,19 +2072,29 @@ var mockDoc = {
     }
     throw new Error('mockDoc.querySelectorAll(\'' + css + '\') error');
   }
 };
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gclitest/testHelp', ['require', 'exports', 'module' , 'gclitest/helpers'], function(require, exports, module) {
 
   var helpers = require('gclitest/helpers');
 
   exports.testHelpStatus = function(options) {
     helpers.status(options, {
@@ -2001,17 +2131,17 @@ define('gclitest/testHelp', ['require', 
       });
     }
     else {
       helpers.exec(options, {
         typed: 'help',
         args: { search: null },
         outputMatch: [
           /Welcome to GCLI/,
-          /Source \(BSD\)/,
+          /Source \(Apache-2.0\)/,
           /Get help/
         ]
       });
     }
 
     helpers.exec(options, {
       typed: 'help nomatch',
       args: { search: 'nomatch' },
@@ -2041,19 +2171,29 @@ define('gclitest/testHelp', ['require', 
         /Commands starting with 'hel':/,
         /Get help on the available commands/
       ]
     });
   };
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gclitest/testHistory', ['require', 'exports', 'module' , 'test/assert', 'gcli/history'], function(require, exports, module) {
 
 var test = require('test/assert');
 var History = require('gcli/history').History;
 
 exports.setup = function() {
@@ -2102,19 +2242,29 @@ exports.testForwardsPastIndex = function
   test.is('', history.forward());
 
   // Going to the 'future' just keeps giving us the empty string.
   test.is('', history.forward());
 };
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gclitest/testInputter', ['require', 'exports', 'module' , 'gclitest/mockCommands', 'gcli/util', 'test/assert'], function(require, exports, module) {
 
 
 var mockCommands = require('gclitest/mockCommands');
 var KeyEvent = require('gcli/util').KeyEvent;
 
@@ -2192,19 +2342,29 @@ exports.testOutput = function(options) {
   test.ok(!focusManager._helpRequested, 'ESCAPE = anti help');
 
   latestOutput.onClose();
 };
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gclitest/testIntro', ['require', 'exports', 'module' , 'gclitest/helpers', 'test/assert'], function(require, exports, module) {
 
   var helpers = require('gclitest/helpers');
   var test = require('test/assert');
 
   exports.testIntroStatus = function(options) {
@@ -2243,19 +2403,29 @@ define('gclitest/testIntro', ['require',
         /F1/,
         /Escape/
       ]
     });
   };
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gclitest/testJs', ['require', 'exports', 'module' , 'gcli/cli', 'gcli/types', 'gcli/types/javascript', 'gcli/canon', 'test/assert'], function(require, exports, module) {
 
 
 var Requisition = require('gcli/cli').Requisition;
 var Status = require('gcli/types').Status;
 var javascript = require('gcli/types/javascript');
@@ -2417,19 +2587,29 @@ exports.testBasic = function(options) {
 
   input('{ donteval.xxx');
   check('VVVVVVVVVVVVVV', Status.VALID, 'donteval.xxx', 0);
 };
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gclitest/testKeyboard', ['require', 'exports', 'module' , 'gcli/cli', 'gcli/canon', 'gclitest/mockCommands', 'gcli/types/javascript', 'test/assert'], function(require, exports, module) {
 
 
 var Requisition = require('gcli/cli').Requisition;
 var canon = require('gcli/canon');
 var mockCommands = require('gclitest/mockCommands');
@@ -2598,19 +2778,29 @@ exports.testIncrDecr = function() {
   check('tselarr 2', KEY_DOWNS_TO, 'tselarr 3');
   check('tselarr 3', KEY_DOWNS_TO, 'tselarr 1');
 
   check('tselarr 3', KEY_UPS_TO, 'tselarr 2');
 };
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gclitest/testPref', ['require', 'exports', 'module' , 'gcli/commands/pref', 'gclitest/helpers', 'gclitest/mockSettings', 'test/assert'], function(require, exports, module) {
 
 
 var pref = require('gcli/commands/pref');
 var helpers = require('gclitest/helpers');
 var mockSettings = require('gclitest/mockSettings');
@@ -2803,19 +2993,29 @@ exports.testPrefExec = function(options)
     },
     outputMatch: /Filter/
   });
 };
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gclitest/mockSettings', ['require', 'exports', 'module' , 'gcli/settings'], function(require, exports, module) {
 
 
 var settings = require('gcli/settings');
 
 
@@ -2903,19 +3103,29 @@ exports.shutdown = function() {
   exports.tempQString = undefined;
   exports.tempNumber = undefined;
   exports.tempSelection = undefined;
 };
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gclitest/testRequire', ['require', 'exports', 'module' , 'test/assert', 'gclitest/requirable'], function(require, exports, module) {
 
 var test = require('test/assert');
 
 
 exports.testWorking = function() {
@@ -2995,35 +3205,55 @@ exports.testRecursive = function() {
   /*
   var recurse = require('gclitest/recurse');
   */
 };
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gclitest/requirable', ['require', 'exports', 'module' ], function(require, exports, module) {
 
   exports.thing1 = 'thing1';
   exports.thing2 = 2;
 
   var status = 'initial';
   exports.setStatus = function(aStatus) { status = aStatus; };
   exports.getStatus = function() { return status; };
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gclitest/testResource', ['require', 'exports', 'module' , 'gcli/types/resource', 'gcli/types', 'test/assert'], function(require, exports, module) {
 
 
 var resource = require('gcli/types/resource');
 var types = require('gcli/types');
 var Status = require('gcli/types').Status;
@@ -3095,19 +3325,29 @@ function checkPrediction(res, prediction
   test.is(strung, name, 'stringify for ' + name);
 
   test.is(typeof value.loadContents, 'function', 'resource for ' + name);
   test.is(typeof value.element, 'object', 'resource for ' + name);
 }
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gclitest/testScratchpad', ['require', 'exports', 'module' , 'test/assert'], function(require, exports, module) {
 
 
 var test = require('test/assert');
 
 var origScratchpad;
@@ -3148,19 +3388,29 @@ exports.testActivate = function(options)
   stubScratchpad.activatedCount = 0;
   options.display.inputter.onKeyUp(ev);
   test.is(1, stubScratchpad.activatedCount, 'scratchpad is activated');
 };
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gclitest/testSettings', ['require', 'exports', 'module' , 'gclitest/mockSettings', 'test/assert'], function(require, exports, module) {
 
 
 var mockSettings = require('gclitest/mockSettings');
 var test = require('test/assert');
 
@@ -3342,19 +3592,29 @@ exports.testSpellerSimple = function(opt
   test.is(speller.correct('odcument'), 'document');
 
   test.is(speller.correct('========='), null);
 };
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gclitest/testSplit', ['require', 'exports', 'module' , 'test/assert', 'gclitest/mockCommands', 'gcli/cli', 'gcli/canon'], function(require, exports, module) {
 
 var test = require('test/assert');
 
 var mockCommands = require('gclitest/mockCommands');
 var Requisition = require('gcli/cli').Requisition;
@@ -3411,19 +3671,29 @@ exports.testJavascript = function() {
   test.is('', requ.commandAssignment.arg.text);
   test.is('{', requ.commandAssignment.value.name);
 };
 
 // BUG 663081 - add tests for sub commands
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gclitest/testTokenize', ['require', 'exports', 'module' , 'test/assert', 'gcli/cli', 'gcli/argument'], function(require, exports, module) {
 
 
 var test = require('test/assert');
 var Requisition = require('gcli/cli').Requisition;
 var Argument = require('gcli/argument').Argument;
@@ -3696,19 +3966,29 @@ exports.testPathological = function() {
   test.is(' \'', args[3].prefix);
   test.is('', args[3].suffix);
   test.ok(args[3] instanceof Argument);
 };
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gclitest/testTooltip', ['require', 'exports', 'module' , 'test/assert', 'gclitest/mockCommands'], function(require, exports, module) {
 
 
 var test = require('test/assert');
 var mockCommands = require('gclitest/mockCommands');
 
@@ -3791,19 +4071,29 @@ exports.testActivate = function(options)
   }, options);
 
   type('', { }, options);
 };
 
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gclitest/testTypes', ['require', 'exports', 'module' , 'test/assert', 'gcli/types'], function(require, exports, module) {
 
 var test = require('test/assert');
 var types = require('gcli/types');
 
 exports.setup = function() {
@@ -3861,19 +4151,29 @@ exports.testDefault = function(options) 
 exports.testNullDefault = function(options) {
   forEachType({ defaultValue: null }, function(type) {
     test.is(type.stringify(null), '', 'stringify(null) for ' + type.name);
   });
 };
 
 });
 /*
- * Copyright 2009-2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE.txt or:
- * http://opensource.org/licenses/BSD-3-Clause
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 define('gclitest/testUtil', ['require', 'exports', 'module' , 'gcli/util', 'test/assert'], function(require, exports, module) {
 
 var util = require('gcli/util');
 var test = require('test/assert');
 
 exports.testFindCssSelector = function(options) {
--- a/browser/devtools/highlighter/highlighter.jsm
+++ b/browser/devtools/highlighter/highlighter.jsm
@@ -325,16 +325,19 @@ Highlighter.prototype = {
    *
    * @param nsIDOMNode aNode
    *        the DOM element in question
    * @returns boolean
    *          True if the node is highlightable or false otherwise.
    */
   isNodeHighlightable: function Highlighter_isNodeHighlightable(aNode)
   {
+    if (!LayoutHelpers.isNodeConnected(aNode)) {
+      return false;
+    }
     if (aNode.nodeType != aNode.ELEMENT_NODE) {
       return false;
     }
     let nodeName = aNode.nodeName.toLowerCase();
     return !INSPECTOR_INVISIBLE_ELEMENTS[nodeName];
   },
 
   /**
--- a/browser/devtools/highlighter/inspector.jsm
+++ b/browser/devtools/highlighter/inspector.jsm
@@ -888,17 +888,19 @@ InspectorUI.prototype = {
   },
 
   /**
    * Clear all pseudo-class locks applied to elements in the node hierarchy
    */
   clearPseudoClassLocks: function IUI_clearPseudoClassLocks()
   {
     this.breadcrumbs.nodeHierarchy.forEach(function(crumb) {
-      DOMUtils.clearPseudoClassLocks(crumb.node);
+      if (LayoutHelpers.isNodeConnected(crumb.node)) {
+        DOMUtils.clearPseudoClassLocks(crumb.node);
+      }
     });
   },
 
   /**
    * Called when the highlighted node is changed by a tool.
    *
    * @param object aUpdater
    *        The tool that triggered the update (if any), that tool's
--- a/browser/devtools/highlighter/test/Makefile.in
+++ b/browser/devtools/highlighter/test/Makefile.in
@@ -35,16 +35,18 @@ include $(topsrcdir)/config/rules.mk
 		browser_inspector_bug_699308_iframe_navigation.js \
 		browser_inspector_changes.js \
 		browser_inspector_ruleviewstore.js \
 		browser_inspector_invalidate.js \
 		browser_inspector_sidebarstate.js \
 		browser_inspector_treePanel_menu.js \
 		browser_inspector_pseudoclass_lock.js \
 		browser_inspector_pseudoClass_menu.js \
+		browser_inspector_destroyselection.html \
+		browser_inspector_destroyselection.js \
 		head.js \
 		$(NULL)
 
 # Disabled due to constant failures
 # 		browser_inspector_treePanel_click.js \
 
 libs::	$(_BROWSER_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/browser/devtools/highlighter/test/browser_inspector_destroyselection.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+
+<h1>mop</h1>
+<iframe src="data:text/html;charset=utf-8,<!DOCTYPE HTML>%0D%0A<h1>kill me<span>.</span><%2Fh1>"></iframe>
new file mode 100644
--- /dev/null
+++ b/browser/devtools/highlighter/test/browser_inspector_destroyselection.js
@@ -0,0 +1,62 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function test()
+{
+  waitForExplicitFinish();
+  //ignoreAllUncaughtExceptions();
+
+  let node, iframe;
+
+  gBrowser.selectedTab = gBrowser.addTab();
+  gBrowser.selectedBrowser.addEventListener("load", function onload() {
+    gBrowser.selectedBrowser.removeEventListener("load", onload, true);
+    waitForFocus(setupTest, content);
+  }, true);
+
+  content.location = "http://mochi.test:8888/browser/browser/devtools/highlighter/test/browser_inspector_destroyselection.html";
+
+  function setupTest()
+  {
+    iframe = content.document.querySelector("iframe");
+    node = iframe.contentDocument.querySelector("span");
+
+    Services.obs.addObserver(runTests,
+      InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED, false);
+    InspectorUI.openInspectorUI(node);
+  }
+
+  function runTests()
+  {
+    Services.obs.removeObserver(runTests,
+      InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED);
+    is(InspectorUI.selection, node, "node selected");
+    iframe.parentNode.removeChild(iframe);
+    iframe = null;
+
+    let tmp = {};
+    Cu.import("resource:///modules/devtools/LayoutHelpers.jsm", tmp);
+    ok(!tmp.LayoutHelpers.isNodeConnected(node), "Node considered as disconnected.");
+
+    Services.obs.addObserver(testBreadcrumbs,
+                             InspectorUI.INSPECTOR_NOTIFICATIONS.CLOSED, false);
+
+    executeSoon(function() {
+      InspectorUI.closeInspectorUI();
+    });
+  }
+
+  function testBreadcrumbs()
+  {
+    Services.obs.removeObserver(testBreadcrumbs, InspectorUI.INSPECTOR_NOTIFICATIONS.CLOSED, false);
+    ok(!InspectorUI.breadcrumbs, "Breadcrumbs destroyed");
+    finishUp();
+  }
+
+  function finishUp() {
+    node = null;
+    gBrowser.removeCurrentTab();
+    finish();
+  }
+}
+
--- a/browser/devtools/layoutview/LayoutView.jsm
+++ b/browser/devtools/layoutview/LayoutView.jsm
@@ -281,17 +281,21 @@ LayoutView.prototype = {
   },
 
   /**
    * Compute the dimensions of the node and update the values in
    * the layoutview/view.xhtml document.
    */
   update: function LV_update() {
     let node = this.inspector.selection;
-    if (!node || !this.documentReady) return;
+    if (!node ||
+        !LayoutHelpers.isNodeConnected(node) ||
+        !this.documentReady) {
+      return;
+    }
 
     // First, we update the first part of the layout view, with
     // the size of the element.
 
     let clientRect = node.getBoundingClientRect();
     let width = Math.round(clientRect.width);
     let height = Math.round(clientRect.height);
 
--- a/browser/devtools/shared/DeveloperToolbar.jsm
+++ b/browser/devtools/shared/DeveloperToolbar.jsm
@@ -502,16 +502,32 @@ function DT__updateErrorsCount(aChangedT
       this._webConsoleButtonLabel + " (" + errors + ")";
   }
   else {
     this._webConsoleButton.label = this._webConsoleButtonLabel;
   }
 };
 
 /**
+ * Reset the errors counter for the given tab.
+ *
+ * @param nsIDOMElement aTab The xul:tab for which you want to reset the page
+ * errors counters.
+ */
+DeveloperToolbar.prototype.resetErrorsCount =
+function DT_resetErrorsCount(aTab)
+{
+  let tabId = aTab.linkedPanel;
+  if (tabId in this._errorsCount) {
+    this._errorsCount[tabId] = 0;
+    this._updateErrorsCount(tabId);
+  }
+};
+
+/**
  * Panel to handle command line output.
  * @param aChromeDoc document from which we can pull the parts we need.
  * @param aInput the input element that should get focus.
  * @param aLoadCallback called when the panel is loaded properly.
  */
 function OutputPanel(aChromeDoc, aInput, aLoadCallback)
 {
   this._input = aInput;
--- a/browser/devtools/shared/LayoutHelpers.jsm
+++ b/browser/devtools/shared/LayoutHelpers.jsm
@@ -286,9 +286,28 @@ LayoutHelpers = {
       }
     }
 
     if (win.parent !== win) {
       // We are inside an iframe.
       LH_scrollIntoViewIfNeeded(win.frameElement, centered);
     }
   },
+
+  /**
+   * Check if a node and its document are still alive
+   * and attached to the window.
+   *
+   * @param aNode
+   */
+  isNodeConnected: function LH_isNodeConnected(aNode)
+  {
+    try {
+      let connected = (aNode.ownerDocument && aNode.ownerDocument.defaultView &&
+                      !(aNode.compareDocumentPosition(aNode.ownerDocument.documentElement) &
+                      aNode.DOCUMENT_POSITION_DISCONNECTED));
+      return connected;
+    } catch (e) {
+      // "can't access dead object" error
+      return false;
+    }
+  },
 };
--- a/browser/devtools/shared/Templater.jsm
+++ b/browser/devtools/shared/Templater.jsm
@@ -1,11 +1,23 @@
-/* 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/. */
+/*
+ * Copyright 2012, Mozilla Foundation and contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 
 var EXPORTED_SYMBOLS = [ "Templater", "template" ];
 
 Components.utils.import("resource://gre/modules/Services.jsm");
 const Node = Components.interfaces.nsIDOMNode;
 
 /**
--- a/browser/devtools/shared/test/browser_toolbar_webconsole_errors_count.js
+++ b/browser/devtools/shared/test/browser_toolbar_webconsole_errors_count.js
@@ -25,17 +25,17 @@ function test() {
     toolbar.doCommand();
   }
 
   ignoreAllUncaughtExceptions();
   addTab(TEST_URI, openToolbar);
 
   function getErrorsCount() {
     let match = webconsole.label.match(/\((\d+)\)$/);
-    return (match || [])[1];
+    return match ? match[1] : 0;
   }
 
   function onOpenToolbar() {
     ok(DeveloperToolbar.visible, "DeveloperToolbar is visible");
 
     waitForValue({
       name: "web console button shows page errors",
       validator: getErrorsCount,
@@ -144,21 +144,33 @@ function test() {
       failure: finish,
     });
 
     let waitForNewError = {
       name: "the Web Console displays the new error",
       validator: function() {
         return hud.outputNode.textContent.indexOf("foobarBug762996click") > -1;
       },
-      success: doPageReload.bind(null, hud),
+      success: doClearConsoleButton.bind(null, hud),
       failure: finish,
     };
   }
 
+  function doClearConsoleButton(hud) {
+    let clearButton = hud.HUDBox
+                      .querySelector(".webconsole-clear-console-button");
+    EventUtils.synthesizeMouse(clearButton, 2, 2, {}, window);
+
+    is(hud.outputNode.textContent.indexOf("foobarBug762996click"), -1,
+       "clear console button worked");
+    is(getErrorsCount(), 0, "page errors counter has been reset");
+
+    doPageReload(hud);
+  }
+
   function doPageReload(hud) {
     tab1.linkedBrowser.addEventListener("load", function _onReload() {
       tab1.linkedBrowser.removeEventListener("load", _onReload, true);
       ignoreAllUncaughtExceptions(false);
       expectUncaughtException();
     }, true);
 
     ignoreAllUncaughtExceptions();
@@ -174,17 +186,17 @@ function test() {
       failure: finish,
     });
 
     let waitForConsoleOutputAfterReload = {
       name: "the Web Console displays the correct number of errors after reload",
       validator: function() {
         return hud.outputNode.querySelectorAll(".hud-exception").length;
       },
-      value: 4,
+      value: 3,
       success: function() {
         isnot(hud.outputNode.textContent.indexOf("foobarBug762996load"), -1,
               "foobarBug762996load found in console output after page reload");
         testEnd();
       },
       failure: testEnd,
     };
   }
--- a/browser/devtools/webconsole/HUDService.jsm
+++ b/browser/devtools/webconsole/HUDService.jsm
@@ -1007,17 +1007,17 @@ HUD_SERVICE.prototype =
         let timestampString = l10n.timestampString(item.timestamp);
         if (newGroup) {
           strings.push("--");
           newGroup = false;
         }
         strings.push("[" + timestampString + "] " + item.clipboardText);
       }
     }
-    clipboardHelper.copyString(strings.join("\n"), this.doc);
+    clipboardHelper.copyString(strings.join("\n"), aOutputNode.ownerDocument);
   }
 };
 
 //////////////////////////////////////////////////////////////////////////
 // HeadsUpDisplay
 //////////////////////////////////////////////////////////////////////////
 
 /**
@@ -1421,17 +1421,17 @@ HeadsUpDisplay.prototype = {
   {
     if (!aRemoteMessages.length) {
       return;
     }
 
     aRemoteMessages.forEach(function(aMessage) {
       switch (aMessage._type) {
         case "PageError": {
-          let category = this.categoryForScriptError(aMessage.category);
+          let category = this.categoryForScriptError(aMessage);
           this.outputMessage(category, this.reportPageError,
                              [category, aMessage]);
           break;
         }
         case "ConsoleAPI":
           this.outputMessage(CATEGORY_WEBDEV, this.logConsoleAPIMessage,
                              [aMessage]);
           break;
@@ -1836,16 +1836,17 @@ HeadsUpDisplay.prototype = {
    * @return void
    */
   makeClearConsoleButton: function HUD_makeClearConsoleButton(aToolbar)
   {
     let hudId = this.hudId;
     function HUD_clearButton_onCommand() {
       let hud = HUDService.getHudReferenceById(hudId);
       hud.jsterm.clearOutput(true);
+      hud.chromeWindow.DeveloperToolbar.resetErrorsCount(hud.tab);
     }
 
     let clearButton = this.makeXULNode("toolbarbutton");
     clearButton.setAttribute("label", l10n.getStr("btnClear"));
     clearButton.classList.add("webconsole-clear-console-button");
     clearButton.addEventListener("command", HUD_clearButton_onCommand, false);
 
     aToolbar.appendChild(clearButton);
--- a/browser/devtools/webconsole/test/browser_cached_messages.js
+++ b/browser/devtools/webconsole/test/browser_cached_messages.js
@@ -46,16 +46,22 @@ function testOpenUI(aTestReopen)
             }
           }
           foundAll = foundAll && found;
         }
         return foundAll;
       },
       successFn: function()
       {
+        // Make sure the CSS warning is given the correct category - bug 768019.
+        let cssNode = hud.outputNode.querySelector(".webconsole-msg-cssparser");
+        ok(cssNode, "CSS warning message element");
+        isnot(cssNode.textContent.indexOf("cssColorBug611032"), -1,
+              "CSS warning message element content is correct");
+
         closeConsole(gBrowser.selectedTab, function() {
           aTestReopen && info("will reopen the Web Console");
           executeSoon(aTestReopen ? testOpenUI : finishTest);
         });
       },
       failureFn: function()
       {
         for (let msg in messages) {
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_618311_close_panels.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_618311_close_panels.js
@@ -94,14 +94,18 @@ function performTest() {
     name: "jsterm output message",
     validatorFn: function()
     {
       return HUD.outputNode.querySelector(".webconsole-msg-output");
     },
     successFn: function()
     {
       let jstermMessage = HUD.outputNode.querySelector(".webconsole-msg-output");
-      EventUtils.synthesizeMouse(jstermMessage, 2, 2, {});
-      EventUtils.synthesizeMouse(networkLink, 2, 2, {});
+      EventUtils.sendMouseEvent({ type: "mousedown" }, jstermMessage);
+      EventUtils.sendMouseEvent({ type: "mouseup" }, jstermMessage);
+      EventUtils.sendMouseEvent({ type: "click" }, jstermMessage);
+      EventUtils.sendMouseEvent({ type: "mousedown" }, networkLink);
+      EventUtils.sendMouseEvent({ type: "mouseup" }, networkLink);
+      EventUtils.sendMouseEvent({ type: "click" }, networkLink);
     },
     failureFn: finishTest,
   });
 }
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_618311_private_browsing.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_618311_private_browsing.js
@@ -119,18 +119,22 @@ function performTest() {
     name: "jsterm output message",
     validatorFn: function()
     {
       return HUD.outputNode.querySelector(".webconsole-msg-output");
     },
     successFn: function()
     {
       let jstermMessage = HUD.outputNode.querySelector(".webconsole-msg-output");
-      EventUtils.synthesizeMouse(jstermMessage, 2, 2, {});
-      EventUtils.synthesizeMouse(networkLink, 2, 2, {});
+      EventUtils.sendMouseEvent({ type: "mousedown" }, jstermMessage);
+      EventUtils.sendMouseEvent({ type: "mouseup" }, jstermMessage);
+      EventUtils.sendMouseEvent({ type: "click" }, jstermMessage);
+      EventUtils.sendMouseEvent({ type: "mousedown" }, networkLink);
+      EventUtils.sendMouseEvent({ type: "mouseup" }, networkLink);
+      EventUtils.sendMouseEvent({ type: "click" }, networkLink);
     },
     failureFn: finishTest,
   });
 }
 
 function togglePBAndThen(callback) {
   function pbObserver(aSubject, aTopic, aData) {
     if (aTopic != "private-browsing-transition-complete") {
--- a/browser/devtools/webconsole/test/browser_webconsole_position_ui.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_position_ui.js
@@ -30,31 +30,31 @@ function onLoad() {
   openConsole();
 
   testMenuitems();
 
   let hudId = HUDService.getHudIdByWindow(content);
   let hudRef = HUDService.hudReferences[hudId];
   let hudBox = hudRef.HUDBox;
 
-  is(hudBox.parentNode.childNodes[0].getAttribute("id"), hudId,
+  is(hudBox.parentNode.childNodes[2].getAttribute("id"), hudId,
      "initial console position is correct");
 
+  is(hudRef.positionMenuitems.below.getAttribute("checked"), "true",
+     "position menu checkbox is below");
+  is(Services.prefs.getCharPref(POSITION_PREF), "below", "pref is below");
+
+  hudRef.positionConsole("above");
+  let id = hudBox.parentNode.childNodes[0].getAttribute("id");
+  is(id, hudId, "above position is correct");
+
   is(hudRef.positionMenuitems.above.getAttribute("checked"), "true",
      "position menu checkbox is above");
   is(Services.prefs.getCharPref(POSITION_PREF), "above", "pref is above");
 
-  hudRef.positionConsole("below");
-  let id = hudBox.parentNode.childNodes[2].getAttribute("id");
-  is(id, hudId, "below position is correct");
-
-  is(hudRef.positionMenuitems.below.getAttribute("checked"), "true",
-     "position menu checkbox is below");
-  is(Services.prefs.getCharPref(POSITION_PREF), "below", "pref is below");
-
   // listen for the panel popupshown event.
   document.addEventListener("popupshown", function popupShown() {
     document.removeEventListener("popupshown", popupShown, false);
 
     document.addEventListener("popuphidden", function popupHidden() {
       document.removeEventListener("popuphidden", popupHidden, false);
 
       id = hudBox.parentNode.childNodes[2].getAttribute("id");
--- a/browser/modules/NewTabUtils.jsm
+++ b/browser/modules/NewTabUtils.jsm
@@ -206,32 +206,39 @@ let PinnedLinks = {
    * @param aLink The link to pin.
    * @param aIndex The grid index to pin the cell at.
    */
   pin: function PinnedLinks_pin(aLink, aIndex) {
     // Clear the link's old position, if any.
     this.unpin(aLink);
 
     this.links[aIndex] = aLink;
-    Storage.set("pinnedLinks", this.links);
+    this.save();
   },
 
   /**
    * Unpins a given link.
    * @param aLink The link to unpin.
    */
   unpin: function PinnedLinks_unpin(aLink) {
     let index = this._indexOfLink(aLink);
     if (index != -1) {
       this.links[index] = null;
-      Storage.set("pinnedLinks", this.links);
+      this.save();
     }
   },
 
   /**
+   * Saves the current list of pinned links.
+   */
+  save: function PinnedLinks_save() {
+    Storage.set("pinnedLinks", this.links);
+  },
+
+  /**
    * Checks whether a given link is pinned.
    * @params aLink The link to check.
    * @return whether The link is pinned.
    */
   isPinned: function PinnedLinks_isPinned(aLink) {
     return this._indexOfLink(aLink) != -1;
   },
 
@@ -279,30 +286,38 @@ let BlockedLinks = {
   },
 
   /**
    * Blocks a given link.
    * @param aLink The link to block.
    */
   block: function BlockedLinks_block(aLink) {
     this.links[aLink.url] = 1;
+    this.save();
 
     // Make sure we unpin blocked links.
     PinnedLinks.unpin(aLink);
-
-    Storage.set("blockedLinks", this.links);
   },
 
   /**
    * Unblocks a given link.
    * @param aLink The link to unblock.
    */
   unblock: function BlockedLinks_unblock(aLink) {
-    if (this.isBlocked(aLink))
+    if (this.isBlocked(aLink)) {
       delete this.links[aLink.url];
+      this.save();
+    }
+  },
+
+  /**
+   * Saves the current list of blocked links.
+   */
+  save: function BlockedLinks_save() {
+    Storage.set("blockedLinks", this.links);
   },
 
   /**
    * Returns whether a given link is blocked.
    * @param aLink The link to check.
    */
   isBlocked: function BlockedLinks_isBlocked(aLink) {
     return (aLink.url in this.links);
--- a/browser/modules/webappsUI.jsm
+++ b/browser/modules/webappsUI.jsm
@@ -103,17 +103,17 @@ let webappsUI = {
   },
 
   doInstall: function(aData, aBrowser, aWindow) {
     let bundle = aWindow.gNavigatorBundle;
 
     let mainAction = {
       label: bundle.getString("webapps.install"),
       accessKey: bundle.getString("webapps.install.accesskey"),
-      callback: function(notification) {
+      callback: function() {
         let app = WebappsInstaller.install(aData);
         if (app) {
           let localDir = null;
           if (app.appcacheDefined && app.appProfile) {
             localDir = app.appProfile.localDir;
           }
 
           DOMApplicationRegistry.confirmInstall(aData, false, localDir);
--- a/build/mobile/sutagent/android/SUTAgentAndroid.java
+++ b/build/mobile/sutagent/android/SUTAgentAndroid.java
@@ -5,17 +5,19 @@
 package com.mozilla.SUTAgentAndroid;
 
 import java.io.File;
 import java.io.PrintWriter;
 import java.net.InetAddress;
 import org.apache.http.conn.util.InetAddressUtils;
 import java.net.NetworkInterface;
 import java.net.SocketException;
+import java.net.UnknownHostException;
 import java.util.Enumeration;
+import java.util.Formatter;
 import java.util.List;
 import java.util.Timer;
 
 import com.mozilla.SUTAgentAndroid.service.ASMozStub;
 import com.mozilla.SUTAgentAndroid.service.DoCommand;
 import android.app.Activity;
 import android.bluetooth.BluetoothAdapter;
 import android.content.BroadcastReceiver;
@@ -117,29 +119,36 @@ public class SUTAgentAndroid extends Act
         SUTAgentAndroid.HardwareID = dc.GetIniData("Registration Server", "HARDWARE", sIniFile);
         SUTAgentAndroid.Pool = dc.GetIniData("Registration Server", "POOL", sIniFile);
 
         tv = (TextView) this.findViewById(R.id.Textview01);
 
         if (getLocalIpAddress() == null)
             setUpNetwork(sIniFile);
 
-        WifiInfo wifi;
-        WifiManager wifiMan = (WifiManager)getSystemService(Context.WIFI_SERVICE);
         String macAddress = "Unknown";
-        if (wifiMan != null)
-            {
-            wifi = wifiMan.getConnectionInfo();
-            if (wifi != null)
+        try {
+            NetworkInterface iface = NetworkInterface.getByInetAddress(InetAddress.getAllByName(getLocalIpAddress())[0]);
+            if (iface != null)
                 {
-                macAddress = wifi.getMacAddress();
-                if (macAddress != null)
-                    sUniqueID = macAddress;
+                    byte[] mac = iface.getHardwareAddress();
+                    if (mac != null)
+                        {
+                            StringBuilder sb = new StringBuilder();
+                            Formatter f = new Formatter(sb);
+                            for (int i = 0; i < mac.length; i++)
+                                {
+                                    f.format("%02x%s", mac[i], (i < mac.length - 1) ? ":" : "");
+                                }
+                            macAddress = sUniqueID = sb.toString();
+                        }
                 }
-            }
+        }
+        catch (UnknownHostException ex) {}
+        catch (SocketException ex) {}
 
         if (sUniqueID == null)
             {
             BluetoothAdapter ba = BluetoothAdapter.getDefaultAdapter();
             if ((ba != null) && (ba.isEnabled() != true))
                 {
                 ba.enable();
                 while(ba.getState() != BluetoothAdapter.STATE_ON)
--- a/build/unix/build-clang/build-clang.py
+++ b/build/unix/build-clang/build-clang.py
@@ -1,14 +1,14 @@
 #!/usr/bin/python
 # 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/.
 
-llvm_revision = "159219"
+llvm_revision = "159409"
 moz_version = "moz0"
 
 ##############################################
 
 import os
 import os.path
 import shutil
 import tarfile
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -1826,16 +1826,21 @@ public:
    * Returns true if requests for full-screen are allowed in the current
    * context. Requests are only allowed if the user initiated them (like with
    * a mouse-click or key press), unless this check has been disabled by
    * setting the pref "full-screen-api.allow-trusted-requests-only" to false.
    */
   static bool IsRequestFullScreenAllowed();
 
   /**
+   * Returns true if the idle observers API is enabled.
+   */
+  static bool IsIdleObserverAPIEnabled() { return sIsIdleObserverAPIEnabled; }
+  
+  /**
    * Returns true if the doc tree branch which contains aDoc contains any
    * plugins which we don't control event dispatch for, i.e. do any plugins
    * in the same tab as this document receive key events outside of our
    * control? This always returns false on MacOSX.
    */
   static bool HasPluginWithUncontrolledEventDispatch(nsIDocument* aDoc);
 
   /**
@@ -2008,16 +2013,29 @@ public:
    * Returns true if the language name is a version of JavaScript and
    * false otherwise
    */
   static bool IsJavaScriptLanguage(const nsString& aName, PRUint32 *aVerFlags);
 
   static void SplitMimeType(const nsAString& aValue, nsString& aType,
                             nsString& aParams);
 
+  /**
+   * Function checks if the user is idle.
+   * 
+   * @param aRequestedIdleTimeInMS    The idle observer's requested idle time.
+   * @param aUserIsIdle               boolean indicating if the user 
+   *                                  is currently idle or not.   *
+   * @return NS_OK                    NS_OK returned if the requested idle service and 
+   *                                  the current idle time were successfully obtained.
+   *                                  NS_ERROR_FAILURE returned if the the requested
+   *                                  idle service or the current idle were not obtained.
+   */
+  static nsresult IsUserIdle(PRUint32 aRequestedIdleTimeInMS, bool* aUserIsIdle);
+
   /** 
    * Takes a window and a string to check prefs against. Assumes that
    * the window is an app window, and that the pref is a comma
    * seperated list of app urls that have permission to use whatever
    * the preference refers to (for example, does the current window
    * have access to mozTelephony). Chrome is always given permissions
    * for the requested preference. Sets aAllowed based on preference.
    *
@@ -2134,16 +2152,17 @@ private:
 
   static nsIInterfaceRequestor* sSameOriginChecker;
 
   static bool sIsHandlingKeyBoardEvent;
   static bool sAllowXULXBL_for_file;
   static bool sIsFullScreenApiEnabled;
   static bool sTrustedFullScreenOnly;
   static PRUint32 sHandlingInputTimeout;
+  static bool sIsIdleObserverAPIEnabled;
 
   static nsHtml5StringParser* sHTMLFragmentParser;
   static nsIParser* sXMLFragmentParser;
   static nsIFragmentContentSink* sXMLFragmentSink;
 
   /**
    * True if there's a fragment parser activation on the stack.
    */
--- a/content/base/src/CSPUtils.jsm
+++ b/content/base/src/CSPUtils.jsm
@@ -5,21 +5,29 @@
 /**
  * Content Security Policy Utilities
  * 
  * Overview
  * This contains a set of classes and utilities for CSP.  It is in this
  * separate file for testing purposes.
  */
 
+const Cu = Components.utils;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+XPCOMUtils.defineLazyModuleGetter(this, "Services",
+                                  "resource://gre/modules/Services.jsm");
+
 // Module stuff
 var EXPORTED_SYMBOLS = ["CSPRep", "CSPSourceList", "CSPSource", "CSPHost",
                         "CSPWarning", "CSPError", "CSPdebug",
-                        "CSPViolationReportListener"];
+                        "CSPViolationReportListener", "CSPLocalizer"];
 
+var STRINGS_URI = "chrome://global/locale/security/csp.properties";
 
 // these are not exported
 var gIoService = Components.classes["@mozilla.org/network/io-service;1"]
                  .getService(Components.interfaces.nsIIOService);
 
 var gETLDService = Components.classes["@mozilla.org/network/effective-tld-service;1"]
                    .getService(Components.interfaces.nsIEffectiveTLDService);
 
@@ -217,17 +225,17 @@ CSPRep.fromString = function(aStr, self,
       // grab value tokens and interpret them
       var options = dirvalue.split(/\s+/);
       for each (var opt in options) {
         if (opt === "inline-script")
           aCSPR._allowInlineScripts = true;
         else if (opt === "eval-script")
           aCSPR._allowEval = true;
         else
-          CSPWarning("don't understand option '" + opt + "'.  Ignoring it.");
+          CSPWarning(CSPLocalizer.getFormatStr("doNotUnderstandOption", [opt]));
       }
       continue directive;
     }
 
     // ALLOW DIRECTIVE //////////////////////////////////////////////////
     // parse "allow" as equivalent to "default-src", at least until the spec
     // stabilizes, at which time we can stop parsing "allow"
     if (dirname === CSPRep.ALLOW_DIRECTIVE) {
@@ -270,115 +278,115 @@ CSPRep.fromString = function(aStr, self,
           uri.host;
 
           // Verify that each report URI is in the same etld + 1 and that the
           // scheme and port match "self" if "self" is defined, and just that
           // it's valid otherwise.
           if (self) {
             if (gETLDService.getBaseDomain(uri) !==
                 gETLDService.getBaseDomain(selfUri)) {
-              CSPWarning("can't use report URI from non-matching eTLD+1: "
-                         + gETLDService.getBaseDomain(uri));
+              CSPWarning(CSPLocalizer.getFormatStr("notETLDPlus1",
+                         [gETLDService.getBaseDomain(uri)]));
               continue;
             }
             if (!uri.schemeIs(selfUri.scheme)) {
-              CSPWarning("can't use report URI with different scheme from "
-                         + "originating document: " + uri.asciiSpec);
+              CSPWarning(CSPLocalizer.getFormatStr("notSameScheme",
+                         [uri.asciiSpec]));
               continue;
             }
             if (uri.port && uri.port !== selfUri.port) {
-              CSPWarning("can't use report URI with different port from "
-                         + "originating document: " + uri.asciiSpec);
+              CSPWarning(CSPLocalizer.getFormatStr("notSamePort",
+                         [uri.asciiSpec]));
               continue;
             }
           }
         } catch(e) {
           switch (e.result) {
             case Components.results.NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS:
             case Components.results.NS_ERROR_HOST_IS_IP_ADDRESS:
               if (uri.host !== selfUri.host) {
-                CSPWarning("page on " + selfUri.host
-                           + " cannot send reports to " + uri.host);
+                CSPWarning(CSPLocalizer.getFormatStr("pageCannotSendReportsTo",
+                         [selfUri.host, uri.host]));
                 continue;
               }
               break;
 
             default:
-              CSPWarning("couldn't parse report URI: " + uriStrings[i]);
+              CSPWarning(CSPLocalizer.getFormatStr("couldNotParseReportURI", [uriStrings[i]]));
               continue;
           }
         }
         // all verification passed: same ETLD+1, scheme, and port.
         okUriStrings.push(uri.asciiSpec);
       }
       aCSPR._directives[UD.REPORT_URI] = okUriStrings.join(' ');
       continue directive;
     }
 
     // POLICY URI //////////////////////////////////////////////////////////
     if (dirname === UD.POLICY_URI) {
       // POLICY_URI can only be alone
       if (aCSPR._directives.length > 0 || dirs.length > 1) {
-        CSPError("policy-uri directive can only appear alone");
+        CSPError(CSPLocalizer.getStr("policyURINotAlone"));
         return CSPRep.fromString("default-src 'none'");
       }
       // if we were called without a reference to the parent document request
       // we won't be able to suspend it while we fetch the policy -> fail closed
       if (!docRequest || !csp) {
-        CSPError("The policy-uri cannot be fetched without a parent request and a CSP.");
+        CSPError(CSPLocalizer.getStr("noParentRequest"));
         return CSPRep.fromString("default-src 'none'");
       }
 
       var uri = '';
       try {
         uri = gIoService.newURI(dirvalue, null, selfUri);
       } catch(e) {
-        CSPError("could not parse URI in policy URI: " + dirvalue);
+        CSPError(CSPLocalizer.getFormatStr("policyURIParseError", [dirvalue]));
         return CSPRep.fromString("default-src 'none'");
       }
 
       // Verify that policy URI comes from the same origin
       if (selfUri) {
         if (selfUri.host !== uri.host){
-          CSPError("can't fetch policy uri from non-matching hostname: " + uri.host);
+          CSPError(CSPLocalizer.getFormatStr("nonMatchingHost", [uri.host]));
           return CSPRep.fromString("default-src 'none'");
         }
         if (selfUri.port !== uri.port){
-          CSPError("can't fetch policy uri from non-matching port: " + uri.port);
+          CSPError(CSPLocalizer.getFormatStr("nonMatchingPort", [uri.port.toString()]));
           return CSPRep.fromString("default-src 'none'");
         }
         if (selfUri.scheme !== uri.scheme){
-          CSPError("can't fetch policy uri from non-matching scheme: " + uri.scheme);
+          CSPError(CSPLocalizer.getFormatStr("nonMatchingScheme", [uri.scheme]));
           return CSPRep.fromString("default-src 'none'");
         }
       }
 
       // suspend the parent document request while we fetch the policy-uri
       try {
         docRequest.suspend();
         var chan = gIoService.newChannel(uri.asciiSpec, null, null);
         // make request anonymous (no cookies, etc.) so the request for the
         // policy-uri can't be abused for CSRF
         chan.loadFlags |= Components.interfaces.nsIChannel.LOAD_ANONYMOUS;
         chan.asyncOpen(new CSPPolicyURIListener(uri, docRequest, csp), null);
       }
       catch (e) {
         // resume the document request and apply most restrictive policy
         docRequest.resume();
-        CSPError("Error fetching policy-uri: " + e);
+        CSPError(CSPLocalizer.getFormatStr("errorFetchingPolicy", [e.toString()]));
         return CSPRep.fromString("default-src 'none'");
       }
 
       // return a fully-open policy to be intersected with the contents of the
       // policy-uri when it returns
       return CSPRep.fromString("default-src *");
     }
 
     // UNIDENTIFIED DIRECTIVE /////////////////////////////////////////////
-    CSPWarning("Couldn't process unknown directive '" + dirname + "'");
+    CSPWarning(CSPLocalizer.getFormatStr("couldNotProcessUnknownDirective", [dirname]));
 
   } // end directive: loop
 
   // if makeExplicit fails for any reason, default to default-src 'none'.  This
   // includes the case where "default-src" is not present.
   if (aCSPR.makeExplicit())
     return aCSPR;
   return CSPRep.fromString("default-src 'none'", self);
@@ -511,17 +519,17 @@ CSPRep.prototype = {
    *      true  if the makeExplicit succeeds
    *      false if it fails (for some weird reason)
    */
   makeExplicit:
   function cspsd_makeExplicit() {
     var SD = CSPRep.SRC_DIRECTIVES;
     var defaultSrcDir = this._directives[SD.DEFAULT_SRC];
     if (!defaultSrcDir) {
-      CSPWarning("'allow' or 'default-src' directive required but not present.  Reverting to \"default-src 'none'\"");
+      CSPWarning(CSPLocalizer.getStr("allowOrDefaultSrcRequired"));
       return false;
     }
 
     for (var dir in SD) {
       var dirv = SD[dir];
       if (dirv === SD.DEFAULT_SRC) continue;
       if (!this._directives[dirv]) {
         // implicit directive, make explicit.
@@ -601,17 +609,17 @@ CSPSourceList.fromString = function(aStr
     return slObj;
   }
 
   var tokens = aStr.split(/\s+/);
   for (var i in tokens) {
     if (tokens[i] === "") continue;
     var src = CSPSource.create(tokens[i], self, enforceSelfChecks);
     if (!src) {
-      CSPWarning("Failed to parse unrecoginzied source " + tokens[i]);
+      CSPWarning(CSPLocalizer.getFormatStr("failedToParseUnrecognizedSource", [tokens[i]]));
       continue;
     }
     slObj._sources.push(src);
   }
 
   return slObj;
 };
 
@@ -827,22 +835,22 @@ CSPSource.create = function(aData, self,
  * @param enforceSelfChecks (optional)
  *        if present, and "true", will check to be sure "self" has the
  *        appropriate values to inherit when they are omitted from aURI.
  * @returns
  *        an instance of CSPSource 
  */
 CSPSource.fromURI = function(aURI, self, enforceSelfChecks) {
   if (!(aURI instanceof Components.interfaces.nsIURI)){
-    CSPError("Provided argument is not an nsIURI");
+    CSPError(CSPLocalizer.getStr("cspSourceNotURI"));
     return null;
   }
 
   if (!self && enforceSelfChecks) {
-    CSPError("Can't use 'self' if self data is not provided");
+    CSPError(CSPLocalizer.getStr("selfDataNotProvided"));
     return null;
   }
 
   if (self && !(self instanceof CSPSource)) {
     self = CSPSource.create(self, undefined, false);
   }
 
   var sObj = new CSPSource();
@@ -851,17 +859,17 @@ CSPSource.fromURI = function(aURI, self,
   // PARSE
   // If 'self' is undefined, then use default port for scheme if there is one.
 
   // grab scheme (if there is one)
   try {
     sObj._scheme = aURI.scheme;
   } catch(e) {
     sObj._scheme = undefined;
-    CSPError("can't parse a URI without a scheme: " + aURI.asciiSpec);
+    CSPError(CSPLocalizer.getFormatStr("uriWithoutScheme", [aURI.asciiSpec]));
     return null;
   }
 
   // grab host (if there is one)
   try {
     // if there's no host, an exception will get thrown
     // (NS_ERROR_FAILURE)
     sObj._host = CSPHost.fromString(aURI.host);
@@ -907,36 +915,36 @@ CSPSource.fromURI = function(aURI, self,
  * @returns
  *        an instance of CSPSource 
  */
 CSPSource.fromString = function(aStr, self, enforceSelfChecks) {
   if (!aStr)
     return null;
 
   if (!(typeof aStr === 'string')) {
-    CSPError("Provided argument is not a string");
+    CSPError(CSPLocalizer.getStr("argumentIsNotString"));
     return null;
   }
 
   if (!self && enforceSelfChecks) {
-    CSPError("Can't use 'self' if self data is not provided");
+    CSPError(CSPLocalizer.getStr("selfDataNotProvided"));
     return null;
   }
 
   if (self && !(self instanceof CSPSource)) {
     self = CSPSource.create(self, undefined, false);
   }
 
   var sObj = new CSPSource();
   sObj._self = self;
 
   // take care of 'self' keyword
   if (aStr === "'self'") {
     if (!self) {
-      CSPError("self keyword used, but no self data specified");
+      CSPError(CSPLocalizer.getStr("selfKeywordNoSelfData"));
       return null;
     }
     sObj._self = self.clone();
     sObj._isSelf = true;
     return sObj;
   }
 
   // We could just create a URI and then send this off to fromURI, but
@@ -945,25 +953,25 @@ CSPSource.fromString = function(aStr, se
 
   // split it up
   var chunks = aStr.split(":");
 
   // If there is only one chunk, it's gotta be a host.
   if (chunks.length == 1) {
     sObj._host = CSPHost.fromString(chunks[0]);
     if (!sObj._host) {
-      CSPError("Couldn't parse invalid source " + aStr);
+      CSPError(CSPLocalizer.getFormatStr("couldntParseInvalidSource",[aStr]));
       return null;
     }
 
     // enforce 'self' inheritance
     if (enforceSelfChecks) {
       // note: the non _scheme accessor checks sObj._self
       if (!sObj.scheme || !sObj.port) {
-        CSPError("Can't create host-only source " + aStr + " without 'self' data");
+        CSPError(CSPLocalizer.getFormatStr("hostSourceWithoutData",[aStr]));
         return null;
       }
     }
     return sObj;
   }
 
   // If there are two chunks, it's either scheme://host or host:port
   //   ... but scheme://host can have an empty host.
@@ -972,27 +980,27 @@ CSPSource.fromString = function(aStr, se
 
     // is the last bit a port?
     if (chunks[1] === "*" || chunks[1].match(/^\d+$/)) {
       sObj._port = chunks[1];
       // then the previous chunk *must* be a host or empty.
       if (chunks[0] !== "") {
         sObj._host = CSPHost.fromString(chunks[0]);
         if (!sObj._host) {
-          CSPError("Couldn't parse invalid source " + aStr);
+          CSPError(CSPLocalizer.getFormatStr("couldntParseInvalidSource",[aStr]));
           return null;
         }
       }
       // enforce 'self' inheritance 
       // (scheme:host requires port, host:port does too.  Wildcard support is
       // only available if the scheme and host are wildcarded)
       if (enforceSelfChecks) {
         // note: the non _scheme accessor checks sObj._self
         if (!sObj.scheme || !sObj.host || !sObj.port) {
-          CSPError("Can't create source " + aStr + " without 'self' data");
+          CSPError(CSPLocalizer.getFormatStr("sourceWithoutData",[aStr]));
           return null;
         }
       }
     }
     // is the first bit a scheme?
     else if (CSPSource.validSchemeName(chunks[0])) {
       sObj._scheme = chunks[0];
       // then the second bit *must* be a host or empty
@@ -1004,48 +1012,48 @@ CSPSource.fromString = function(aStr, se
         if (!sObj._port) sObj._port = "*";
       } else {
         // some host was defined.
         // ... remove <= 3 leading slashes (from the scheme) and parse
         var cleanHost = chunks[1].replace(/^\/{0,3}/,"");
         // ... and parse
         sObj._host = CSPHost.fromString(cleanHost);
         if (!sObj._host) {
-          CSPError("Couldn't parse invalid host " + cleanHost);
+          CSPError(CSPLocalizer.getFormatStr("couldntParseInvalidHost",[cleanHost]));
           return null;
         }
       }
 
       // enforce 'self' inheritance (scheme-only should be scheme:*:* now, and
       // if there was a host provided it should be scheme:host:selfport
       if (enforceSelfChecks) {
         // note: the non _scheme accessor checks sObj._self
         if (!sObj.scheme || !sObj.host || !sObj.port) {
-          CSPError("Can't create source " + aStr + " without 'self' data");
+          CSPError(CSPLocalizer.getFormatStr("sourceWithoutData",[aStr]));
           return null;
         }
       }
     }
     else  {
       // AAAH!  Don't know what to do!  No valid scheme or port!
-      CSPError("Couldn't parse invalid source " + aStr);
+      CSPError(CSPLocalizer.getFormatStr("couldntParseInvalidSource",[aStr]));
       return null;
     }
 
     return sObj;
   }
 
   // If there are three chunks, we got 'em all!
   if (!CSPSource.validSchemeName(chunks[0])) {
-    CSPError("Couldn't parse scheme in " + aStr);
+    CSPError(CSPLocalizer.getFormatStr("couldntParseScheme",[aStr]));
     return null;
   }
   sObj._scheme = chunks[0];
   if (!(chunks[2] === "*" || chunks[2].match(/^\d+$/))) {
-    CSPError("Couldn't parse port in " + aStr);
+    CSPError(CSPLocalizer.getFormatStr("couldntParsePort",[aStr]));
     return null;
   }
 
   sObj._port = chunks[2];
 
   // ... remove <= 3 leading slashes (from the scheme) and parse
   var cleanHost = chunks[1].replace(/^\/{0,3}/,"");
   sObj._host = CSPHost.fromString(cleanHost);
@@ -1197,58 +1205,55 @@ CSPSource.prototype = {
       newSource._port = this._port;
     else if (this._port === "*") 
       newSource._port = that._port;
     else if (that._port === "*")
       newSource._port = this._port;
     else if (that._port === this._port)
       newSource._port = this._port;
     else {
-      CSPError("Could not intersect " + this + " with " + that
-               + " due to port problems.");
+      CSPError(CSPLocalizer.getFormatStr("notIntersectPort", [this.toString(), that.toString()]));
       return null;
     }
 
     // scheme
     if (!this._scheme)
       newSource._scheme = that._scheme;
     else if (!that._scheme)
       newSource._scheme = this._scheme;
     if (this._scheme === "*")
       newSource._scheme = that._scheme;
     else if (that._scheme === "*")
       newSource._scheme = this._scheme;
     else if (that._scheme === this._scheme)
       newSource._scheme = this._scheme;
     else {
-      CSPError("Could not intersect " + this + " with " + that
-               + " due to scheme problems.");
+      CSPError(CSPLocalizer.getFormatStr("notIntersectScheme", [this.toString(), that.toString()]));
       return null;
     }
 
     // NOTE: Both sources must have a host, if they don't, something funny is
     // going on.  The fromString() factory method should have set the host to
     // * if there's no host specified in the input. Regardless, if a host is
     // not present either the scheme is hostless or any host should be allowed.
     // This means we can use the other source's host as the more restrictive
     // host expression, or if neither are present, we can use "*", but the
     // error should still be reported.
 
     // host
     if (this._host && that._host) {
       newSource._host = this._host.intersectWith(that._host);
     } else if (this._host) {
-      CSPError("intersecting source with undefined host: " + that.toString());
+      CSPError(CSPLocalizer.getFormatStr("intersectingSourceWithUndefinedHost", [that.toString()]));
       newSource._host = this._host.clone();
     } else if (that._host) {
-      CSPError("intersecting source with undefined host: " + this.toString());
+      CSPError(CSPLocalizer.getFormatStr("intersectingSourceWithUndefinedHost", [this.toString()]));
       newSource._host = that._host.clone();
     } else {
-      CSPError("intersecting two sources with undefined hosts: " +
-               this.toString() + " and " + that.toString());
+      CSPError(CSPLocalizer.getFormatStr("intersectingSourcesWithUndefinedHosts", [this.toString(), that.toString()]));
       newSource._host = CSPHost.fromString("*");
     }
 
     return newSource;
   },
 
   /**
    * Compares one CSPSource to another.
@@ -1481,8 +1486,60 @@ CSPViolationReportListener.prototype = {
   onStartRequest:
   function(request, context) { },
 
   onDataAvailable:
   function(request, context, inputStream, offset, count) { },
 
 };
 
+//////////////////////////////////////////////////////////////////////
+
+CSPLocalizer = {
+  /**
+   * Retrieve a localized string.
+   *
+   * @param string aName
+   *        The string name you want from the CSP string bundle.
+   * @return string
+   *         The localized string.
+   */
+  getStr: function CSPLoc_getStr(aName)
+  {
+    let result;
+    try {
+      result = this.stringBundle.GetStringFromName(aName);
+    }
+    catch (ex) {
+      Cu.reportError("Failed to get string: " + aName);
+      throw ex;
+    }
+    return result;
+  },
+
+  /**
+   * Retrieve a localized string formatted with values coming from the given
+   * array.
+   *
+   * @param string aName
+   *        The string name you want from the CSP string bundle.
+   * @param array aArray
+   *        The array of values you want in the formatted string.
+   * @return string
+   *         The formatted local string.
+   */
+  getFormatStr: function CSPLoc_getFormatStr(aName, aArray)
+  {
+    let result;
+    try {
+      result = this.stringBundle.formatStringFromName(aName, aArray, aArray.length);
+    }
+    catch (ex) {
+      Cu.reportError("Failed to format string: " + aName);
+      throw ex;
+    }
+    return result;
+  },
+};
+
+XPCOMUtils.defineLazyGetter(CSPLocalizer, "stringBundle", function() {
+  return Services.strings.createBundle(STRINGS_URI);
+});
--- a/content/base/src/contentSecurityPolicy.js
+++ b/content/base/src/contentSecurityPolicy.js
@@ -279,18 +279,23 @@ ContentSecurityPolicy.prototype = {
       if (aScriptSample)
         report["csp-report"]["script-sample"] = aScriptSample;
       if (aLineNum)
         report["csp-report"]["line-number"] = aLineNum;
 
       var reportString = JSON.stringify(report);
       CSPdebug("Constructed violation report:\n" + reportString);
 
-      CSPWarning("Directive \"" + violatedDirective + "\" violated"
-               + (blockedUri['asciiSpec'] ? " by " + blockedUri.asciiSpec : ""),
+      var violationMessage = null;
+      if(blockedUri["asciiSpec"]){
+         violationMessage = CSPLocalizer.getFormatStr("directiveViolatedWithURI", [violatedDirective, blockedUri.asciiSpec]);
+      } else {
+         violationMessage = CSPLocalizer.getFormatStr("directiveViolated", [violatedDirective]);
+      }
+      CSPWarning(violationMessage,
                  this.innerWindowID,
                  (aSourceFile) ? aSourceFile : null,
                  (aScriptSample) ? decodeURIComponent(aScriptSample) : null,
                  (aLineNum) ? aLineNum : null);
 
       // For each URI in the report list, send out a report.
       // We make the assumption that all of the URIs are absolute URIs; this
       // should be taken care of in CSPRep.fromString (where it converts any
@@ -342,18 +347,18 @@ ContentSecurityPolicy.prototype = {
           }
 
           //send data (and set up error notifications)
           chan.asyncOpen(new CSPViolationReportListener(uris[i]), null);
           CSPdebug("Sent violation report to " + uris[i]);
         } catch(e) {
           // it's possible that the URI was invalid, just log a
           // warning and skip over that.
-          CSPWarning("Tried to send report to invalid URI: \"" + uris[i] + "\"", this.innerWindowID);
-          CSPWarning("error was: \"" + e + "\"", this.innerWindowID);
+          CSPWarning(CSPLocalizer.getFormatStr("triedToSendReport", [uris[i]]), this.innerWindowID);
+          CSPWarning(CSPLocalizer.getFormatStr("errorWas", [e.toString()]), this.innerWindowID);
         }
       }
     }
   },
 
   /**
    * Exposed Method to analyze docShell for approved frame ancestry.
    * Also sends violation reports if necessary.
@@ -545,18 +550,17 @@ CSPReportRedirectSink.prototype = {
       return this;
 
     throw Components.results.NS_ERROR_NO_INTERFACE;
   },
 
   // nsIChannelEventSink
   asyncOnChannelRedirect: function channel_redirect(oldChannel, newChannel,
                                                     flags, callback) {
-    CSPWarning("Post of violation report to " + oldChannel.URI.asciiSpec +
-               " failed, as a redirect occurred", this.innerWindowID);
+    CSPWarning(CSPLocalizer.getFormatStr("reportPostRedirect", [oldChannel.URI.asciiSpec]));
 
     // cancel the old channel so XHR failure callback happens
     oldChannel.cancel(Cr.NS_ERROR_ABORT);
 
     // notify an observer that we have blocked the report POST due to a redirect,
     // used in testing, do this async since we're in an async call now to begin with
     Services.tm.mainThread.dispatch(
       function() {
--- a/content/base/src/nsContentIterator.cpp
+++ b/content/base/src/nsContentIterator.cpp
@@ -1263,34 +1263,39 @@ nsContentSubtreeIterator::Init(nsIDOMRan
   // node.
   mFirst = GetTopAncestorInRange(firstCandidate);
 
   // now to find the last node
   offset = mRange->EndOffset();
   PRInt32 numChildren = endParent->GetChildCount();
 
   if (offset > numChildren) {
+    // Can happen for text nodes -- or if we're being called from
+    // nsNodeUtils::ContentRemoved and the range hasn't been adjusted yet (bug
+    // 767169).
     offset = numChildren;
   }
-  if (!offset) {
-    node = endParent;
-  } else if (!numChildren) {
-    // no children, must be a text node
+  if (!offset || !numChildren) {
     node = endParent;
   } else {
     lastCandidate = endParent->GetChildAt(--offset);
     NS_ASSERTION(lastCandidate,
                  "tree traversal trouble in nsContentSubtreeIterator::Init");
   }
 
   if (!lastCandidate) {
     // then lastCandidate is prev node before node
     lastCandidate = GetPrevSibling(node);
   }
 
+  if (!lastCandidate) {
+    MakeEmpty();
+    return NS_OK;
+  }
+
   lastCandidate = GetDeepLastChild(lastCandidate);
 
   // confirm that this last possible contained node is indeed contained.  Else
   // we have a range that does not fully contain any node.
 
   MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
     nsRange::CompareNodeToRange(lastCandidate, mRange, &nodeBefore, &nodeAfter)));
 
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -24,16 +24,17 @@
 #include "nsDOMCID.h"
 #include "nsContentUtils.h"
 #include "nsIXPConnect.h"
 #include "nsIContent.h"
 #include "mozilla/dom/Element.h"
 #include "nsIDocument.h"
 #include "nsINodeInfo.h"
 #include "nsReadableUtils.h"
+#include "nsIIdleService.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMNodeList.h"
 #include "nsIDOMNode.h"
 #include "nsIIOService.h"
 #include "nsNetCID.h"
 #include "nsNetUtil.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsDOMError.h"
@@ -238,16 +239,17 @@ nsString* nsContentUtils::sShiftText = n
 nsString* nsContentUtils::sControlText = nsnull;
 nsString* nsContentUtils::sMetaText = nsnull;
 nsString* nsContentUtils::sAltText = nsnull;
 nsString* nsContentUtils::sModifierSeparator = nsnull;
 
 bool nsContentUtils::sInitialized = false;
 bool nsContentUtils::sIsFullScreenApiEnabled = false;
 bool nsContentUtils::sTrustedFullScreenOnly = true;
+bool nsContentUtils::sIsIdleObserverAPIEnabled = false;
 
 PRUint32 nsContentUtils::sHandlingInputTimeout = 1000;
 
 nsHtml5StringParser* nsContentUtils::sHTMLFragmentParser = nsnull;
 nsIParser* nsContentUtils::sXMLFragmentParser = nsnull;
 nsIFragmentContentSink* nsContentUtils::sXMLFragmentSink = nsnull;
 bool nsContentUtils::sFragmentParsingActive = false;
 
@@ -413,16 +415,18 @@ nsContentUtils::Init()
                                "dom.allow_XUL_XBL_for_file");
 
   Preferences::AddBoolVarCache(&sIsFullScreenApiEnabled,
                                "full-screen-api.enabled");
 
   Preferences::AddBoolVarCache(&sTrustedFullScreenOnly,
                                "full-screen-api.allow-trusted-requests-only");
 
+  sIsIdleObserverAPIEnabled = Preferences::GetBool("dom.idle-observers-api.enabled", true);
+
   Preferences::AddUintVarCache(&sHandlingInputTimeout,
                                "dom.event.handling-user-input-time-limit",
                                1000);
 
   nsGenericElement::InitCCCallbacks();
 
   sInitialized = true;
 
@@ -864,16 +868,32 @@ nsContentUtils::SplitMimeType(const nsAS
     aParams.StripWhitespace();
   }
   else {
     aType = aValue;
   }
   aType.StripWhitespace();
 }
 
+nsresult 
+nsContentUtils::IsUserIdle(PRUint32 aRequestedIdleTimeInMS, bool* aUserIsIdle)
+{
+  nsresult rv;
+  nsCOMPtr<nsIIdleService> idleService = 
+    do_GetService("@mozilla.org/widget/idleservice;1", &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+    
+  PRUint32 idleTimeInMS;
+  rv = idleService->GetIdleTime(&idleTimeInMS);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  *aUserIsIdle = idleTimeInMS >= aRequestedIdleTimeInMS;
+  return NS_OK;
+}
+
 /**
  * Access a cached parser service. Don't addref. We need only one
  * reference to it and this class has that one.
  */
 /* static */
 nsIParserService*
 nsContentUtils::GetParserService()
 {
--- a/content/base/src/nsFrameLoader.cpp
+++ b/content/base/src/nsFrameLoader.cpp
@@ -103,24 +103,16 @@ public:
     if (base_win) {
       base_win->Destroy();
     }
     return NS_OK;
   }
   nsRefPtr<nsIDocShell> mDocShell;
 };
 
-static void InvalidateFrame(nsIFrame* aFrame, PRUint32 aFlags)
-{
-  if (!aFrame)
-    return;
-  nsRect rect = nsRect(nsPoint(0, 0), aFrame->GetRect().Size());
-  aFrame->InvalidateWithFlags(rect, aFlags);
-}
-
 NS_IMPL_ISUPPORTS1(nsContentView, nsIContentView)
 
 bool
 nsContentView::IsRoot() const
 {
   return mScrollId == FrameMetrics::ROOT_SCROLL_ID;
 }
 
@@ -145,23 +137,16 @@ nsContentView::Update(const ViewConfig& 
       return NS_ERROR_NOT_AVAILABLE;
     }
   }
 
   if (RenderFrameParent* rfp = mFrameLoader->GetCurrentRemoteFrame()) {
     rfp->ContentViewScaleChanged(this);
   }
 
-  // XXX could be clever here and compute a smaller invalidation
-  // rect
-  // NB: we pass INVALIDATE_NO_THEBES_LAYERS here to keep view
-  // semantics the same for both in-process and out-of-process
-  // <browser>.  This is just a transform of the layer subtree in
-  // both.
-  InvalidateFrame(mFrameLoader->GetPrimaryFrameOfOwningContent(), nsIFrame::INVALIDATE_NO_THEBES_LAYERS);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsContentView::ScrollTo(float aXpx, float aYpx)
 {
   ViewConfig config(mConfig);
   config.mScrollOffset = nsPoint(nsPresContext::CSSPixelsToAppUnits(aXpx),
@@ -617,17 +602,17 @@ SetTreeOwnerAndChromeEventHandlerOnDocsh
     nsCOMPtr<nsIDocShellTreeItem> item;
     aItem->GetChildAt(i, getter_AddRefs(item));
     SetTreeOwnerAndChromeEventHandlerOnDocshellTree(item, aOwner, aHandler);
   }
 }
 
 /**
  * Set the type of the treeitem and hook it up to the treeowner.
- * @param aItem the treeitem we're wrking working with
+ * @param aItem the treeitem we're working with
  * @param aOwningContent the content node that owns aItem
  * @param aTreeOwner the relevant treeowner; might be null
  * @param aParentType the nsIDocShellTreeItem::GetType of our parent docshell
  * @param aParentNode if non-null, the docshell we should be added as a child to
  *
  * @return whether aItem is top-level content
  */
 static bool
@@ -638,16 +623,18 @@ AddTreeItemToTreeOwner(nsIDocShellTreeIt
   NS_PRECONDITION(aItem, "Must have docshell treeitem");
   NS_PRECONDITION(aOwningContent, "Must have owning content");
   
   nsAutoString value;
   bool isContent = false;
 
   if (aOwningContent->IsXUL()) {
       aOwningContent->GetAttr(kNameSpaceID_None, nsGkAtoms::type, value);
+  } else {
+      aOwningContent->GetAttr(kNameSpaceID_None, nsGkAtoms::mozframetype, value);
   }
 
   // we accept "content" and "content-xxx" values.
   // at time of writing, we expect "xxx" to be "primary" or "targetable", but
   // someday it might be an integer expressing priority or something else.
 
   isContent = value.LowerCaseEqualsLiteral("content") ||
     StringBeginsWith(value, NS_LITERAL_STRING("content-"),
@@ -1738,21 +1725,16 @@ nsFrameLoader::GetRenderMode(PRUint32* a
 NS_IMETHODIMP
 nsFrameLoader::SetRenderMode(PRUint32 aRenderMode)
 {
   if (aRenderMode == mRenderMode) {
     return NS_OK;
   }
 
   mRenderMode = aRenderMode;
-  // NB: we pass INVALIDATE_NO_THEBES_LAYERS here to keep view
-  // semantics the same for both in-process and out-of-process
-  // <browser>.  This is just a transform of the layer subtree in
-  // both.
-  InvalidateFrame(GetPrimaryFrameOfOwningContent(), nsIFrame::INVALIDATE_NO_THEBES_LAYERS);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsFrameLoader::GetEventMode(PRUint32* aEventMode)
 {
   *aEventMode = mEventMode;
   return NS_OK;
@@ -1773,17 +1755,17 @@ nsFrameLoader::GetClipSubdocument(bool* 
 }
 
 NS_IMETHODIMP
 nsFrameLoader::SetClipSubdocument(bool aClip)
 {
   mClipSubdocument = aClip;
   nsIFrame* frame = GetPrimaryFrameOfOwningContent();
   if (frame) {
-    InvalidateFrame(frame, 0);
+    frame->InvalidateFrame();
     frame->PresContext()->PresShell()->
       FrameNeedsReflow(frame, nsIPresShell::eResize, NS_FRAME_IS_DIRTY);
     nsSubDocumentFrame* subdocFrame = do_QueryFrame(frame);
     if (subdocFrame) {
       nsIFrame* subdocRootFrame = subdocFrame->GetSubdocumentRootFrame();
       if (subdocRootFrame) {
         nsIFrame* subdocRootScrollFrame = subdocRootFrame->PresContext()->PresShell()->
           GetRootScrollFrame();
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -26,16 +26,17 @@
 #endif 
 
 //---------------------------------------------------------------------------
 // Generic atoms
 //---------------------------------------------------------------------------
 
 GK_ATOM(_empty, "")
 GK_ATOM(moz, "_moz")
+GK_ATOM(mozframetype, "mozframetype")
 GK_ATOM(mozallowfullscreen, "mozallowfullscreen")
 GK_ATOM(moztype, "_moz-type")
 GK_ATOM(mozdirty, "_moz_dirty")
 GK_ATOM(mozdonotsend, "moz-do-not-send")
 GK_ATOM(mozeditorbogusnode, "_moz_editor_bogus_node")
 GK_ATOM(mozgeneratedcontentbefore, "_moz_generated_content_before")
 GK_ATOM(mozgeneratedcontentafter, "_moz_generated_content_after")
 GK_ATOM(mozgeneratedcontentimage, "_moz_generated_content_image")
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -1095,17 +1095,17 @@ nsObjectLoadingContent::HasNewFrame(nsIO
   DisconnectFrame();
 
   // Set up relationship between instance owner and frame.
   nsObjectFrame *objFrame = static_cast<nsObjectFrame*>(aFrame);
   mInstanceOwner->SetFrame(objFrame);
 
   // Set up new frame to draw.
   objFrame->FixupWindow(objFrame->GetContentRectRelativeToSelf().Size());
-  objFrame->Invalidate(objFrame->GetContentRectRelativeToSelf());
+  objFrame->InvalidateFrame();
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsObjectLoadingContent::DisconnectFrame()
 {
   if (mInstanceOwner) {
--- a/content/base/test/test_blobconstructor.html
+++ b/content/base/test/test_blobconstructor.html
@@ -46,26 +46,47 @@ try {
 blob = Blob(null);
 ok(false, "NOT REACHED");
 } catch(e) {
 ok(true, "a null blobParts member should throw");
 }
 
 try {
 blob = Blob([], null);
-ok(false, "NOT REACHED");
+ok(true, "a null options member should not throw");
 } catch(e) {
-ok(true, "a null options member should throw");
+ok(false, "NOT REACHED");
 }
 
 try {
 blob = Blob([], undefined);
+ok(true, "an undefined options member should not throw");
+} catch(e) {
+ok(false, "NOT REACHED");
+}
+
+try {
+blob = Blob([], false);
 ok(false, "NOT REACHED");
 } catch(e) {
-ok(true, "an undefined options member should throw");
+ok(true, "a boolean options member should throw");
+}
+
+try {
+blob = Blob([], 0);
+ok(false, "NOT REACHED");
+} catch(e) {
+ok(true, "a numeric options member should throw");
+}
+
+try {
+blob = Blob([], "");
+ok(false, "NOT REACHED");
+} catch(e) {
+ok(true, "a string options member should throw");
 }
 
 /** Test for dictionary initialization order **/
 (function() {
   var o = {};
   var p = {type: "text/plain", endings: "transparent"};
   var called = [];
   function add_to_called(n) {
--- a/content/canvas/public/nsICanvasRenderingContextInternal.h
+++ b/content/canvas/public/nsICanvasRenderingContextInternal.h
@@ -124,12 +124,20 @@ public:
   // anything into this canvas before changing the shmem state, it will be
   // lost.
   NS_IMETHOD SetIsIPC(bool isIPC) = 0;
 
 protected:
   nsRefPtr<nsHTMLCanvasElement> mCanvasElement;
 };
 
+namespace mozilla {
+namespace dom {
+
+extern bool AzureCanvasEnabled();
+
+}
+}
+
 NS_DEFINE_STATIC_IID_ACCESSOR(nsICanvasRenderingContextInternal,
                               NS_ICANVASRENDERINGCONTEXTINTERNAL_IID)
 
 #endif /* nsICanvasRenderingContextInternal_h___ */
--- a/content/canvas/src/CanvasImageCache.cpp
+++ b/content/canvas/src/CanvasImageCache.cpp
@@ -4,27 +4,29 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "CanvasImageCache.h"
 #include "nsIImageLoadingContent.h"
 #include "nsExpirationTracker.h"
 #include "imgIRequest.h"
 #include "gfxASurface.h"
 #include "gfxPoint.h"
-#include "nsIDOMElement.h"
+#include "mozilla/dom/Element.h"
 #include "nsTHashtable.h"
 #include "nsHTMLCanvasElement.h"
 #include "nsContentUtils.h"
 
 namespace mozilla {
 
+using namespace dom;
+
 struct ImageCacheKey {
-  ImageCacheKey(nsIDOMElement* aImage, nsHTMLCanvasElement* aCanvas)
+  ImageCacheKey(Element* aImage, nsHTMLCanvasElement* aCanvas)
     : mImage(aImage), mCanvas(aCanvas) {}
-  nsIDOMElement* mImage;
+  Element* mImage;
   nsHTMLCanvasElement* mCanvas;
 };
 
 struct ImageCacheEntryData {
   ImageCacheEntryData(const ImageCacheEntryData& aOther)
     : mImage(aOther.mImage)
     , mILC(aOther.mILC)
     , mCanvas(aOther.mCanvas)
@@ -36,17 +38,17 @@ struct ImageCacheEntryData {
     : mImage(aKey.mImage)
     , mILC(nsnull)
     , mCanvas(aKey.mCanvas)
   {}
 
   nsExpirationState* GetExpirationState() { return &mState; }
 
   // Key
-  nsCOMPtr<nsIDOMElement> mImage;
+  nsRefPtr<Element> mImage;
   nsIImageLoadingContent* mILC;
   nsRefPtr<nsHTMLCanvasElement> mCanvas;
   // Value
   nsCOMPtr<imgIRequest> mRequest;
   nsRefPtr<gfxASurface> mSurface;
   gfxIntSize mSize;
   nsExpirationState mState;
 };
@@ -105,17 +107,17 @@ static ImageCache* gImageCache = nsnull;
 class CanvasImageCacheShutdownObserver MOZ_FINAL : public nsIObserver
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIOBSERVER
 };
 
 void
-CanvasImageCache::NotifyDrawImage(nsIDOMElement* aImage,
+CanvasImageCache::NotifyDrawImage(Element* aImage,
                                   nsHTMLCanvasElement* aCanvas,
                                   imgIRequest* aRequest,
                                   gfxASurface* aSurface,
                                   const gfxIntSize& aSize)
 {
   if (!gImageCache) {
     gImageCache = new ImageCache();
     nsContentUtils::RegisterShutdownObserver(new CanvasImageCacheShutdownObserver());
@@ -136,17 +138,17 @@ CanvasImageCache::NotifyDrawImage(nsIDOM
     }
     entry->mData->mILC = ilc;
     entry->mData->mSurface = aSurface;
     entry->mData->mSize = aSize;
   }
 }
 
 gfxASurface*
-CanvasImageCache::Lookup(nsIDOMElement* aImage,
+CanvasImageCache::Lookup(Element* aImage,
                          nsHTMLCanvasElement* aCanvas,
                          gfxIntSize* aSize)
 {
   if (!gImageCache)
     return nsnull;
 
   ImageCacheEntry* entry = gImageCache->mCache.GetEntry(ImageCacheKey(aImage, aCanvas));
   if (!entry || !entry->mData->mILC)
--- a/content/canvas/src/CanvasImageCache.h
+++ b/content/canvas/src/CanvasImageCache.h
@@ -1,44 +1,48 @@
 /* -*- Mode: C++; tab-width: 2; 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/. */
 
 #ifndef CANVASIMAGECACHE_H_
 #define CANVASIMAGECACHE_H_
 
-class nsIDOMElement;
+namespace mozilla {
+namespace dom {
+class Element;
+} // namespace dom
+} // namespace mozilla
 class nsHTMLCanvasElement;
 class imgIRequest;
 class gfxASurface;
 
 #include "gfxPoint.h"
 
 namespace mozilla {
 
 class CanvasImageCache {
 public:
   /**
    * Notify that image element aImage was (or is about to be) drawn to aCanvas
    * using the first frame of aRequest's image. The data for the surface is
    * in aSurface, and the image size is in aSize.
    */
-  static void NotifyDrawImage(nsIDOMElement* aImage,
+  static void NotifyDrawImage(dom::Element* aImage,
                               nsHTMLCanvasElement* aCanvas,
                               imgIRequest* aRequest,
                               gfxASurface* aSurface,
                               const gfxIntSize& aSize);
 
   /**
    * Check whether aImage has recently been drawn into aCanvas. If we return
    * a non-null surface, then the image was recently drawn into the canvas
    * (with the same image request) and the returned surface contains the image
    * data, and the image size will be returned in aSize.
    */
-  static gfxASurface* Lookup(nsIDOMElement* aImage,
+  static gfxASurface* Lookup(dom::Element* aImage,
                              nsHTMLCanvasElement* aCanvas,
                              gfxIntSize* aSize);
 };
 
 }
 
 #endif /* CANVASIMAGECACHE_H_ */
--- a/content/canvas/src/ImageData.cpp
+++ b/content/canvas/src/ImageData.cpp
@@ -3,16 +3,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 "mozilla/dom/ImageData.h"
 
 #include "nsDOMClassInfoID.h"
 #include "nsContentUtils.h"
+#include "mozilla/dom/CanvasRenderingContext2DBinding.h"
 
 #include "jsapi.h"
 
 DOMCI_DATA(ImageData, mozilla::dom::ImageData)
 
 namespace mozilla {
 namespace dom {
 
--- a/content/canvas/src/ImageData.h
+++ b/content/canvas/src/ImageData.h
@@ -46,16 +46,20 @@ public:
   uint32_t GetWidth()
   {
     return mWidth;
   }
   uint32_t GetHeight()
   {
     return mHeight;
   }
+  JSObject* GetData(JSContext* cx)
+  {
+    return GetDataObject();
+  }
   JSObject* GetDataObject()
   {
     xpc_UnmarkGrayObject(mData);
     return mData;
   }
 
 private:
   void HoldData();
--- a/content/canvas/src/Makefile.in
+++ b/content/canvas/src/Makefile.in
@@ -72,12 +72,13 @@ include $(topsrcdir)/ipc/chromium/chromi
 CXXFLAGS	+= $(MOZ_CAIRO_CFLAGS) $(MOZ_PIXMAN_CFLAGS) $(TK_CFLAGS)
 
 INCLUDES	+= \
 		-I$(srcdir)/../../../layout/xul/base/src \
 		-I$(srcdir)/../../../layout/style \
 		-I$(srcdir)/../../../layout/generic \
 		-I$(srcdir)/../../base/src \
 		-I$(srcdir)/../../html/content/src \
+		-I$(srcdir)/../../../js/xpconnect/src \
 		-I$(srcdir)/../../../dom/base \
 		$(NULL)
 
 DEFINES += -D_IMPL_NS_LAYOUT
--- a/content/canvas/src/nsCanvasRenderingContext2D.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp
@@ -1417,30 +1417,30 @@ nsCanvasRenderingContext2D::GetCanvas(ns
     return NS_OK;
 }
 
 //
 // state
 //
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::Save()
+nsCanvasRenderingContext2D::MozSave()
 {
     if (!EnsureSurface())
         return NS_ERROR_FAILURE;
 
     ContextState state = CurrentState();
     mStyleStack.AppendElement(state);
     mThebes->Save();
     mSaveCount++;
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::Restore()
+nsCanvasRenderingContext2D::MozRestore()
 {
     if (!EnsureSurface()) 
         return NS_ERROR_FAILURE;
 
     if (mSaveCount == 0)
         return NS_OK;
 
     mStyleStack.RemoveElementAt(mSaveCount);
@@ -1946,32 +1946,32 @@ nsCanvasRenderingContext2D::SetShadowBlu
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::GetShadowBlur(float *blur)
 {
     *blur = CurrentState().shadowBlur;
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::SetShadowColor(const nsAString& aColor)
+nsCanvasRenderingContext2D:: SetMozShadowColor(const nsAString& aColor)
 {
     nscolor color;
     if (!ParseColor(aColor, &color)) {
         return NS_OK;
     }
 
     CurrentState().SetColorStyle(STYLE_SHADOW, color);
 
     mDirtyStyle[STYLE_SHADOW] = true;
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::GetShadowColor(nsAString& color)
+nsCanvasRenderingContext2D::GetMozShadowColor(nsAString& color)
 {
     StyleColorToString(CurrentState().colorStyles[STYLE_SHADOW], color);
 
     return NS_OK;
 }
 
 static const gfxFloat SIGMA_MAX = 100;
 
@@ -2212,58 +2212,58 @@ nsCanvasRenderingContext2D::StrokeRect(f
     return DrawRect(gfxRect(x, y, w, h), STYLE_STROKE);
 }
 
 //
 // path bits
 //
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::BeginPath()
+nsCanvasRenderingContext2D::MozBeginPath()
 {
     if (!EnsureSurface())
         return NS_ERROR_FAILURE;
 
     mHasPath = false;
     mThebes->NewPath();
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::ClosePath()
+nsCanvasRenderingContext2D::MozClosePath()
 {
     if (!EnsureSurface())
         return NS_ERROR_FAILURE;
 
     mThebes->ClosePath();
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::Fill()
+nsCanvasRenderingContext2D::MozFill()
 {
     gfxRect dirty;
     nsresult rv = DrawPath(STYLE_FILL, &dirty);
     if (NS_FAILED(rv))
         return rv;
     return RedrawUser(dirty);
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::Stroke()
+nsCanvasRenderingContext2D::MozStroke()
 {
     gfxRect dirty;
     nsresult rv = DrawPath(STYLE_STROKE, &dirty);
     if (NS_FAILED(rv))
         return rv;
     return RedrawUser(dirty);
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::Clip()
+nsCanvasRenderingContext2D::MozClip()
 {
     if (!EnsureSurface())
         return NS_ERROR_FAILURE;
 
     mThebes->Clip();
     return NS_OK;
 }
 
@@ -2482,17 +2482,17 @@ CreateFontStyleRule(const nsAString& aFo
 
     rule->RuleMatched();
 
     rule.forget(aResult);
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::SetFont(const nsAString& font)
+nsCanvasRenderingContext2D::SetMozFont(const nsAString& font)
 {
     nsresult rv;
 
     /*
      * If font is defined with relative units (e.g. ems) and the parent
      * style context changes in between calls, setting the font to the
      * same value as previous could result in a different computed value,
      * so we cannot have the optimization where we check if the new font
@@ -2611,44 +2611,44 @@ nsCanvasRenderingContext2D::SetFont(cons
     // the spec required font sizes be converted to pixels, but that no
     // longer seems to be required.)
     declaration->GetValue(eCSSProperty_font, CurrentState().font);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::GetFont(nsAString& font)
+nsCanvasRenderingContext2D::GetMozFont(nsAString& font)
 {
     /* will initilize the value if not set, else does nothing */
     GetCurrentFontStyle();
 
     font = CurrentState().font;
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::SetTextAlign(const nsAString& ta)
+nsCanvasRenderingContext2D::SetMozTextAlign(const nsAString& ta)
 {
     if (ta.EqualsLiteral("start"))
         CurrentState().textAlign = TEXT_ALIGN_START;
     else if (ta.EqualsLiteral("end"))
         CurrentState().textAlign = TEXT_ALIGN_END;
     else if (ta.EqualsLiteral("left"))
         CurrentState().textAlign = TEXT_ALIGN_LEFT;
     else if (ta.EqualsLiteral("right"))
         CurrentState().textAlign = TEXT_ALIGN_RIGHT;
     else if (ta.EqualsLiteral("center"))
         CurrentState().textAlign = TEXT_ALIGN_CENTER;
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::GetTextAlign(nsAString& ta)
+nsCanvasRenderingContext2D::GetMozTextAlign(nsAString& ta)
 {
     switch (CurrentState().textAlign)
     {
     case TEXT_ALIGN_START:
         ta.AssignLiteral("start");
         break;
     case TEXT_ALIGN_END:
         ta.AssignLiteral("end");
@@ -2663,17 +2663,17 @@ nsCanvasRenderingContext2D::GetTextAlign
         ta.AssignLiteral("center");
         break;
     }
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::SetTextBaseline(const nsAString& tb)
+nsCanvasRenderingContext2D::SetMozTextBaseline(const nsAString& tb)
 {
     if (tb.EqualsLiteral("top"))
         CurrentState().textBaseline = TEXT_BASELINE_TOP;
     else if (tb.EqualsLiteral("hanging"))
         CurrentState().textBaseline = TEXT_BASELINE_HANGING;
     else if (tb.EqualsLiteral("middle"))
         CurrentState().textBaseline = TEXT_BASELINE_MIDDLE;
     else if (tb.EqualsLiteral("alphabetic"))
@@ -2682,17 +2682,17 @@ nsCanvasRenderingContext2D::SetTextBasel
         CurrentState().textBaseline = TEXT_BASELINE_IDEOGRAPHIC;
     else if (tb.EqualsLiteral("bottom"))
         CurrentState().textBaseline = TEXT_BASELINE_BOTTOM;
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::GetTextBaseline(nsAString& tb)
+nsCanvasRenderingContext2D::GetMozTextBaseline(nsAString& tb)
 {
     switch (CurrentState().textBaseline)
     {
     case TEXT_BASELINE_TOP:
         tb.AssignLiteral("top");
         break;
     case TEXT_BASELINE_HANGING:
         tb.AssignLiteral("hanging");
@@ -3109,35 +3109,35 @@ nsCanvasRenderingContext2D::DrawOrMeasur
 
     if (aOp == nsCanvasRenderingContext2D::TEXT_DRAW_OPERATION_FILL && !doDrawShadow)
         return RedrawUser(boundingBox);
 
     return Redraw();
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::SetMozTextStyle(const nsAString& textStyle)
+nsCanvasRenderingContext2D::SetTextStyle(const nsAString& textStyle)
 {
     // font and mozTextStyle are the same value
-    return SetFont(textStyle);
+    return SetMozFont(textStyle);
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::GetMozTextStyle(nsAString& textStyle)
+nsCanvasRenderingContext2D::GetTextStyle(nsAString& textStyle)
 {
     // font and mozTextStyle are the same value
-    return GetFont(textStyle);
+    return GetMozFont(textStyle);
 }
 
 gfxFontGroup*
 nsCanvasRenderingContext2D::GetCurrentFontStyle()
 {
     // use lazy initilization for the font group since it's rather expensive
     if(!CurrentState().fontGroup) {
-        nsresult rv = SetMozTextStyle(kDefaultFontStyle);
+        nsresult rv = SetTextStyle(kDefaultFontStyle);
         if (NS_FAILED(rv)) {
             gfxFontStyle style;
             style.size = kDefaultFontSize;
             CurrentState().fontGroup =
                 gfxPlatform::GetPlatform()->CreateFontGroup(kDefaultFontName,
                                                             &style,
                                                             nsnull);
             if (CurrentState().fontGroup) {
@@ -3192,17 +3192,17 @@ nsCanvasRenderingContext2D::GetLineWidth
         return NS_ERROR_FAILURE;
  
     gfxFloat d = mThebes->CurrentLineWidth();
     *width = static_cast<float>(d);
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::SetLineCap(const nsAString& capstyle)
+nsCanvasRenderingContext2D::SetMozLineCap(const nsAString& capstyle)
 {
     if (!EnsureSurface())
         return NS_ERROR_FAILURE;
 
     gfxContext::GraphicsLineCap cap;
 
     if (capstyle.EqualsLiteral("butt"))
         cap = gfxContext::LINE_CAP_BUTT;
@@ -3214,17 +3214,17 @@ nsCanvasRenderingContext2D::SetLineCap(c
         // XXX ERRMSG we need to report an error to developers here! (bug 329026)
         return NS_OK;
 
     mThebes->SetLineCap(cap);
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::GetLineCap(nsAString& capstyle)
+nsCanvasRenderingContext2D::GetMozLineCap(nsAString& capstyle)
 {
     if (!EnsureSurface())
         return NS_ERROR_FAILURE;
 
     gfxContext::GraphicsLineCap cap = mThebes->CurrentLineCap();
 
     if (cap == gfxContext::LINE_CAP_BUTT)
         capstyle.AssignLiteral("butt");
@@ -3234,17 +3234,17 @@ nsCanvasRenderingContext2D::GetLineCap(n
         capstyle.AssignLiteral("square");
     else
         return NS_ERROR_FAILURE;
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::SetLineJoin(const nsAString& joinstyle)
+nsCanvasRenderingContext2D::SetMozLineJoin(const nsAString& joinstyle)
 {
     if (!EnsureSurface())
         return NS_ERROR_FAILURE;
 
     gfxContext::GraphicsLineJoin j;
 
     if (joinstyle.EqualsLiteral("round"))
         j = gfxContext::LINE_JOIN_ROUND;
@@ -3256,17 +3256,17 @@ nsCanvasRenderingContext2D::SetLineJoin(
         // XXX ERRMSG we need to report an error to developers here! (bug 329026)
         return NS_OK;
 
     mThebes->SetLineJoin(j);
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2D::GetLineJoin(nsAString& joinstyle)
+nsCanvasRenderingContext2D::GetMozLineJoin(nsAString& joinstyle)
 {
     if (!EnsureSurface())
         return NS_ERROR_FAILURE;
 
     gfxContext::GraphicsLineJoin j = mThebes->CurrentLineJoin();
 
     if (j == gfxContext::LINE_JOIN_ROUND)
         joinstyle.AssignLiteral("round");
@@ -3417,17 +3417,17 @@ nsCanvasRenderingContext2D::DrawImage(ns
             return NS_ERROR_DOM_INVALID_STATE_ERR;
         }
     }
 
     gfxMatrix matrix;
     nsRefPtr<gfxPattern> pattern;
     gfxIntSize imgSize;
     nsRefPtr<gfxASurface> imgsurf =
-      CanvasImageCache::Lookup(imgElt, mCanvasElement, &imgSize);
+      CanvasImageCache::Lookup(content->AsElement(), mCanvasElement, &imgSize);
 
     if (!imgsurf) {
         // The canvas spec says that drawImage should draw the first frame
         // of animated images
         PRUint32 sfeFlags = nsLayoutUtils::SFE_WANT_FIRST_FRAME;
         nsLayoutUtils::SurfaceFromElementResult res =
             nsLayoutUtils::SurfaceFromElement(content->AsElement(), sfeFlags);
         if (!res.mSurface) {
@@ -3451,17 +3451,17 @@ nsCanvasRenderingContext2D::DrawImage(ns
         if (mCanvasElement) {
             CanvasUtils::DoDrawImageSecurityCheck(mCanvasElement,
                                                   res.mPrincipal,
                                                   res.mIsWriteOnly,
                                                   res.mCORSUsed);
         }
 
         if (res.mImageRequest) {
-            CanvasImageCache::NotifyDrawImage(imgElt, mCanvasElement,
+            CanvasImageCache::NotifyDrawImage(content->AsElement(), mCanvasElement,
                                               res.mImageRequest, imgsurf, imgSize);
         }
     }
 
     double sx,sy,sw,sh;
     double dx,dy,dw,dh;
     if (optional_argc == 0) {
         dx = a1;
--- a/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
@@ -1,29 +1,28 @@
 /* -*- Mode: C++; tab-width: 2; 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 "base/basictypes.h"
+#include "nsCanvasRenderingContext2DAzure.h"
 
 #include "nsIDOMXULElement.h"
 
 #include "prmem.h"
 #include "prenv.h"
 
 #include "nsIServiceManager.h"
 #include "nsMathUtils.h"
 
 #include "nsContentUtils.h"
 
 #include "nsIDOMDocument.h"
 #include "nsIDocument.h"
-#include "nsIDOMCanvasRenderingContext2D.h"
-#include "nsICanvasRenderingContextInternal.h"
 #include "nsHTMLCanvasElement.h"
 #include "nsSVGEffects.h"
 #include "nsPresContext.h"
 #include "nsIPresShell.h"
 #include "nsIVariant.h"
 
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIFrame.h"
@@ -78,24 +77,31 @@
 #include "jsapi.h"
 #include "jsfriendapi.h"
 
 #include "mozilla/Assertions.h"
 #include "mozilla/CheckedInt.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/ImageData.h"
 #include "mozilla/dom/PBrowserParent.h"
+#include "mozilla/dom/TypedArray.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/PathHelpers.h"
 #include "mozilla/ipc/DocumentRendererParent.h"
 #include "mozilla/ipc/PDocumentRendererParent.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/unused.h"
 #include "nsCCUncollectableMarker.h"
 #include "nsWrapperCacheInlines.h"
+#include "nsJSUtils.h"
+#include "XPCQuickStubs.h"
+#include "mozilla/dom/BindingUtils.h"
+#include "nsHTMLImageElement.h"
+#include "nsHTMLVideoElement.h"
+#include "mozilla/dom/CanvasRenderingContext2DBinding.h"
 
 #ifdef XP_WIN
 #include "gfxWindowsPlatform.h"
 #endif
 
 // windows.h (included by chromium code) defines this, in its infinite wisdom
 #undef DrawText
 
@@ -127,92 +133,16 @@ static PRInt64 GetCanvasAzureMemoryUsed(
 NS_MEMORY_REPORTER_IMPLEMENT(CanvasAzureMemory,
   "canvas-2d-pixel-bytes",
   KIND_OTHER,
   UNITS_BYTES,
   GetCanvasAzureMemoryUsed,
   "Memory used by 2D canvases. Each canvas requires (width * height * 4) "
   "bytes.")
 
-/**
- ** nsCanvasGradientAzure
- **/
-#define NS_CANVASGRADIENTAZURE_PRIVATE_IID \
-    {0x28425a6a, 0x90e0, 0x4d42, {0x9c, 0x75, 0xff, 0x60, 0x09, 0xb3, 0x10, 0xa8}}
-class nsCanvasGradientAzure : public nsIDOMCanvasGradient
-{
-public:
-  NS_DECLARE_STATIC_IID_ACCESSOR(NS_CANVASGRADIENTAZURE_PRIVATE_IID)
-
-  enum Type
-  {
-    LINEAR = 0,
-    RADIAL
-  };
-
-  Type GetType()
-  {
-    return mType;
-  }
-
-
-  GradientStops *GetGradientStopsForTarget(DrawTarget *aRT)
-  {
-    if (mStops && mStops->GetBackendType() == aRT->GetType()) {
-      return mStops;
-    }
-
-    mStops = aRT->CreateGradientStops(mRawStops.Elements(), mRawStops.Length());
-
-    return mStops;
-  }
-
-  NS_DECL_ISUPPORTS
-
-  /* nsIDOMCanvasGradient */
-  NS_IMETHOD AddColorStop (float offset,
-                            const nsAString& colorstr)
-  {
-    if (!FloatValidate(offset) || offset < 0.0 || offset > 1.0) {
-      return NS_ERROR_DOM_INDEX_SIZE_ERR;
-    }
-
-    nsCSSValue value;
-    nsCSSParser parser;
-    if (!parser.ParseColorString(colorstr, nsnull, 0, value)) {
-      return NS_ERROR_DOM_SYNTAX_ERR;
-    }
-
-    nscolor color;
-    if (!nsRuleNode::ComputeColor(value, nsnull, nsnull, color)) {
-      return NS_ERROR_DOM_SYNTAX_ERR;
-    }
-
-    mStops = nsnull;
-
-    GradientStop newStop;
-
-    newStop.offset = offset;
-    newStop.color = Color::FromABGR(color);
-
-    mRawStops.AppendElement(newStop);
-
-    return NS_OK;
-  }
-
-protected:
-  nsCanvasGradientAzure(Type aType) : mType(aType)
-  {}
-
-  nsTArray<GradientStop> mRawStops;
-  RefPtr<GradientStops> mStops;
-  Type mType;
-  virtual ~nsCanvasGradientAzure() {}
-};
-
 class nsCanvasRadialGradientAzure : public nsCanvasGradientAzure
 {
 public:
   nsCanvasRadialGradientAzure(const Point &aBeginOrigin, Float aBeginRadius,
                               const Point &aEndOrigin, Float aEndRadius)
     : nsCanvasGradientAzure(RADIAL)
     , mCenter1(aBeginOrigin)
     , mCenter2(aEndOrigin)
@@ -233,79 +163,244 @@ public:
   nsCanvasLinearGradientAzure(const Point &aBegin, const Point &aEnd)
     : nsCanvasGradientAzure(LINEAR)
     , mBegin(aBegin)
     , mEnd(aEnd)
   {
   }
 
 protected:
-  friend class nsCanvasRenderingContext2DAzure;
+  friend class CanvasGeneralPattern;
 
   // Beginning of linear gradient.
   Point mBegin;
   // End of linear gradient.
   Point mEnd;
 };
 
+// This class is named 'GeneralCanvasPattern' instead of just
+// 'GeneralPattern' to keep Windows PGO builds from confusing the
+// GeneralPattern class in gfxContext.cpp with this one.
+
+class CanvasGeneralPattern
+{
+public:
+  typedef nsCanvasRenderingContext2DAzure::Style Style;
+  typedef nsCanvasRenderingContext2DAzure::ContextState ContextState;
+
+  CanvasGeneralPattern() : mPattern(nsnull) {}
+  ~CanvasGeneralPattern()
+  {
+    if (mPattern) {
+      mPattern->~Pattern();
+    }
+  }
+
+  Pattern& ForStyle(nsCanvasRenderingContext2DAzure *aCtx,
+                    Style aStyle,
+                    DrawTarget *aRT)
+  {
+    // This should only be called once or the mPattern destructor will
+    // not be executed.
+    NS_ASSERTION(!mPattern, "ForStyle() should only be called once on CanvasGeneralPattern!");
+
+    const ContextState &state = aCtx->CurrentState();
+
+    if (state.StyleIsColor(aStyle)) {
+      mPattern = new (mColorPattern.addr()) ColorPattern(Color::FromABGR(state.colorStyles[aStyle]));
+    } else if (state.gradientStyles[aStyle] &&
+               state.gradientStyles[aStyle]->GetType() == nsCanvasGradientAzure::LINEAR) {
+      nsCanvasLinearGradientAzure *gradient =
+        static_cast<nsCanvasLinearGradientAzure*>(state.gradientStyles[aStyle].get());
+
+      mPattern = new (mLinearGradientPattern.addr())
+        LinearGradientPattern(gradient->mBegin, gradient->mEnd,
+                              gradient->GetGradientStopsForTarget(aRT));
+    } else if (state.gradientStyles[aStyle] &&
+               state.gradientStyles[aStyle]->GetType() == nsCanvasGradientAzure::RADIAL) {
+      nsCanvasRadialGradientAzure *gradient =
+        static_cast<nsCanvasRadialGradientAzure*>(state.gradientStyles[aStyle].get());
+
+      mPattern = new (mRadialGradientPattern.addr())
+        RadialGradientPattern(gradient->mCenter1, gradient->mCenter2, gradient->mRadius1,
+                              gradient->mRadius2, gradient->GetGradientStopsForTarget(aRT));
+    } else if (state.patternStyles[aStyle]) {
+      if (aCtx->mCanvasElement) {
+        CanvasUtils::DoDrawImageSecurityCheck(aCtx->mCanvasElement,
+                                              state.patternStyles[aStyle]->mPrincipal,
+                                              state.patternStyles[aStyle]->mForceWriteOnly,
+                                              state.patternStyles[aStyle]->mCORSUsed);
+      }
+
+      ExtendMode mode;
+      if (state.patternStyles[aStyle]->mRepeat == nsCanvasPatternAzure::NOREPEAT) {
+        mode = EXTEND_CLAMP;
+      } else {
+        mode = EXTEND_REPEAT;
+      }
+      mPattern = new (mSurfacePattern.addr())
+        SurfacePattern(state.patternStyles[aStyle]->mSurface, mode);
+    }
+
+    return *mPattern;
+  }
+
+  union {
+    AlignedStorage2<ColorPattern> mColorPattern;
+    AlignedStorage2<LinearGradientPattern> mLinearGradientPattern;
+    AlignedStorage2<RadialGradientPattern> mRadialGradientPattern;
+    AlignedStorage2<SurfacePattern> mSurfacePattern;
+  };
+  Pattern *mPattern;
+};
+
+/* This is an RAII based class that can be used as a drawtarget for
+ * operations that need a shadow drawn. It will automatically provide a
+ * temporary target when needed, and if so blend it back with a shadow.
+ *
+ * aBounds specifies the bounds of the drawing operation that will be
+ * drawn to the target, it is given in device space! This function will
+ * change aBounds to incorporate shadow bounds. If this is NULL the drawing
+ * operation will be assumed to cover an infinite rect.
+ */
+class AdjustedTarget
+{
+public:
+  typedef nsCanvasRenderingContext2DAzure::ContextState ContextState;
+
+  AdjustedTarget(nsCanvasRenderingContext2DAzure *ctx,
+                 mgfx::Rect *aBounds = nsnull)
+    : mCtx(nsnull)
+  {
+    if (!ctx->NeedToDrawShadow()) {
+      mTarget = ctx->mTarget;
+      return;
+    }
+    mCtx = ctx;
+
+    const ContextState &state = mCtx->CurrentState();
+
+    mSigma = state.shadowBlur / 2.0f;
+
+    if (mSigma > SIGMA_MAX) {
+      mSigma = SIGMA_MAX;
+    }
+      
+    Matrix transform = mCtx->mTarget->GetTransform();
+
+    mTempRect = mgfx::Rect(0, 0, ctx->mWidth, ctx->mHeight);
+
+    Float blurRadius = mSigma * 3;
+
+    // We need to enlarge and possibly offset our temporary surface
+    // so that things outside of the canvas may cast shadows.
+    mTempRect.Inflate(Margin(blurRadius + NS_MAX<Float>(state.shadowOffset.x, 0),
+                             blurRadius + NS_MAX<Float>(state.shadowOffset.y, 0),
+                             blurRadius + NS_MAX<Float>(-state.shadowOffset.x, 0),
+                             blurRadius + NS_MAX<Float>(-state.shadowOffset.y, 0)));
+
+    if (aBounds) {
+      // We actually include the bounds of the shadow blur, this makes it
+      // easier to execute the actual blur on hardware, and shouldn't affect
+      // the amount of pixels that need to be touched.
+      aBounds->Inflate(Margin(blurRadius, blurRadius,
+                              blurRadius, blurRadius));
+      mTempRect = mTempRect.Intersect(*aBounds);
+    }
+
+    mTempRect.ScaleRoundOut(1.0f);
+
+    transform._31 -= mTempRect.x;
+    transform._32 -= mTempRect.y;
+      
+    mTarget =
+      mCtx->mTarget->CreateSimilarDrawTarget(IntSize(int32_t(mTempRect.width), int32_t(mTempRect.height)),
+                                             FORMAT_B8G8R8A8);
+
+    if (!mTarget) {
+      // XXX - Deal with the situation where our temp size is too big to
+      // fit in a texture.
+      mTarget = ctx->mTarget;
+      mCtx = nsnull;
+    } else {
+      mTarget->SetTransform(transform);
+    }
+  }
+
+  ~AdjustedTarget()
+  {
+    if (!mCtx) {
+      return;
+    }
+
+    RefPtr<SourceSurface> snapshot = mTarget->Snapshot();
+    
+    mCtx->mTarget->DrawSurfaceWithShadow(snapshot, mTempRect.TopLeft(),
+                                         Color::FromABGR(mCtx->CurrentState().shadowColor),
+                                         mCtx->CurrentState().shadowOffset, mSigma,
+                                         mCtx->CurrentState().op);
+  }
+
+  DrawTarget* operator->()
+  {
+    return mTarget;
+  }
+
+private:
+  RefPtr<DrawTarget> mTarget;
+  nsCanvasRenderingContext2DAzure *mCtx;
+  Float mSigma;
+  mgfx::Rect mTempRect;
+};
+
+NS_IMETHODIMP
+nsCanvasGradientAzure::AddColorStop(float offset, const nsAString& colorstr)
+{
+  if (!FloatValidate(offset) || offset < 0.0 || offset > 1.0) {
+    return NS_ERROR_DOM_INDEX_SIZE_ERR;
+  }
+
+  nsCSSValue value;
+  nsCSSParser parser;
+  if (!parser.ParseColorString(colorstr, nsnull, 0, value)) {
+    return NS_ERROR_DOM_SYNTAX_ERR;
+  }
+
+  nscolor color;
+  if (!nsRuleNode::ComputeColor(value, nsnull, nsnull, color)) {
+    return NS_ERROR_DOM_SYNTAX_ERR;
+  }
+
+  mStops = nsnull;
+
+  GradientStop newStop;
+
+  newStop.offset = offset;
+  newStop.color = Color::FromABGR(color);
+
+  mRawStops.AppendElement(newStop);
+
+  return NS_OK;
+}
+
 NS_DEFINE_STATIC_IID_ACCESSOR(nsCanvasGradientAzure, NS_CANVASGRADIENTAZURE_PRIVATE_IID)
 
 NS_IMPL_ADDREF(nsCanvasGradientAzure)
 NS_IMPL_RELEASE(nsCanvasGradientAzure)
 
 // XXX
 // DOMCI_DATA(CanvasGradient, nsCanvasGradientAzure)
 
 NS_INTERFACE_MAP_BEGIN(nsCanvasGradientAzure)
   NS_INTERFACE_MAP_ENTRY(nsCanvasGradientAzure)
   NS_INTERFACE_MAP_ENTRY(nsIDOMCanvasGradient)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CanvasGradient)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
-/**
- ** nsCanvasPatternAzure
- **/
-#define NS_CANVASPATTERNAZURE_PRIVATE_IID \
-    {0xc9bacc25, 0x28da, 0x421e, {0x9a, 0x4b, 0xbb, 0xd6, 0x93, 0x05, 0x12, 0xbc}}
-class nsCanvasPatternAzure MOZ_FINAL : public nsIDOMCanvasPattern
-{
-public:
-  NS_DECLARE_STATIC_IID_ACCESSOR(NS_CANVASPATTERNAZURE_PRIVATE_IID)
-
-  enum RepeatMode
-  {
-    REPEAT,
-    REPEATX,
-    REPEATY,
-    NOREPEAT
-  };
-
-  nsCanvasPatternAzure(SourceSurface* aSurface,
-                       RepeatMode aRepeat,
-                       nsIPrincipal* principalForSecurityCheck,
-                       bool forceWriteOnly,
-                       bool CORSUsed)
-    : mSurface(aSurface)
-    , mRepeat(aRepeat)
-    , mPrincipal(principalForSecurityCheck)
-    , mForceWriteOnly(forceWriteOnly)
-    , mCORSUsed(CORSUsed)
-  {
-  }
-
-  NS_DECL_ISUPPORTS
-
-  RefPtr<SourceSurface> mSurface;
-  const RepeatMode mRepeat;
-  nsCOMPtr<nsIPrincipal> mPrincipal;
-  const bool mForceWriteOnly;
-  const bool mCORSUsed;
-};
-
 NS_DEFINE_STATIC_IID_ACCESSOR(nsCanvasPatternAzure, NS_CANVASPATTERNAZURE_PRIVATE_IID)
 
 NS_IMPL_ADDREF(nsCanvasPatternAzure)
 NS_IMPL_RELEASE(nsCanvasPatternAzure)
 
 // XXX
 // DOMCI_DATA(CanvasPattern, nsCanvasPatternAzure)
 
@@ -351,599 +446,18 @@ NS_IMPL_RELEASE(nsTextMetricsAzure)
 
 NS_INTERFACE_MAP_BEGIN(nsTextMetricsAzure)
   NS_INTERFACE_MAP_ENTRY(nsTextMetricsAzure)
   NS_INTERFACE_MAP_ENTRY(nsIDOMTextMetrics)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(TextMetrics)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
-struct nsCanvasBidiProcessorAzure;
-class CanvasRenderingContext2DUserDataAzure;
-
 // Cap sigma to avoid overly large temp surfaces.
-static const Float SIGMA_MAX = 100;
-
-/**
- ** nsCanvasRenderingContext2DAzure
- **/
-class nsCanvasRenderingContext2DAzure :
-  public nsIDOMCanvasRenderingContext2D,
-  public nsICanvasRenderingContextInternal,
-  public nsWrapperCache
-{
-public:
-  nsCanvasRenderingContext2DAzure();
-  virtual ~nsCanvasRenderingContext2DAzure();
-
-  nsresult Redraw();
-
-  // nsICanvasRenderingContextInternal
-  NS_IMETHOD SetDimensions(PRInt32 width, PRInt32 height);
-  NS_IMETHOD InitializeWithSurface(nsIDocShell *shell, gfxASurface *surface, PRInt32 width, PRInt32 height)
-  { return NS_ERROR_NOT_IMPLEMENTED; }
-
-  NS_IMETHOD Render(gfxContext *ctx,
-                    gfxPattern::GraphicsFilter aFilter,
-                    PRUint32 aFlags = RenderFlagPremultAlpha);
-  NS_IMETHOD GetInputStream(const char* aMimeType,
-                            const PRUnichar* aEncoderOptions,
-                            nsIInputStream **aStream);
-  NS_IMETHOD GetThebesSurface(gfxASurface **surface);
-
-  TemporaryRef<SourceSurface> GetSurfaceSnapshot()
-  { return mTarget ? mTarget->Snapshot() : nsnull; }
-
-  NS_IMETHOD SetIsOpaque(bool isOpaque);
-  NS_IMETHOD Reset();
-  already_AddRefed<CanvasLayer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
-                                                CanvasLayer *aOldLayer,
-                                                LayerManager *aManager);
-  void MarkContextClean();
-  NS_IMETHOD SetIsIPC(bool isIPC);
-  // this rect is in canvas device space
-  void Redraw(const mgfx::Rect &r);
-  NS_IMETHOD Redraw(const gfxRect &r) { Redraw(ToRect(r)); return NS_OK; }
-
-  // this rect is in mTarget's current user space
-  nsresult RedrawUser(const gfxRect &r);
-
-  // nsISupports interface + CC
-  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-
-  NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(
-    nsCanvasRenderingContext2DAzure, nsIDOMCanvasRenderingContext2D)
-
-  // nsIDOMCanvasRenderingContext2D interface
-  NS_DECL_NSIDOMCANVASRENDERINGCONTEXT2D
-
-  enum Style {
-    STYLE_STROKE = 0,
-    STYLE_FILL,
-    STYLE_MAX
-  };
-  
-  nsresult LineTo(const Point& aPoint);
-  nsresult BezierTo(const Point& aCP1, const Point& aCP2, const Point& aCP3);
-
-  friend class CanvasRenderingContext2DUserDataAzure;
-
-protected:
-  nsresult GetImageDataArray(JSContext* aCx, int32_t aX, int32_t aY,
-                             uint32_t aWidth, uint32_t aHeight,
-                             JSObject** aRetval);
-
-  nsresult InitializeWithTarget(DrawTarget *surface, PRInt32 width, PRInt32 height);
-
-  /**
-    * The number of living nsCanvasRenderingContexts.  When this goes down to
-    * 0, we free the premultiply and unpremultiply tables, if they exist.
-    */
-  static PRUint32 sNumLivingContexts;
-
-  /**
-    * Lookup table used to speed up GetImageData().
-    */
-  static PRUint8 (*sUnpremultiplyTable)[256];
-
-  /**
-    * Lookup table used to speed up PutImageData().
-    */
-  static PRUint8 (*sPremultiplyTable)[256];
-
-  // Some helpers.  Doesn't modify a color on failure.
-  nsresult SetStyleFromStringOrInterface(const nsAString& aStr, nsISupports *aInterface, Style aWhichStyle);
-  nsresult GetStyleAsStringOrInterface(nsAString& aStr, nsISupports **aInterface, PRInt32 *aType, Style aWhichStyle);
-
-  // Returns whether a color was successfully parsed.
-  bool ParseColor(const nsAString& aString, nscolor* aColor);
-
-  void StyleColorToString(const nscolor& aColor, nsAString& aStr);
-
-  /**
-    * Creates the unpremultiply lookup table, if it doesn't exist.
-    */
-  void EnsureUnpremultiplyTable();
-
-  /**
-    * Creates the premultiply lookup table, if it doesn't exist.
-    */
-  void EnsurePremultiplyTable();
-
-  /* This function ensures there is a writable pathbuilder available, this
-   * pathbuilder may be working in user space or in device space or
-   * device space.
-   */
-  void EnsureWritablePath();
-
-  // Ensures a path in UserSpace is available.
-  void EnsureUserSpacePath();
-
-  void TransformWillUpdate();
-
-  // Report the fillRule has changed.
-  void FillRuleChanged();
-
-  /**
-    * Returns the surface format this canvas should be allocated using. Takes
-    * into account mOpaque, platform requirements, etc.
-    */
-  SurfaceFormat GetSurfaceFormat() const;
-
-  // Member vars
-  PRInt32 mWidth, mHeight;
-
-  // This is true when the canvas is valid, false otherwise, this occurs when
-  // for some reason initialization of the drawtarget fails. If the canvas
-  // is invalid certain behavior is expected.
-  bool mValid;
-  // This is true when the canvas is valid, but of zero size, this requires
-  // specific behavior on some operations.
-  bool mZero;
-
-  bool mOpaque;
-
-  // This is true when the next time our layer is retrieved we need to
-  // recreate it (i.e. our backing surface changed)
-  bool mResetLayer;
-  // This is needed for drawing in drawAsyncXULElement
-  bool mIPC;
-
-  nsTArray<CanvasRenderingContext2DUserDataAzure*> mUserDatas;
-
-  // If mCanvasElement is not provided, then a docshell is
-  nsCOMPtr<nsIDocShell> mDocShell;
-
-  // our drawing surfaces, contexts, and layers
-  RefPtr<DrawTarget> mTarget;
-
-  /**
-    * Flag to avoid duplicate calls to InvalidateFrame. Set to true whenever
-    * Redraw is called, reset to false when Render is called.
-    */
-  bool mIsEntireFrameInvalid;
-  /**
-    * When this is set, the first call to Redraw(gfxRect) should set
-    * mIsEntireFrameInvalid since we expect it will be followed by
-    * many more Redraw calls.
-    */
-  bool mPredictManyRedrawCalls;
-
-  // This is stored after GetThebesSurface has been called once to avoid
-  // excessive ThebesSurface initialization overhead.
-  nsRefPtr<gfxASurface> mThebesSurface;
-
-  /**
-    * We also have a device space pathbuilder. The reason for this is as
-    * follows, when a path is being built, but the transform changes, we
-    * can no longer keep a single path in userspace, considering there's
-    * several 'user spaces' now. We therefore transform the current path
-    * into device space, and add all operations to this path in device
-    * space.
-    *
-    * When then finally executing a render, the Azure drawing API expects
-    * the path to be in userspace. We could then set an identity transform
-    * on the DrawTarget and do all drawing in device space. This is
-    * undesirable because it requires transforming patterns, gradients,
-    * clips, etc. into device space and it would not work for stroking.
-    * What we do instead is convert the path back to user space when it is
-    * drawn, and draw it with the current transform. This makes all drawing
-    * occur correctly.
-    *
-    * There's never both a device space path builder and a user space path
-    * builder present at the same time. There is also never a path and a
-    * path builder present at the same time. When writing proceeds on an
-    * existing path the Path is cleared and a new builder is created.
-    *
-    * mPath is always in user-space.
-    */
-  RefPtr<Path> mPath;
-  RefPtr<PathBuilder> mDSPathBuilder;
-  RefPtr<PathBuilder> mPathBuilder;
-  bool mPathTransformWillUpdate;
-  Matrix mPathToDS;
-
-  /**
-    * Number of times we've invalidated before calling redraw
-    */
-  PRUint32 mInvalidateCount;
-  static const PRUint32 kCanvasMaxInvalidateCount = 100;
-
-  /**
-    * Returns true if a shadow should be drawn along with a
-    * drawing operation.
-    */
-  bool NeedToDrawShadow()
-  {
-    const ContextState& state = CurrentState();
-
-    // The spec says we should not draw shadows if the operator is OVER.
-    // If it's over and the alpha value is zero, nothing needs to be drawn.
-    return NS_GET_A(state.shadowColor) != 0 && 
-      (state.shadowBlur != 0 || state.shadowOffset.x != 0 || state.shadowOffset.y != 0);
-  }
-
-  CompositionOp UsedOperation()
-  {
-    if (NeedToDrawShadow()) {
-      // In this case the shadow rendering will use the operator.
-      return OP_OVER;
-    }
-
-    return CurrentState().op;
-  }
-
-  /**
-    * Gets the pres shell from either the canvas element or the doc shell
-    */
-  nsIPresShell *GetPresShell() {
-    if (mCanvasElement) {
-      return mCanvasElement->OwnerDoc()->GetShell();
-    }
-    if (mDocShell) {
-      nsCOMPtr<nsIPresShell> shell;
-      mDocShell->GetPresShell(getter_AddRefs(shell));
-      return shell.get();
-    }
-    return nsnull;
-  }
-
-  // text
-  enum TextAlign {
-    TEXT_ALIGN_START,
-    TEXT_ALIGN_END,
-    TEXT_ALIGN_LEFT,
-    TEXT_ALIGN_RIGHT,
-    TEXT_ALIGN_CENTER
-  };
-
-  enum TextBaseline {
-    TEXT_BASELINE_TOP,
-    TEXT_BASELINE_HANGING,
-    TEXT_BASELINE_MIDDLE,
-    TEXT_BASELINE_ALPHABETIC,
-    TEXT_BASELINE_IDEOGRAPHIC,
-    TEXT_BASELINE_BOTTOM
-  };
-
-  gfxFontGroup *GetCurrentFontStyle();
-
-  enum TextDrawOperation {
-    TEXT_DRAW_OPERATION_FILL,
-    TEXT_DRAW_OPERATION_STROKE,
-    TEXT_DRAW_OPERATION_MEASURE
-  };
-
-  /*
-    * Implementation of the fillText, strokeText, and measure functions with
-    * the operation abstracted to a flag.
-    */
-  nsresult DrawOrMeasureText(const nsAString& text,
-                              float x,
-                              float y,
-                              float maxWidth,
-                              TextDrawOperation op,
-                              float* aWidth);
-
-  // state stack handling
-  class ContextState {
-  public:
-      ContextState() : textAlign(TEXT_ALIGN_START),
-                       textBaseline(TEXT_BASELINE_ALPHABETIC),
-                       lineWidth(1.0f),
-                       miterLimit(10.0f),
-                       globalAlpha(1.0f),
-                       shadowBlur(0.0),
-                       dashOffset(0.0f),
-                       op(OP_OVER),
-                       fillRule(FILL_WINDING),
-                       lineCap(CAP_BUTT),
-                       lineJoin(JOIN_MITER_OR_BEVEL),
-                       imageSmoothingEnabled(true)
-      { }
-
-      ContextState(const ContextState& other)
-          : fontGroup(other.fontGroup),
-            font(other.font),
-            textAlign(other.textAlign),
-            textBaseline(other.textBaseline),
-            shadowColor(other.shadowColor),
-            transform(other.transform),
-            shadowOffset(other.shadowOffset),
-            lineWidth(other.lineWidth),
-            miterLimit(other.miterLimit),
-            globalAlpha(other.globalAlpha),
-            shadowBlur(other.shadowBlur),
-            dash(other.dash),
-            dashOffset(other.dashOffset),
-            op(other.op),
-            fillRule(other.fillRule),
-            lineCap(other.lineCap),
-            lineJoin(other.lineJoin),
-            imageSmoothingEnabled(other.imageSmoothingEnabled)
-      {
-          for (int i = 0; i < STYLE_MAX; i++) {
-              colorStyles[i] = other.colorStyles[i];
-              gradientStyles[i] = other.gradientStyles[i];
-              patternStyles[i] = other.patternStyles[i];
-          }
-      }
-
-      void SetColorStyle(Style whichStyle, nscolor color) {
-          colorStyles[whichStyle] = color;
-          gradientStyles[whichStyle] = nsnull;
-          patternStyles[whichStyle] = nsnull;
-      }
-
-      void SetPatternStyle(Style whichStyle, nsCanvasPatternAzure* pat) {
-          gradientStyles[whichStyle] = nsnull;
-          patternStyles[whichStyle] = pat;
-      }
-
-      void SetGradientStyle(Style whichStyle, nsCanvasGradientAzure* grad) {
-          gradientStyles[whichStyle] = grad;
-          patternStyles[whichStyle] = nsnull;
-      }
-
-      /**
-        * returns true iff the given style is a solid color.
-        */
-      bool StyleIsColor(Style whichStyle) const
-      {
-          return !(patternStyles[whichStyle] ||
-                    gradientStyles[whichStyle]);
-      }
-
-
-      std::vector<RefPtr<Path> > clipsPushed;
-
-      nsRefPtr<gfxFontGroup> fontGroup;
-      nsRefPtr<nsCanvasGradientAzure> gradientStyles[STYLE_MAX];
-      nsRefPtr<nsCanvasPatternAzure> patternStyles[STYLE_MAX];
-
-      nsString font;
-      TextAlign textAlign;
-      TextBaseline textBaseline;
-
-      nscolor colorStyles[STYLE_MAX];
-      nscolor shadowColor;
-
-      Matrix transform;
-      Point shadowOffset;
-      Float lineWidth;
-      Float miterLimit;
-      Float globalAlpha;
-      Float shadowBlur;
-      FallibleTArray<Float> dash;
-      Float dashOffset;
-
-      CompositionOp op;
-      FillRule fillRule;
-      CapStyle lineCap;
-      JoinStyle lineJoin;
-
-      bool imageSmoothingEnabled;
-  };
-
-  class GeneralPattern
-  {
-  public:
-    GeneralPattern() : mPattern(nsnull) {}
-    ~GeneralPattern()
-    {
-      if (mPattern) {
-        mPattern->~Pattern();
-      }
-    }
-
-    Pattern& ForStyle(nsCanvasRenderingContext2DAzure *aCtx,
-                      Style aStyle,
-                      DrawTarget *aRT)
-    {
-      // This should only be called once or the mPattern destructor will
-      // not be executed.
-      NS_ASSERTION(!mPattern, "ForStyle() should only be called once on GeneralPattern!");
-
-      const nsCanvasRenderingContext2DAzure::ContextState &state = aCtx->CurrentState();
-
-      if (state.StyleIsColor(aStyle)) {
-        mPattern = new (mColorPattern.addr()) ColorPattern(Color::FromABGR(state.colorStyles[aStyle]));
-      } else if (state.gradientStyles[aStyle] &&
-                 state.gradientStyles[aStyle]->GetType() == nsCanvasGradientAzure::LINEAR) {
-        nsCanvasLinearGradientAzure *gradient =
-          static_cast<nsCanvasLinearGradientAzure*>(state.gradientStyles[aStyle].get());
-
-        mPattern = new (mLinearGradientPattern.addr())
-          LinearGradientPattern(gradient->mBegin, gradient->mEnd,
-                                gradient->GetGradientStopsForTarget(aRT));
-      } else if (state.gradientStyles[aStyle] &&
-                 state.gradientStyles[aStyle]->GetType() == nsCanvasGradientAzure::RADIAL) {
-        nsCanvasRadialGradientAzure *gradient =
-          static_cast<nsCanvasRadialGradientAzure*>(state.gradientStyles[aStyle].get());
-
-        mPattern = new (mRadialGradientPattern.addr())
-          RadialGradientPattern(gradient->mCenter1, gradient->mCenter2, gradient->mRadius1,
-                                gradient->mRadius2, gradient->GetGradientStopsForTarget(aRT));
-      } else if (state.patternStyles[aStyle]) {
-        if (aCtx->mCanvasElement) {
-          CanvasUtils::DoDrawImageSecurityCheck(aCtx->mCanvasElement,
-                                                state.patternStyles[aStyle]->mPrincipal,
-                                                state.patternStyles[aStyle]->mForceWriteOnly,
-                                                state.patternStyles[aStyle]->mCORSUsed);
-        }
-
-        ExtendMode mode;
-        if (state.patternStyles[aStyle]->mRepeat == nsCanvasPatternAzure::NOREPEAT) {
-          mode = EXTEND_CLAMP;
-        } else {
-          mode = EXTEND_REPEAT;
-        }
-        mPattern = new (mSurfacePattern.addr())
-          SurfacePattern(state.patternStyles[aStyle]->mSurface, mode);
-      }
-
-      return *mPattern;
-    }
-
-    union {
-      AlignedStorage2<ColorPattern> mColorPattern;
-      AlignedStorage2<LinearGradientPattern> mLinearGradientPattern;
-      AlignedStorage2<RadialGradientPattern> mRadialGradientPattern;
-      AlignedStorage2<SurfacePattern> mSurfacePattern;
-    };
-    Pattern *mPattern;
-  };
-
-  /* This is an RAII based class that can be used as a drawtarget for
-   * operations that need a shadow drawn. It will automatically provide a
-   * temporary target when needed, and if so blend it back with a shadow.
-   *
-   * aBounds specifies the bounds of the drawing operation that will be
-   * drawn to the target, it is given in device space! This function will
-   * change aBounds to incorporate shadow bounds. If this is NULL the drawing
-   * operation will be assumed to cover an infinite rect.
-   */
-  class AdjustedTarget
-  {
-  public:
-    AdjustedTarget(nsCanvasRenderingContext2DAzure *ctx,
-                   mgfx::Rect *aBounds = nsnull)
-      : mCtx(nsnull)
-    {
-      if (!ctx->NeedToDrawShadow()) {
-        mTarget = ctx->mTarget;
-        return;
-      }
-      mCtx = ctx;
-
-      const ContextState &state = mCtx->CurrentState();
-
-      mSigma = state.shadowBlur / 2.0f;
-
-      if (mSigma > SIGMA_MAX) {
-        mSigma = SIGMA_MAX;
-      }
-        
-      Matrix transform = mCtx->mTarget->GetTransform();
-
-      mTempRect = mgfx::Rect(0, 0, ctx->mWidth, ctx->mHeight);
-
-      Float blurRadius = mSigma * 3;
-
-      // We need to enlarge and possibly offset our temporary surface
-      // so that things outside of the canvas may cast shadows.
-      mTempRect.Inflate(Margin(blurRadius + NS_MAX<Float>(state.shadowOffset.x, 0),
-                               blurRadius + NS_MAX<Float>(state.shadowOffset.y, 0),
-                               blurRadius + NS_MAX<Float>(-state.shadowOffset.x, 0),
-                               blurRadius + NS_MAX<Float>(-state.shadowOffset.y, 0)));
-
-      if (aBounds) {
-        // We actually include the bounds of the shadow blur, this makes it
-        // easier to execute the actual blur on hardware, and shouldn't affect
-        // the amount of pixels that need to be touched.
-        aBounds->Inflate(Margin(blurRadius, blurRadius,
-                                blurRadius, blurRadius));
-        mTempRect = mTempRect.Intersect(*aBounds);
-      }
-
-      mTempRect.ScaleRoundOut(1.0f);
-
-      transform._31 -= mTempRect.x;
-      transform._32 -= mTempRect.y;
-        
-      mTarget =
-        mCtx->mTarget->CreateSimilarDrawTarget(IntSize(int32_t(mTempRect.width), int32_t(mTempRect.height)),
-                                               FORMAT_B8G8R8A8);
-
-      if (!mTarget) {
-        // XXX - Deal with the situation where our temp size is too big to
-        // fit in a texture.
-        mTarget = ctx->mTarget;
-        mCtx = nsnull;
-      } else {
-        mTarget->SetTransform(transform);
-      }
-    }
-
-    ~AdjustedTarget()
-    {
-      if (!mCtx) {
-        return;
-      }
-
-      RefPtr<SourceSurface> snapshot = mTarget->Snapshot();
-      
-      mCtx->mTarget->DrawSurfaceWithShadow(snapshot, mTempRect.TopLeft(),
-                                           Color::FromABGR(mCtx->CurrentState().shadowColor),
-                                           mCtx->CurrentState().shadowOffset, mSigma,
-                                           mCtx->CurrentState().op);
-    }
-
-    DrawTarget* operator->()
-    {
-      return mTarget;
-    }
-
-  private:
-    RefPtr<DrawTarget> mTarget;
-    nsCanvasRenderingContext2DAzure *mCtx;
-    Float mSigma;
-    mgfx::Rect mTempRect;
-  };
-
-  nsAutoTArray<ContextState, 3> mStyleStack;
-
-  inline ContextState& CurrentState() {
-    return mStyleStack[mStyleStack.Length() - 1];
-  }
-    
-  // other helpers
-  void GetAppUnitsValues(PRUint32 *perDevPixel, PRUint32 *perCSSPixel) {
-    // If we don't have a canvas element, we just return something generic.
-    PRUint32 devPixel = 60;
-    PRUint32 cssPixel = 60;
-
-    nsIPresShell *ps = GetPresShell();
-    nsPresContext *pc;
-
-    if (!ps) goto FINISH;
-    pc = ps->GetPresContext();
-    if (!pc) goto FINISH;
-    devPixel = pc->AppUnitsPerDevPixel();
-    cssPixel = pc->AppUnitsPerCSSPixel();
-
-  FINISH:
-    if (perDevPixel)
-      *perDevPixel = devPixel;
-    if (perCSSPixel)
-      *perCSSPixel = cssPixel;
-  }
-
-  friend struct nsCanvasBidiProcessorAzure;
-};
+const Float SIGMA_MAX = 100;
 
 class CanvasRenderingContext2DUserDataAzure : public LayerUserData {
 public:
     CanvasRenderingContext2DUserDataAzure(nsCanvasRenderingContext2DAzure *aContext)
     : mContext(aContext)
   {
     aContext->mUserDatas.AppendElement(this);
   }
@@ -1028,29 +542,61 @@ NS_INTERFACE_MAP_END
  **/
 
 
 // Initialize our static variables.
 PRUint32 nsCanvasRenderingContext2DAzure::sNumLivingContexts = 0;
 PRUint8 (*nsCanvasRenderingContext2DAzure::sUnpremultiplyTable)[256] = nsnull;
 PRUint8 (*nsCanvasRenderingContext2DAzure::sPremultiplyTable)[256] = nsnull;
 
+namespace mozilla {
+namespace dom {
+
+static bool
+AzureCanvasEnabledOnPlatform()
+{
+#ifdef XP_WIN
+  if (gfxWindowsPlatform::GetPlatform()->GetRenderMode() !=
+      gfxWindowsPlatform::RENDER_DIRECT2D ||
+      !gfxWindowsPlatform::GetPlatform()->DWriteEnabled()) {
+    static bool checkedPref = false;
+    static bool preferSkia;
+    if (!checkedPref) {
+      preferSkia = Preferences::GetBool("gfx.canvas.azure.prefer-skia", false);
+      checkedPref = true;
+    }
+    return preferSkia;
+  }
+#elif !defined(XP_MACOSX) && !defined(ANDROID) && !defined(LINUX)
+  return false;
+#endif
+  return true;
+}
+
+bool
+AzureCanvasEnabled()
+{
+  static bool checkedPref = false;
+  static bool azureEnabled;
+  if (!checkedPref) {
+    azureEnabled = Preferences::GetBool("gfx.canvas.azure.enabled", false);
+    checkedPref = true;
+  }
+  return azureEnabled && AzureCanvasEnabledOnPlatform();
+}
+
+}
+}
+
 nsresult
 NS_NewCanvasRenderingContext2DAzure(nsIDOMCanvasRenderingContext2D** aResult)
 {
-#ifdef XP_WIN
-  if ((gfxWindowsPlatform::GetPlatform()->GetRenderMode() !=
-      gfxWindowsPlatform::RENDER_DIRECT2D ||
-      !gfxWindowsPlatform::GetPlatform()->DWriteEnabled()) &&
-      !Preferences::GetBool("gfx.canvas.azure.prefer-skia", false)) {
+  if (!AzureCanvasEnabledOnPlatform()) {
     return NS_ERROR_NOT_AVAILABLE;
   }
-#elif !defined(XP_MACOSX) && !defined(ANDROID) && !defined(LINUX)
-  return NS_ERROR_NOT_AVAILABLE;
-#endif
 
   nsRefPtr<nsIDOMCanvasRenderingContext2D> ctx = new nsCanvasRenderingContext2DAzure();
   if (!ctx)
     return NS_ERROR_OUT_OF_MEMORY;
 
   *aResult = ctx.forget().get();
   return NS_OK;
 }
@@ -1058,16 +604,17 @@ NS_NewCanvasRenderingContext2DAzure(nsID
 nsCanvasRenderingContext2DAzure::nsCanvasRenderingContext2DAzure()
   : mValid(false), mZero(false), mOpaque(false), mResetLayer(true)
   , mIPC(false)
   , mIsEntireFrameInvalid(false)
   , mPredictManyRedrawCalls(false), mPathTransformWillUpdate(false)
   , mInvalidateCount(0)
 {
   sNumLivingContexts++;
+  SetIsDOMBinding();
 }
 
 nsCanvasRenderingContext2DAzure::~nsCanvasRenderingContext2DAzure()
 {
   Reset();
   // Drop references from all CanvasRenderingContext2DUserDataAzure to this context
   for (PRUint32 i = 0; i < mUserDatas.Length(); ++i) {
     mUserDatas[i]->Forget();
@@ -1076,16 +623,23 @@ nsCanvasRenderingContext2DAzure::~nsCanv
   if (!sNumLivingContexts) {
     delete[] sUnpremultiplyTable;
     delete[] sPremultiplyTable;
     sUnpremultiplyTable = nsnull;
     sPremultiplyTable = nsnull;
   }
 }
 
+JSObject*
+nsCanvasRenderingContext2DAzure::WrapObject(JSContext *cx, JSObject *scope,
+                                            bool *triedToWrap)
+{
+  return CanvasRenderingContext2DBinding::Wrap(cx, scope, this, triedToWrap);
+}
+
 bool
 nsCanvasRenderingContext2DAzure::ParseColor(const nsAString& aString,
                                             nscolor* aColor)
 {
   nsIDocument* document = mCanvasElement
                           ? mCanvasElement->OwnerDoc()
                           : nsnull;
 
@@ -1131,80 +685,92 @@ nsCanvasRenderingContext2DAzure::Reset()
   mThebesSurface = nsnull;
   mValid = false;
   mIsEntireFrameInvalid = false;
   mPredictManyRedrawCalls = false;
 
   return NS_OK;
 }
 
-nsresult
+static void
+WarnAboutUnexpectedStyle(nsHTMLCanvasElement* canvasElement)
+{
+  nsContentUtils::ReportToConsole(
+    nsIScriptError::warningFlag,
+    "Canvas",
+    canvasElement ? canvasElement->OwnerDoc() : nsnull,
+    nsContentUtils::eDOM_PROPERTIES,
+    "UnexpectedCanvasVariantStyle");
+}
+
+void
+nsCanvasRenderingContext2DAzure::SetStyleFromString(const nsAString& str,
+                                                    Style whichStyle)
+{
+  MOZ_ASSERT(!str.IsVoid());
+
+  nscolor color;
+  if (!ParseColor(str, &color)) {
+    return;
+  }
+
+  CurrentState().SetColorStyle(whichStyle, color);
+}
+
+void
 nsCanvasRenderingContext2DAzure::SetStyleFromStringOrInterface(const nsAString& aStr,
                                                                nsISupports *aInterface,
                                                                Style aWhichStyle)
 {
   if (!aStr.IsVoid()) {
-    nscolor color;
-    if (!ParseColor(aStr, &color)) {
-      return NS_OK;
-    }
-
-    CurrentState().SetColorStyle(aWhichStyle, color);
-    return NS_OK;
+    SetStyleFromString(aStr, aWhichStyle);
+    return;
   }
 
   if (aInterface) {
     nsCOMPtr<nsCanvasGradientAzure> grad(do_QueryInterface(aInterface));
     if (grad) {
-      CurrentState().SetGradientStyle(aWhichStyle, grad);
-      return NS_OK;
+      SetStyleFromGradient(grad, aWhichStyle);
+      return;
     }
 
     nsCOMPtr<nsCanvasPatternAzure> pattern(do_QueryInterface(aInterface));
     if (pattern) {
-      CurrentState().SetPatternStyle(aWhichStyle, pattern);
-      return NS_OK;
+      SetStyleFromPattern(pattern, aWhichStyle);
+      return;
     }
   }
 
-  nsContentUtils::ReportToConsole(
-    nsIScriptError::warningFlag,
-    "Canvas",
-    mCanvasElement ? mCanvasElement->OwnerDoc() : nsnull,
-    nsContentUtils::eDOM_PROPERTIES,
-    "UnexpectedCanvasVariantStyle");
-
-  return NS_OK;
+  WarnAboutUnexpectedStyle(mCanvasElement);
 }
 
-nsresult
+nsISupports*
 nsCanvasRenderingContext2DAzure::GetStyleAsStringOrInterface(nsAString& aStr,
-                                                             nsISupports **aInterface,
-                                                             PRInt32 *aType,
+                                                             CanvasMultiGetterType& aType,
                                                              Style aWhichStyle)
 {
   const ContextState &state = CurrentState();
-
+  nsISupports* supports;
   if (state.patternStyles[aWhichStyle]) {
     aStr.SetIsVoid(true);
-    NS_ADDREF(*aInterface = state.patternStyles[aWhichStyle]);
-    *aType = CMG_STYLE_PATTERN;
+    supports = state.patternStyles[aWhichStyle];
+    aType = CMG_STYLE_PATTERN;
   } else if (state.gradientStyles[aWhichStyle]) {
     aStr.SetIsVoid(true);
-    NS_ADDREF(*aInterface = state.gradientStyles[aWhichStyle]);
-    *aType = CMG_STYLE_GRADIENT;
+    supports = state.gradientStyles[aWhichStyle];
+    aType = CMG_STYLE_GRADIENT;
   } else {
     StyleColorToString(state.colorStyles[aWhichStyle], aStr);
-    *aInterface = nsnull;
-    *aType = CMG_STYLE_STRING;
-  }
-
-  return NS_OK;
+    supports = nsnull;
+    aType = CMG_STYLE_STRING;
+  }
+  return supports;
 }
 
+// static
 void
 nsCanvasRenderingContext2DAzure::StyleColorToString(const nscolor& aColor, nsAString& aStr)
 {
   // We can't reuse the normal CSS color stringification code,
   // because the spec calls for a different algorithm for canvas.
   if (NS_GET_A(aColor) == 255) {
     CopyUTF8toUTF16(nsPrintfCString("#%02x%02x%02x",
                                     NS_GET_R(aColor),
@@ -1276,29 +842,27 @@ nsCanvasRenderingContext2DAzure::Redraw(
   nsSVGEffects::InvalidateDirectRenderingObservers(mCanvasElement);
 
   gfxRect tmpR = ThebesRect(r);
   mCanvasElement->InvalidateCanvasContent(&tmpR);
 
   return;
 }
 
-nsresult
+void
 nsCanvasRenderingContext2DAzure::RedrawUser(const gfxRect& r)
 {
   if (mIsEntireFrameInvalid) {
     ++mInvalidateCount;
-    return NS_OK;
+    return;
   }
 
   mgfx::Rect newr =
     mTarget->GetTransform().TransformBounds(ToRect(r));
   Redraw(newr);
-
-  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::SetDimensions(PRInt32 width, PRInt32 height)
 {
   RefPtr<DrawTarget> target;
 
   // Zero sized surfaces cause issues, so just go with 1x1.
@@ -1559,238 +1123,454 @@ nsCanvasRenderingContext2DAzure::GetSurf
 
 //
 // nsCanvasRenderingContext2DAzure impl
 //
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetCanvas(nsIDOMHTMLCanvasElement **canvas)
 {
-  NS_IF_ADDREF(*canvas = mCanvasElement);
+  NS_IF_ADDREF(*canvas = GetCanvas());
 
   return NS_OK;
 }
 
 //
 // state
 //
 
-NS_IMETHODIMP
+void
 nsCanvasRenderingContext2DAzure::Save()
 {
   mStyleStack[mStyleStack.Length() - 1].transform = mTarget->GetTransform();
   mStyleStack.SetCapacity(mStyleStack.Length() + 1);
   mStyleStack.AppendElement(CurrentState());
-  return NS_OK;
 }
 
 NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::MozSave()
+{
+  Save();
+  return NS_OK;
+}
+
+void
 nsCanvasRenderingContext2DAzure::Restore()
 {
   if (mStyleStack.Length() - 1 == 0)
-    return NS_OK;
+    return;
 
   for (PRUint32 i = 0; i < CurrentState().clipsPushed.size(); i++) {
     mTarget->PopClip();
   }
 
   mStyleStack.RemoveElementAt(mStyleStack.Length() - 1);
 
   TransformWillUpdate();
 
   mTarget->SetTransform(CurrentState().transform);
-
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::MozRestore()
+{
+  Restore();
   return NS_OK;
 }
 
 //
 // transformations
 //
 
-NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::Scale(float x, float y)
+void
+nsCanvasRenderingContext2DAzure::Scale(double x, double y, ErrorResult& error)
 {
   if (!mTarget) {
-    return NS_ERROR_FAILURE;
-  }
+    error.Throw(NS_ERROR_FAILURE);
+    return;
+  }
+
   if (!FloatValidate(x,y)) {
-    return NS_OK;
+    return;
   }
 
   TransformWillUpdate();
 
   Matrix newMatrix = mTarget->GetTransform();
   mTarget->SetTransform(newMatrix.Scale(x, y));
-  return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::Rotate(float angle)
+nsCanvasRenderingContext2DAzure::Scale(float x, float y)
+{
+  ErrorResult rv;
+  Scale((double)x, (double)y, rv);
+  return rv.ErrorCode();
+}
+
+void
+nsCanvasRenderingContext2DAzure::Rotate(double angle, ErrorResult& error)
 {
   if (!mTarget) {
-    return NS_ERROR_FAILURE;
-  }
+    error.Throw(NS_ERROR_FAILURE);
+    return;
+  }
+
   if (!FloatValidate(angle)) {
-    return NS_OK;
+    return;
   }
 
   TransformWillUpdate();
 
   Matrix rotation = Matrix::Rotation(angle);
   mTarget->SetTransform(rotation * mTarget->GetTransform());
-  return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::Translate(float x, float y)
+nsCanvasRenderingContext2DAzure::Rotate(float angle)
+{
+  ErrorResult rv;
+  Rotate((double)angle, rv);
+  return rv.ErrorCode();
+}
+
+void
+nsCanvasRenderingContext2DAzure::Translate(double x, double y, ErrorResult& error)
 {
   if (!mTarget) {
-    return NS_ERROR_FAILURE;
-  }
+    error.Throw(NS_ERROR_FAILURE);
+    return;
+  }
+
   if (!FloatValidate(x,y)) {
-    return NS_OK;
+    return;
   }
 
   TransformWillUpdate();
 
   Matrix newMatrix = mTarget->GetTransform();
   mTarget->SetTransform(newMatrix.Translate(x, y));
-  return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::Transform(float m11, float m12, float m21, float m22, float dx, float dy)
+nsCanvasRenderingContext2DAzure::Translate(float x, float y)
+{
+  ErrorResult rv;
+  Translate((double)x, (double)y, rv);
+  return rv.ErrorCode();
+}
+
+void
+nsCanvasRenderingContext2DAzure::Transform(double m11, double m12, double m21,
+                                           double m22, double dx, double dy,
+                                           ErrorResult& error)
 {
   if (!mTarget) {
-    return NS_ERROR_FAILURE;
-  }
+    error.Throw(NS_ERROR_FAILURE);
+    return;
+  }
+
   if (!FloatValidate(m11,m12,m21,m22,dx,dy)) {
-    return NS_OK;
+    return;
   }
 
   TransformWillUpdate();
 
   Matrix matrix(m11, m12, m21, m22, dx, dy);
   mTarget->SetTransform(matrix * mTarget->GetTransform());
-  return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::SetTransform(float m11, float m12, float m21, float m22, float dx, float dy)
+nsCanvasRenderingContext2DAzure::Transform(float m11, float m12, float m21, float m22, float dx, float dy)
+{
+  ErrorResult rv;
+  Transform((double)m11, (double)m12, (double)m21, (double)m22, (double)dx,
+            (double)dy, rv);
+  return rv.ErrorCode();
+}
+
+void
+nsCanvasRenderingContext2DAzure::SetTransform(double m11, double m12,
+                                              double m21, double m22,
+                                              double dx, double dy,
+                                              ErrorResult& error)
 {
   if (!mTarget) {
-    return NS_ERROR_FAILURE;
-  }
+    error.Throw(NS_ERROR_FAILURE);
+    return;
+  }
+
   if (!FloatValidate(m11,m12,m21,m22,dx,dy)) {
-    return NS_OK;
+    return;
   }
 
   TransformWillUpdate();
 
   Matrix matrix(m11, m12, m21, m22, dx, dy);
   mTarget->SetTransform(matrix);
-
-  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::SetTransform(float m11, float m12, float m21, float m22, float dx, float dy)
+{
+  ErrorResult rv;
+  SetTransform((double)m11, (double)m12, (double)m21, (double)m22, (double)dx,
+               (double)dy, rv);
+  return rv.ErrorCode();
+}
+
+JSObject*
+MatrixToJSObject(JSContext* cx, const Matrix& matrix, ErrorResult& error)
+{
+  jsval elts[] = {
+      DOUBLE_TO_JSVAL(matrix._11), DOUBLE_TO_JSVAL(matrix._12),
+      DOUBLE_TO_JSVAL(matrix._21), DOUBLE_TO_JSVAL(matrix._22),
+      DOUBLE_TO_JSVAL(matrix._31), DOUBLE_TO_JSVAL(matrix._32)
+  };
+
+  // XXX Should we enter GetWrapper()'s compartment?
+  JSObject* obj = JS_NewArrayObject(cx, 6, elts);
+  if  (!obj) {
+      error.Throw(NS_ERROR_OUT_OF_MEMORY);
+  }
+  return obj;
+}
+
+bool
+ObjectToMatrix(JSContext* cx, JSObject& obj, Matrix& matrix, ErrorResult& error)
+{
+  uint32_t length;
+  if (!JS_GetArrayLength(cx, &obj, &length) || length != 6) {
+    // Not an array-like thing or wrong size
+    error.Throw(NS_ERROR_INVALID_ARG);
+    return false;
+  }
+
+  Float* elts[] = { &matrix._11, &matrix._12, &matrix._21, &matrix._22,
+                    &matrix._31, &matrix._32 };
+  for (PRUint32 i = 0; i < 6; ++i) {
+    jsval elt;
+    double d;
+    if (!JS_GetElement(cx, &obj, i, &elt)) {
+      error.Throw(NS_ERROR_FAILURE);
+      return false;
+    }
+    if (!CoerceDouble(elt, &d)) {
+      error.Throw(NS_ERROR_INVALID_ARG);
+      return false;
+    }
+    if (!FloatValidate(d)) {
+      // This is weird, but it's the behavior of SetTransform()
+      return false;
+    }
+    *elts[i] = Float(d);
+  }
+  return true;
+}
+
+void
+nsCanvasRenderingContext2DAzure::SetMozCurrentTransform(JSContext* cx,
+                                                        JSObject& currentTransform,
+                                                        ErrorResult& error)
+{
+  if (!mTarget) {
+    error.Throw(NS_ERROR_FAILURE);
+    return;
+  }
+
+  Matrix newCTM;
+  if (ObjectToMatrix(cx, currentTransform, newCTM, error)) {
+    mTarget->SetTransform(newCTM);
+  }
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::SetMozCurrentTransform(JSContext* cx,
                                                         const jsval& matrix)
 {
+  if (!matrix.isObject()) {
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  ErrorResult rv;
+  SetMozCurrentTransform(cx, matrix.toObject(), rv);
+  return rv.ErrorCode();
+}
+
+JSObject*
+nsCanvasRenderingContext2DAzure::GetMozCurrentTransform(JSContext* cx,
+                                                        ErrorResult& error) const
+{
   if (!mTarget) {
-    return NS_ERROR_FAILURE;
-  }
-
-  nsresult rv;
-  Matrix newCTM;
-
-  if (!JSValToMatrix(cx, matrix, &newCTM, &rv)) {
-    return rv;
-  }
-
-  mTarget->SetTransform(newCTM);
-
-  return NS_OK;
+    error.Throw(NS_ERROR_FAILURE);
+    return NULL;
+  }
+
+  return MatrixToJSObject(cx, mTarget->GetTransform(), error);
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetMozCurrentTransform(JSContext* cx,
                                                         jsval* matrix)
 {
+  ErrorResult rv;
+  JSObject* obj = GetMozCurrentTransform(cx, rv);
+  if (!rv.Failed()) {
+    *matrix = OBJECT_TO_JSVAL(obj);
+  }
+  return rv.ErrorCode();
+}
+
+void
+nsCanvasRenderingContext2DAzure::SetMozCurrentTransformInverse(JSContext* cx,
+                                                               JSObject& currentTransform,
+                                                               ErrorResult& error)
+{
   if (!mTarget) {
-    return NS_ERROR_FAILURE;
-  }
-
-  return MatrixToJSVal(mTarget->GetTransform(), cx, matrix);
+    error.Throw(NS_ERROR_FAILURE);
+    return;
+  }
+
+  Matrix newCTMInverse;
+  if (ObjectToMatrix(cx, currentTransform, newCTMInverse, error)) {
+    // XXX ERRMSG we need to report an error to developers here! (bug 329026)
+    if (newCTMInverse.Invert()) {
+      mTarget->SetTransform(newCTMInverse);
+    }
+  }
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::SetMozCurrentTransformInverse(JSContext* cx,
                                                                const jsval& matrix)
 {
-  if (!mTarget) {
-    return NS_ERROR_FAILURE;
-  }
-
-  nsresult rv;
-  Matrix newCTMInverse;
-
-  if (!JSValToMatrix(cx, matrix, &newCTMInverse, &rv)) {
-    return rv;
-  }
-
-  // XXX ERRMSG we need to report an error to developers here! (bug 329026)
-  if (newCTMInverse.Invert()) {
-    mTarget->SetTransform(newCTMInverse);
-  }
-
-  return NS_OK;
+  if (!matrix.isObject()) {
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  ErrorResult rv;
+  SetMozCurrentTransformInverse(cx, matrix.toObject(), rv);
+  return rv.ErrorCode();
 }
 
-NS_IMETHODIMP
+JSObject*
 nsCanvasRenderingContext2DAzure::GetMozCurrentTransformInverse(JSContext* cx,
-                                                               jsval* matrix)
+                                                               ErrorResult& error) const
 {
   if (!mTarget) {
-    return NS_ERROR_FAILURE;
+    error.Throw(NS_ERROR_FAILURE);
+    return NULL;
   }
 
   Matrix ctm = mTarget->GetTransform();
 
   if (!ctm.Invert()) {
     double NaN = JSVAL_TO_DOUBLE(JS_GetNaNValue(cx));
     ctm = Matrix(NaN, NaN, NaN, NaN, NaN, NaN);
   }
 
-  return MatrixToJSVal(ctm, cx, matrix);
+  return MatrixToJSObject(cx, ctm, error);
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::GetMozCurrentTransformInverse(JSContext* cx,
+                                                               jsval* matrix)
+{
+  ErrorResult rv;
+  JSObject* obj = GetMozCurrentTransformInverse(cx, rv);
+  if (!rv.Failed()) {
+    *matrix = OBJECT_TO_JSVAL(obj);
+  }
+  return rv.ErrorCode();
 }
 
 //
 // colors
 //
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::SetGlobalAlpha(float aGlobalAlpha)
 {
-  if (!FloatValidate(aGlobalAlpha) || aGlobalAlpha < 0.0 || aGlobalAlpha > 1.0) {
-    return NS_OK;
-  }
-
-  CurrentState().globalAlpha = aGlobalAlpha;
-    
+  SetGlobalAlpha((double)aGlobalAlpha);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetGlobalAlpha(float *aGlobalAlpha)
 {
-  *aGlobalAlpha = CurrentState().globalAlpha;
+  *aGlobalAlpha = GetGlobalAlpha();
   return NS_OK;
 }
 
+void
+nsCanvasRenderingContext2DAzure::SetStyleFromJSValue(JSContext* cx,
+                                                     JS::Value& value,
+                                                     Style whichStyle)
+{
+  if (value.isString()) {
+    nsDependentJSString strokeStyle;
+    if (strokeStyle.init(cx, value.toString())) {
+      SetStyleFromString(strokeStyle, whichStyle);
+    }
+    return;
+  }
+
+  if (value.isObject()) {
+    nsCOMPtr<nsISupports> holder;
+
+    nsCanvasGradientAzure* gradient;
+    nsresult rv = xpc_qsUnwrapArg<nsCanvasGradientAzure>(cx, value, &gradient,
+                                                         static_cast<nsISupports**>(getter_AddRefs(holder)),
+                                                         &value);
+    if (NS_SUCCEEDED(rv)) {
+      SetStyleFromGradient(gradient, whichStyle);
+      return;
+    }
+
+    nsCanvasPatternAzure* pattern;
+    rv = xpc_qsUnwrapArg<nsCanvasPatternAzure>(cx, value, &pattern,
+                                               static_cast<nsISupports**>(getter_AddRefs(holder)),
+                                               &value);
+    if (NS_SUCCEEDED(rv)) {
+      SetStyleFromPattern(pattern, whichStyle);
+      return;
+    }
+  }
+
+  WarnAboutUnexpectedStyle(mCanvasElement);
+}
+
+static JS::Value
+WrapStyle(JSContext* cx, JSObject* obj,
+          nsIDOMCanvasRenderingContext2D::CanvasMultiGetterType type,
+          nsAString& str, nsISupports* supports, ErrorResult& error)
+{
+  JS::Value v;
+  bool ok;
+  switch (type) {
+    case nsIDOMCanvasRenderingContext2D::CMG_STYLE_STRING:
+    {
+      ok = xpc::StringToJsval(cx, str, &v);
+      break;
+    }
+    case nsIDOMCanvasRenderingContext2D::CMG_STYLE_PATTERN:
+    case nsIDOMCanvasRenderingContext2D::CMG_STYLE_GRADIENT:
+    {
+      ok = dom::WrapObject(cx, obj, supports, &v);
+      break;
+    }
+    default:
+      MOZ_NOT_REACHED("unexpected CanvasMultiGetterType");
+  }
+  if (!ok) {
+    error.Throw(NS_ERROR_FAILURE);
+  }
+  return v;
+}
+
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::SetStrokeStyle(nsIVariant *aValue)
 {
   if (!aValue)
       return NS_ERROR_FAILURE;
 
   nsString str;
 
@@ -1815,16 +1595,26 @@ nsCanvasRenderingContext2DAzure::SetStro
   }
 
   rv = aValue->GetAsAString(str);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return SetStrokeStyle_multi(str, nsnull);
 }
 
+JS::Value
+nsCanvasRenderingContext2DAzure::GetStrokeStyle(JSContext* cx,
+                                                ErrorResult& error)
+{
+  nsString str;
+  CanvasMultiGetterType t;
+  nsISupports* supports = GetStyleAsStringOrInterface(str, t, STYLE_STROKE);
+  return WrapStyle(cx, GetWrapper(), t, str, supports, error);
+}
+
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetStrokeStyle(nsIVariant **aResult)
 {
   nsCOMPtr<nsIWritableVariant> wv = do_CreateInstance(NS_VARIANT_CONTRACTID);
 
   nsCOMPtr<nsISupports> sup;
   nsString str;
   PRInt32 t;
@@ -1875,16 +1665,26 @@ nsCanvasRenderingContext2DAzure::SetFill
   }
 
   rv = aValue->GetAsAString(str);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return SetFillStyle_multi(str, nsnull);
 }
 
+JS::Value
+nsCanvasRenderingContext2DAzure::GetFillStyle(JSContext* cx,
+                                              ErrorResult& error)
+{
+  nsString str;
+  CanvasMultiGetterType t;
+  nsISupports* supports = GetStyleAsStringOrInterface(str, t, STYLE_FILL);
+  return WrapStyle(cx, GetWrapper(), t, str, supports, error);
+}
+
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetFillStyle(nsIVariant **aResult)
 {
   nsCOMPtr<nsIWritableVariant> wv = do_CreateInstance(NS_VARIANT_CONTRACTID);
 
   nsCOMPtr<nsISupports> sup;
   nsString str;
   PRInt32 t;
@@ -1904,278 +1704,336 @@ nsCanvasRenderingContext2DAzure::GetFill
     return NS_ERROR_FAILURE;
   }
   NS_ENSURE_SUCCESS(rv, rv);
 
   NS_IF_ADDREF(*aResult = wv.get());
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::SetMozFillRule(const nsAString& aString)
+void
+nsCanvasRenderingContext2DAzure::SetFillRule(const nsAString& aString)
 {
   FillRule rule;
 
   if (aString.EqualsLiteral("evenodd"))
     rule = FILL_EVEN_ODD;
   else if (aString.EqualsLiteral("nonzero"))
     rule = FILL_WINDING;
   else
-    return NS_OK;
+    return;
 
   CurrentState().fillRule = rule;
-  return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::GetMozFillRule(nsAString& aString)
+nsCanvasRenderingContext2DAzure::SetMozFillRule(const nsAString& aString)
+{
+  SetFillRule(aString);
+  return NS_OK;
+}
+
+void
+nsCanvasRenderingContext2DAzure::GetFillRule(nsAString& aString)
 {
     switch (CurrentState().fillRule) {
     case FILL_WINDING:
         aString.AssignLiteral("nonzero"); break;
     case FILL_EVEN_ODD:
         aString.AssignLiteral("evenodd"); break;
     }
-
-    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::GetMozFillRule(nsAString& aString)
+{
+  GetFillRule(aString);
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::SetStrokeStyle_multi(const nsAString& aStr, nsISupports *aInterface)
 {
-    return SetStyleFromStringOrInterface(aStr, aInterface, STYLE_STROKE);
+  SetStyleFromStringOrInterface(aStr, aInterface, STYLE_STROKE);
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetStrokeStyle_multi(nsAString& aStr, nsISupports **aInterface, PRInt32 *aType)
 {
-    return GetStyleAsStringOrInterface(aStr, aInterface, aType, STYLE_STROKE);
+  CanvasMultiGetterType type;
+  NS_IF_ADDREF(*aInterface = GetStyleAsStringOrInterface(aStr, type, STYLE_STROKE));
+  *aType = type;
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::SetFillStyle_multi(const nsAString& aStr, nsISupports *aInterface)
 {
-    return SetStyleFromStringOrInterface(aStr, aInterface, STYLE_FILL);
+  SetStyleFromStringOrInterface(aStr, aInterface, STYLE_FILL);
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetFillStyle_multi(nsAString& aStr, nsISupports **aInterface, PRInt32 *aType)
 {
-    return GetStyleAsStringOrInterface(aStr, aInterface, aType, STYLE_FILL);
+  CanvasMultiGetterType type;
+  NS_IF_ADDREF(*aInterface = GetStyleAsStringOrInterface(aStr, type, STYLE_FILL));
+  *aType = type;
+  return NS_OK;
 }
 
 //
 // gradients and patterns
 //
+already_AddRefed<nsIDOMCanvasGradient>
+nsCanvasRenderingContext2DAzure::CreateLinearGradient(double x0, double y0, double x1, double y1,
+                                                      ErrorResult& aError)
+{
+  if (!FloatValidate(x0,y0,x1,y1)) {
+    aError.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
+    return nsnull;
+  }
+
+  nsRefPtr<nsIDOMCanvasGradient> grad =
+    new nsCanvasLinearGradientAzure(Point(x0, y0), Point(x1, y1));
+
+  return grad.forget();
+}
+
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::CreateLinearGradient(float x0, float y0, float x1, float y1,
                                                       nsIDOMCanvasGradient **_retval)
 {
-  if (!FloatValidate(x0,y0,x1,y1)) {
-    return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
+  ErrorResult rv;
+  *_retval = CreateLinearGradient(x0, y0, x1, y1, rv).get();
+  return rv.ErrorCode();
+}
+
+already_AddRefed<nsIDOMCanvasGradient>
+nsCanvasRenderingContext2DAzure::CreateRadialGradient(double x0, double y0, double r0,
+                                                      double x1, double y1, double r1,
+                                                      ErrorResult& aError)
+{
+  if (!FloatValidate(x0,y0,r0,x1,y1,r1)) {
+    aError.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
+    return nsnull;
+  }
+
+  if (r0 < 0.0 || r1 < 0.0) {
+    aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+    return nsnull;
   }
 
   nsRefPtr<nsIDOMCanvasGradient> grad =
-    new nsCanvasLinearGradientAzure(Point(x0, y0), Point(x1, y1));
-
-  *_retval = grad.forget().get();
-  return NS_OK;
+    new nsCanvasRadialGradientAzure(Point(x0, y0), r0, Point(x1, y1), r1);
+
+  return grad.forget();
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::CreateRadialGradient(float x0, float y0, float r0,
                                                       float x1, float y1, float r1,
                                                       nsIDOMCanvasGradient **_retval)
 {
-  if (!FloatValidate(x0,y0,r0,x1,y1,r1)) {
-    return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
-  }
-
-  if (r0 < 0.0 || r1 < 0.0) {
-    return NS_ERROR_DOM_INDEX_SIZE_ERR;
-  }
-
-  nsRefPtr<nsIDOMCanvasGradient> grad =
-    new nsCanvasRadialGradientAzure(Point(x0, y0), r0, Point(x1, y1), r1);
-
-  *_retval = grad.forget().get();
-  return NS_OK;
+  ErrorResult rv;
+  *_retval = CreateRadialGradient(x0, y0, r0, x1, y1, r1, rv).get();
+  return rv.ErrorCode();
 }
 
-NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::CreatePattern(nsIDOMHTMLElement *image,
+already_AddRefed<nsIDOMCanvasPattern>
+nsCanvasRenderingContext2DAzure::CreatePattern(const HTMLImageOrCanvasOrVideoElement& element,
                                                const nsAString& repeat,
-                                               nsIDOMCanvasPattern **_retval)
+                                               ErrorResult& error)
 {
-  nsCOMPtr<nsIContent> content = do_QueryInterface(image);
-  if (!content) {
-    return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
-  }
-
   nsCanvasPatternAzure::RepeatMode repeatMode =
     nsCanvasPatternAzure::NOREPEAT;
 
   if (repeat.IsEmpty() || repeat.EqualsLiteral("repeat")) {
     repeatMode = nsCanvasPatternAzure::REPEAT;
   } else if (repeat.EqualsLiteral("repeat-x")) {
     repeatMode = nsCanvasPatternAzure::REPEATX;
   } else if (repeat.EqualsLiteral("repeat-y")) {
     repeatMode = nsCanvasPatternAzure::REPEATY;
   } else if (repeat.EqualsLiteral("no-repeat")) {
     repeatMode = nsCanvasPatternAzure::NOREPEAT;
   } else {
-    return NS_ERROR_DOM_SYNTAX_ERR;
-  }
-
-  nsHTMLCanvasElement* canvas = nsHTMLCanvasElement::FromContent(content);
-  if (canvas) {
+    error.Throw(NS_ERROR_DOM_SYNTAX_ERR);
+    return NULL;
+  }
+
+  Element* htmlElement;
+  if (element.IsHTMLCanvasElement()) {
+    nsHTMLCanvasElement* canvas = element.GetAsHTMLCanvasElement();
+    htmlElement = canvas;
+
     nsIntSize size = canvas->GetSize();
     if (size.width == 0 || size.height == 0) {
-      return NS_ERROR_DOM_INVALID_STATE_ERR;
+      error.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+      return NULL;
     }
 
     // Special case for Canvas, which could be an Azure canvas!
     nsICanvasRenderingContextInternal *srcCanvas = canvas->GetContextAtIndex(0);
     if (srcCanvas) {
       // This might not be an Azure canvas!
       RefPtr<SourceSurface> srcSurf = srcCanvas->GetSurfaceSnapshot();
 
       nsRefPtr<nsCanvasPatternAzure> pat =
-        new nsCanvasPatternAzure(srcSurf, repeatMode, content->NodePrincipal(), canvas->IsWriteOnly(), false);
-
-      *_retval = pat.forget().get();
-      return NS_OK;
+        new nsCanvasPatternAzure(srcSurf, repeatMode, htmlElement->NodePrincipal(), canvas->IsWriteOnly(), false);
+
+      return pat.forget();
     }
+  } else if (element.IsHTMLImageElement()) {
+    htmlElement = element.GetAsHTMLImageElement();
+  } else {
+    htmlElement = element.GetAsHTMLVideoElement();
   }
 
   // The canvas spec says that createPattern should use the first frame
   // of animated images
   nsLayoutUtils::SurfaceFromElementResult res =
-    nsLayoutUtils::SurfaceFromElement(content->AsElement(),
+    nsLayoutUtils::SurfaceFromElement(htmlElement,
       nsLayoutUtils::SFE_WANT_FIRST_FRAME | nsLayoutUtils::SFE_WANT_NEW_SURFACE);
 
   if (!res.mSurface) {
-    return NS_ERROR_NOT_AVAILABLE;
+    error.Throw(NS_ERROR_NOT_AVAILABLE);
+    return NULL;
   }
 
   // Ignore nsnull cairo surfaces! See bug 666312.
   if (!res.mSurface->CairoSurface() || res.mSurface->CairoStatus()) {
-    return NS_OK;
+    return NULL;
   }
 
   RefPtr<SourceSurface> srcSurf =
     gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(mTarget, res.mSurface);
 
   nsRefPtr<nsCanvasPatternAzure> pat =
     new nsCanvasPatternAzure(srcSurf, repeatMode, res.mPrincipal,
                              res.mIsWriteOnly, res.mCORSUsed);
 
-  *_retval = pat.forget().get();
-  return NS_OK;
+  return pat.forget();
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::CreatePattern(nsIDOMHTMLElement *image,
+                                               const nsAString& repeat,
+                                               nsIDOMCanvasPattern **_retval)
+{
+  HTMLImageOrCanvasOrVideoElement element;
+  if (!ToHTMLImageOrCanvasOrVideoElement(image, element)) {
+    return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
+  }
+
+  ErrorResult rv;
+  *_retval = CreatePattern(element, repeat, rv).get();
+  return rv.ErrorCode();
 }
 
 //
 // shadows
 //
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::SetShadowOffsetX(float x)
 {
-  if (!FloatValidate(x)) {
-    return NS_OK;
-  }
-
-  CurrentState().shadowOffset.x = x;
+  SetShadowOffsetX((double)x);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetShadowOffsetX(float *x)
 {
-  *x = static_cast<float>(CurrentState().shadowOffset.x);
+  *x = static_cast<float>(GetShadowOffsetX());
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::SetShadowOffsetY(float y)
 {
-  if (!FloatValidate(y)) {
-    return NS_OK;
-  }
-
-  CurrentState().shadowOffset.y = y;
+  SetShadowOffsetY((double)y);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetShadowOffsetY(float *y)
 {
-  *y = static_cast<float>(CurrentState().shadowOffset.y);
+  *y = static_cast<float>(GetShadowOffsetY());
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::SetShadowBlur(float blur)
 {
-  if (!FloatValidate(blur) || blur < 0.0) {
-    return NS_OK;
-  }
-
-  CurrentState().shadowBlur = blur;
+  SetShadowBlur((double)blur);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetShadowBlur(float *blur)
 {
-  *blur = CurrentState().shadowBlur;
+  *blur = GetShadowBlur();
+  return NS_OK;
+}
+
+void
+nsCanvasRenderingContext2DAzure::SetShadowColor(const nsAString& shadowColor)
+{
+  nscolor color;
+  if (!ParseColor(shadowColor, &color)) {
+    return;
+  }
+
+  CurrentState().shadowColor = color;
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::SetMozShadowColor(const nsAString& colorstr)
+{
+  SetShadowColor(colorstr);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::SetShadowColor(const nsAString& aColor)
+nsCanvasRenderingContext2DAzure::GetMozShadowColor(nsAString& color)
 {
-  nscolor color;
-  if (!ParseColor(aColor, &color)) {
-    return NS_OK;
-  }
-
-  CurrentState().shadowColor = color;
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::GetShadowColor(nsAString& color)
-{
-  StyleColorToString(CurrentState().shadowColor, color);
-
+  GetShadowColor(color);
   return NS_OK;
 }
 
 //
 // rects
 //
 
-NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::ClearRect(float x, float y, float w, float h)
+void
+nsCanvasRenderingContext2DAzure::ClearRect(double x, double y, double w,
+                                           double h)
 {
   if (!FloatValidate(x,y,w,h)) {
-    return NS_OK;
+    return;
   }
  
   mTarget->ClearRect(mgfx::Rect(x, y, w, h));
 
-  return RedrawUser(gfxRect(x, y, w, h));
+  RedrawUser(gfxRect(x, y, w, h));
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::FillRect(float x, float y, float w, float h)
+nsCanvasRenderingContext2DAzure::ClearRect(float x, float y, float w, float h)
+{
+  ClearRect((double)x, (double)y, (double)w, (double)h);
+  return NS_OK;
+}
+
+void
+nsCanvasRenderingContext2DAzure::FillRect(double x, double y, double w,
+                                          double h)
 {
   if (!FloatValidate(x,y,w,h)) {
-    return NS_OK;
+    return;
   }
 
   const ContextState &state = CurrentState();
 
   if (state.patternStyles[STYLE_FILL]) {
     nsCanvasPatternAzure::RepeatMode repeat = 
       state.patternStyles[STYLE_FILL]->mRepeat;
     // In the FillRect case repeat modes are easy to deal with.
@@ -2225,315 +2083,297 @@ nsCanvasRenderingContext2DAzure::FillRec
   
   if (NeedToDrawShadow()) {
     bounds = mgfx::Rect(x, y, w, h);
     bounds = mTarget->GetTransform().TransformBounds(bounds);
   }
 
   AdjustedTarget(this, bounds.IsEmpty() ? nsnull : &bounds)->
     FillRect(mgfx::Rect(x, y, w, h),
-             GeneralPattern().ForStyle(this, STYLE_FILL, mTarget),
+             CanvasGeneralPattern().ForStyle(this, STYLE_FILL, mTarget),
              DrawOptions(state.globalAlpha, UsedOperation()));
 
-  return RedrawUser(gfxRect(x, y, w, h));
+  RedrawUser(gfxRect(x, y, w, h));
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::StrokeRect(float x, float y, float w, float h)
+nsCanvasRenderingContext2DAzure::FillRect(float x, float y, float w, float h)
+{
+  FillRect((double)x, (double)y, (double)w, (double)h);
+  return NS_OK;
+}
+
+void
+nsCanvasRenderingContext2DAzure::StrokeRect(double x, double y, double w,
+                                            double h)
 {
   if (!FloatValidate(x,y,w,h)) {
-    return NS_OK;
+    return;
   }
 
   const ContextState &state = CurrentState();
 
   mgfx::Rect bounds;
   
   if (NeedToDrawShadow()) {
     bounds = mgfx::Rect(x - state.lineWidth / 2.0f, y - state.lineWidth / 2.0f,
                         w + state.lineWidth, h + state.lineWidth);
     bounds = mTarget->GetTransform().TransformBounds(bounds);
   }
 
   if (!w && !h) {
-    return NS_OK;
-  } else if (!h) {
+    return;
+  }
+
+  if (!h) {
     CapStyle cap = CAP_BUTT;
     if (state.lineJoin == JOIN_ROUND) {
       cap = CAP_ROUND;
     }
     AdjustedTarget(this, bounds.IsEmpty() ? nsnull : &bounds)->
       StrokeLine(Point(x, y), Point(x + w, y),
-                  GeneralPattern().ForStyle(this, STYLE_STROKE, mTarget),
+                  CanvasGeneralPattern().ForStyle(this, STYLE_STROKE, mTarget),
                   StrokeOptions(state.lineWidth, state.lineJoin,
                                 cap, state.miterLimit,
                                 state.dash.Length(),
                                 state.dash.Elements(),
                                 state.dashOffset),
                   DrawOptions(state.globalAlpha, UsedOperation()));
-    return NS_OK;
-  } else if (!w) {
+    return;
+  }
+
+  if (!w) {
     CapStyle cap = CAP_BUTT;
     if (state.lineJoin == JOIN_ROUND) {
       cap = CAP_ROUND;
     }
     AdjustedTarget(this, bounds.IsEmpty() ? nsnull : &bounds)->
       StrokeLine(Point(x, y), Point(x, y + h),
-                  GeneralPattern().ForStyle(this, STYLE_STROKE, mTarget),
+                  CanvasGeneralPattern().ForStyle(this, STYLE_STROKE, mTarget),
                   StrokeOptions(state.lineWidth, state.lineJoin,
                                 cap, state.miterLimit,
                                 state.dash.Length(),
                                 state.dash.Elements(),
                                 state.dashOffset),
                   DrawOptions(state.globalAlpha, UsedOperation()));
-    return NS_OK;
+    return;
   }
 
   AdjustedTarget(this, bounds.IsEmpty() ? nsnull : &bounds)->
     StrokeRect(mgfx::Rect(x, y, w, h),
-                GeneralPattern().ForStyle(this, STYLE_STROKE, mTarget),
+                CanvasGeneralPattern().ForStyle(this, STYLE_STROKE, mTarget),
                 StrokeOptions(state.lineWidth, state.lineJoin,
                               state.lineCap, state.miterLimit,
                               state.dash.Length(),
                               state.dash.Elements(),
                               state.dashOffset),
                 DrawOptions(state.globalAlpha, UsedOperation()));
 
-  return Redraw();
+  Redraw();
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::StrokeRect(float x, float y, float w, float h)
+{
+  StrokeRect((double)x, (double)y, (double)w, (double)h);
+  return NS_OK;
 }
 
 //
 // path bits
 //
 
-NS_IMETHODIMP
+void
 nsCanvasRenderingContext2DAzure::BeginPath()
 {
   mPath = nsnull;
   mPathBuilder = nsnull;
   mDSPathBuilder = nsnull;
   mPathTransformWillUpdate = false;
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::MozBeginPath()
+{
+  BeginPath();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::ClosePath()
+nsCanvasRenderingContext2DAzure::MozClosePath()
 {
-  EnsureWritablePath();
-
-  if (mPathBuilder) {
-    mPathBuilder->Close();
-  } else {
-    mDSPathBuilder->Close();
-  }
-
+  ClosePath();
   return NS_OK;
 }
 
-NS_IMETHODIMP
+void
 nsCanvasRenderingContext2DAzure::Fill()
 {
   EnsureUserSpacePath();
 
   if (!mPath) {
-    return NS_OK;
+    return;
   }
 
   mgfx::Rect bounds;
 
   if (NeedToDrawShadow()) {
     bounds = mPath->GetBounds(mTarget->GetTransform());
   }
 
   AdjustedTarget(this, bounds.IsEmpty() ? nsnull : &bounds)->
-    Fill(mPath, GeneralPattern().ForStyle(this, STYLE_FILL, mTarget),
+    Fill(mPath, CanvasGeneralPattern().ForStyle(this, STYLE_FILL, mTarget),
          DrawOptions(CurrentState().globalAlpha, UsedOperation()));
 
-  return Redraw();
+  Redraw();
 }
 
 NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::MozFill()
+{
+  Fill();
+  return NS_OK;
+}
+
+void
 nsCanvasRenderingContext2DAzure::Stroke()
 {
   EnsureUserSpacePath();
 
   if (!mPath) {
-    return NS_OK;
+    return;
   }
 
   const ContextState &state = CurrentState();
 
   StrokeOptions strokeOptions(state.lineWidth, state.lineJoin,
                               state.lineCap, state.miterLimit,
                               state.dash.Length(), state.dash.Elements(),
                               state.dashOffset);
 
   mgfx::Rect bounds;
   if (NeedToDrawShadow()) {
     bounds =
       mPath->GetStrokedBounds(strokeOptions, mTarget->GetTransform());
   }
 
   AdjustedTarget(this, bounds.IsEmpty() ? nsnull : &bounds)->
-    Stroke(mPath, GeneralPattern().ForStyle(this, STYLE_STROKE, mTarget),
+    Stroke(mPath, CanvasGeneralPattern().ForStyle(this, STYLE_STROKE, mTarget),
            strokeOptions, DrawOptions(state.globalAlpha, UsedOperation()));
 
-  return Redraw();
+  Redraw();
 }
 
 NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::MozStroke()
+{
+  Stroke();
+  return NS_OK;
+}
+
+void
 nsCanvasRenderingContext2DAzure::Clip()
 {
   EnsureUserSpacePath();
 
   if (!mPath) {
-    return NS_OK;
+    return;
   }
 
   mTarget->PushClip(mPath);
   CurrentState().clipsPushed.push_back(mPath);
-
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::MozClip()
+{
+  Clip();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::MoveTo(float x, float y)
 {
-  if (!FloatValidate(x,y))
-      return NS_OK;
-
-  EnsureWritablePath();
-
-  if (mPathBuilder) {
-    mPathBuilder->MoveTo(Point(x, y));
-  } else {
-    mDSPathBuilder->MoveTo(mTarget->GetTransform() * Point(x, y));
-  }
-
+  MoveTo((double)x, (double)y);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::LineTo(float x, float y)
 {
-  if (!FloatValidate(x,y))
-      return NS_OK;
-
-  EnsureWritablePath();
-    
-  return LineTo(Point(x, y));;
+  LineTo((double)x, (double)y);
+  return NS_OK;
 }
   
-nsresult 
-nsCanvasRenderingContext2DAzure::LineTo(const Point& aPoint)
+NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::QuadraticCurveTo(float cpx, float cpy, float x,
+                                                  float y)
 {
-  if (mPathBuilder) {
-    mPathBuilder->LineTo(aPoint);
-  } else {
-    mDSPathBuilder->LineTo(mTarget->GetTransform() * aPoint);
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::QuadraticCurveTo(float cpx, float cpy, float x, float y)
-{
-  if (!FloatValidate(cpx, cpy, x, y)) {
-    return NS_OK;
-  }
-
-  EnsureWritablePath();
-
-  if (mPathBuilder) {
-    mPathBuilder->QuadraticBezierTo(Point(cpx, cpy), Point(x, y));
-  } else {
-    Matrix transform = mTarget->GetTransform();
-    mDSPathBuilder->QuadraticBezierTo(transform * Point(cpx, cpy), transform * Point(x, y));
-  }
-
+  QuadraticCurveTo((double)cpx, (double)cpy, (double)x, (double)y);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::BezierCurveTo(float cp1x, float cp1y,
-                                              float cp2x, float cp2y,
-                                              float x, float y)
+                                               float cp2x, float cp2y,
+                                               float x, float y)
 {
-  if (!FloatValidate(cp1x, cp1y, cp2x, cp2y, x, y)) {
-    return NS_OK;
-  }
-
-  EnsureWritablePath();
-
-  return BezierTo(Point(cp1x, cp1y), Point(cp2x, cp2y), Point(x, y));
-}
-
-nsresult
-nsCanvasRenderingContext2DAzure::BezierTo(const Point& aCP1,
-                                          const Point& aCP2,
-                                          const Point& aCP3)
-{
-  if (mPathBuilder) {
-    mPathBuilder->BezierTo(aCP1, aCP2, aCP3);
-  } else {
-    Matrix transform = mTarget->GetTransform();
-    mDSPathBuilder->BezierTo(transform * aCP1,
-                              transform * aCP2,
-                              transform * aCP3);
-  }
-
+  BezierCurveTo((double)cp1x, (double)cp1y, (double)cp2x, (double)cp2y,
+                (double)x, (double)y);
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::ArcTo(float x1, float y1, float x2, float y2, float radius)
+void
+nsCanvasRenderingContext2DAzure::ArcTo(double x1, double y1, double x2,
+                                       double y2, double radius,
+                                       ErrorResult& error)
 {
   if (!FloatValidate(x1, y1, x2, y2, radius)) {
-    return NS_OK;
+    return;
   }
 
   if (radius < 0) {
-    return NS_ERROR_DOM_INDEX_SIZE_ERR;
+    error.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+    return;
   }
 
   EnsureWritablePath();
 
   // Current point in user space!
   Point p0;
   if (mPathBuilder) {
     p0 = mPathBuilder->CurrentPoint();
   } else {
     Matrix invTransform = mTarget->GetTransform();
     if (!invTransform.Invert()) {
-      return NS_OK;
+      return;
     }
 
     p0 = invTransform * mDSPathBuilder->CurrentPoint();
   }
 
   Point p1(x1, y1);
   Point p2(x2, y2);
 
   // Execute these calculations in double precision to avoid cumulative
   // rounding errors.
   double dir, a2, b2, c2, cosx, sinx, d, anx, any,
           bnx, bny, x3, y3, x4, y4, cx, cy, angle0, angle1;
   bool anticlockwise;
 
   if (p0 == p1 || p1 == p2 || radius == 0) {
     LineTo(p1.x, p1.y);
-    return NS_OK;
+    return;
   }
 
   // Check for colinearity
   dir = (p2.x - p1.x) * (p0.y - p1.y) + (p2.y - p1.y) * (p1.x - p0.x);
   if (dir == 0) {
     LineTo(p1.x, p1.y);
-    return NS_OK;
+    return;
   }
 
 
   // XXX - Math for this code was already available from the non-azure code
   // and would be well tested. Perhaps converting to bezier directly might
   // be more efficient longer run.
   a2 = (p0.x-x1)*(p0.x-x1) + (p0.y-y1)*(p0.y-y1);
   b2 = (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2);
@@ -2556,43 +2396,61 @@ nsCanvasRenderingContext2DAzure::ArcTo(f
   cy = y3 - anx*radius*(anticlockwise ? 1 : -1);
   angle0 = atan2((y3-cy), (x3-cx));
   angle1 = atan2((y4-cy), (x4-cx));
 
 
   LineTo(x3, y3);
 
   Arc(cx, cy, radius, angle0, angle1, anticlockwise);
-  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::ArcTo(float x1, float y1, float x2, float y2, float radius)
+{
+  ErrorResult rv;
+  ArcTo(x1, y1, x2, y2, radius, rv);
+  return rv.ErrorCode();
+}
+
+void
+nsCanvasRenderingContext2DAzure::Arc(double x, double y, double r,
+                                     double startAngle, double endAngle,
+                                     bool anticlockwise, ErrorResult& error)
+{
+  if (!FloatValidate(x, y, r, startAngle, endAngle)) {
+    return;
+  }
+
+  if (r < 0.0) {
+    error.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+    return;
+  }
+
+  EnsureWritablePath();
+
+  ArcToBezier(this, Point(x, y), r, startAngle, endAngle, anticlockwise);
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::Arc(float x, float y,
                                      float r,
                                      float startAngle, float endAngle,
                                      bool ccw)
 {
-  if (!FloatValidate(x, y, r, startAngle, endAngle)) {
-    return NS_OK;
-  }
-
-  if (r < 0.0)
-      return NS_ERROR_DOM_INDEX_SIZE_ERR;
-
-  EnsureWritablePath();
-
-  ArcToBezier(this, Point(x, y), r, startAngle, endAngle, ccw);
-  return NS_OK;
+  ErrorResult rv;
+  Arc(x, y, r, startAngle, endAngle, ccw, rv);
+  return rv.ErrorCode();
 }
 
-NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::Rect(float x, float y, float w, float h)
+void
+nsCanvasRenderingContext2DAzure::Rect(double x, double y, double w, double h)
 {
   if (!FloatValidate(x, y, w, h)) {
-    return NS_OK;
+    return;
   }
 
   EnsureWritablePath();
 
   if (mPathBuilder) {
     mPathBuilder->MoveTo(Point(x, y));
     mPathBuilder->LineTo(Point(x + w, y));
     mPathBuilder->LineTo(Point(x + w, y + h));
@@ -2600,17 +2458,22 @@ nsCanvasRenderingContext2DAzure::Rect(fl
     mPathBuilder->Close();
   } else {
     mDSPathBuilder->MoveTo(mTarget->GetTransform() * Point(x, y));
     mDSPathBuilder->LineTo(mTarget->GetTransform() * Point(x + w, y));
     mDSPathBuilder->LineTo(mTarget->GetTransform() * Point(x + w, y + h));
     mDSPathBuilder->LineTo(mTarget->GetTransform() * Point(x, y + h));
     mDSPathBuilder->Close();
   }
-
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::Rect(float x, float y, float w, float h)
+{
+  Rect((double)x, (double)y, (double)w, (double)h);
   return NS_OK;
 }
 
 void
 nsCanvasRenderingContext2DAzure::EnsureWritablePath()
 {
   if (mDSPathBuilder) {
     return;
@@ -2751,63 +2614,64 @@ CreateFontStyleRule(const nsAString& aFo
   }
 
   rule->RuleMatched();
 
   rule.forget(aResult);
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::SetFont(const nsAString& font)
+void
+nsCanvasRenderingContext2DAzure::SetFont(const nsAString& font,
+                                         ErrorResult& error)
 {
-  nsresult rv;
-
   /*
     * If font is defined with relative units (e.g. ems) and the parent
     * style context changes in between calls, setting the font to the
     * same value as previous could result in a different computed value,
     * so we cannot have the optimization where we check if the new font
     * string is equal to the old one.
     */
 
   if (!mCanvasElement && !mDocShell) {
-      NS_WARNING("Canvas element must be non-null or a docshell must be provided");
-      return NS_ERROR_FAILURE;
+    NS_WARNING("Canvas element must be non-null or a docshell must be provided");
+    error.Throw(NS_ERROR_FAILURE);
+    return;
   }
 
   nsIPresShell* presShell = GetPresShell();
   if (!presShell) {
-    return NS_ERROR_FAILURE;
+    error.Throw(NS_ERROR_FAILURE);
+    return;
   }
   nsIDocument* document = presShell->GetDocument();
 
   nsCOMArray<nsIStyleRule> rules;
 
   nsRefPtr<css::StyleRule> rule;
-  rv = CreateFontStyleRule(font, document, getter_AddRefs(rule));
-
-  if (NS_FAILED(rv)) {
-    return rv;
+  error = CreateFontStyleRule(font, document, getter_AddRefs(rule));
+
+  if (error.Failed()) {
+    return;
   }
 
   css::Declaration *declaration = rule->GetDeclaration();
   // The easiest way to see whether we got a syntax error or whether
   // we got 'inherit' or 'initial' is to look at font-size-adjust,
   // which the shorthand resets to either 'none' or
   // '-moz-system-font'.
   // We know the declaration is not !important, so we can use
   // GetNormalBlock().
   const nsCSSValue *fsaVal =
     declaration->GetNormalBlock()->ValueFor(eCSSProperty_font_size_adjust);
   if (!fsaVal || (fsaVal->GetUnit() != eCSSUnit_None &&
                   fsaVal->GetUnit() != eCSSUnit_System_Font)) {
       // We got an all-property value or a syntax error.  The spec says
       // this value must be ignored.
-    return NS_OK;
+    return;
   }
 
   rules.AppendObject(rule);
 
   nsStyleSet* styleSet = presShell->StyleSet();
 
   // have to get a parent style context for inherit-like relative
   // values (2em, bolder, etc.)
@@ -2817,37 +2681,39 @@ nsCanvasRenderingContext2DAzure::SetFont
       // inherit from the canvas element
       parentContext = nsComputedDOMStyle::GetStyleContextForElement(
               mCanvasElement,
               nsnull,
               presShell);
   } else {
     // otherwise inherit from default (10px sans-serif)
     nsRefPtr<css::StyleRule> parentRule;
-    rv = CreateFontStyleRule(NS_LITERAL_STRING("10px sans-serif"),
-                              document,
-                              getter_AddRefs(parentRule));
-
-    if (NS_FAILED(rv)) {
-      return rv;
+    error = CreateFontStyleRule(NS_LITERAL_STRING("10px sans-serif"),
+                                document,
+                                getter_AddRefs(parentRule));
+
+    if (error.Failed()) {
+      return;
     }
 
     nsCOMArray<nsIStyleRule> parentRules;
     parentRules.AppendObject(parentRule);
     parentContext = styleSet->ResolveStyleForRules(nsnull, parentRules);
   }
 
   if (!parentContext) {
-      return NS_ERROR_FAILURE;
+    error.Throw(NS_ERROR_FAILURE);
+    return;
   }
 
   nsRefPtr<nsStyleContext> sc =
       styleSet->ResolveStyleForRules(parentContext, rules);
   if (!sc) {
-    return NS_ERROR_FAILURE;
+    error.Throw(NS_ERROR_FAILURE);
+    return;
   }
 
   const nsStyleFont* fontStyle = sc->GetStyleFont();
 
   NS_ASSERTION(fontStyle, "Could not obtain font style");
 
   nsIAtom* language = sc->GetStyleFont()->mLanguage;
   if (!language) {
@@ -2885,48 +2751,56 @@ nsCanvasRenderingContext2DAzure::SetFont
                                                   presShell->GetPresContext()->GetUserFontSet());
   NS_ASSERTION(CurrentState().fontGroup, "Could not get font group");
 
   // The font getter is required to be reserialized based on what we
   // parsed (including having line-height removed).  (Older drafts of
   // the spec required font sizes be converted to pixels, but that no
   // longer seems to be required.)
   declaration->GetValue(eCSSProperty_font, CurrentState().font);
-
-  return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::GetFont(nsAString& font)
+nsCanvasRenderingContext2DAzure::SetMozFont(const nsAString& font)
 {
-  /* will initilize the value if not set, else does nothing */
-  GetCurrentFontStyle();
-
-  font = CurrentState().font;
-  return NS_OK;
+  ErrorResult rv;
+  SetFont(font, rv);
+  return rv.ErrorCode();
 }
 
 NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::GetMozFont(nsAString& font)
+{
+  font = GetFont();
+  return NS_OK;
+}
+
+void
 nsCanvasRenderingContext2DAzure::SetTextAlign(const nsAString& ta)
 {
   if (ta.EqualsLiteral("start"))
     CurrentState().textAlign = TEXT_ALIGN_START;
   else if (ta.EqualsLiteral("end"))
     CurrentState().textAlign = TEXT_ALIGN_END;
   else if (ta.EqualsLiteral("left"))
     CurrentState().textAlign = TEXT_ALIGN_LEFT;
   else if (ta.EqualsLiteral("right"))
     CurrentState().textAlign = TEXT_ALIGN_RIGHT;
   else if (ta.EqualsLiteral("center"))
     CurrentState().textAlign = TEXT_ALIGN_CENTER;
-
-  return NS_OK;
 }
 
 NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::SetMozTextAlign(const nsAString& ta)
+{
+  SetTextAlign(ta);
+  return NS_OK;
+}
+
+void
 nsCanvasRenderingContext2DAzure::GetTextAlign(nsAString& ta)
 {
   switch (CurrentState().textAlign)
   {
   case TEXT_ALIGN_START:
     ta.AssignLiteral("start");
     break;
   case TEXT_ALIGN_END:
@@ -2937,40 +2811,50 @@ nsCanvasRenderingContext2DAzure::GetText
     break;
   case TEXT_ALIGN_RIGHT:
     ta.AssignLiteral("right");
     break;
   case TEXT_ALIGN_CENTER:
     ta.AssignLiteral("center");
     break;
   }
-
-  return NS_OK;
 }
 
 NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::GetMozTextAlign(nsAString& ta)
+{
+  GetTextAlign(ta);
+  return NS_OK;
+}
+
+void
 nsCanvasRenderingContext2DAzure::SetTextBaseline(const nsAString& tb)
 {
   if (tb.EqualsLiteral("top"))
     CurrentState().textBaseline = TEXT_BASELINE_TOP;
   else if (tb.EqualsLiteral("hanging"))
     CurrentState().textBaseline = TEXT_BASELINE_HANGING;
   else if (tb.EqualsLiteral("middle"))
     CurrentState().textBaseline = TEXT_BASELINE_MIDDLE;
   else if (tb.EqualsLiteral("alphabetic"))
     CurrentState().textBaseline = TEXT_BASELINE_ALPHABETIC;
   else if (tb.EqualsLiteral("ideographic"))
     CurrentState().textBaseline = TEXT_BASELINE_IDEOGRAPHIC;
   else if (tb.EqualsLiteral("bottom"))
     CurrentState().textBaseline = TEXT_BASELINE_BOTTOM;
-
-  return NS_OK;
 }
 
 NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::SetMozTextBaseline(const nsAString& tb)
+{
+  SetTextBaseline(tb);
+  return NS_OK;
+}
+
+void
 nsCanvasRenderingContext2DAzure::GetTextBaseline(nsAString& tb)
 {
   switch (CurrentState().textBaseline)
   {
   case TEXT_BASELINE_TOP:
     tb.AssignLiteral("top");
     break;
   case TEXT_BASELINE_HANGING:
@@ -2984,65 +2868,101 @@ nsCanvasRenderingContext2DAzure::GetText
     break;
   case TEXT_BASELINE_IDEOGRAPHIC:
     tb.AssignLiteral("ideographic");
     break;
   case TEXT_BASELINE_BOTTOM:
     tb.AssignLiteral("bottom");
     break;
   }
-
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::GetMozTextBaseline(nsAString& tb)
+{
+  GetTextBaseline(tb);
   return NS_OK;
 }
 
 /*
  * Helper function that replaces the whitespace characters in a string
  * with U+0020 SPACE. The whitespace characters are defined as U+0020 SPACE,
  * U+0009 CHARACTER TABULATION (tab), U+000A LINE FEED (LF), U+000B LINE
  * TABULATION, U+000C FORM FEED (FF), and U+000D CARRIAGE RETURN (CR).
  * @param str The string whose whitespace characters to replace.
  */
 static inline void
 TextReplaceWhitespaceCharacters(nsAutoString& str)
 {
   str.ReplaceChar("\x09\x0A\x0B\x0C\x0D", PRUnichar(' '));
 }
 
+void
+nsCanvasRenderingContext2DAzure::FillText(const nsAString& text, double x,
+                                          double y,
+                                          const Optional<double>& maxWidth,
+                                          ErrorResult& error)
+{
+  error = DrawOrMeasureText(text, x, y, maxWidth, TEXT_DRAW_OPERATION_FILL, nsnull);
+}
+
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::FillText(const nsAString& text, float x, float y, float maxWidth)
 {
-  return DrawOrMeasureText(text, x, y, maxWidth, TEXT_DRAW_OPERATION_FILL, nsnull);
+  ErrorResult rv;
+  Optional<double> optionalMaxWidth;
+  optionalMaxWidth.Construct();
+  optionalMaxWidth.Value() = maxWidth;
+  FillText(text, x, y, optionalMaxWidth, rv);
+  return rv.ErrorCode();
+}
+
+void
+nsCanvasRenderingContext2DAzure::StrokeText(const nsAString& text, double x,
+                                            double y,
+                                            const Optional<double>& maxWidth,
+                                            ErrorResult& error)
+{
+  error = DrawOrMeasureText(text, x, y, maxWidth, TEXT_DRAW_OPERATION_STROKE, nsnull);
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::StrokeText(const nsAString& text, float x, float y, float maxWidth)
 {
-  return DrawOrMeasureText(text, x, y, maxWidth, TEXT_DRAW_OPERATION_STROKE, nsnull);
+  ErrorResult rv;
+  Optional<double> optionalMaxWidth;
+  optionalMaxWidth.Construct();
+  optionalMaxWidth.Value() = maxWidth;
+  StrokeText(text, x, y, optionalMaxWidth, rv);
+  return rv.ErrorCode();
+}
+
+already_AddRefed<nsIDOMTextMetrics>
+nsCanvasRenderingContext2DAzure::MeasureText(const nsAString& rawText,
+                                             ErrorResult& error)
+{
+  float width;
+  Optional<double> maxWidth;
+  error = DrawOrMeasureText(rawText, 0, 0, maxWidth, TEXT_DRAW_OPERATION_MEASURE, &width);
+  if (error.Failed()) {
+    return NULL;
+  }
+
+  nsRefPtr<nsIDOMTextMetrics> textMetrics = new nsTextMetricsAzure(width);
+
+  return textMetrics.forget();
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::MeasureText(const nsAString& rawText,
-                                      nsIDOMTextMetrics** _retval)
+                                             nsIDOMTextMetrics** _retval)
 {
-  float width;
-
-  nsresult rv = DrawOrMeasureText(rawText, 0, 0, 0, TEXT_DRAW_OPERATION_MEASURE, &width);
-
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  nsRefPtr<nsIDOMTextMetrics> textMetrics = new nsTextMetricsAzure(width);
-  if (!textMetrics.get()) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-
-  *_retval = textMetrics.forget().get();
-
-  return NS_OK;
+  ErrorResult rv;
+  *_retval = MeasureText(rawText, rv).get();
+  return rv.ErrorCode();
 }
 
 /**
  * Used for nsBidiPresUtils::ProcessText
  */
 struct NS_STACK_CLASS nsCanvasBidiProcessorAzure : public nsBidiPresUtils::BidiProcessor
 {
   typedef nsCanvasRenderingContext2DAzure::ContextState ContextState;
@@ -3177,27 +3097,27 @@ struct NS_STACK_CLASS nsCanvasBidiProces
         // This may happen for glyph runs for a 0 size font.
         continue;
       }
 
       buffer.mGlyphs = &glyphBuf.front();
       buffer.mNumGlyphs = glyphBuf.size();
 
       if (mOp == nsCanvasRenderingContext2DAzure::TEXT_DRAW_OPERATION_FILL) {
-        nsCanvasRenderingContext2DAzure::AdjustedTarget(mCtx)->
+        AdjustedTarget(mCtx)->
           FillGlyphs(scaledFont, buffer,
-                      nsCanvasRenderingContext2DAzure::GeneralPattern().
+                     CanvasGeneralPattern().
                         ForStyle(mCtx, nsCanvasRenderingContext2DAzure::STYLE_FILL, mCtx->mTarget),
                       DrawOptions(mState->globalAlpha, mCtx->UsedOperation()));
       } else if (mOp == nsCanvasRenderingContext2DAzure::TEXT_DRAW_OPERATION_STROKE) {
         RefPtr<Path> path = scaledFont->GetPathForGlyphs(buffer, mCtx->mTarget);
 
         const ContextState& state = *mState;
-        nsCanvasRenderingContext2DAzure::AdjustedTarget(mCtx)->
-          Stroke(path, nsCanvasRenderingContext2DAzure::GeneralPattern().
+        AdjustedTarget(mCtx)->
+          Stroke(path, CanvasGeneralPattern().
                     ForStyle(mCtx, nsCanvasRenderingContext2DAzure::STYLE_STROKE, mCtx->mTarget),
                   StrokeOptions(state.lineWidth, state.lineJoin,
                                 state.lineCap, state.miterLimit,
                                 state.dash.Length(),
                                 state.dash.Elements(),
                                 state.dashOffset),
                   DrawOptions(state.globalAlpha, mCtx->UsedOperation()));
 
@@ -3235,30 +3155,31 @@ struct NS_STACK_CLASS nsCanvasBidiProces
   // true iff the bounding box should be measured
   bool mDoMeasureBoundingBox;
 };
 
 nsresult
 nsCanvasRenderingContext2DAzure::DrawOrMeasureText(const nsAString& aRawText,
                                                    float aX,
                                                    float aY,
-                                                   float aMaxWidth,
+                                                   const Optional<double>& aMaxWidth,
                                                    TextDrawOperation aOp,
                                                    float* aWidth)
 {
   nsresult rv;
 
-  if (!FloatValidate(aX, aY, aMaxWidth))
+  if (!FloatValidate(aX, aY) ||
+      (aMaxWidth.WasPassed() && !FloatValidate(aMaxWidth.Value())))
       return NS_ERROR_DOM_SYNTAX_ERR;
 
   // spec isn't clear on what should happen if aMaxWidth <= 0, so
   // treat it as an invalid argument
   // technically, 0 should be an invalid value as well, but 0 is the default
   // arg, and there is no way to tell if the default was used
-  if (aMaxWidth < 0)
+  if (aMaxWidth.WasPassed() && aMaxWidth.Value() < 0)
     return NS_ERROR_INVALID_ARG;
 
   if (!mCanvasElement && !mDocShell) {
     NS_WARNING("Canvas element must be non-null or a docshell must be provided");
     return NS_ERROR_FAILURE;
   }
 
   nsCOMPtr<nsIPresShell> presShell = GetPresShell();
@@ -3366,49 +3287,51 @@ nsCanvasRenderingContext2DAzure::DrawOrM
 
   switch (state.textBaseline)
   {
   case TEXT_BASELINE_HANGING:
       // fall through; best we can do with the information available
   case TEXT_BASELINE_TOP:
     anchorY = fontMetrics.emAscent;
     break;
-    break;
   case TEXT_BASELINE_MIDDLE:
     anchorY = (fontMetrics.emAscent - fontMetrics.emDescent) * .5f;
     break;
   case TEXT_BASELINE_IDEOGRAPHIC:
     // fall through; best we can do with the information available
   case TEXT_BASELINE_ALPHABETIC:
     anchorY = 0;
     break;
   case TEXT_BASELINE_BOTTOM:
     anchorY = -fontMetrics.emDescent;
     break;
+  default:
+      MOZ_NOT_REACHED("unexpected TextBaseline");
   }
 
   processor.mPt.y += anchorY;
 
   // correct bounding box to get it to be the correct size/position
   processor.mBoundingBox.width = totalWidth;
   processor.mBoundingBox.MoveBy(processor.mPt);
 
   processor.mPt.x *= processor.mAppUnitsPerDevPixel;
   processor.mPt.y *= processor.mAppUnitsPerDevPixel;
 
   Matrix oldTransform = mTarget->GetTransform();
   // if text is over aMaxWidth, then scale the text horizontally such that its
   // width is precisely aMaxWidth
-  if (aMaxWidth > 0 && totalWidth > aMaxWidth) {
+  if (aMaxWidth.WasPassed() && aMaxWidth.Value() > 0 &&
+      totalWidth > aMaxWidth.Value()) {
     Matrix newTransform = oldTransform;
 
     // Translate so that the anchor point is at 0,0, then scale and then
     // translate back.
     newTransform.Translate(aX, 0);
-    newTransform.Scale(aMaxWidth / totalWidth, 1);
+    newTransform.Scale(aMaxWidth.Value() / totalWidth, 1);
     newTransform.Translate(-aX, 0);
     /* we do this to avoid an ICE in the android compiler */
     Matrix androidCompilerBug = newTransform;
     mTarget->SetTransform(androidCompilerBug);
   }
 
   // save the previous bounding box
   gfxRect boundingBox = processor.mBoundingBox;
@@ -3425,41 +3348,46 @@ nsCanvasRenderingContext2DAzure::DrawOrM
                                     nsnull,
                                     0,
                                     nsnull,
                                     &bidiEngine);
 
 
   mTarget->SetTransform(oldTransform);
 
-  if (aOp == nsCanvasRenderingContext2DAzure::TEXT_DRAW_OPERATION_FILL && !doDrawShadow)
-    return RedrawUser(boundingBox);
-
-  return Redraw();
+  if (aOp == nsCanvasRenderingContext2DAzure::TEXT_DRAW_OPERATION_FILL &&
+      !doDrawShadow) {
+    RedrawUser(boundingBox);
+    return NS_OK;
+  }
+
+  Redraw();
+  return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::SetMozTextStyle(const nsAString& textStyle)
+nsCanvasRenderingContext2DAzure::SetTextStyle(const nsAString& textStyle)
 {
-    // font and mozTextStyle are the same value
-    return SetFont(textStyle);
+  ErrorResult rv;
+  SetMozTextStyle(textStyle, rv);
+  return rv.ErrorCode();
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::GetMozTextStyle(nsAString& textStyle)
+nsCanvasRenderingContext2DAzure::GetTextStyle(nsAString& textStyle)
 {
-    // font and mozTextStyle are the same value
-    return GetFont(textStyle);
+  GetMozTextStyle(textStyle);
+  return NS_OK;
 }
 
 gfxFontGroup *nsCanvasRenderingContext2DAzure::GetCurrentFontStyle()
 {
   // use lazy initilization for the font group since it's rather expensive
   if (!CurrentState().fontGroup) {
-    nsresult rv = SetFont(kDefaultFontStyle);
+    nsresult rv = SetMozFont(kDefaultFontStyle);
     if (NS_FAILED(rv)) {
       gfxFontStyle style;
       style.size = kDefaultFontSize;
       CurrentState().fontGroup =
         gfxPlatform::GetPlatform()->CreateFontGroup(kDefaultFontName,
                                                     &style,
                                                     nsnull);
       if (CurrentState().fontGroup) {
@@ -3474,151 +3402,188 @@ gfxFontGroup *nsCanvasRenderingContext2D
   }
 
   return CurrentState().fontGroup;
 }
 
 //
 // line caps/joins
 //
+
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::SetLineWidth(float width)
 {
-  if (!FloatValidate(width) || width <= 0.0) {
-    return NS_OK;
-  }
-
-  CurrentState().lineWidth = width;
+  SetLineWidth((double)width);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetLineWidth(float *width)
 {
-  *width = CurrentState().lineWidth;
+  *width = GetLineWidth();
   return NS_OK;
 }
 
-NS_IMETHODIMP
+void
 nsCanvasRenderingContext2DAzure::SetLineCap(const nsAString& capstyle)
 {
   CapStyle cap;
 
   if (capstyle.EqualsLiteral("butt")) {
     cap = CAP_BUTT;
   } else if (capstyle.EqualsLiteral("round")) {
     cap = CAP_ROUND;
   } else if (capstyle.EqualsLiteral("square")) {
     cap = CAP_SQUARE;
   } else {
     // XXX ERRMSG we need to report an error to developers here! (bug 329026)
-    return NS_OK;
+    return;
   }
 
   CurrentState().lineCap = cap;
-
-  return NS_OK;
 }
 
 NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::SetMozLineCap(const nsAString& capstyle)
+{
+  SetLineCap(capstyle);
+  return NS_OK;
+}
+
+void
 nsCanvasRenderingContext2DAzure::GetLineCap(nsAString& capstyle)
 {
   switch (CurrentState().lineCap) {
   case CAP_BUTT:
     capstyle.AssignLiteral("butt");
     break;
   case CAP_ROUND:
     capstyle.AssignLiteral("round");
     break;
   case CAP_SQUARE:
     capstyle.AssignLiteral("square");
     break;
   }
-
-  return NS_OK;
 }
 
 NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::GetMozLineCap(nsAString& capstyle)
+{
+  GetLineCap(capstyle);
+  return NS_OK;
+}
+
+void
 nsCanvasRenderingContext2DAzure::SetLineJoin(const nsAString& joinstyle)
 {
   JoinStyle j;
 
   if (joinstyle.EqualsLiteral("round")) {
     j = JOIN_ROUND;
   } else if (joinstyle.EqualsLiteral("bevel")) {
     j = JOIN_BEVEL;
   } else if (joinstyle.EqualsLiteral("miter")) {
     j = JOIN_MITER_OR_BEVEL;
   } else {
     // XXX ERRMSG we need to report an error to developers here! (bug 329026)
-    return NS_OK;
+    return;
   }
 
   CurrentState().lineJoin = j;
-   
-  return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::GetLineJoin(nsAString& joinstyle)
+nsCanvasRenderingContext2DAzure::SetMozLineJoin(const nsAString& joinstyle)
+{
+  SetLineJoin(joinstyle);
+  return NS_OK;
+}
+
+void
+nsCanvasRenderingContext2DAzure::GetLineJoin(nsAString& joinstyle, ErrorResult& error)
 {
   switch (CurrentState().lineJoin) {
   case JOIN_ROUND:
     joinstyle.AssignLiteral("round");
     break;
   case JOIN_BEVEL:
     joinstyle.AssignLiteral("bevel");
     break;
   case JOIN_MITER_OR_BEVEL:
     joinstyle.AssignLiteral("miter");
     break;
   default:
-    return NS_ERROR_FAILURE;
-  }
-
-  return NS_OK;
+    error.Throw(NS_ERROR_FAILURE);
+  }
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::GetMozLineJoin(nsAString& joinstyle)
+{
+  ErrorResult rv;
+  nsString linejoin;
+  GetLineJoin(linejoin, rv);
+  if (!rv.Failed()) {
+    joinstyle = linejoin;
+  }
+  return rv.ErrorCode();
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::SetMiterLimit(float miter)
 {
-  if (!FloatValidate(miter) || miter <= 0.0)
-    return NS_OK;
-
-  CurrentState().miterLimit = miter;
-
+  SetMiterLimit((double)miter);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetMiterLimit(float *miter)
 {
-  *miter = CurrentState().miterLimit;
+  *miter = GetMiterLimit();
   return NS_OK;
 }
 
+void
+nsCanvasRenderingContext2DAzure::SetMozDash(JSContext* cx,
+                                            const JS::Value& mozDash,
+                                            ErrorResult& error)
+{
+  FallibleTArray<Float> dash;
+  error = JSValToDashArray(cx, mozDash, dash);
+  if (!error.Failed()) {
+    ContextState& state = CurrentState();
+    state.dash = dash;
+    if (state.dash.IsEmpty()) {
+      state.dashOffset = 0;
+    }
+  }
+}
+
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::SetMozDash(JSContext *cx, const jsval& patternArray)
 {
-  FallibleTArray<Float> dash;
-  nsresult rv = JSValToDashArray(cx, patternArray, dash);
-  if (NS_SUCCEEDED(rv)) {
-    ContextState& state = CurrentState();
-    state.dash = dash;
-    if (state.dash.IsEmpty()) {
-      state.dashOffset = 0;
-    }
-  }
-  return rv;
+  ErrorResult rv;
+  SetMozDash(cx, patternArray, rv);
+  return rv.ErrorCode();
+}
+
+JS::Value
+nsCanvasRenderingContext2DAzure::GetMozDash(JSContext* cx, ErrorResult& error)
+{
+  JS::Value mozDash;
+  DashArrayToJSVal(CurrentState().dash, cx, &mozDash);
+  return mozDash;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetMozDash(JSContext* cx, jsval* dashArray)
 {
-  return DashArrayToJSVal(CurrentState().dash, cx, dashArray);
+  ErrorResult rv;
+  *dashArray = GetMozDash(cx, rv);
+  return rv.ErrorCode();
 }
  
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::SetMozDashOffset(float offset)
 {
   if (!FloatValidate(offset)) {
     return NS_ERROR_ILLEGAL_VALUE;
   }
@@ -3627,187 +3592,172 @@ nsCanvasRenderingContext2DAzure::SetMozD
     state.dashOffset = offset;
   }
   return NS_OK;
 }
  
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetMozDashOffset(float* offset)
 {
-  *offset = CurrentState().dashOffset;
+  *offset = GetMozDashOffset();
   return NS_OK;
 }
 
+bool
+nsCanvasRenderingContext2DAzure::IsPointInPath(double x, double y)
+{
+  if (!FloatValidate(x,y)) {
+    return false;
+  }
+
+  EnsureUserSpacePath();
+
+  return mPath && mPath->ContainsPoint(Point(x, y), mTarget->GetTransform());
+}
+
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::IsPointInPath(float x, float y, bool *retVal)
 {
-  if (!FloatValidate(x,y)) {
-    *retVal = false;
-    return NS_OK;
-  }
-
-  EnsureUserSpacePath();
-
-  *retVal = false;
-
-  if (mPath) {
-    *retVal = mPath->ContainsPoint(Point(x, y), mTarget->GetTransform());
-  }
-
+  *retVal = IsPointInPath(x, y);
   return NS_OK;
 }
 
 //
 // image
 //
 
 // drawImage(in HTMLImageElement image, in float dx, in float dy);
 //   -- render image from 0,0 at dx,dy top-left coords
 // drawImage(in HTMLImageElement image, in float dx, in float dy, in float sw, in float sh);
 //   -- render image from 0,0 at dx,dy top-left coords clipping it to sw,sh
 // drawImage(in HTMLImageElement image, in float sx, in float sy, in float sw, in float sh, in float dx, in float dy, in float dw, in float dh);
 //   -- render the region defined by (sx,sy,sw,wh) in image-local space into the region (dx,dy,dw,dh) on the canvas
 
-NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::DrawImage(nsIDOMElement *imgElt, float a1,
-                                           float a2, float a3, float a4, float a5,
-                                           float a6, float a7, float a8,
-                                           PRUint8 optional_argc)
+// If only dx and dy are passed in then optional_argc should be 0. If only
+// dx, dy, dw and dh are passed in then optional_argc should be 2. The only
+// other valid value for optional_argc is 6 if sx, sy, sw, sh, dx, dy, dw and dh
+// are all passed in.
+
+void
+nsCanvasRenderingContext2DAzure::DrawImage(const HTMLImageOrCanvasOrVideoElement& image,
+                                           double sx, double sy, double sw,
+                                           double sh, double dx, double dy,
+                                           double dw, double dh, 
+                                           PRUint8 optional_argc,
+                                           ErrorResult& error)
 {
-  nsCOMPtr<nsIContent> content = do_QueryInterface(imgElt);
-  if (!content) {
-    return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
-  }
-
-  if (optional_argc == 0) {
-    if (!FloatValidate(a1, a2)) {
-      return NS_OK;
-    }
-  } else if (optional_argc == 2) {
-    if (!FloatValidate(a1, a2, a3, a4)) {
-      return NS_OK;
-    }
-  } else if (optional_argc == 6) {
-    if (!FloatValidate(a1, a2, a3, a4, a5, a6) || !FloatValidate(a7, a8)) {
-      return NS_OK;
-    }
-  }
-
-  double sx,sy,sw,sh;
-  double dx,dy,dw,dh;
+  MOZ_ASSERT(optional_argc == 0 || optional_argc == 2 || optional_argc == 6);
 
   RefPtr<SourceSurface> srcSurf;
   gfxIntSize imgSize;
 
-  nsHTMLCanvasElement* canvas = nsHTMLCanvasElement::FromContent(content);
-  if (canvas) {
+  Element* element;
+  if (image.IsHTMLCanvasElement()) {
+    nsHTMLCanvasElement* canvas = image.GetAsHTMLCanvasElement();
+    element = canvas;
     nsIntSize size = canvas->GetSize();
     if (size.width == 0 || size.height == 0) {
-      return NS_ERROR_DOM_INVALID_STATE_ERR;
+      error.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+      return;
     }
 
     // Special case for Canvas, which could be an Azure canvas!
     nsICanvasRenderingContextInternal *srcCanvas = canvas->GetContextAtIndex(0);
     if (srcCanvas == this) {
       // Self-copy.
       srcSurf = mTarget->Snapshot();
       imgSize = gfxIntSize(mWidth, mHeight);
     } else if (srcCanvas) {
       // This might not be an Azure canvas!
       srcSurf = srcCanvas->GetSurfaceSnapshot();
 
       if (srcSurf && mCanvasElement) {
         // Do security check here.
         CanvasUtils::DoDrawImageSecurityCheck(mCanvasElement,
-                                              content->NodePrincipal(), canvas->IsWriteOnly(),
+                                              element->NodePrincipal(),
+                                              canvas->IsWriteOnly(),
                                               false);
         imgSize = gfxIntSize(srcSurf->GetSize().width, srcSurf->GetSize().height);
       }
     }
   } else {
+    if (image.IsHTMLImageElement()) {
+      nsHTMLImageElement* img = image.GetAsHTMLImageElement();
+      element = img;
+    } else {
+      nsHTMLVideoElement* video = image.GetAsHTMLVideoElement();
+      element = video;
+    }
+
     gfxASurface* imgsurf =
-      CanvasImageCache::Lookup(imgElt, mCanvasElement, &imgSize);
+      CanvasImageCache::Lookup(element, mCanvasElement, &imgSize);
     if (imgsurf) {
       srcSurf = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(mTarget, imgsurf);
     }
   }
 
   if (!srcSurf) {
     // The canvas spec says that drawImage should draw the first frame
     // of animated images
     PRUint32 sfeFlags = nsLayoutUtils::SFE_WANT_FIRST_FRAME;
     nsLayoutUtils::SurfaceFromElementResult res =
-      nsLayoutUtils::SurfaceFromElement(content->AsElement(), sfeFlags);
+      nsLayoutUtils::SurfaceFromElement(element, sfeFlags);
 
     if (!res.mSurface) {
       // Spec says to silently do nothing if the element is still loading.
-      return res.mIsStillLoading ? NS_OK : NS_ERROR_NOT_AVAILABLE;
+      if (!res.mIsStillLoading) {
+        error.Throw(NS_ERROR_NOT_AVAILABLE);
+      }
+      return;
     }
 
     // Ignore cairo surfaces that are bad! See bug 666312.
     if (res.mSurface->CairoStatus()) {
-      return NS_OK;
+      return;
     }
 
     imgSize = res.mSize;
 
     if (mCanvasElement) {
       CanvasUtils::DoDrawImageSecurityCheck(mCanvasElement,
                                             res.mPrincipal, res.mIsWriteOnly,
                                             res.mCORSUsed);
     }
 
     if (res.mImageRequest) {
-      CanvasImageCache::NotifyDrawImage(imgElt, mCanvasElement,
+      CanvasImageCache::NotifyDrawImage(element, mCanvasElement,
                                         res.mImageRequest, res.mSurface, imgSize);
     }
 
     srcSurf = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(mTarget, res.mSurface);
   }
 
   if (optional_argc == 0) {
-    dx = a1;
-    dy = a2;
     sx = sy = 0.0;
     dw = sw = (double) imgSize.width;
     dh = sh = (double) imgSize.height;
   } else if (optional_argc == 2) {
-    dx = a1;
-    dy = a2;
-    dw = a3;
-    dh = a4;
     sx = sy = 0.0;
     sw = (double) imgSize.width;
     sh = (double) imgSize.height;
-  } else if (optional_argc == 6) {
-    sx = a1;
-    sy = a2;
-    sw = a3;
-    sh = a4;
-    dx = a5;
-    dy = a6;
-    dw = a7;
-    dh = a8;
-  } else {
-    // XXX ERRMSG we need to report an error to developers here! (bug 329026)
-    return NS_ERROR_INVALID_ARG;
   }
 
   if (dw == 0.0 || dh == 0.0) {
     // not really failure, but nothing to do --
     // and noone likes a divide-by-zero
-    return NS_OK;
+    return;
   }
 
   if (sx < 0.0 || sy < 0.0 ||
       sw < 0.0 || sw > (double) imgSize.width ||
       sh < 0.0 || sh > (double) imgSize.height ||
       dw < 0.0 || dh < 0.0) {
     // XXX - Unresolved spec issues here, for now return error.
-    return NS_ERROR_DOM_INDEX_SIZE_ERR;
+    error.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+    return;
   }
 
   Filter filter;
 
   if (CurrentState().imageSmoothingEnabled)
     filter = mgfx::FILTER_LINEAR;
   else
     filter = mgfx::FILTER_POINT;
@@ -3821,21 +3771,57 @@ nsCanvasRenderingContext2DAzure::DrawIma
 
   AdjustedTarget(this, bounds.IsEmpty() ? nsnull : &bounds)->
     DrawSurface(srcSurf,
                 mgfx::Rect(dx, dy, dw, dh),
                 mgfx::Rect(sx, sy, sw, sh),
                 DrawSurfaceOptions(filter),
                 DrawOptions(CurrentState().globalAlpha, UsedOperation()));
 
-  return RedrawUser(gfxRect(dx, dy, dw, dh));
+  RedrawUser(gfxRect(dx, dy, dw, dh));
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::SetGlobalCompositeOperation(const nsAString& op)
+nsCanvasRenderingContext2DAzure::DrawImage(nsIDOMElement *imgElt, float a1,
+                                           float a2, float a3, float a4, float a5,
+                                           float a6, float a7, float a8,
+                                           PRUint8 optional_argc)
+{
+  if (!(optional_argc == 0 || optional_argc == 2 || optional_argc == 6)) {
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  HTMLImageOrCanvasOrVideoElement element;
+  if (!ToHTMLImageOrCanvasOrVideoElement(imgElt, element)) {
+    return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
+  }
+
+  ErrorResult rv;
+  if (optional_argc == 0) {
+    if (!FloatValidate(a1, a2)) {
+      return NS_OK;
+    }
+    DrawImage(element, 0, 0, 0, 0, a1, a2, 0, 0, 0, rv);
+  } else if (optional_argc == 2) {
+    if (!FloatValidate(a1, a2, a3, a4)) {
+      return NS_OK;
+    }
+    DrawImage(element, 0, 0, 0, 0, a1, a2, a3, a4, 2, rv);
+  } else if (optional_argc == 6) {
+    if (!FloatValidate(a1, a2, a3, a4) || !FloatValidate(a5, a6, a7, a8)) {
+      return NS_OK;
+    }
+    DrawImage(element, a1, a2, a3, a4, a5, a6, a7, a8, 6, rv);
+  }
+  return rv.ErrorCode();
+}
+
+void
+nsCanvasRenderingContext2DAzure::SetGlobalCompositeOperation(const nsAString& op,
+                                                             ErrorResult& error)
 {
   CompositionOp comp_op;
 
 #define CANVAS_OP_TO_GFX_OP(cvsop, op2d) \
   if (op.EqualsLiteral(cvsop))   \
     comp_op = OP_##op2d;
 
   CANVAS_OP_TO_GFX_OP("copy", SOURCE)
@@ -3845,25 +3831,33 @@ nsCanvasRenderingContext2DAzure::SetGlob
   else CANVAS_OP_TO_GFX_OP("source-over", OVER)
   else CANVAS_OP_TO_GFX_OP("destination-in", DEST_IN)
   else CANVAS_OP_TO_GFX_OP("destination-out", DEST_OUT)
   else CANVAS_OP_TO_GFX_OP("destination-over", DEST_OVER)
   else CANVAS_OP_TO_GFX_OP("destination-atop", DEST_ATOP)
   else CANVAS_OP_TO_GFX_OP("lighter", ADD)
   else CANVAS_OP_TO_GFX_OP("xor", XOR)
   // XXX ERRMSG we need to report an error to developers here! (bug 329026)
-  else return NS_OK;
+  else return;
 
 #undef CANVAS_OP_TO_GFX_OP
   CurrentState().op = comp_op;
-  return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::GetGlobalCompositeOperation(nsAString& op)
+nsCanvasRenderingContext2DAzure::SetGlobalCompositeOperation(const nsAString& op)
+{
+  ErrorResult rv;
+  SetGlobalCompositeOperation(op, rv);
+  return rv.ErrorCode();
+}
+
+void
+nsCanvasRenderingContext2DAzure::GetGlobalCompositeOperation(nsAString& op,
+                                                             ErrorResult& error)
 {
   CompositionOp comp_op = CurrentState().op;
 
 #define CANVAS_OP_TO_GFX_OP(cvsop, op2d) \
   if (comp_op == OP_##op2d) \
     op.AssignLiteral(cvsop);
 
   CANVAS_OP_TO_GFX_OP("copy", SOURCE)
@@ -3872,36 +3866,48 @@ nsCanvasRenderingContext2DAzure::GetGlob
   else CANVAS_OP_TO_GFX_OP("destination-out", DEST_OUT)
   else CANVAS_OP_TO_GFX_OP("destination-over", DEST_OVER)
   else CANVAS_OP_TO_GFX_OP("lighter", ADD)
   else CANVAS_OP_TO_GFX_OP("source-atop", ATOP)
   else CANVAS_OP_TO_GFX_OP("source-in", IN)
   else CANVAS_OP_TO_GFX_OP("source-out", OUT)
   else CANVAS_OP_TO_GFX_OP("source-over", OVER)
   else CANVAS_OP_TO_GFX_OP("xor", XOR)
-  else return NS_ERROR_FAILURE;
+  else {
+    error.Throw(NS_ERROR_FAILURE);
+  }
 
 #undef CANVAS_OP_TO_GFX_OP
-    
-  return NS_OK;
 }
 
 NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::DrawWindow(nsIDOMWindow* aWindow, float aX, float aY,
-                                            float aW, float aH,
-                                            const nsAString& aBGColor,
-                                            PRUint32 flags)
+nsCanvasRenderingContext2DAzure::GetGlobalCompositeOperation(nsAString& op)
 {
-  NS_ENSURE_ARG(aWindow != nsnull);
-
+  nsString globalCompositeOperation;
+  ErrorResult rv;
+  GetGlobalCompositeOperation(globalCompositeOperation, rv);
+  if (!rv.Failed()) {
+    op = globalCompositeOperation;
+  }
+  return rv.ErrorCode();
+}
+
+void
+nsCanvasRenderingContext2DAzure::DrawWindow(nsIDOMWindow* window, double x,
+                                            double y, double w, double h,
+                                            const nsAString& bgColor,
+                                            uint32_t flags, ErrorResult& error)
+{
   // protect against too-large surfaces that will cause allocation
   // or overflow issues
-  if (!gfxASurface::CheckSurfaceSize(gfxIntSize(PRInt32(aW), PRInt32(aH)),
-                                     0xffff))
-    return NS_ERROR_FAILURE;
+  if (!gfxASurface::CheckSurfaceSize(gfxIntSize(PRInt32(w), PRInt32(h)),
+                                     0xffff)) {
+    error.Throw(NS_ERROR_FAILURE);
+    return;
+  }
 
   nsRefPtr<gfxASurface> drawSurf;
   GetThebesSurface(getter_AddRefs(drawSurf));
 
   nsRefPtr<gfxContext> thebes = new gfxContext(drawSurf);
 
   Matrix matrix = mTarget->GetTransform();
   thebes->SetMatrix(gfxMatrix(matrix._11, matrix._12, matrix._21,
@@ -3911,43 +3917,47 @@ nsCanvasRenderingContext2DAzure::DrawWin
   // following potential security issues:
   // -- rendering cross-domain IFRAMEs and then extracting the results
   // -- rendering the user's theme and then extracting the results
   // -- rendering native anonymous content (e.g., file input paths;
   // scrollbars should be allowed)
   if (!nsContentUtils::IsCallerTrustedForRead()) {
     // not permitted to use DrawWindow
     // XXX ERRMSG we need to report an error to developers here! (bug 329026)
-    return NS_ERROR_DOM_SECURITY_ERR;
+    error.Throw(NS_ERROR_DOM_SECURITY_ERR);
+    return;
   }
 
   // Flush layout updates
   if (!(flags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_DO_NOT_FLUSH))
-      nsContentUtils::FlushLayoutForTree(aWindow);
+    nsContentUtils::FlushLayoutForTree(window);
 
   nsRefPtr<nsPresContext> presContext;
-  nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(aWindow);
+  nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(window);
   if (win) {
     nsIDocShell* docshell = win->GetDocShell();
     if (docshell) {
       docshell->GetPresContext(getter_AddRefs(presContext));
     }
   }
-  if (!presContext)
-    return NS_ERROR_FAILURE;
-
-  nscolor bgColor;
-  if (!ParseColor(aBGColor, &bgColor)) {
-    return NS_ERROR_FAILURE;
-  }
-
-  nsRect r(nsPresContext::CSSPixelsToAppUnits(aX),
-           nsPresContext::CSSPixelsToAppUnits(aY),
-           nsPresContext::CSSPixelsToAppUnits(aW),
-           nsPresContext::CSSPixelsToAppUnits(aH));
+  if (!presContext) {
+    error.Throw(NS_ERROR_FAILURE);
+    return;
+  }
+
+  nscolor backgroundColor;
+  if (!ParseColor(bgColor, &backgroundColor)) {
+    error.Throw(NS_ERROR_FAILURE);
+    return;
+  }
+
+  nsRect r(nsPresContext::CSSPixelsToAppUnits((float)x),
+           nsPresContext::CSSPixelsToAppUnits((float)y),
+           nsPresContext::CSSPixelsToAppUnits((float)w),
+           nsPresContext::CSSPixelsToAppUnits((float)h));
   PRUint32 renderDocFlags = (nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING |
                              nsIPresShell::RENDER_DOCUMENT_RELATIVE);
   if (flags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_DRAW_CARET) {
     renderDocFlags |= nsIPresShell::RENDER_CARET;
   }
   if (flags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_DRAW_VIEW) {
     renderDocFlags &= ~(nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING |
                         nsIPresShell::RENDER_DOCUMENT_RELATIVE);
@@ -3955,103 +3965,135 @@ nsCanvasRenderingContext2DAzure::DrawWin
   if (flags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_USE_WIDGET_LAYERS) {
     renderDocFlags |= nsIPresShell::RENDER_USE_WIDGET_LAYERS;
   }
   if (flags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_ASYNC_DECODE_IMAGES) {
     renderDocFlags |= nsIPresShell::RENDER_ASYNC_DECODE_IMAGES;
   }
 
   unused << presContext->PresShell()->
-    RenderDocument(r, renderDocFlags, bgColor, thebes);
-
-  // note that aX and aY are coordinates in the document that
-  // we're drawing; aX and aY are drawn to 0,0 in current user
+    RenderDocument(r, renderDocFlags, backgroundColor, thebes);
+
+  // note that x and y are coordinates in the document that
+  // we're drawing; x and y are drawn to 0,0 in current user
   // space.
-  RedrawUser(gfxRect(0, 0, aW, aH));
-
-  return NS_OK;
+  RedrawUser(gfxRect(0, 0, w, h));
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::DrawWindow(nsIDOMWindow* aWindow, float aX, float aY,
+                                            float aW, float aH,
+                                            const nsAString& aBGColor,
+                                            PRUint32 flags)
+{
+  NS_ENSURE_ARG(aWindow);
+
+  ErrorResult rv;
+  DrawWindow(aWindow, aX, aY, aW, aH, aBGColor, flags, rv);
+  return rv.ErrorCode();
+}
+
+void
+nsCanvasRenderingContext2DAzure::AsyncDrawXULElement(nsIDOMXULElement* elem,
+                                                     double x, double y,
+                                                     double w, double h,
+                                                     const nsAString& bgColor,
+                                                     uint32_t flags,
+                                                     ErrorResult& error)
+{
+  // We can't allow web apps to call this until we fix at least the
+  // following potential security issues:
+  // -- rendering cross-domain IFRAMEs and then extracting the results
+  // -- rendering the user's theme and then extracting the results
+  // -- rendering native anonymous content (e.g., file input paths;
+  // scrollbars should be allowed)
+  if (!nsContentUtils::IsCallerTrustedForRead()) {
+      // not permitted to use DrawWindow
+      // XXX ERRMSG we need to report an error to developers here! (bug 329026)
+    error.Throw(NS_ERROR_DOM_SECURITY_ERR);
+    return;
+  }
+
+#if 0
+  nsCOMPtr<nsIFrameLoaderOwner> loaderOwner = do_QueryInterface(elem);
+  if (!loaderOwner) {
+    error.Throw(NS_ERROR_FAILURE);
+    return;
+  }
+
+  nsRefPtr<nsFrameLoader> frameloader = loaderOwner->GetFrameLoader();
+  if (!frameloader) {
+    error.Throw(NS_ERROR_FAILURE);
+    return;
+  }
+
+  PBrowserParent *child = frameloader->GetRemoteBrowser();
+  if (!child) {
+    nsCOMPtr<nsIDOMWindow> window =
+      do_GetInterface(frameloader->GetExistingDocShell());
+    if (!window) {
+      error.Throw(NS_ERROR_FAILURE);
+      return;
+    }
+
+    return DrawWindow(window, x, y, w, h, bgColor, flags);
+  }
+
+  // protect against too-large surfaces that will cause allocation
+  // or overflow issues
+  if (!gfxASurface::CheckSurfaceSize(gfxIntSize(w, h), 0xffff)) {
+    error.Throw(NS_ERROR_FAILURE);
+    return;
+  }
+
+  bool flush =
+    (flags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_DO_NOT_FLUSH) == 0;
+
+  PRUint32 renderDocFlags = nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING;
+  if (flags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_DRAW_CARET) {
+    renderDocFlags |= nsIPresShell::RENDER_CARET;
+  }
+  if (flags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_DRAW_VIEW) {
+    renderDocFlags &= ~nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING;
+  }
+
+  nsRect rect(nsPresContext::CSSPixelsToAppUnits(x),
+              nsPresContext::CSSPixelsToAppUnits(y),
+              nsPresContext::CSSPixelsToAppUnits(w),
+              nsPresContext::CSSPixelsToAppUnits(h));
+  if (mIPC) {
+    PDocumentRendererParent *pdocrender =
+      child->SendPDocumentRendererConstructor(rect,
+                                              mThebes->CurrentMatrix(),
+                                              nsString(aBGColor),
+                                              renderDocFlags, flush,
+                                              nsIntSize(mWidth, mHeight));
+    if (!pdocrender)
+      return NS_ERROR_FAILURE;
+
+    DocumentRendererParent *docrender =
+      static_cast<DocumentRendererParent *>(pdocrender);
+
+    docrender->SetCanvasContext(this, mThebes);
+  }
+#endif
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::AsyncDrawXULElement(nsIDOMXULElement* aElem,
                                                      float aX, float aY,
                                                      float aW, float aH,
                                                      const nsAString& aBGColor,
                                                      PRUint32 flags)
 {
-    NS_ENSURE_ARG(aElem != nsnull);
-
-    // We can't allow web apps to call this until we fix at least the
-    // following potential security issues:
-    // -- rendering cross-domain IFRAMEs and then extracting the results
-    // -- rendering the user's theme and then extracting the results
-    // -- rendering native anonymous content (e.g., file input paths;
-    // scrollbars should be allowed)
-    if (!nsContentUtils::IsCallerTrustedForRead()) {
-        // not permitted to use DrawWindow
-        // XXX ERRMSG we need to report an error to developers here! (bug 329026)
-        return NS_ERROR_DOM_SECURITY_ERR;
-    }
-
-#if 0
-    nsCOMPtr<nsIFrameLoaderOwner> loaderOwner = do_QueryInterface(aElem);
-    if (!loaderOwner)
-        return NS_ERROR_FAILURE;
-
-    nsRefPtr<nsFrameLoader> frameloader = loaderOwner->GetFrameLoader();
-    if (!frameloader)
-        return NS_ERROR_FAILURE;
-
-    PBrowserParent *child = frameloader->GetRemoteBrowser();
-    if (!child) {
-        nsCOMPtr<nsIDOMWindow> window =
-            do_GetInterface(frameloader->GetExistingDocShell());
-        if (!window)
-            return NS_ERROR_FAILURE;
-
-        return DrawWindow(window, aX, aY, aW, aH, aBGColor, flags);
-    }
-
-    // protect against too-large surfaces that will cause allocation
-    // or overflow issues
-    if (!gfxASurface::CheckSurfaceSize(gfxIntSize(aW, aH), 0xffff))
-        return NS_ERROR_FAILURE;
-
-    bool flush =
-        (flags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_DO_NOT_FLUSH) == 0;
-
-    PRUint32 renderDocFlags = nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING;
-    if (flags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_DRAW_CARET) {
-        renderDocFlags |= nsIPresShell::RENDER_CARET;
-    }
-    if (flags & nsIDOMCanvasRenderingContext2D::DRAWWINDOW_DRAW_VIEW) {
-        renderDocFlags &= ~nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING;
-    }
-
-    nsRect rect(nsPresContext::CSSPixelsToAppUnits(aX),
-                nsPresContext::CSSPixelsToAppUnits(aY),
-                nsPresContext::CSSPixelsToAppUnits(aW),
-                nsPresContext::CSSPixelsToAppUnits(aH));
-    if (mIPC) {
-        PDocumentRendererParent *pdocrender =
-            child->SendPDocumentRendererConstructor(rect,
-                                                    mThebes->CurrentMatrix(),
-                                                    nsString(aBGColor),
-                                                    renderDocFlags, flush,
-                                                    nsIntSize(mWidth, mHeight));
-        if (!pdocrender)
-            return NS_ERROR_FAILURE;
-
-        DocumentRendererParent *docrender =
-            static_cast<DocumentRendererParent *>(pdocrender);
-
-        docrender->SetCanvasContext(this, mThebes);
-    }
-#endif
-    return NS_OK;
+  NS_ENSURE_ARG(aElem);
+
+  ErrorResult rv;
+  AsyncDrawXULElement(aElem, aX, aY, aW, aH, aBGColor, flags, rv);
+  return rv.ErrorCode();
 }
 
 //
 // device pixel getting/setting
 //
 
 void
 nsCanvasRenderingContext2DAzure::EnsureUnpremultiplyTable() {
@@ -4075,46 +4117,51 @@ nsCanvasRenderingContext2DAzure::EnsureU
   for (int a = 1; a <= 255; a++) {
     for (int c = 0; c <= 255; c++) {
       sUnpremultiplyTable[a][c] = (PRUint8)((c * 255) / a);
     }
   }
 }
 
 
-NS_IMETHODIMP
-nsCanvasRenderingContext2DAzure::GetImageData(double aSx, double aSy,
-                                              double aSw, double aSh,
-                                              JSContext* aCx,
-                                              nsIDOMImageData** aRetval)
+already_AddRefed<ImageData>
+nsCanvasRenderingContext2DAzure::GetImageData(JSContext* aCx, double aSx,
+                                              double aSy, double aSw,
+                                              double aSh, ErrorResult& error)
 {
-  if (!mValid)
-    return NS_ERROR_FAILURE;
+  if (!mValid) {
+    error.Throw(NS_ERROR_FAILURE);
+    return NULL;
+  }
 
   if (!mCanvasElement && !mDocShell) {
     NS_ERROR("No canvas element and no docshell in GetImageData!!!");
-    return NS_ERROR_DOM_SECURITY_ERR;
+    error.Throw(NS_ERROR_DOM_SECURITY_ERR);
+    return NULL;
   }
 
   // Check only if we have a canvas element; if we were created with a docshell,
   // then it's special internal use.
   if (mCanvasElement && mCanvasElement->IsWriteOnly() &&
       !nsContentUtils::IsCallerTrustedForRead())
   {
     // XXX ERRMSG we need to report an error to developers here! (bug 329026)
-    return NS_ERROR_DOM_SECURITY_ERR;
+    error.Throw(NS_ERROR_DOM_SECURITY_ERR);
+    return NULL;
   }
 
   if (!NS_finite(aSx) || !NS_finite(aSy) ||
       !NS_finite(aSw) || !NS_finite(aSh)) {
-    return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
+    error.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
+    return NULL;
   }
 
   if (!aSw || !aSh) {
-    return NS_ERROR_DOM_INDEX_SIZE_ERR;
+    error.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+    return NULL;
   }
 
   int32_t x = JS_DoubleToInt32(aSx);
   int32_t y = JS_DoubleToInt32(aSy);
   int32_t wi = JS_DoubleToInt32(aSw);
   int32_t hi = JS_DoubleToInt32(aSh);
 
   // Handle negative width and height by flipping the rectangle over in the
@@ -4136,23 +4183,35 @@ nsCanvasRenderingContext2DAzure::GetImag
   if (w == 0) {
     w = 1;
   }
   if (h == 0) {
     h = 1;
   }
 
   JSObject* array;
-  nsresult rv = GetImageDataArray(aCx, x, y, w, h, &array);
-  NS_ENSURE_SUCCESS(rv, rv);
+  error = GetImageDataArray(aCx, x, y, w, h, &array);
+  if (error.Failed()) {
+    return NULL;
+  }
   MOZ_ASSERT(array);
 
   nsRefPtr<ImageData> imageData = new ImageData(w, h, *array);
-  imageData.forget(aRetval);
-  return NS_OK;
+  return imageData.forget();
+}
+
+NS_IMETHODIMP
+nsCanvasRenderingContext2DAzure::GetImageData(double aSx, double aSy,
+                                              double aSw, double aSh,
+                                              JSContext* aCx,
+                                              nsIDOMImageData** aRetval)
+{
+  ErrorResult rv;
+  *aRetval = GetImageData(aCx, aSx, aSy, aSw, aSh, rv).get();
+  return rv.ErrorCode();
 }
 
 nsresult
 nsCanvasRenderingContext2DAzure::GetImageDataArray(JSContext* aCx,
                                                    int32_t aX,
                                                    int32_t aY,
                                                    uint32_t aWidth,
                                                    uint32_t aHeight,
@@ -4262,16 +4321,57 @@ void
 nsCanvasRenderingContext2DAzure::FillRuleChanged()
 {
   if (mPath) {
     mPathBuilder = mPath->CopyToBuilder(CurrentState().fillRule);
     mPath = nsnull;
   }
 }
 
+void
+nsCanvasRenderingContext2DAzure::PutImageData(JSContext* cx,
+                                              ImageData* imageData, double dx,
+                                              double dy, ErrorResult& error)
+{
+  if (!FloatValidate(dx, dy)) {
+    error.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
+    return;
+  }
+
+  dom::Uint8ClampedArray arr(cx, imageData->GetDataObject());
+
+  error = PutImageData_explicit(JS_DoubleToInt32(dx), JS_DoubleToInt32(dy),
+                                imageData->GetWidth(), imageData->GetHeight(),
+                                arr.mData, arr.mLength, false, 0, 0, 0, 0);
+}
+
+void
+nsCanvasRenderingContext2DAzure::PutImageData(JSContext* cx,
+                                              ImageData* imageData, double dx,
+                                              double dy, double dirtyX,
+                                              double dirtyY, double dirtyWidth,
+                                              double dirtyHeight,
+                                              ErrorResult& error)
+{
+  if (!FloatValidate(dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight)) {
+    error.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
+    return;
+  }
+
+  dom::Uint8ClampedArray arr(cx, imageData->GetDataObject());
+
+  error = PutImageData_explicit(JS_DoubleToInt32(dx), JS_DoubleToInt32(dy),
+                                imageData->GetWidth(), imageData->GetHeight(),
+                                arr.mData, arr.mLength, true,
+                                JS_DoubleToInt32(dirtyX),
+                                JS_DoubleToInt32(dirtyY),
+                                JS_DoubleToInt32(dirtyWidth),
+                                JS_DoubleToInt32(dirtyHeight));
+}
+
 // void putImageData (in ImageData d, in float x, in float y);
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::PutImageData()
 {
   /* Should never be called -- PutImageData_explicit is the QS entry point */
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
@@ -4411,37 +4511,92 @@ nsCanvasRenderingContext2DAzure::GetTheb
   }
 
   *surface = mThebesSurface;
   NS_ADDREF(*surface);
 
   return NS_OK;
 }
 
+static already_AddRefed<ImageData>
+CreateImageData(JSContext* cx, nsCanvasRenderingContext2DAzure* context,
+                uint32_t w, uint32_t h, ErrorResult& error)
+{
+  if (w == 0)
+      w = 1;
+  if (h == 0)
+      h = 1;
+
+  CheckedInt<uint32_t> len = CheckedInt<uint32_t>(w) * h * 4;
+  if (!len.isValid()) {
+    error.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+    return NULL;
+  }
+
+  // Create the fast typed array; it's initialized to 0 by default.
+  JSObject* darray = Uint8ClampedArray::Create(cx, context, len.value());
+  if (!darray) {
+    error.Throw(NS_ERROR_OUT_OF_MEMORY);
+    return NULL;
+  }
+
+  nsRefPtr<mozilla::dom::ImageData> imageData =
+    new mozilla::dom::ImageData(w, h, *darray);
+  return imageData.forget();
+}
+
+already_AddRefed<ImageData>
+nsCanvasRenderingContext2DAzure::CreateImageData(JSContext* cx, double sw,
+                                                 double sh, ErrorResult& error)
+{
+  if (!FloatValidate(sw, sh)) {
+    error.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
+    return NULL;
+  }
+
+  if (!sw || !sh) {
+    error.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+    return NULL;
+  }
+
+  int32_t wi = JS_DoubleToInt32(sw);
+  int32_t hi = JS_DoubleToInt32(sh);
+
+  uint32_t w = NS_ABS(wi);
+  uint32_t h = NS_ABS(hi);
+  return ::CreateImageData(cx, this, w, h, error);
+}
+
+already_AddRefed<ImageData>
+nsCanvasRenderingContext2DAzure::CreateImageData(JSContext* cx,
+                                                 ImageData* imagedata,
+                                                 ErrorResult& error)
+{
+  return ::CreateImageData(cx, this, imagedata->GetWidth(),
+                           imagedata->GetHeight(), error);
+}
+
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::CreateImageData()
 {
   /* Should never be called; handled entirely in the quickstub */
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::GetMozImageSmoothingEnabled(bool *retVal)
 {
-  *retVal = CurrentState().imageSmoothingEnabled;
+  *retVal = GetImageSmoothingEnabled();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2DAzure::SetMozImageSmoothingEnabled(bool val)
 {
-  if (val != CurrentState().imageSmoothingEnabled) {
-      CurrentState().imageSmoothingEnabled = val;
-  }
-
+  SetImageSmoothingEnabled(val);
   return NS_OK;
 }
 
 static PRUint8 g2DContextLayerUserData;
 
 already_AddRefed<CanvasLayer>
 nsCanvasRenderingContext2DAzure::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
                                            CanvasLayer *aOldLayer,
new file mode 100644
--- /dev/null
+++ b/content/canvas/src/nsCanvasRenderingContext2DAzure.h
@@ -0,0 +1,943 @@
+/* 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 nsCanvasRenderingContext2DAzure_h
+#define nsCanvasRenderingContext2DAzure_h
+
+#include <vector>
+#include "nsIDOMCanvasRenderingContext2D.h"
+#include "nsICanvasRenderingContextInternal.h"
+#include "mozilla/RefPtr.h"
+#include "nsColor.h"
+#include "nsHTMLCanvasElement.h"
+#include "CanvasUtils.h"
+#include "nsHTMLImageElement.h"
+#include "nsHTMLVideoElement.h"
+#include "gfxFont.h"
+#include "mozilla/ErrorResult.h"
+#include "mozilla/dom/ImageData.h"
+#include "mozilla/dom/UnionTypes.h"
+
+namespace mozilla {
+namespace dom {
+template<typename T> class Optional;
+}
+namespace gfx {
+struct Rect;
+class SourceSurface;
+}
+}
+
+extern const mozilla::gfx::Float SIGMA_MAX;
+
+/**
+ ** nsCanvasGradientAzure
+ **/
+#define NS_CANVASGRADIENTAZURE_PRIVATE_IID \
+    {0x28425a6a, 0x90e0, 0x4d42, {0x9c, 0x75, 0xff, 0x60, 0x09, 0xb3, 0x10, 0xa8}}
+class nsCanvasGradientAzure : public nsIDOMCanvasGradient
+{
+public:
+  NS_DECLARE_STATIC_IID_ACCESSOR(NS_CANVASGRADIENTAZURE_PRIVATE_IID)
+
+  enum Type
+  {
+    LINEAR = 0,
+    RADIAL
+  };
+
+  Type GetType()
+  {
+    return mType;
+  }
+
+
+  mozilla::gfx::GradientStops *
+  GetGradientStopsForTarget(mozilla::gfx::DrawTarget *aRT)
+  {
+    if (mStops && mStops->GetBackendType() == aRT->GetType()) {
+      return mStops;
+    }
+
+    mStops = aRT->CreateGradientStops(mRawStops.Elements(), mRawStops.Length());
+
+    return mStops;
+  }
+
+  NS_DECL_ISUPPORTS
+
+  /* nsIDOMCanvasGradient */
+  NS_IMETHOD AddColorStop(float offset, const nsAString& colorstr);
+
+protected:
+  nsCanvasGradientAzure(Type aType) : mType(aType)
+  {}
+
+  nsTArray<mozilla::gfx::GradientStop> mRawStops;
+  mozilla::RefPtr<mozilla::gfx::GradientStops> mStops;
+  Type mType;
+  virtual ~nsCanvasGradientAzure() {}
+};
+
+/**
+ ** nsCanvasPatternAzure
+ **/
+#define NS_CANVASPATTERNAZURE_PRIVATE_IID \
+    {0xc9bacc25, 0x28da, 0x421e, {0x9a, 0x4b, 0xbb, 0xd6, 0x93, 0x05, 0x12, 0xbc}}
+class nsCanvasPatternAzure MOZ_FINAL : public nsIDOMCanvasPattern
+{
+public:
+  NS_DECLARE_STATIC_IID_ACCESSOR(NS_CANVASPATTERNAZURE_PRIVATE_IID)
+
+  enum RepeatMode
+  {
+    REPEAT,
+    REPEATX,
+    REPEATY,
+    NOREPEAT
+  };
+
+  nsCanvasPatternAzure(mozilla::gfx::SourceSurface* aSurface,
+                       RepeatMode aRepeat,
+                       nsIPrincipal* principalForSecurityCheck,
+                       bool forceWriteOnly,
+                       bool CORSUsed)
+    : mSurface(aSurface)
+    , mRepeat(aRepeat)
+    , mPrincipal(principalForSecurityCheck)
+    , mForceWriteOnly(forceWriteOnly)
+    , mCORSUsed(CORSUsed)
+  {
+  }
+
+  NS_DECL_ISUPPORTS
+
+  mozilla::RefPtr<mozilla::gfx::SourceSurface> mSurface;
+  const RepeatMode mRepeat;
+  nsCOMPtr<nsIPrincipal> mPrincipal;
+  const bool mForceWriteOnly;
+  const bool mCORSUsed;
+};
+
+struct nsCanvasBidiProcessorAzure;
+class CanvasRenderingContext2DUserDataAzure;
+
+/**
+ ** nsCanvasRenderingContext2DAzure
+ **/
+class nsCanvasRenderingContext2DAzure :
+  public nsIDOMCanvasRenderingContext2D,
+  public nsICanvasRenderingContextInternal,
+  public nsWrapperCache
+{
+typedef mozilla::dom::HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement
+  HTMLImageOrCanvasOrVideoElement;
+
+public:
+  nsCanvasRenderingContext2DAzure();
+  virtual ~nsCanvasRenderingContext2DAzure();
+
+  virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
+                               bool *triedToWrap);
+
+  nsHTMLCanvasElement* GetCanvas() const
+  {
+    return mCanvasElement;
+  }
+
+  void Save();
+  void Restore();
+  void Scale(double x, double y, mozilla::ErrorResult& error);
+  void Rotate(double angle, mozilla::ErrorResult& error);
+  void Translate(double x, double y, mozilla::ErrorResult& error);
+  void Transform(double m11, double m12, double m21, double m22, double dx,
+                 double dy, mozilla::ErrorResult& error);
+  void SetTransform(double m11, double m12, double m21, double m22, double dx,
+                    double dy, mozilla::ErrorResult& error);
+
+  double GetGlobalAlpha()
+  {
+    return CurrentState().globalAlpha;
+  }
+
+  void SetGlobalAlpha(double globalAlpha)
+  {
+    if (mozilla::CanvasUtils::FloatValidate(globalAlpha) &&
+        globalAlpha >= 0.0 && globalAlpha <= 1.0) {
+      CurrentState().globalAlpha = globalAlpha;
+    }
+  }
+
+  void GetGlobalCompositeOperation(nsAString& op, mozilla::ErrorResult& error);
+  void SetGlobalCompositeOperation(const nsAString& op,
+                                   mozilla::ErrorResult& error);
+  JS::Value GetStrokeStyle(JSContext* cx, mozilla::ErrorResult& error);
+
+  void SetStrokeStyle(JSContext* cx, JS::Value& value)
+  {
+    SetStyleFromJSValue(cx, value, STYLE_STROKE);
+  }
+
+  JS::Value GetFillStyle(JSContext* cx, mozilla::ErrorResult& error);
+
+  void SetFillStyle(JSContext* cx, JS::Value& value)
+  {
+    SetStyleFromJSValue(cx, value, STYLE_FILL);
+  }
+
+  already_AddRefed<nsIDOMCanvasGradient>
+    CreateLinearGradient(double x0, double y0, double x1, double y1,
+                         mozilla::ErrorResult& aError);
+  already_AddRefed<nsIDOMCanvasGradient>
+    CreateRadialGradient(double x0, double y0, double r0, double x1, double y1,
+                         double r1, mozilla::ErrorResult& aError);
+  already_AddRefed<nsIDOMCanvasPattern>
+    CreatePattern(const HTMLImageOrCanvasOrVideoElement& element,
+                  const nsAString& repeat, mozilla::ErrorResult& error);
+
+  double GetShadowOffsetX()
+  {
+    return CurrentState().shadowOffset.x;
+  }
+
+  void SetShadowOffsetX(double shadowOffsetX)
+  {
+    if (mozilla::CanvasUtils::FloatValidate(shadowOffsetX)) {
+      CurrentState().shadowOffset.x = shadowOffsetX;
+    }
+  }
+
+  double GetShadowOffsetY()
+  {
+    return CurrentState().shadowOffset.y;
+  }
+
+  void SetShadowOffsetY(double shadowOffsetY)
+  {
+    if (mozilla::CanvasUtils::FloatValidate(shadowOffsetY)) {
+      CurrentState().shadowOffset.y = shadowOffsetY;
+    }
+  }
+
+  double GetShadowBlur()
+  {
+    return CurrentState().shadowBlur;
+  }
+
+  void SetShadowBlur(double shadowBlur)
+  {
+    if (mozilla::CanvasUtils::FloatValidate(shadowBlur) && shadowBlur >= 0.0) {
+      CurrentState().shadowBlur = shadowBlur;
+    }
+  }
+
+  void GetShadowColor(nsAString& shadowColor)
+  {
+    StyleColorToString(CurrentState().shadowColor, shadowColor);
+  }
+
+  void SetShadowColor(const nsAString& shadowColor);
+  void ClearRect(double x, double y, double w, double h);
+  void FillRect(double x, double y, double w, double h);
+  void StrokeRect(double x, double y, double w, double h);
+  void BeginPath();
+  void Fill();
+  void Stroke();
+  void Clip();
+  bool IsPointInPath(double x, double y);
+  void FillText(const nsAString& text, double x, double y,
+                const mozilla::dom::Optional<double>& maxWidth,
+                mozilla::ErrorResult& error);
+  void StrokeText(const nsAString& text, double x, double y,
+                  const mozilla::dom::Optional<double>& maxWidth,
+                  mozilla::ErrorResult& error);
+  already_AddRefed<nsIDOMTextMetrics>
+    MeasureText(const nsAString& rawText, mozilla::ErrorResult& error);
+
+  void DrawImage(const HTMLImageOrCanvasOrVideoElement& image,
+                 double dx, double dy, mozilla::ErrorResult& error)
+  {
+    if (!mozilla::CanvasUtils::FloatValidate(dx, dy)) {
+      return;
+    }
+    DrawImage(image, 0.0, 0.0, 0.0, 0.0, dx, dy, 0.0, 0.0, 0, error);
+  }
+
+  void DrawImage(const HTMLImageOrCanvasOrVideoElement& image,
+                 double dx, double dy, double dw, double dh,
+                 mozilla::ErrorResult& error)
+  {
+    if (!mozilla::CanvasUtils::FloatValidate(dx, dy, dw, dh)) {
+      return;
+    }
+    DrawImage(image, 0.0, 0.0, 0.0, 0.0, dx, dy, dw, dh, 2, error);
+  }
+
+  void DrawImage(const HTMLImageOrCanvasOrVideoElement& image,
+                 double sx, double sy, double sw, double sh, double dx,
+                 double dy, double dw, double dh, mozilla::ErrorResult& error)
+  {
+    if (!mozilla::CanvasUtils::FloatValidate(sx, sy, sw, sh) ||
+        !mozilla::CanvasUtils::FloatValidate(dx, dy, dw, dh)) {
+      return;
+    }
+    DrawImage(image, sx, sy, sw, sh, dx, dy, dw, dh, 6, error);
+  }
+
+  already_AddRefed<mozilla::dom::ImageData>
+    CreateImageData(JSContext* cx, double sw, double sh,
+                    mozilla::ErrorResult& error);
+  already_AddRefed<mozilla::dom::ImageData>
+    CreateImageData(JSContext* cx, mozilla::dom::ImageData* imagedata,
+                    mozilla::ErrorResult& error);
+  already_AddRefed<mozilla::dom::ImageData>
+    GetImageData(JSContext* cx, double sx, double sy, double sw, double sh,
+                 mozilla::ErrorResult& error);
+  void PutImageData(JSContext* cx, mozilla::dom::ImageData* imageData,
+                    double dx, double dy, mozilla::ErrorResult& error);
+  void PutImageData(JSContext* cx, mozilla::dom::ImageData* imageData,
+                    double dx, double dy, double dirtyX, double dirtyY,
+                    double dirtyWidth, double dirtyHeight,
+                    mozilla::ErrorResult& error);
+
+  double GetLineWidth()
+  {
+    return CurrentState().lineWidth;
+  }
+
+  void SetLineWidth(double width)
+  {
+    if (mozilla::CanvasUtils::FloatValidate(width) && width > 0.0) {
+      CurrentState().lineWidth = width;
+    }
+  }
+  void GetLineCap(nsAString& linecap);
+  void SetLineCap(const nsAString& linecap);
+  void GetLineJoin(nsAString& linejoin, mozilla::ErrorResult& error);
+  void SetLineJoin(const nsAString& linejoin);
+
+  double GetMiterLimit()
+  {
+    return CurrentState().miterLimit;
+  }
+
+  void SetMiterLimit(double miter)
+  {
+    if (mozilla::CanvasUtils::FloatValidate(miter) && miter > 0.0) {
+      CurrentState().miterLimit = miter;
+    }
+  }
+
+  void GetFont(nsAString& font)
+  {
+    font = GetFont();
+  }
+
+  void SetFont(const nsAString& font, mozilla::ErrorResult& error);
+  void GetTextAlign(nsAString& textAlign);
+  void SetTextAlign(const nsAString& textAlign);
+  void GetTextBaseline(nsAString& textBaseline);
+  void SetTextBaseline(const nsAString& textBaseline);
+
+  void ClosePath()
+  {
+    EnsureWritablePath();
+
+    if (mPathBuilder) {
+      mPathBuilder->Close();
+    } else {
+      mDSPathBuilder->Close();
+    }
+  }
+
+  void MoveTo(double x, double y)
+  {
+    if (mozilla::CanvasUtils::FloatValidate(x, y)) {
+      EnsureWritablePath();
+
+      if (mPathBuilder) {
+        mPathBuilder->MoveTo(mozilla::gfx::Point(x, y));
+      } else {
+        mDSPathBuilder->MoveTo(mTarget->GetTransform() *
+                                 mozilla::gfx::Point(x, y));
+      }
+    }
+  }
+
+  void LineTo(double x, double y)
+  {
+    if (mozilla::CanvasUtils::FloatValidate(x, y)) {
+      EnsureWritablePath();
+    
+      LineTo(mozilla::gfx::Point(x, y));
+    }
+  }
+
+  void QuadraticCurveTo(double cpx, double cpy, double x, double y)
+  {
+    if (mozilla::CanvasUtils::FloatValidate(cpx, cpy, x, y)) {
+      EnsureWritablePath();
+
+      if (mPathBuilder) {
+        mPathBuilder->QuadraticBezierTo(mozilla::gfx::Point(cpx, cpy),
+                                        mozilla::gfx::Point(x, y));
+      } else {
+        mozilla::gfx::Matrix transform = mTarget->GetTransform();
+        mDSPathBuilder->QuadraticBezierTo(transform *
+                                            mozilla::gfx::Point(cpx, cpy),
+                                          transform *
+                                            mozilla::gfx::Point(x, y));
+      }
+    }
+  }
+
+  void BezierCurveTo(double cp1x, double cp1y, double cp2x, double cp2y, double x, double y)
+  {
+    if (mozilla::CanvasUtils::FloatValidate(cp1x, cp1y, cp2x, cp2y, x, y)) {
+      EnsureWritablePath();
+
+      BezierTo(mozilla::gfx::Point(cp1x, cp1y),
+               mozilla::gfx::Point(cp2x, cp2y),
+               mozilla::gfx::Point(x, y));
+    }
+  }
+
+  void ArcTo(double x1, double y1, double x2, double y2, double radius,
+             mozilla::ErrorResult& error);
+  void Rect(double x, double y, double w, double h);
+  void Arc(double x, double y, double radius, double startAngle,
+           double endAngle, bool anticlockwise, mozilla::ErrorResult& error);
+
+  JSObject* GetMozCurrentTransform(JSContext* cx,
+                                   mozilla::ErrorResult& error) const;
+  void SetMozCurrentTransform(JSContext* cx, JSObject& currentTransform,
+                              mozilla::ErrorResult& error);
+  JSObject* GetMozCurrentTransformInverse(JSContext* cx,
+                                          mozilla::ErrorResult& error) const;
+  void SetMozCurrentTransformInverse(JSContext* cx, JSObject& currentTransform, 
+                                     mozilla::ErrorResult& error);
+  void GetFillRule(nsAString& fillRule);
+  void SetFillRule(const nsAString& fillRule);
+  JS::Value GetMozDash(JSContext* cx, mozilla::ErrorResult& error);
+  void SetMozDash(JSContext* cx, const JS::Value& mozDash,
+                  mozilla::ErrorResult& error);
+
+  double GetMozDashOffset()
+  {
+    return CurrentState().dashOffset;
+  }
+
+  void SetMozDashOffset(double mozDashOffset, mozilla::ErrorResult& error);
+
+  void GetMozTextStyle(nsAString& mozTextStyle)
+  {
+    GetFont(mozTextStyle);
+  }
+
+  void SetMozTextStyle(const nsAString& mozTextStyle,
+                       mozilla::ErrorResult& error)
+  {
+    SetFont(mozTextStyle, error);
+  }
+
+  bool GetImageSmoothingEnabled()
+  {
+    return CurrentState().imageSmoothingEnabled;
+  }
+
+  void SetImageSmoothingEnabled(bool imageSmoothingEnabled)
+  {
+    if (imageSmoothingEnabled != CurrentState().imageSmoothingEnabled) {
+      CurrentState().imageSmoothingEnabled = imageSmoothingEnabled;
+    }
+  }
+
+  void DrawWindow(nsIDOMWindow* window, double x, double y, double w, double h,
+                  const nsAString& bgColor, uint32_t flags,
+                  mozilla::ErrorResult& error);
+  void AsyncDrawXULElement(nsIDOMXULElement* elem, double x, double y, double w,
+                           double h, const nsAString& bgColor, uint32_t flags,
+                           mozilla::ErrorResult& error);
+
+  nsresult Redraw();
+
+  // nsICanvasRenderingContextInternal
+  NS_IMETHOD SetDimensions(PRInt32 width, PRInt32 height);
+  NS_IMETHOD InitializeWithSurface(nsIDocShell *shell, gfxASurface *surface, PRInt32 width, PRInt32 height)
+  { return NS_ERROR_NOT_IMPLEMENTED; }
+
+  NS_IMETHOD Render(gfxContext *ctx,
+                    gfxPattern::GraphicsFilter aFilter,
+                    PRUint32 aFlags = RenderFlagPremultAlpha);
+  NS_IMETHOD GetInputStream(const char* aMimeType,
+                            const PRUnichar* aEncoderOptions,
+                            nsIInputStream **aStream);
+  NS_IMETHOD GetThebesSurface(gfxASurface **surface);
+
+  mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot()
+  { return mTarget ? mTarget->Snapshot() : nsnull; }
+
+  NS_IMETHOD SetIsOpaque(bool isOpaque);
+  NS_IMETHOD Reset();
+  already_AddRefed<CanvasLayer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
+                                                CanvasLayer *aOldLayer,
+                                                LayerManager *aManager);
+  void MarkContextClean();
+  NS_IMETHOD SetIsIPC(bool isIPC);
+  // this rect is in canvas device space
+  void Redraw(const mozilla::gfx::Rect &r);
+  NS_IMETHOD Redraw(const gfxRect &r) { Redraw(ToRect(r)); return NS_OK; }
+
+  // this rect is in mTarget's current user space
+  void RedrawUser(const gfxRect &r);
+
+  // nsISupports interface + CC
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+
+  NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsCanvasRenderingContext2DAzure,
+                                                                   nsIDOMCanvasRenderingContext2D)
+
+  // nsIDOMCanvasRenderingContext2D interface
+  NS_DECL_NSIDOMCANVASRENDERINGCONTEXT2D
+
+  enum Style {
+    STYLE_STROKE = 0,
+    STYLE_FILL,
+    STYLE_MAX
+  };
+
+  nsINode* GetParentObject()
+  {
+    return mCanvasElement;
+  }
+
+  void LineTo(const mozilla::gfx::Point& aPoint)
+  {
+    if (mPathBuilder) {
+      mPathBuilder->LineTo(aPoint);
+    } else {
+      mDSPathBuilder->LineTo(mTarget->GetTransform() * aPoint);
+    }
+  }
+
+  void BezierTo(const mozilla::gfx::Point& aCP1,
+                const mozilla::gfx::Point& aCP2,
+                const mozilla::gfx::Point& aCP3)
+  {
+    if (mPathBuilder) {
+      mPathBuilder->BezierTo(aCP1, aCP2, aCP3);
+    } else {
+      mozilla::gfx::Matrix transform = mTarget->GetTransform();
+      mDSPathBuilder->BezierTo(transform * aCP1,
+                                transform * aCP2,
+                                transform * aCP3);
+    }
+  }
+
+  friend class CanvasRenderingContext2DUserDataAzure;
+
+protected:
+  nsresult GetImageDataArray(JSContext* aCx, int32_t aX, int32_t aY,
+                             uint32_t aWidth, uint32_t aHeight,
+                             JSObject** aRetval);
+
+  nsresult InitializeWithTarget(mozilla::gfx::DrawTarget *surface,
+                                PRInt32 width, PRInt32 height);
+
+  /**
+    * The number of living nsCanvasRenderingContexts.  When this goes down to
+    * 0, we free the premultiply and unpremultiply tables, if they exist.
+    */