Merge last green changeset from inbound to mozilla-central
authorMatt Brubeck <mbrubeck@mozilla.com>
Wed, 29 Feb 2012 10:47:38 -0800
changeset 87984 3812d0ce274e8ad01f579efcd2dffd4d83be0295
parent 87912 cb01e23f83cffb4ef934c3aa1ab7c17757928826 (current diff)
parent 87983 57cf4086191d3bb7dae8df7399eda0453edcf634 (diff)
child 87985 1c3b291d08306cf3535e1a1f262ce8567f99e218
child 88054 434247f598689624d72d03b3b3109a856608826d
push id22164
push usermbrubeck@mozilla.com
push dateWed, 29 Feb 2012 18:48:10 +0000
treeherdermozilla-central@3812d0ce274e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone13.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge last green changeset from inbound to mozilla-central
browser/base/content/aboutSyncTabs-bindings.xml
browser/base/content/aboutSyncTabs.css
browser/base/content/aboutSyncTabs.js
browser/base/content/aboutSyncTabs.xul
browser/base/content/syncAddDevice.js
browser/base/content/syncAddDevice.xul
browser/base/content/syncGenericChange.js
browser/base/content/syncGenericChange.xul
browser/base/content/syncKey.xhtml
browser/base/content/syncNotification.xml
browser/base/content/syncProgress.js
browser/base/content/syncProgress.xhtml
browser/base/content/syncQuota.js
browser/base/content/syncQuota.xul
browser/base/content/syncSetup.js
browser/base/content/syncSetup.xul
browser/base/content/syncUtils.js
browser/components/places/tests/unit/test_placesTxn.js
browser/components/places/tests/unit/test_txnGUIDs.js
build/mobile/devicemanager-run-test.py
content/canvas/test/webgl/test_webgl_conformance_test_suite.html
js/src/jscompat.h
xpcom/ds/nsHashSets.cpp
xpcom/ds/nsHashSets.h
--- a/accessible/src/atk/nsMaiInterfaceText.cpp
+++ b/accessible/src/atk/nsMaiInterfaceText.cpp
@@ -38,16 +38,18 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsMaiInterfaceText.h"
 
 #include "nsHyperTextAccessible.h"
 #include "nsRoleMap.h"
 
+#include "nsIPersistentProperties2.h"
+
 AtkAttributeSet* ConvertToAtkAttributeSet(nsIPersistentProperties* aAttributes);
 
 void
 textInterfaceInitCB(AtkTextIface *aIface)
 {
     NS_ASSERTION(aIface, "Invalid aIface");
     if (!aIface)
         return;
--- a/accessible/src/base/StyleInfo.cpp
+++ b/accessible/src/base/StyleInfo.cpp
@@ -107,19 +107,27 @@ StyleInfo::Margin(css::Side aSide, nsASt
   aValue.Truncate();
 
   nscoord coordVal = mElement->GetPrimaryFrame()->GetUsedMargin().Side(aSide);
   aValue.AppendFloat(nsPresContext::AppUnitsToFloatCSSPixels(coordVal));
   aValue.AppendLiteral("px");
 }
 
 void
-StyleInfo::Format(const nscolor& aValue, nsString& aFormattedValue)
+StyleInfo::FormatColor(const nscolor& aValue, nsString& aFormattedValue)
 {
   // Combine the string like rgb(R, G, B) from nscolor.
   aFormattedValue.AppendLiteral("rgb(");
   aFormattedValue.AppendInt(NS_GET_R(aValue));
   aFormattedValue.AppendLiteral(", ");
   aFormattedValue.AppendInt(NS_GET_G(aValue));
   aFormattedValue.AppendLiteral(", ");
   aFormattedValue.AppendInt(NS_GET_B(aValue));
   aFormattedValue.Append(')');
 }
+
+void
+StyleInfo::FormatFontStyle(const nscoord& aValue, nsAString& aFormattedValue)
+{
+  nsCSSKeyword keyword =
+    nsCSSProps::ValueToKeywordEnum(aValue, nsCSSProps::kFontStyleKTable);
+  AppendUTF8toUTF16(nsCSSKeywords::GetStringValue(keyword), aFormattedValue);
+}
--- a/accessible/src/base/StyleInfo.h
+++ b/accessible/src/base/StyleInfo.h
@@ -55,17 +55,18 @@ public:
   void Display(nsAString& aValue);
   void TextAlign(nsAString& aValue);
   void TextIndent(nsAString& aValue);
   void MarginLeft(nsAString& aValue) { Margin(css::eSideLeft, aValue); }
   void MarginRight(nsAString& aValue) { Margin(css::eSideRight, aValue); }
   void MarginTop(nsAString& aValue) { Margin(css::eSideTop, aValue); }
   void MarginBottom(nsAString& aValue) { Margin(css::eSideBottom, aValue); }
 
-  static void Format(const nscolor& aValue, nsString& aFormattedValue);
+  static void FormatColor(const nscolor& aValue, nsString& aFormattedValue);
+  static void FormatFontStyle(const nscoord& aValue, nsAString& aFormattedValue);
 
 private:
   StyleInfo() MOZ_DELETE;
   StyleInfo(const StyleInfo&) MOZ_DELETE;
   StyleInfo& operator = (const StyleInfo&) MOZ_DELETE;
 
   void Margin(css::Side aSide, nsAString& aValue);
 
--- a/accessible/src/base/nsTextAttrs.cpp
+++ b/accessible/src/base/nsTextAttrs.cpp
@@ -69,18 +69,16 @@ struct nsCSSTextAttrMapItem
  * The map of CSS properties to text attributes.
  */
 const char* const kAnyValue = nsnull;
 const char* const kCopyValue = nsnull;
 
 static nsCSSTextAttrMapItem gCSSTextAttrsMap[] =
 {
   // CSS name            CSS value        Attribute name                                Attribute value
-  { "font-family",       kAnyValue,       &nsGkAtoms::font_family,            kCopyValue },
-  { "font-style",        kAnyValue,       &nsGkAtoms::font_style,             kCopyValue },
   { "text-decoration",   "line-through",  &nsGkAtoms::textLineThroughStyle,  "solid" },
   { "text-decoration",   "underline",     &nsGkAtoms::textUnderlineStyle,    "solid" },
   { "vertical-align",    kAnyValue,       &nsGkAtoms::textPosition,          kCopyValue }
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsTextAttrs
 
@@ -150,53 +148,53 @@ nsTextAttrsMgr::GetAttributes(nsIPersist
     offsetElm = nsCoreUtils::GetDOMElementFor(offsetNode);
     frame = offsetElm->GetPrimaryFrame();
   }
 
   nsTArray<nsITextAttr*> textAttrArray(10);
 
   // "language" text attribute
   nsLangTextAttr langTextAttr(mHyperTextAcc, hyperTextElm, offsetNode);
-  textAttrArray.AppendElement(static_cast<nsITextAttr*>(&langTextAttr));
-
-  // "font-family" text attribute
-  nsCSSTextAttr fontFamilyTextAttr(0, hyperTextElm, offsetElm);
-  textAttrArray.AppendElement(static_cast<nsITextAttr*>(&fontFamilyTextAttr));
-
-  // "font-style" text attribute
-  nsCSSTextAttr fontStyleTextAttr(1, hyperTextElm, offsetElm);
-  textAttrArray.AppendElement(static_cast<nsITextAttr*>(&fontStyleTextAttr));
+  textAttrArray.AppendElement(&langTextAttr);
 
   // "text-line-through-style" text attribute
-  nsCSSTextAttr lineThroughTextAttr(2, hyperTextElm, offsetElm);
-  textAttrArray.AppendElement(static_cast<nsITextAttr*>(&lineThroughTextAttr));
+  nsCSSTextAttr lineThroughTextAttr(0, hyperTextElm, offsetElm);
+  textAttrArray.AppendElement(&lineThroughTextAttr);
 
   // "text-underline-style" text attribute
-  nsCSSTextAttr underlineTextAttr(3, hyperTextElm, offsetElm);
-  textAttrArray.AppendElement(static_cast<nsITextAttr*>(&underlineTextAttr));
+  nsCSSTextAttr underlineTextAttr(1, hyperTextElm, offsetElm);
+  textAttrArray.AppendElement(&underlineTextAttr);
 
   // "text-position" text attribute
-  nsCSSTextAttr posTextAttr(4, hyperTextElm, offsetElm);
-  textAttrArray.AppendElement(static_cast<nsITextAttr*>(&posTextAttr));
+  nsCSSTextAttr posTextAttr(2, hyperTextElm, offsetElm);
+  textAttrArray.AppendElement(&posTextAttr);
 
   // "background-color" text attribute
   nsBGColorTextAttr bgColorTextAttr(rootFrame, frame);
-  textAttrArray.AppendElement(static_cast<nsITextAttr*>(&bgColorTextAttr));
+  textAttrArray.AppendElement(&bgColorTextAttr);
 
   // "color" text attribute
   ColorTextAttr colorTextAttr(rootFrame, frame);
-  textAttrArray.AppendElement(static_cast<nsITextAttr*>(&colorTextAttr));
+  textAttrArray.AppendElement(&colorTextAttr);
+
+  // "font-family" text attribute
+  FontFamilyTextAttr fontFamilyTextAttr(rootFrame, frame);
+  textAttrArray.AppendElement(&fontFamilyTextAttr);
 
   // "font-size" text attribute
   nsFontSizeTextAttr fontSizeTextAttr(rootFrame, frame);
-  textAttrArray.AppendElement(static_cast<nsITextAttr*>(&fontSizeTextAttr));
+  textAttrArray.AppendElement(&fontSizeTextAttr);
+
+  // "font-style" text attribute
+  FontStyleTextAttr fontStyleTextAttr(rootFrame, frame);
+  textAttrArray.AppendElement(&fontStyleTextAttr);
 
   // "font-weight" text attribute
   nsFontWeightTextAttr fontWeightTextAttr(rootFrame, frame);
-  textAttrArray.AppendElement(static_cast<nsITextAttr*>(&fontWeightTextAttr));
+  textAttrArray.AppendElement(&fontWeightTextAttr);
 
   // Expose text attributes if applicable.
   if (aAttributes) {
     PRUint32 len = textAttrArray.Length();
     for (PRUint32 idx = 0; idx < len; idx++) {
       nsITextAttr *textAttr = textAttrArray[idx];
 
       nsAutoString value;
@@ -386,17 +384,17 @@ nsBGColorTextAttr::GetValueFor(nsIConten
 
   return GetColor(frame, aValue);
 }
 
 void
 nsBGColorTextAttr::Format(const nscolor& aValue, nsAString& aFormattedValue)
 {
   nsAutoString value;
-  StyleInfo::Format(aValue, value);
+  StyleInfo::FormatColor(aValue, value);
   aFormattedValue = value;
 }
 
 bool
 nsBGColorTextAttr::GetColor(nsIFrame *aFrame, nscolor *aColor)
 {
   const nsStyleBackground *styleBackground = aFrame->GetStyleBackground();
 
@@ -448,22 +446,66 @@ ColorTextAttr::GetValueFor(nsIContent* a
 
   return false;
 }
 
 void
 ColorTextAttr::Format(const nscolor& aValue, nsAString& aFormattedValue)
 {
   nsAutoString value;
-  StyleInfo::Format(aValue, value);
+  StyleInfo::FormatColor(aValue, value);
   aFormattedValue = value;
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
+// FontFamilyTextAttr
+////////////////////////////////////////////////////////////////////////////////
+
+FontFamilyTextAttr::FontFamilyTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
+  nsTextAttr<nsAutoString>(aFrame == nsnull)
+{
+  mIsRootDefined = GetFontFamily(aRootFrame, mRootNativeValue);
+
+  if (aFrame)
+    mIsDefined = GetFontFamily(aFrame, mNativeValue);
+}
+
+bool
+FontFamilyTextAttr::GetValueFor(nsIContent* aElm, nsAutoString* aValue)
+{
+  nsIFrame* frame = aElm->GetPrimaryFrame();
+  if (!frame)
+    return false;
+
+  return GetFontFamily(frame, *aValue);
+}
+
+void
+FontFamilyTextAttr::Format(const nsAutoString& aValue,
+                           nsAString& aFormattedValue)
+{
+  aFormattedValue = aValue;
+}
+
+bool
+FontFamilyTextAttr::GetFontFamily(nsIFrame* aFrame, nsAutoString& aFamily)
+{
+  nsRefPtr<nsFontMetrics> fm;
+  nsLayoutUtils::GetFontMetricsForFrame(aFrame, getter_AddRefs(fm));
+
+  gfxFontGroup* fontGroup = fm->GetThebesFontGroup();
+  gfxFont* font = fontGroup->GetFontAt(0);
+  gfxFontEntry* fontEntry = font->GetFontEntry();
+  aFamily = fontEntry->FamilyName();
+  return true;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
 // nsFontSizeTextAttr
 ////////////////////////////////////////////////////////////////////////////////
 
 nsFontSizeTextAttr::nsFontSizeTextAttr(nsIFrame *aRootFrame, nsIFrame *aFrame) :
   nsTextAttr<nscoord>(aFrame == nsnull)
 {
   mDC = aRootFrame->PresContext()->DeviceContext();
 
@@ -477,29 +519,29 @@ nsFontSizeTextAttr::nsFontSizeTextAttr(n
 }
 
 bool
 nsFontSizeTextAttr::GetValueFor(nsIContent *aContent, nscoord *aValue)
 {
   nsIFrame *frame = aContent->GetPrimaryFrame();
   if (!frame)
     return false;
-  
+
   *aValue = GetFontSize(frame);
   return true;
 }
 
 void
 nsFontSizeTextAttr::Format(const nscoord& aValue, nsAString& aFormattedValue)
 {
   // Convert from nscoord to pt.
   //
   // Note: according to IA2, "The conversion doesn't have to be exact.
   // The intent is to give the user a feel for the size of the text."
-  // 
+  //
   // ATK does not specify a unit and will likely follow IA2 here.
   //
   // XXX todo: consider sharing this code with layout module? (bug 474621)
   float px =
     NSAppUnitsToFloatPixels(aValue, nsDeviceContext::AppUnitsPerCSSPixel());
   // Each pt is 4/3 of a CSS pixel.
   int pts = NS_lround(px*3/4);
 
@@ -512,16 +554,51 @@ nsFontSizeTextAttr::Format(const nscoord
 nscoord
 nsFontSizeTextAttr::GetFontSize(nsIFrame *aFrame)
 {
   return aFrame->GetStyleFont()->mSize;
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
+// FontStyleTextAttr
+////////////////////////////////////////////////////////////////////////////////
+
+FontStyleTextAttr::FontStyleTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
+  nsTextAttr<nscoord>(!aFrame)
+{
+  mRootNativeValue = aRootFrame->GetStyleFont()->mFont.style;
+  mIsRootDefined = true;
+
+  if (aFrame) {
+    mNativeValue = aFrame->GetStyleFont()->mFont.style;
+    mIsDefined = true;
+  }
+}
+
+bool
+FontStyleTextAttr::GetValueFor(nsIContent* aContent, nscoord* aValue)
+{
+  nsIFrame* frame = aContent->GetPrimaryFrame();
+  if (frame) {
+    *aValue = frame->GetStyleFont()->mFont.style;
+    return true;
+  }
+
+  return false;
+}
+
+void
+FontStyleTextAttr::Format(const nscoord& aValue, nsAString& aFormattedValue)
+{
+  StyleInfo::FormatFontStyle(aValue, aFormattedValue);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
 // nsFontWeightTextAttr
 ////////////////////////////////////////////////////////////////////////////////
 
 nsFontWeightTextAttr::nsFontWeightTextAttr(nsIFrame *aRootFrame,
                                            nsIFrame *aFrame) :
   nsTextAttr<PRInt32>(aFrame == nsnull)
 {
   mRootNativeValue = GetFontWeight(aRootFrame);
--- a/accessible/src/base/nsTextAttrs.h
+++ b/accessible/src/base/nsTextAttrs.h
@@ -36,27 +36,20 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsTextAttrs_h_
 #define nsTextAttrs_h_
 
 class nsHyperTextAccessible;
 
-
-#include "nsIDOMNode.h"
-#include "nsIDOMElement.h"
-
 #include "nsIContent.h"
 #include "nsIFrame.h"
 #include "nsIPersistentProperties2.h"
 
-#include "nsCOMPtr.h"
-#include "nsString.h"
-
 class nsITextAttr;
 
 /**
  * Used to expose text attributes for the hyper text accessible (see
  * nsHyperTextAccessible class). It is indended for the work with 'language' and
  * CSS based text attributes.
  *
  * @note "invalid: spelling" text attrbiute is implemented entirerly in
@@ -95,17 +88,16 @@ public:
    * @param aStartHTOffset [out, optional] start hyper text offset
    * @param aEndHTOffset   [out, optional] end hyper text offset
    */
   nsresult GetAttributes(nsIPersistentProperties *aAttributes,
                          PRInt32 *aStartHTOffset = nsnull,
                          PRInt32 *aEndHTOffset = nsnull);
 
 protected:
-
   /**
    * Calculates range (start and end offsets) of text where the text attributes
    * are stretched. New offsets may be smaller if one of text attributes changes
    * its value before or after the given offsets.
    *
    * @param aTextAttrArray  [in] text attributes array
    * @param aStartHTOffset  [in, out] the start offset
    * @param aEndHTOffset    [in, out] the end offset
@@ -322,16 +314,40 @@ public:
 protected:
   // nsTextAttr
   virtual bool GetValueFor(nsIContent* aContent, nscolor* aValue);
   virtual void Format(const nscolor& aValue, nsAString& aFormattedValue);
 };
 
 
 /**
+ * Class is used for the work with "font-family" text attribute in
+ * nsTextAttrsMgr class.
+ */
+class FontFamilyTextAttr : public nsTextAttr<nsAutoString>
+{
+public:
+  FontFamilyTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
+
+  // nsITextAttr
+  virtual nsIAtom* GetName() const { return nsGkAtoms::font_family; }
+
+protected:
+
+  // nsTextAttr
+  virtual bool GetValueFor(nsIContent* aContent, nsAutoString* aValue);
+  virtual void Format(const nsAutoString& aValue, nsAString& aFormattedValue);
+
+private:
+
+  bool GetFontFamily(nsIFrame* aFrame, nsAutoString& aFamily);
+};
+
+
+/**
  * Class is used for the work with "font-size" text attribute in nsTextAttrsMgr
  * class.
  */
 class nsFontSizeTextAttr : public nsTextAttr<nscoord>
 {
 public:
   nsFontSizeTextAttr(nsIFrame *aRootFrame, nsIFrame *aFrame);
 
@@ -354,16 +370,36 @@ private:
    */
    nscoord GetFontSize(nsIFrame *aFrame);
 
   nsDeviceContext *mDC;
 };
 
 
 /**
+ * Class is used for the work with "font-style" text attribute in nsTextAttrsMgr
+ * class.
+ */
+class FontStyleTextAttr : public nsTextAttr<nscoord>
+{
+public:
+  FontStyleTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
+
+  // nsITextAttr
+  virtual nsIAtom* GetName() const { return nsGkAtoms::font_style; }
+
+protected:
+
+  // nsTextAttr
+  virtual bool GetValueFor(nsIContent* aContent, nscoord* aValue);
+  virtual void Format(const nscoord &aValue, nsAString &aFormattedValue);
+};
+
+
+/**
  * Class is used for the work with "font-weight" text attribute in
  * nsTextAttrsMgr class.
  */
 class nsFontWeightTextAttr : public nsTextAttr<PRInt32>
 {
 public:
   nsFontWeightTextAttr(nsIFrame *aRootFrame, nsIFrame *aFrame);
 
--- a/accessible/src/html/nsHyperTextAccessible.h
+++ b/accessible/src/html/nsHyperTextAccessible.h
@@ -41,17 +41,16 @@
 #define _nsHyperTextAccessible_H_
 
 #include "nsIAccessibleText.h"
 #include "nsIAccessibleHyperText.h"
 #include "nsIAccessibleEditableText.h"
 
 #include "AccCollector.h"
 #include "nsAccessibleWrap.h"
-#include "nsTextAttrs.h"
 
 #include "nsFrameSelection.h"
 #include "nsISelectionController.h"
 
 enum EGetTextType { eGetBefore=-1, eGetAt=0, eGetAfter=1 };
 
 // This character marks where in the text returned via nsIAccessibleText(),
 // that embedded object characters exist
--- a/accessible/src/msaa/CAccessibleText.cpp
+++ b/accessible/src/msaa/CAccessibleText.cpp
@@ -40,16 +40,18 @@
 
 #include "CAccessibleText.h"
 
 #include "Accessible2.h"
 #include "AccessibleText_i.c"
 
 #include "nsHyperTextAccessible.h"
 
+#include "nsIPersistentProperties2.h"
+
 // IUnknown
 
 STDMETHODIMP
 CAccessibleText::QueryInterface(REFIID iid, void** ppv)
 {
   *ppv = NULL;
 
   if (IID_IAccessibleText == iid) {
--- a/accessible/tests/mochitest/attributes.js
+++ b/accessible/tests/mochitest/attributes.js
@@ -203,38 +203,71 @@ const kNormalFontWeight =
 
 const kBoldFontWeight =
   function equalsToBold(aWeight) { return aWeight > 400; }
 
 // The pt font size of the input element can vary by Linux distro.
 const kInputFontSize = WIN ?
   "10pt" : (MAC ? "8pt" : function() { return true; });
 
+const kAbsentFontFamily =
+  function(aFontFamily) { return aFontFamily != "sans-serif"; }
+const kInputFontFamily =
+  function(aFontFamily) { return aFontFamily != "sans-serif"; }
+
+const kMonospaceFontFamily =
+  function(aFontFamily) { return aFontFamily != "monospace"; }
+const kSansSerifFontFamily =
+  function(aFontFamily) { return aFontFamily != "sans-serif"; }
+const kSerifFontFamily =
+  function(aFontFamily) { return aFontFamily != "serif"; }
+
+const kCursiveFontFamily = WIN ? "Comic Sans MS" :
+  (LINUX ? "DejaVu Serif" : "MacFont");
+
+/**
+ * Return used font from the given computed style.
+ */
+function fontFamily(aComputedStyle)
+{
+  var name = aComputedStyle.fontFamily;
+  switch (name) {
+    case "monospace":
+      return kMonospaceFontFamily;
+    case "sans-serif":
+      return kSansSerifFontFamily;
+    case "serif":
+      return kSerifFontFamily;
+    default:
+      return name;
+  }
+}
+
 /**
  * Build an object of default text attributes expected for the given accessible.
  *
  * @param aID          [in] identifier of accessible
  * @param aFontSize    [in] font size
  * @param aFontWeight  [in, optional] kBoldFontWeight or kNormalFontWeight,
  *                      default value is kNormalFontWeight
  */
-function buildDefaultTextAttrs(aID, aFontSize, aFontWeight)
+function buildDefaultTextAttrs(aID, aFontSize, aFontWeight, aFontFamily)
 {
   var elm = getNode(aID);
   var computedStyle = document.defaultView.getComputedStyle(elm, "");
   var bgColor = computedStyle.backgroundColor == "transparent" ?
     "rgb(255, 255, 255)" : computedStyle.backgroundColor;
 
   var defAttrs = {
     "font-style": computedStyle.fontStyle,
     "font-size": aFontSize,
     "background-color": bgColor,
     "font-weight": aFontWeight ? aFontWeight : kNormalFontWeight,
     "color": computedStyle.color,
-    "font-family": computedStyle.fontFamily,
+    "font-family": aFontFamily ? aFontFamily : fontFamily(computedStyle),
     "text-position": computedStyle.verticalAlign
   };
 
   return defAttrs;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // Private.
--- a/accessible/tests/mochitest/attributes/test_text.html
+++ b/accessible/tests/mochitest/attributes/test_text.html
@@ -258,17 +258,17 @@
       testTextAttrs(ID, 45, attrs, defAttrs, 44, 61);
 
       attrs = {};
       testTextAttrs(ID, 62, attrs, defAttrs, 61, 69);
 
       // Walk from span with font-style to the one with font-family.
       tempElem = tempElem.nextSibling.nextSibling;
       gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
-      attrs = { "font-family": gComputedStyle.fontFamily };
+      attrs = { "font-family": kMonospaceFontFamily };
       testTextAttrs(ID, 70, attrs, defAttrs, 69, 83);
 
       attrs = {};
       testTextAttrs(ID, 84, attrs, defAttrs, 83, 91);
 
       attrs = { "text-underline-style": "solid" };
       testTextAttrs(ID, 92, attrs, defAttrs, 91, 101);
 
@@ -276,16 +276,17 @@
       testTextAttrs(ID, 102, attrs, defAttrs, 101, 109);
 
       attrs = { "text-line-through-style": "solid" };
       testTextAttrs(ID, 110, attrs, defAttrs, 109, 122);
 
       attrs = {};
       testTextAttrs(ID, 123, attrs, defAttrs, 122, 130);
 
+      //////////////////////////////////////////////////////////////////////////
       // area10, different single style spans in non-styled paragraph
       ID = "area10";
       defAttrs = buildDefaultTextAttrs(ID, "12pt");
       testDefaultTextAttrs(ID, defAttrs);
 
       attrs = {};
       testTextAttrs(ID, 0, attrs, defAttrs, 0, 7);
 
@@ -311,17 +312,17 @@
       testTextAttrs(ID, 46, attrs, defAttrs, 45, 62);
 
       attrs = {};
       testTextAttrs(ID, 63, attrs, defAttrs, 62, 70);
 
       // Walk from span with font-style to the one with font-family.
       tempElem = tempElem.nextSibling.nextSibling;
       gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
-      attrs = {"font-family": gComputedStyle.fontFamily};
+      attrs = { "font-family": kMonospaceFontFamily };
       testTextAttrs(ID, 71, attrs, defAttrs, 70, 84);
 
       attrs = {};
       testTextAttrs(ID, 85, attrs, defAttrs, 84, 92);
 
       attrs = { "text-underline-style": "solid" };
       testTextAttrs(ID, 93, attrs, defAttrs, 92, 102);
 
@@ -329,16 +330,17 @@
       testTextAttrs(ID, 103, attrs, defAttrs, 102, 110);
 
       attrs = { "text-line-through-style": "solid" };
       testTextAttrs(ID, 111, attrs, defAttrs, 110, 123);
 
       attrs = {};
       testTextAttrs(ID, 124, attrs, defAttrs, 123, 131);
 
+      //////////////////////////////////////////////////////////////////////////
       // area11, "font-weight" tests
       ID = "area11";
       defAttrs = buildDefaultTextAttrs(ID, "12pt", kBoldFontWeight);
       testDefaultTextAttrs(ID, defAttrs);
 
       attrs = { };
       testTextAttrs(ID, 0, attrs, defAttrs, 0, 13);
 
@@ -368,17 +370,18 @@
       //////////////////////////////////////////////////////////////////////////
       // test zero offset on empty hypertext accessibles
       ID = "area13";
       defAttrs = buildDefaultTextAttrs(ID, "12pt");
       attrs = { };
       testTextAttrs(ID, 0, attrs, defAttrs, 0, 0);
 
       ID = "area14";
-      defAttrs = buildDefaultTextAttrs(ID, kInputFontSize);
+      defAttrs = buildDefaultTextAttrs(ID, kInputFontSize,
+                                       kNormalFontWeight, kInputFontFamily);
 
       attrs = { };
       testTextAttrs(ID, 0, attrs, defAttrs, 0, 0);
 
       //////////////////////////////////////////////////////////////////////////
       // area15, embed char tests, "*plain*plain**bold*bold*"
       ID = "area15";
       defAttrs = buildDefaultTextAttrs(ID, "12pt");
@@ -399,29 +402,64 @@
       // p
       testTextAttrs(ID, 18, { }, { }, 18, 19);
       // bold
       attrs = { "font-weight": kBoldFontWeight };
       testTextAttrs(ID, 19, attrs, defAttrs, 19, 23);
       // p
       testTextAttrs(ID, 23, { }, { }, 23, 24);
 
+      //////////////////////////////////////////////////////////////////////////
+      // area16, "font-family" tests
+      ID = "area16";
+      defAttrs = buildDefaultTextAttrs(ID, "12pt");
+      testDefaultTextAttrs(ID, defAttrs);
+
+      attrs = { "font-family": kMonospaceFontFamily };
+      testTextAttrs(ID, 0, attrs, defAttrs, 0, 4);
+
+      attrs = { };
+      testTextAttrs(ID, 4, attrs, defAttrs, 4, 9);
+
+      attrs = { "font-family": kSerifFontFamily };
+      testTextAttrs(ID, 9, attrs, defAttrs, 9, 13);
+
+      attrs = { };
+      testTextAttrs(ID, 13, attrs, defAttrs, 13, 18);
+
+      attrs = { "font-family": kAbsentFontFamily };
+      testTextAttrs(ID, 18, attrs, defAttrs, 18, 22);
+
+      attrs = { };
+      testTextAttrs(ID, 22, attrs, defAttrs, 22, 27);
+
+      attrs = { "font-family": kCursiveFontFamily };
+      testTextAttrs(ID, 27, attrs, defAttrs, 27, 31);
+
+      attrs = { };
+      testTextAttrs(ID, 31, attrs, defAttrs, 31, 45);
+
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 </head>
 <body style="font-size: 12pt">
 
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=345759"
      title="Implement text attributes">
     Mozilla Bug 345759
+  </a><br>
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=473576"
+     title="font-family text attribute should expose actual font used">
+    Mozilla Bug 473576
   </a>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <p id="area1" style="font-size: smaller">Normal <b>Bold</b> Normal</p>
   <p id="area2" style="font-size: 120%">Normal <b>Bold <i>Italic </i>Bold</b> Normal</p>
@@ -464,26 +502,26 @@
       <span style="color: magenta">Magenta<b>Bold</b>Magenta</span>
     </span>
   </p>
 
   <p id="area9" style="font-size: smaller">Small
     <span style="font-size: 120%">bigger</span> smaller
     <span style="background-color: blue;">background blue</span> normal
     <span style="font-style: italic;">Different styling</span> normal
-    <span style="font-family: tahoma;">Different font</span> normal
+    <span style="font-family: monospace;">Different font</span> normal
     <span style="text-decoration: underline;">underlined</span> normal
     <span style="text-decoration: line-through;">strikethrough</span> normal
   </p>
 
   <p id="area10">Normal
     <span style="font-size: 120%">bigger</span> smaller
     <span style="background-color: blue;">background blue</span> normal
     <span style="font-style: italic;">Different styling</span> normal
-    <span style="font-family: tahoma;">Different font</span> normal
+    <span style="font-family: monospace;">Different font</span> normal
     <span style="text-decoration: underline;">underlined</span> normal
     <span style="text-decoration: line-through;">strikethrough</span> normal
   </p>
 
   <p id="area11" style="font-weight: bolder;">
     <span style="font-weight: bolder;">bolder</span>bolder
     <span style="font-weight: lighter;">lighter</span>bolder
     <span style="font-weight: normal;">normal</span>bolder
@@ -495,10 +533,18 @@
   </p>
 
   <p id="area12">hello</p>
   <p id="area13"></p>
   <input id="area14">
 
   <!-- *plain*plain**bold*bold*-->
   <div id="area15"><p>embed</p>plain<p>embed</p>plain<p>embed</p><img src="../moz.png" alt="image"/><b>bold</b><p>embed</p><b>bold</b><p>embed</p></div>
+
+  <p id="area16" style="font-family: sans-serif;">
+    <span style="font-family: monospace;">text</span>text
+    <span style="font-family: serif;">text</span>text
+    <span style="font-family: BodoniThatDoesntExist;">text</span>text
+    <span style="font-family: Comic Sans MS, cursive;">text</span>text
+    <span style="font-family: sans-serif, fantasy;">text</span>text
+  </p>
 </body>
 </html>
--- a/accessible/tests/mochitest/events/test_textattrchange.html
+++ b/accessible/tests/mochitest/events/test_textattrchange.html
@@ -44,17 +44,19 @@
         //var spellchecker = editor.getInlineSpellChecker(true);
         //spellchecker.enableRealTimeSpell = true;
 
         this.DOMNode.value = "valid text inalid tixt";
       }
 
       this.finalCheck = function spelledTextInvoker_finalCheck()
       {
-        var defAttrs = buildDefaultTextAttrs(this.DOMNode, kInputFontSize);
+        var defAttrs = buildDefaultTextAttrs(this.DOMNode, kInputFontSize,
+                                             kNormalFontWeight,
+                                             kInputFontFamily);
         testDefaultTextAttrs(aID, defAttrs);
 
         var attrs = { };
         var misspelledAttrs = {
           "invalid": "spelling"
         };
 
         testTextAttrs(aID, 0, attrs, defAttrs, 0, 11);
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -405,16 +405,20 @@ pref("browser.link.open_newwindow.restri
 // Enable browser frame
 pref("dom.mozBrowserFramesEnabled", true);
 pref("dom.mozBrowserFramesWhitelist", "http://localhost:7777");
 
 // Temporary permission hack for WebSMS
 pref("dom.sms.enabled", true);
 pref("dom.sms.whitelist", "file://,http://localhost:7777");
 
+// Temporary permission hack for WebContacts
+pref("dom.mozContacts.enabled", true);
+pref("dom.mozContacts.whitelist", "http://localhost:7777");
+
 // Ignore X-Frame-Options headers.
 pref("b2g.ignoreXFrameOptions", true);
 
 // controls if we want camera support
 pref("device.camera.enabled", true);
 pref("media.realtime_decoder.enabled", true);
 
 // "Preview" landing of bug 710563, which is bogged down in analysis
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -11,16 +11,17 @@ const CC = Components.Constructor;
 const Cr = Components.results;
 
 const LocalFile = CC('@mozilla.org/file/local;1',
                      'nsILocalFile',
                      'initWithPath');
 
 Cu.import('resource://gre/modules/XPCOMUtils.jsm');
 Cu.import('resource://gre/modules/Services.jsm');
+Cu.import('resource://gre/modules/ContactService.jsm');
 
 XPCOMUtils.defineLazyGetter(Services, 'env', function() {
   return Cc['@mozilla.org/process/environment;1']
            .getService(Ci.nsIEnvironment);
 });
 
 XPCOMUtils.defineLazyGetter(Services, 'ss', function() {
   return Cc['@mozilla.org/content/style-sheet-service;1']
@@ -55,17 +56,17 @@ function startupHttpd(baseDir, port) {
 #endif
 
 // FIXME Bug 707625
 // until we have a proper security model, add some rights to
 // the pre-installed web applications
 // XXX never grant 'content-camera' to non-gaia apps
 function addPermissions(urls) {
   let permissions = [
-    'indexedDB', 'indexedDB-unlimited', 'webapps-manage', 'offline-app', 'content-camera'
+    'indexedDB', 'indexedDB-unlimited', 'webapps-manage', 'offline-app', 'content-camera', 'webcontacts-manage'
   ];
   urls.forEach(function(url) {
     let uri = Services.io.newURI(url, null, null);
     let allow = Ci.nsIPermissionManager.ALLOW_ACTION;
 
     permissions.forEach(function(permission) {
       Services.perms.add(uri, permission, allow);
     });
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -150,16 +150,17 @@
 @BINPATH@/components/dom_wifi.xpt
 @BINPATH@/components/dom_system_b2g.xpt
 #endif
 @BINPATH@/components/dom_battery.xpt
 #ifdef MOZ_B2G_BT
 @BINPATH@/components/dom_bluetooth.xpt
 #endif
 @BINPATH@/components/dom_canvas.xpt
+@BINPATH@/components/dom_contacts.xpt
 @BINPATH@/components/dom_core.xpt
 @BINPATH@/components/dom_css.xpt
 @BINPATH@/components/dom_events.xpt
 @BINPATH@/components/dom_geolocation.xpt
 @BINPATH@/components/dom_network.xpt
 @BINPATH@/components/dom_notification.xpt
 @BINPATH@/components/dom_html.xpt
 @BINPATH@/components/dom_indexeddb.xpt
@@ -289,16 +290,18 @@
 @BINPATH@/components/xuldoc.xpt
 @BINPATH@/components/xultmpl.xpt
 @BINPATH@/components/zipwriter.xpt
 @BINPATH@/components/webapps.xpt
 
 ; JavaScript components
 @BINPATH@/components/ConsoleAPI.manifest
 @BINPATH@/components/ConsoleAPI.js
+@BINPATH@/components/ContactManager.js
+@BINPATH@/components/ContactManager.manifest
 @BINPATH@/components/FeedProcessor.manifest
 @BINPATH@/components/FeedProcessor.js
 @BINPATH@/components/BrowserFeeds.manifest
 @BINPATH@/components/FeedConverter.js
 @BINPATH@/components/FeedWriter.js
 @BINPATH@/components/fuelApplication.manifest
 @BINPATH@/components/fuelApplication.js
 @BINPATH@/components/WebContentConverter.js
--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -96,35 +96,35 @@ var StarUI = {
       case "popuphidden":
         if (aEvent.originalTarget == this.panel) {
           if (!this._element("editBookmarkPanelContent").hidden)
             this.quitEditMode();
 
           this._restoreCommandsState();
           this._itemId = -1;
           if (this._batching) {
-            PlacesUIUtils.ptm.endBatch();
+            PlacesUtils.transactionManager.endBatch();
             this._batching = false;
           }
 
           switch (this._actionOnHide) {
             case "cancel": {
-              PlacesUIUtils.ptm.undoTransaction();
+              PlacesUtils.transactionManager.undoTransaction();
               break;
             }
             case "remove": {
               // Remove all bookmarks for the bookmark's url, this also removes
               // the tags for the url.
-              PlacesUIUtils.ptm.beginBatch();
+              PlacesUtils.transactionManager.beginBatch();
               let itemIds = PlacesUtils.getBookmarksForURI(this._uriForRemoval);
               for (let i = 0; i < itemIds.length; i++) {
-                let txn = PlacesUIUtils.ptm.removeItem(itemIds[i]);
-                PlacesUIUtils.ptm.doTransaction(txn);
+                let txn = new PlacesRemoveItemTransaction(itemIds[i]);
+                PlacesUtils.transactionManager.doTransaction(txn);
               }
-              PlacesUIUtils.ptm.endBatch();
+              PlacesUtils.transactionManager.endBatch();
               break;
             }
           }
           this._actionOnHide = "";
         }
         break;
       case "keypress":
         if (aEvent.defaultPrevented) {
@@ -270,17 +270,17 @@ var StarUI = {
   removeBookmarkButtonCommand: function SU_removeBookmarkButtonCommand() {
     this._uriForRemoval = PlacesUtils.bookmarks.getBookmarkURI(this._itemId);
     this._actionOnHide = "remove";
     this.panel.hidePopup();
   },
 
   beginBatch: function SU_beginBatch() {
     if (!this._batching) {
-      PlacesUIUtils.ptm.beginBatch();
+      PlacesUtils.transactionManager.beginBatch();
       this._batching = true;
     }
   }
 }
 
 var PlacesCommandHook = {
   /**
    * Adds a bookmark to the page loaded in the given browser.
@@ -320,19 +320,20 @@ var PlacesCommandHook = {
         // but open right into the "edit" state, start batching here, so
         // "Cancel" in that state removes the bookmark.
         StarUI.beginBatch();
       }
 
       var parent = aParent != undefined ?
                    aParent : PlacesUtils.unfiledBookmarksFolderId;
       var descAnno = { name: PlacesUIUtils.DESCRIPTION_ANNO, value: description };
-      var txn = PlacesUIUtils.ptm.createItem(uri, parent, -1,
-                                             title, null, [descAnno]);
-      PlacesUIUtils.ptm.doTransaction(txn);
+      var txn = new PlacesCreateBookmarkTransaction(uri, parent, 
+                                                    PlacesUtils.bookmarks.DEFAULT_INDEX,
+                                                    title, null, [descAnno]);
+      PlacesUtils.transactionManager.doTransaction(txn);
       // Set the character-set
       if (charset)
         PlacesUtils.history.setCharsetForURI(uri, charset);
       itemId = PlacesUtils.getMostRecentBookmarkForURI(uri);
     }
 
     // Revert the contents of the location bar
     if (gURLBar)
--- a/browser/base/content/browser-syncui.js
+++ b/browser/base/content/browser-syncui.js
@@ -286,41 +286,41 @@ let gSyncUI = {
    *          "reset" -- reset sync
    */
 
   openSetup: function SUI_openSetup(wizardType) {
     let win = Services.wm.getMostRecentWindow("Weave:AccountSetup");
     if (win)
       win.focus();
     else {
-      window.openDialog("chrome://browser/content/syncSetup.xul",
+      window.openDialog("chrome://browser/content/sync/setup.xul",
                         "weaveSetup", "centerscreen,chrome,resizable=no",
                         wizardType);
     }
   },
 
   openAddDevice: function () {
     if (!Weave.Utils.ensureMPUnlocked())
       return;
 
     let win = Services.wm.getMostRecentWindow("Sync:AddDevice");
     if (win)
       win.focus();
     else
-      window.openDialog("chrome://browser/content/syncAddDevice.xul",
+      window.openDialog("chrome://browser/content/sync/addDevice.xul",
                         "syncAddDevice", "centerscreen,chrome,resizable=no");
   },
 
   openQuotaDialog: function SUI_openQuotaDialog() {
     let win = Services.wm.getMostRecentWindow("Sync:ViewQuota");
     if (win)
       win.focus();
     else
       Services.ww.activeWindow.openDialog(
-        "chrome://browser/content/syncQuota.xul", "",
+        "chrome://browser/content/sync/quota.xul", "",
         "centerscreen,chrome,dialog,modal");
   },
 
   openPrefs: function SUI_openPrefs() {
     openPreferences("paneSync");
   },
 
 
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -324,22 +324,22 @@ window[chromehidden~="toolbar"] toolbar:
 #status-bar ,
 #mainPopupSet {
   min-width: 1px;
 }
 
 %ifdef MOZ_SERVICES_SYNC
 /* Sync notification UI */
 #sync-notifications {
-  -moz-binding: url("chrome://browser/content/syncNotification.xml#notificationbox");
+  -moz-binding: url("chrome://browser/content/sync/notification.xml#notificationbox");
   overflow-y: visible !important;
 }
 
 #sync-notifications notification {
-  -moz-binding: url("chrome://browser/content/syncNotification.xml#notification");
+  -moz-binding: url("chrome://browser/content/sync/notification.xml#notification");
 }
 %endif
 
 /* Identity UI */
 #identity-popup-content-box.unknownIdentity > #identity-popup-connectedToLabel ,
 #identity-popup-content-box.unknownIdentity > #identity-popup-runByLabel ,
 #identity-popup-content-box.unknownIdentity > #identity-popup-content-host ,
 #identity-popup-content-box.unknownIdentity > #identity-popup-content-owner ,
--- a/browser/base/content/overrides/app-license.html
+++ b/browser/base/content/overrides/app-license.html
@@ -1,3 +1,3 @@
     <p><b>Binaries</b> of this product have been made available to you by the
     <a href="http://www.mozilla.org/">Mozilla Project</a> under the Mozilla
-    Public License. <a href="about:rights">Know your rights</a>.</p>
+    Public License 2.0 (MPL). <a href="about:rights">Know your rights</a>.</p>
rename from browser/base/content/aboutSyncTabs-bindings.xml
rename to browser/base/content/sync/aboutSyncTabs-bindings.xml
rename from browser/base/content/aboutSyncTabs.css
rename to browser/base/content/sync/aboutSyncTabs.css
--- a/browser/base/content/aboutSyncTabs.css
+++ b/browser/base/content/sync/aboutSyncTabs.css
@@ -1,7 +1,7 @@
 richlistitem[type="tab"] {
-  -moz-binding: url(chrome://browser/content/aboutSyncTabs-bindings.xml#tab-listing);
+  -moz-binding: url(chrome://browser/content/sync/aboutSyncTabs-bindings.xml#tab-listing);
 }
 
 richlistitem[type="client"] {
-  -moz-binding: url(chrome://browser/content/aboutSyncTabs-bindings.xml#client-listing);
+  -moz-binding: url(chrome://browser/content/sync/aboutSyncTabs-bindings.xml#client-listing);
 }
rename from browser/base/content/aboutSyncTabs.js
rename to browser/base/content/sync/aboutSyncTabs.js
rename from browser/base/content/aboutSyncTabs.xul
rename to browser/base/content/sync/aboutSyncTabs.xul
--- a/browser/base/content/aboutSyncTabs.xul
+++ b/browser/base/content/sync/aboutSyncTabs.xul
@@ -35,30 +35,30 @@
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
 <?xml-stylesheet href="chrome://browser/skin/" type="text/css"?>
 <?xml-stylesheet href="chrome://browser/skin/aboutSyncTabs.css" type="text/css"?>
-<?xml-stylesheet href="chrome://browser/content/aboutSyncTabs.css" type="text/css"?>
+<?xml-stylesheet href="chrome://browser/content/sync/aboutSyncTabs.css" type="text/css"?>
 
 <!DOCTYPE window [
   <!ENTITY % aboutSyncTabsDTD SYSTEM "chrome://browser/locale/aboutSyncTabs.dtd">
   %aboutSyncTabsDTD;
 ]>
 
 <window id="tabs-display"
         onload="RemoteTabViewer.init()"
         onunload="RemoteTabViewer.uninit()"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         xmlns:html="http://www.w3.org/1999/xhtml"
         title="&tabs.otherComputers.label;">
-  <script type="application/javascript;version=1.8" src="chrome://browser/content/aboutSyncTabs.js"/>
+  <script type="application/javascript;version=1.8" src="chrome://browser/content/sync/aboutSyncTabs.js"/>
   <script type="application/javascript" src="chrome://browser/content/utilityOverlay.js"/>
   <html:head>
     <html:link rel="icon" href="chrome://browser/skin/sync-16.png"/>
   </html:head>
 
   <popupset id="contextmenus">
     <menupopup id="tabListContext">
       <menuitem label="&tabs.context.openTab.label;"
rename from browser/base/content/syncAddDevice.js
rename to browser/base/content/sync/addDevice.js
rename from browser/base/content/syncAddDevice.xul
rename to browser/base/content/sync/addDevice.xul
--- a/browser/base/content/syncAddDevice.xul
+++ b/browser/base/content/sync/addDevice.xul
@@ -56,19 +56,19 @@
         windowtype="Sync:AddDevice"
         persist="screenX screenY"
         onwizardnext="return gSyncAddDevice.onWizardAdvance();"
         onwizardback="return gSyncAddDevice.onWizardBack();"
         onwizardcancel="gSyncAddDevice.onWizardCancel();"
         onload="gSyncAddDevice.init();">
 
   <script type="application/javascript"
-          src="chrome://browser/content/syncAddDevice.js"/>
+          src="chrome://browser/content/sync/addDevice.js"/>
   <script type="application/javascript"
-          src="chrome://browser/content/syncUtils.js"/>
+          src="chrome://browser/content/sync/utils.js"/>
   <script type="application/javascript"
           src="chrome://browser/content/utilityOverlay.js"/>
   <script type="application/javascript"
           src="chrome://global/content/printUtils.js"/>
 
   <wizardpage id="addDevicePage"
               label="&pairDevice.title.label;"
               onpageshow="gSyncAddDevice.onPageShow();">
rename from browser/base/content/syncGenericChange.js
rename to browser/base/content/sync/genericChange.js
rename from browser/base/content/syncGenericChange.xul
rename to browser/base/content/sync/genericChange.xul
--- a/browser/base/content/syncGenericChange.xul
+++ b/browser/base/content/sync/genericChange.xul
@@ -55,19 +55,19 @@
         xmlns:html="http://www.w3.org/1999/xhtml"
         id="change-dialog"
         windowtype="Weave:ChangeSomething"
         persist="screenX screenY"
         onwizardnext="Change.onLoad()"
         onwizardfinish="return Change.onDialogAccept();">
 
   <script type="application/javascript"
-          src="chrome://browser/content/syncGenericChange.js"/>
+          src="chrome://browser/content/sync/genericChange.js"/>
   <script type="application/javascript"
-          src="chrome://browser/content/syncUtils.js"/>
+          src="chrome://browser/content/sync/utils.js"/>
   <script type="application/javascript"
           src="chrome://global/content/printUtils.js"/>
 
   <wizardpage id="change-page"
               label="">
 
     <description id="introText">
     </description>
rename from browser/base/content/syncKey.xhtml
rename to browser/base/content/sync/key.xhtml
rename from browser/base/content/syncNotification.xml
rename to browser/base/content/sync/notification.xml
rename from browser/base/content/syncProgress.js
rename to browser/base/content/sync/progress.js
rename from browser/base/content/syncProgress.xhtml
rename to browser/base/content/sync/progress.xhtml
--- a/browser/base/content/syncProgress.xhtml
+++ b/browser/base/content/sync/progress.xhtml
@@ -56,17 +56,17 @@
 
     <link rel="stylesheet" type="text/css" media="all"
           href="chrome://browser/skin/syncProgress.css"/>
 
     <link rel="icon" type="image/png" id="favicon"
           href="chrome://browser/skin/sync-16.png"/>
 
     <script type="text/javascript;version=1.8"
-            src="chrome://browser/content/syncProgress.js"/>
+            src="chrome://browser/content/sync/progress.js"/>
   </head>
   <body onload="onLoad(event)" onunload="onUnload(event)">
     <title>&setup.successPage.title;</title>
     <div id="floatingBox" class="main-content">
       <div id="title">
         <h1>&setup.successPage.title;</h1>
       </div>
       <div id="successLogo">
rename from browser/base/content/syncQuota.js
rename to browser/base/content/sync/quota.js
rename from browser/base/content/syncQuota.xul
rename to browser/base/content/sync/quota.xul
--- a/browser/base/content/syncQuota.xul
+++ b/browser/base/content/sync/quota.xul
@@ -55,17 +55,17 @@
         xmlns:html="http://www.w3.org/1999/xhtml"
         onload="gSyncQuota.init()"
         buttons="accept,cancel"
         title="&quota.dialogTitle.label;"
         ondialogcancel="return gSyncQuota.onCancel();"
         ondialogaccept="return gSyncQuota.onAccept();">
 
   <script type="application/javascript"
-          src="chrome://browser/content/syncQuota.js"/>
+          src="chrome://browser/content/sync/quota.js"/>
 
   <stringbundleset id="stringbundleset">
     <stringbundle id="quotaStrings"
                   src="chrome://browser/locale/syncQuota.properties"/>
   </stringbundleset>
 
   <vbox flex="1">
     <label id="usageLabel"
rename from browser/base/content/syncSetup.js
rename to browser/base/content/sync/setup.js
rename from browser/base/content/syncSetup.xul
rename to browser/base/content/sync/setup.xul
--- a/browser/base/content/syncSetup.xul
+++ b/browser/base/content/sync/setup.xul
@@ -60,19 +60,19 @@
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         xmlns:html="http://www.w3.org/1999/xhtml"
         onwizardnext="return gSyncSetup.onWizardAdvance()"
         onwizardback="return gSyncSetup.onWizardBack()"
         onwizardcancel="gSyncSetup.onWizardCancel()"
         onload="gSyncSetup.init()">
 
   <script type="application/javascript"
-          src="chrome://browser/content/syncSetup.js"/>
+          src="chrome://browser/content/sync/setup.js"/>
   <script type="application/javascript"
-          src="chrome://browser/content/syncUtils.js"/>
+          src="chrome://browser/content/sync/utils.js"/>
   <script type="application/javascript"
           src="chrome://browser/content/utilityOverlay.js"/>
   <script type="application/javascript"
           src="chrome://global/content/printUtils.js"/>
 
   <wizardpage id="addDevicePage"
               label="&pairDevice.title.label;"
               onpageshow="gSyncSetup.onPageShow()">
rename from browser/base/content/syncUtils.js
rename to browser/base/content/sync/utils.js
--- a/browser/base/content/syncUtils.js
+++ b/browser/base/content/sync/utils.js
@@ -71,17 +71,17 @@ let gSyncUtils = {
     // Just re-show the dialog if it's already open
     let openedDialog = Services.wm.getMostRecentWindow("Sync:" + type);
     if (openedDialog != null) {
       openedDialog.focus();
       return;
     }
 
     // Open up the change dialog
-    let changeXUL = "chrome://browser/content/syncGenericChange.xul";
+    let changeXUL = "chrome://browser/content/sync/genericChange.xul";
     let changeOpt = "centerscreen,chrome,resizable=no";
     Services.ww.activeWindow.openDialog(changeXUL, "", changeOpt,
                                         type, duringSetup);
   },
 
   changePassword: function () {
     if (Weave.Utils.ensureMPUnlocked())
       this.openChange("ChangePassword");
@@ -120,17 +120,17 @@ let gSyncUtils = {
    * @param elid : ID of the form element containing the passphrase.
    * @param callback : Function called once the iframe has loaded.
    */
   _preparePPiframe: function(elid, callback) {
     let pp = document.getElementById(elid).value;
 
     // Create an invisible iframe whose contents we can print.
     let iframe = document.createElement("iframe");
-    iframe.setAttribute("src", "chrome://browser/content/syncKey.xhtml");
+    iframe.setAttribute("src", "chrome://browser/content/sync/key.xhtml");
     iframe.collapsed = true;
     document.documentElement.appendChild(iframe);
     iframe.contentWindow.addEventListener("load", function() {
       iframe.contentWindow.removeEventListener("load", arguments.callee, false);
 
       // Insert the Sync Key into the page.
       let el = iframe.contentDocument.getElementById("synckey");
       el.firstChild.nodeValue = pp;
--- a/browser/base/jar.mn
+++ b/browser/base/jar.mn
@@ -36,51 +36,51 @@ browser.jar:
 *       content/browser/pageinfo/pageInfo.xul         (content/pageinfo/pageInfo.xul)
 *       content/browser/pageinfo/pageInfo.js          (content/pageinfo/pageInfo.js)
 *       content/browser/pageinfo/pageInfo.css         (content/pageinfo/pageInfo.css)
 *       content/browser/pageinfo/pageInfo.xml         (content/pageinfo/pageInfo.xml)
 *       content/browser/pageinfo/feeds.js             (content/pageinfo/feeds.js)
 *       content/browser/pageinfo/feeds.xml            (content/pageinfo/feeds.xml)
 *       content/browser/pageinfo/permissions.js       (content/pageinfo/permissions.js)
 *       content/browser/pageinfo/security.js          (content/pageinfo/security.js)
+#ifdef MOZ_SERVICES_SYNC
+*       content/browser/sync/aboutSyncTabs.xul        (content/sync/aboutSyncTabs.xul)
+        content/browser/sync/aboutSyncTabs.js         (content/sync/aboutSyncTabs.js)
+        content/browser/sync/aboutSyncTabs.css        (content/sync/aboutSyncTabs.css)
+*       content/browser/sync/aboutSyncTabs-bindings.xml  (content/sync/aboutSyncTabs-bindings.xml)
+*       content/browser/sync/setup.xul                (content/sync/setup.xul)
+        content/browser/sync/addDevice.js             (content/sync/addDevice.js)
+*       content/browser/sync/addDevice.xul            (content/sync/addDevice.xul)
+        content/browser/sync/setup.js                 (content/sync/setup.js)
+*       content/browser/sync/genericChange.xul        (content/sync/genericChange.xul)
+        content/browser/sync/genericChange.js         (content/sync/genericChange.js)
+*       content/browser/sync/key.xhtml                (content/sync/key.xhtml)
+*       content/browser/sync/notification.xml         (content/sync/notification.xml)
+*       content/browser/sync/quota.xul                (content/sync/quota.xul)
+        content/browser/sync/quota.js                 (content/sync/quota.js)
+        content/browser/sync/utils.js                 (content/sync/utils.js)
+        content/browser/sync/progress.js              (content/sync/progress.js)
+*       content/browser/sync/progress.xhtml           (content/sync/progress.xhtml)
+#endif
 *       content/browser/openLocation.js               (content/openLocation.js)
 *       content/browser/openLocation.xul              (content/openLocation.xul)
 *       content/browser/safeMode.js                   (content/safeMode.js)
 *       content/browser/safeMode.xul                  (content/safeMode.xul)
 *       content/browser/sanitize.js                   (content/sanitize.js)
 *       content/browser/sanitize.xul                  (content/sanitize.xul)
 *       content/browser/sanitizeDialog.js             (content/sanitizeDialog.js)
         content/browser/sanitizeDialog.css            (content/sanitizeDialog.css)
 *       content/browser/tabbrowser.css                (content/tabbrowser.css)
 *       content/browser/tabbrowser.xml                (content/tabbrowser.xml)
 *       content/browser/urlbarBindings.xml            (content/urlbarBindings.xml)
 *       content/browser/utilityOverlay.js             (content/utilityOverlay.js)
 *       content/browser/web-panels.js                 (content/web-panels.js)
 *       content/browser/web-panels.xul                (content/web-panels.xul)
 *       content/browser/baseMenuOverlay.xul           (content/baseMenuOverlay.xul)
 *       content/browser/nsContextMenu.js              (content/nsContextMenu.js)
-#ifdef MOZ_SERVICES_SYNC
-*       content/browser/aboutSyncTabs.xul             (content/aboutSyncTabs.xul)
-        content/browser/aboutSyncTabs.js              (content/aboutSyncTabs.js)
-        content/browser/aboutSyncTabs.css             (content/aboutSyncTabs.css)
-*       content/browser/aboutSyncTabs-bindings.xml    (content/aboutSyncTabs-bindings.xml)
-*       content/browser/syncSetup.xul                 (content/syncSetup.xul)
-        content/browser/syncAddDevice.js              (content/syncAddDevice.js)
-*       content/browser/syncAddDevice.xul             (content/syncAddDevice.xul)
-        content/browser/syncSetup.js                  (content/syncSetup.js)
-*       content/browser/syncGenericChange.xul         (content/syncGenericChange.xul)
-        content/browser/syncGenericChange.js          (content/syncGenericChange.js)
-*       content/browser/syncKey.xhtml                 (content/syncKey.xhtml)
-*       content/browser/syncNotification.xml          (content/syncNotification.xml)
-*       content/browser/syncQuota.xul                 (content/syncQuota.xul)
-        content/browser/syncQuota.js                  (content/syncQuota.js)
-        content/browser/syncUtils.js                  (content/syncUtils.js)
-        content/browser/syncProgress.js               (content/syncProgress.js)
-*       content/browser/syncProgress.xhtml            (content/syncProgress.xhtml)
-#endif
 # XXX: We should exclude this one as well (bug 71895)
 *       content/browser/hiddenWindow.xul              (content/hiddenWindow.xul)
 #ifdef XP_MACOSX
 *       content/browser/macBrowserOverlay.xul         (content/macBrowserOverlay.xul)
 *       content/browser/downloadManagerOverlay.xul    (content/downloadManagerOverlay.xul)
 *       content/browser/jsConsoleOverlay.xul          (content/jsConsoleOverlay.xul)
 *       content/browser/softwareUpdateOverlay.xul  (content/softwareUpdateOverlay.xul)
 #endif
--- a/browser/components/about/AboutRedirector.cpp
+++ b/browser/components/about/AboutRedirector.cpp
@@ -92,19 +92,19 @@ static RedirEntry kRedirMap[] = {
     nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
     nsIAboutModule::ALLOW_SCRIPT },
   { "robots", "chrome://browser/content/aboutRobots.xhtml",
     nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
     nsIAboutModule::ALLOW_SCRIPT },
   { "sessionrestore", "chrome://browser/content/aboutSessionRestore.xhtml",
     nsIAboutModule::ALLOW_SCRIPT },
 #ifdef MOZ_SERVICES_SYNC
-  { "sync-progress", "chrome://browser/content/syncProgress.xhtml",
+  { "sync-progress", "chrome://browser/content/sync/progress.xhtml",
     nsIAboutModule::ALLOW_SCRIPT },
-  { "sync-tabs", "chrome://browser/content/aboutSyncTabs.xul",
+  { "sync-tabs", "chrome://browser/content/sync/aboutSyncTabs.xul",
     nsIAboutModule::ALLOW_SCRIPT },
 #endif
   { "home", "chrome://browser/content/aboutHome.xhtml",
     nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
     nsIAboutModule::ALLOW_SCRIPT },
   { "newtab", "chrome://browser/content/newtab/newTab.xul",
     nsIAboutModule::ALLOW_SCRIPT },
   { "permissions", "chrome://browser/content/preferences/aboutPermissions.xul",
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -1,8 +1,9 @@
+# -*- indent-tabs-mode: nil -*-
 # ***** BEGIN LICENSE BLOCK *****
 # Version: MPL 1.1/GPL 2.0/LGPL 2.1
 #
 # The contents of this file are subject to the Mozilla Public License Version
 # 1.1 (the "License"); you may not use this file except in compliance with
 # the License. You may obtain a copy of the License at
 # http://www.mozilla.org/MPL/
 #
@@ -769,51 +770,94 @@ BrowserGlue.prototype = {
 
 #ifdef MOZ_TELEMETRY_REPORTING
   _showTelemetryNotification: function BG__showTelemetryNotification() {
     const PREF_TELEMETRY_PROMPTED = "toolkit.telemetry.prompted";
     const PREF_TELEMETRY_ENABLED  = "toolkit.telemetry.enabled";
     const PREF_TELEMETRY_REJECTED  = "toolkit.telemetry.rejected";
     const PREF_TELEMETRY_INFOURL  = "toolkit.telemetry.infoURL";
     const PREF_TELEMETRY_SERVER_OWNER = "toolkit.telemetry.server_owner";
+    const PREF_TELEMETRY_ENABLED_BY_DEFAULT = "toolkit.telemetry.enabledByDefault";
+    const PREF_TELEMETRY_NOTIFIED_OPTOUT = "toolkit.telemetry.notifiedOptOut";
     // This is used to reprompt users when privacy message changes
     const TELEMETRY_PROMPT_REV = 2;
 
-    function appendTelemetryNotification(notifyBox, message, buttons, hideclose) {
+    // Stick notifications onto the selected tab of the active browser window.
+    var win = this.getMostRecentBrowserWindow();
+    var tabbrowser = win.gBrowser;
+    var notifyBox = tabbrowser.getNotificationBox();
+
+    var browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
+    var brandBundle = Services.strings.createBundle("chrome://branding/locale/brand.properties");
+    var productName = brandBundle.GetStringFromName("brandFullName");
+    var serverOwner = Services.prefs.getCharPref(PREF_TELEMETRY_SERVER_OWNER);
+
+    function appendTelemetryNotification(message, buttons, hideclose) {
       let notification = notifyBox.appendNotification(message, "telemetry", null,
-						      notifyBox.PRIORITY_INFO_LOW,
-						      buttons);
-      notification.setAttribute("hideclose", hideclose);
+                                                      notifyBox.PRIORITY_INFO_LOW,
+                                                      buttons);
+      if (hideclose)
+        notification.setAttribute("hideclose", hideclose);
       notification.persistence = -1;  // Until user closes it
       return notification;
     }
 
+    function appendLearnMoreLink(notification) {
+      let XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+      let link = notification.ownerDocument.createElementNS(XULNS, "label");
+      link.className = "text-link telemetry-text-link";
+      link.setAttribute("value", browserBundle.GetStringFromName("telemetryLinkLabel"));
+      let description = notification.ownerDocument.getAnonymousElementByAttribute(notification, "anonid", "messageText");
+      description.appendChild(link);
+      return link;
+    }
+
+    var telemetryEnabledByDefault = false;
+    try {
+      telemetryEnabledByDefault = Services.prefs.getBoolPref(PREF_TELEMETRY_ENABLED_BY_DEFAULT);
+    } catch(e) {}
+    if (telemetryEnabledByDefault) {
+      var telemetryNotifiedOptOut = false;
+      try {
+        telemetryNotifiedOptOut = Services.prefs.getBoolPref(PREF_TELEMETRY_NOTIFIED_OPTOUT);
+      } catch(e) {}
+      if (telemetryNotifiedOptOut)
+        return;
+
+      var telemetryPrompt = browserBundle.formatStringFromName("telemetryOptOutPrompt",
+                                                               [productName, serverOwner, productName], 3);
+
+      Services.prefs.setBoolPref(PREF_TELEMETRY_NOTIFIED_OPTOUT, true);
+
+      let notification = appendTelemetryNotification(telemetryPrompt, null, false);
+      let link = appendLearnMoreLink(notification);
+      link.addEventListener('click', function() {
+        // Open the learn more url in a new tab
+        let url = Services.urlFormatter.formatURLPref("app.support.baseURL");
+        url += "how-can-i-help-submitting-performance-data";
+        tabbrowser.selectedTab = tabbrowser.addTab(url);
+        // Remove the notification on which the user clicked
+        notification.parentNode.removeNotification(notification, true);
+      }, false);
+      return;
+    }
+
     var telemetryPrompted = null;
     try {
       telemetryPrompted = Services.prefs.getIntPref(PREF_TELEMETRY_PROMPTED);
     } catch(e) {}
     // If the user has seen the latest telemetry prompt, do not prompt again
     // else clear old prefs and reprompt
     if (telemetryPrompted === TELEMETRY_PROMPT_REV)
       return;
     
     Services.prefs.clearUserPref(PREF_TELEMETRY_PROMPTED);
     Services.prefs.clearUserPref(PREF_TELEMETRY_ENABLED);
     
-    // Stick the notification onto the selected tab of the active browser window.
-    var win = this.getMostRecentBrowserWindow();
-    var browser = win.gBrowser; // for closure in notification bar callback
-    var notifyBox = browser.getNotificationBox();
-
-    var browserBundle   = Services.strings.createBundle("chrome://browser/locale/browser.properties");
-    var brandBundle     = Services.strings.createBundle("chrome://branding/locale/brand.properties");
-
-    var productName        = brandBundle.GetStringFromName("brandFullName");
-    var serverOwner        = Services.prefs.getCharPref(PREF_TELEMETRY_SERVER_OWNER);
-    var telemetryPrompt    = browserBundle.formatStringFromName("telemetryPrompt", [productName, serverOwner], 2);
+    var telemetryPrompt = browserBundle.formatStringFromName("telemetryPrompt", [productName, serverOwner], 2);
 
     var buttons = [
                     {
                       label:     browserBundle.GetStringFromName("telemetryYesButtonLabel2"),
                       accessKey: browserBundle.GetStringFromName("telemetryYesButtonAccessKey"),
                       popup:     null,
                       callback:  function(aNotificationBar, aButton) {
                         Services.prefs.setBoolPref(PREF_TELEMETRY_ENABLED, true);
@@ -827,33 +871,27 @@ BrowserGlue.prototype = {
                         Services.prefs.setBoolPref(PREF_TELEMETRY_REJECTED, true);
                       }
                     }
                   ];
 
     // Set pref to indicate we've shown the notification.
     Services.prefs.setIntPref(PREF_TELEMETRY_PROMPTED, TELEMETRY_PROMPT_REV);
 
-    let notification = appendTelemetryNotification(notifyBox, telemetryPrompt,
-						   buttons, true);
-    let XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
-    let link = notification.ownerDocument.createElementNS(XULNS, "label");
-    link.className = "text-link telemetry-text-link";
-    link.setAttribute("value", browserBundle.GetStringFromName("telemetryLinkLabel"));
+    let notification = appendTelemetryNotification(telemetryPrompt, buttons, true);
+    let link = appendLearnMoreLink(notification);
     link.addEventListener('click', function() {
       // Open the learn more url in a new tab
-      browser.selectedTab = browser.addTab(Services.prefs.getCharPref(PREF_TELEMETRY_INFOURL));
+      tabbrowser.selectedTab = tabbrowser.addTab(Services.prefs.getCharPref(PREF_TELEMETRY_INFOURL));
       // Remove the notification on which the user clicked
       notification.parentNode.removeNotification(notification, true);
       // Add a new notification to that tab, with no "Learn more" link
-      notifyBox = browser.getNotificationBox();
-      appendTelemetryNotification(notifyBox, telemetryPrompt, buttons, true);
+      notifyBox = tabbrowser.getNotificationBox();
+      appendTelemetryNotification(telemetryPrompt, buttons, true);
     }, false);
-    let description = notification.ownerDocument.getAnonymousElementByAttribute(notification, "anonid", "messageText");
-    description.appendChild(link);
   },
 #endif
 
   _showPluginUpdatePage: function BG__showPluginUpdatePage() {
     Services.prefs.setBoolPref(PREF_PLUGINS_NOTIFYUSER, false);
 
     var formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"].
                     getService(Ci.nsIURLFormatter);
--- a/browser/components/places/content/bookmarkProperties.js
+++ b/browser/components/places/content/bookmarkProperties.js
@@ -431,25 +431,25 @@ var BookmarkPropertiesPanel = {
         break;
     }
   },
 
   _beginBatch: function BPP__beginBatch() {
     if (this._batching)
       return;
 
-    PlacesUIUtils.ptm.beginBatch();
+    PlacesUtils.transactionManager.beginBatch();
     this._batching = true;
   },
 
   _endBatch: function BPP__endBatch() {
     if (!this._batching)
       return;
 
-    PlacesUIUtils.ptm.endBatch();
+    PlacesUtils.transactionManager.endBatch();
     this._batching = false;
   },
 
   _fillEditProperties: function BPP__fillEditProperties() {
     gEditItemOverlay.initPanel(this._itemId,
                                { hiddenRows: this._hiddenRows,
                                  forceReadOnly: this._readOnly });
   },
@@ -509,17 +509,17 @@ var BookmarkPropertiesPanel = {
 
   onDialogCancel: function BPP_onDialogCancel() {
     // The order here is important! We have to uninit the panel first, otherwise
     // changes done as part of Undo may change the panel contents and by
     // that force it to commit more transactions.
     gEditItemOverlay.uninitPanel(true);
     gEditItemOverlay = null;
     this._endBatch();
-    PlacesUIUtils.ptm.undoTransaction();
+    PlacesUtils.transactionManager.undoTransaction();
     window.arguments[0].performed = false;
   },
 
   /**
    * This method checks to see if the input fields are in a valid state.
    *
    * @returns  true if the input is valid, false otherwise
    */
@@ -572,54 +572,69 @@ var BookmarkPropertiesPanel = {
    * various fields and opening arguments of the dialog.
    */
   _getCreateNewBookmarkTransaction:
   function BPP__getCreateNewBookmarkTransaction(aContainer, aIndex) {
     var annotations = [];
     var childTransactions = [];
 
     if (this._description) {
-      childTransactions.push(
-        PlacesUIUtils.ptm.editItemDescription(-1, this._description));
+      let annoObj = { name   : PlacesUIUtils.DESCRIPTION_ANNO,
+                      type   : Ci.nsIAnnotationService.TYPE_STRING,
+                      flags  : 0,
+                      value  : this._description,
+                      expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
+      let editItemTxn = new PlacesSetItemAnnotationTransaction(-1, annoObj);
+      childTransactions.push(editItemTxn);
     }
 
     if (this._loadInSidebar) {
-      childTransactions.push(
-        PlacesUIUtils.ptm.setLoadInSidebar(-1, this._loadInSidebar));
+      let annoObj = { name   : PlacesUIUtils.LOAD_IN_SIDEBAR_ANNO,
+                      type   : Ci.nsIAnnotationService.TYPE_INT32,
+                      flags  : 0,
+                      value  : this._loadInSidebar,
+                      expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
+      let setLoadTxn = new PlacesSetItemAnnotationTransaction(-1, annoObj);
+      childTransactions.push(setLoadTxn);
     }
 
     if (this._postData) {
-      childTransactions.push(
-        PlacesUIUtils.ptm.editBookmarkPostData(-1, this._postData));
+      let postDataTxn = new PlacesEditBookmarkPostDataTransaction(-1, this._postData);
+      childTransactions.push(postDataTxn);
     }
 
     //XXX TODO: this should be in a transaction!
     if (this._charSet)
       PlacesUtils.history.setCharsetForURI(this._uri, this._charSet);
 
-    var transactions = [PlacesUIUtils.ptm.createItem(this._uri,
-                                                     aContainer, aIndex,
-                                                     this._title, this._keyword,
-                                                     annotations,
-                                                     childTransactions)];
+    let createTxn = new PlacesCreateBookmarkTransaction(this._uri,
+                                                        aContainer,
+                                                        aIndex,
+                                                        this._title,
+                                                        this._keyword,
+                                                        annotations,
+                                                        childTransactions);
 
-    return PlacesUIUtils.ptm.aggregateTransactions(this._getDialogTitle(),
-                                                   transactions);
+    return new PlacesAggregatedTransaction(this._getDialogTitle(),
+                                           [createTxn]);
   },
 
   /**
    * Returns a childItems-transactions array representing the URIList with
    * which the dialog has been opened.
    */
   _getTransactionsForURIList: function BPP__getTransactionsForURIList() {
     var transactions = [];
     for (var i = 0; i < this._URIs.length; ++i) {
       var uri = this._URIs[i];
       var title = this._getURITitleFromHistory(uri);
-      transactions.push(PlacesUIUtils.ptm.createItem(uri, -1, -1, title));
+      var createTxn = new PlacesCreateBookmarkTransaction(uri, -1, 
+                                                          PlacesUtils.bookmarks.DEFAULT_INDEX,
+                                                          title);
+      transactions.push(createTxn);
     }
     return transactions; 
   },
 
   /**
    * Returns a transaction for creating a new folder item representing the
    * various fields and opening arguments of the dialog.
    */
@@ -628,29 +643,30 @@ var BookmarkPropertiesPanel = {
     var annotations = [];
     var childItemsTransactions;
     if (this._URIs.length)
       childItemsTransactions = this._getTransactionsForURIList();
 
     if (this._description)
       annotations.push(this._getDescriptionAnnotation(this._description));
 
-    return PlacesUIUtils.ptm.createFolder(this._title, aContainer, aIndex,
-                                          annotations, childItemsTransactions);
+    return new PlacesCreateFolderTransaction(this._title, aContainer,
+                                             aIndex, annotations,
+                                             childItemsTransactions);
   },
 
   /**
    * Returns a transaction for creating a new live-bookmark item representing
    * the various fields and opening arguments of the dialog.
    */
   _getCreateNewLivemarkTransaction:
   function BPP__getCreateNewLivemarkTransaction(aContainer, aIndex) {
-    return PlacesUIUtils.ptm.createLivemark(this._feedURI, this._siteURI,
-                                            this._title,
-                                            aContainer, aIndex);
+    return new PlacesCreateLivemarkTransaction(this._feedURI, this._siteURI,
+                                               this._title,
+                                               aContainer, aIndex);
   },
 
   /**
    * Dialog-accept code-path for creating a new item (any type)
    */
   _createNewItem: function BPP__getCreateItemTransaction() {
     var [container, index] = this._getInsertionPointDetails();
     var txn;
@@ -661,12 +677,12 @@ var BookmarkPropertiesPanel = {
         break;
       case LIVEMARK_CONTAINER:
         txn = this._getCreateNewLivemarkTransaction(container, index);
         break;      
       default: // BOOKMARK_ITEM
         txn = this._getCreateNewBookmarkTransaction(container, index);
     }
 
-    PlacesUIUtils.ptm.doTransaction(txn);
+    PlacesUtils.transactionManager.doTransaction(txn);
     this._itemId = PlacesUtils.bookmarks.getIdForItemAt(container, index);
   }
 };
--- a/browser/components/places/content/browserPlacesViews.js
+++ b/browser/components/places/content/browserPlacesViews.js
@@ -1853,23 +1853,26 @@ PlacesMenu.prototype = {
         this._onPopupHidden(aEvent);
         break;
     }
   },
 
   _onPopupHidden: function PM__onPopupHidden(aEvent) {
     // Avoid handling popuphidden of inner views.
     let popup = aEvent.originalTarget;
-    if (!popup._placesNode || PlacesUIUtils.getViewForNode(popup) != this)
+    let placesNode = popup._placesNode;
+    if (!placesNode || PlacesUIUtils.getViewForNode(popup) != this)
       return;
 
     // UI performance: folder queries are cheap, keep the resultnode open
     // so we don't rebuild its contents whenever the popup is reopened.
-    if (!PlacesUtils.nodeIsFolder(popup._placesNode))
-      popup._placesNode.containerOpen = false;
+    // Though, we want to always close feed containers so their expiration
+    // status will be checked at next opening.
+    if (!PlacesUtils.nodeIsFolder(placesNode) || placesNode._feedURI)
+      placesNode.containerOpen = false;
 
     // The autoopened attribute is set for folders which have been
     // automatically opened when dragged over.  Turn off this attribute
     // when the folder closes because it is no longer applicable.
     popup.removeAttribute("autoopened");
     popup.removeAttribute("dragstart");
   }
 };
--- a/browser/components/places/content/controller.js
+++ b/browser/components/places/content/controller.js
@@ -152,19 +152,19 @@ PlacesController.prototype = {
     // filters out other commands that we do _not_ support (see 329587).
     const CMD_PREFIX = "placesCmd_";
     return (aCommand.substr(0, CMD_PREFIX.length) == CMD_PREFIX);
   },
 
   isCommandEnabled: function PC_isCommandEnabled(aCommand) {
     switch (aCommand) {
     case "cmd_undo":
-      return PlacesUIUtils.ptm.numberOfUndoItems > 0;
+      return PlacesUtils.transactionManager.numberOfUndoItems > 0;
     case "cmd_redo":
-      return PlacesUIUtils.ptm.numberOfRedoItems > 0;
+      return PlacesUtils.transactionManager.numberOfRedoItems > 0;
     case "cmd_cut":
     case "placesCmd_cut":
       var nodes = this._view.selectedNodes;
       // If selection includes history nodes there's no reason to allow cut.
       for (var i = 0; i < nodes.length; i++) {
         if (nodes[i].itemId == -1)
           return false;
       }
@@ -225,20 +225,20 @@ PlacesController.prototype = {
     default:
       return false;
     }
   },
 
   doCommand: function PC_doCommand(aCommand) {
     switch (aCommand) {
     case "cmd_undo":
-      PlacesUIUtils.ptm.undoTransaction();
+      PlacesUtils.transactionManager.undoTransaction();
       break;
     case "cmd_redo":
-      PlacesUIUtils.ptm.redoTransaction();
+      PlacesUtils.transactionManager.redoTransaction();
       break;
     case "cmd_cut":
     case "placesCmd_cut":
       this.cut();
       break;
     case "cmd_copy":
     case "placesCmd_copy":
       this.copy();
@@ -780,18 +780,18 @@ PlacesController.prototype = {
 
   /**
    * Create a new Bookmark separator somewhere.
    */
   newSeparator: function PC_newSeparator() {
     var ip = this._view.insertionPoint;
     if (!ip)
       throw Cr.NS_ERROR_NOT_AVAILABLE;
-    var txn = PlacesUIUtils.ptm.createSeparator(ip.itemId, ip.index);
-    PlacesUIUtils.ptm.doTransaction(txn);
+    var txn = new PlacesCreateSeparatorTransaction(ip.itemId, ip.index);
+    PlacesUtils.transactionManager.doTransaction(txn);
     // select the new item
     var insertedNodeId = PlacesUtils.bookmarks
                                     .getIdForItemAt(ip.itemId, ip.index);
     this._view.selectItems([insertedNodeId], false);
   },
 
   /**
    * Opens a dialog for moving the selected nodes.
@@ -802,18 +802,18 @@ PlacesController.prototype = {
                       this._view.selectedNodes);
   },
 
   /**
    * Sort the selected folder by name
    */
   sortFolderByName: function PC_sortFolderByName() {
     var itemId = PlacesUtils.getConcreteItemId(this._view.selectedNode);
-    var txn = PlacesUIUtils.ptm.sortFolderByName(itemId);
-    PlacesUIUtils.ptm.doTransaction(txn);
+    var txn = new PlacesSortFolderByNameTransaction(itemId);
+    PlacesUtils.transactionManager.doTransaction(txn);
   },
 
   /**
    * Walk the list of folders we're removing in this delete operation, and
    * see if the selected node specified is already implicitly being removed
    * because it is a child of that folder.
    * @param   node
    *          Node to check for containment.
@@ -867,30 +867,33 @@ PlacesController.prototype = {
       if (this._shouldSkipNode(node, removedFolders))
         continue;
 
       if (PlacesUtils.nodeIsTagQuery(node.parent)) {
         // This is a uri node inside a tag container.  It needs a special
         // untag transaction.
         var tagItemId = PlacesUtils.getConcreteItemId(node.parent);
         var uri = NetUtil.newURI(node.uri);
-        transactions.push(PlacesUIUtils.ptm.untagURI(uri, [tagItemId]));
+        let txn = new PlacesUntagURITransaction(uri, [tagItemId]);
+        transactions.push(txn);
       }
       else if (PlacesUtils.nodeIsTagQuery(node) && node.parent &&
                PlacesUtils.nodeIsQuery(node.parent) &&
                PlacesUtils.asQuery(node.parent).queryOptions.resultType ==
                  Ci.nsINavHistoryQueryOptions.RESULTS_AS_TAG_QUERY) {
         // This is a tag container.
         // Untag all URIs tagged with this tag only if the tag container is
         // child of the "Tags" query in the library, in all other places we
         // must only remove the query node.
         var tag = node.title;
         var URIs = PlacesUtils.tagging.getURIsForTag(tag);
-        for (var j = 0; j < URIs.length; j++)
-          transactions.push(PlacesUIUtils.ptm.untagURI(URIs[j], [tag]));
+        for (var j = 0; j < URIs.length; j++) {
+          let txn = new PlacesUntagURITransaction(URIs[j], [tag]);
+          transactions.push(txn);
+        }
       }
       else if (PlacesUtils.nodeIsURI(node) &&
                PlacesUtils.nodeIsQuery(node.parent) &&
                PlacesUtils.asQuery(node.parent).queryOptions.queryType ==
                  Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY) {
         // This is a uri node inside an history query.
         PlacesUtils.bhistory.removePage(NetUtil.newURI(node.uri));
         // History deletes are not undoable, so we don't have a transaction.
@@ -907,17 +910,18 @@ PlacesController.prototype = {
       }
       else {
         // This is a common bookmark item.
         if (PlacesUtils.nodeIsFolder(node)) {
           // If this is a folder we add it to our array of folders, used
           // to skip nodes that are children of an already removed folder.
           removedFolders.push(node);
         }
-        transactions.push(PlacesUIUtils.ptm.removeItem(node.itemId));
+        let txn = new PlacesRemoveItemTransaction(node.itemId);
+        transactions.push(txn);
       }
     }
   },
 
   /**
    * Removes the set of selected ranges from bookmarks.
    * @param   txnName
    *          See |remove|.
@@ -926,18 +930,18 @@ PlacesController.prototype = {
     var ranges = this._view.removableSelectionRanges;
     var transactions = [];
     var removedFolders = [];
 
     for (var i = 0; i < ranges.length; i++)
       this._removeRange(ranges[i], transactions, removedFolders);
 
     if (transactions.length > 0) {
-      var txn = PlacesUIUtils.ptm.aggregateTransactions(txnName, transactions);
-      PlacesUIUtils.ptm.doTransaction(txn);
+      var txn = new PlacesAggregatedTransaction(txnName, transactions);
+      PlacesUtils.transactionManager.doTransaction(txn);
     }
   },
 
   /**
    * Removes the set of selected ranges from history.
    *
    * @note history deletes are not undoable.
    */
@@ -1273,37 +1277,35 @@ PlacesController.prototype = {
     }
 
     let transactions = [];
     let insertionIndex = ip.index;
     for (let i = 0; i < items.length; ++i) {
       if (ip.isTag) {
         // Pasting into a tag container means tagging the item, regardless of
         // the requested action.
-        transactions.push(
-          new PlacesTagURITransaction(NetUtil.newURI(items[i].uri),
-                                      [ip.itemId])
-        );
+        let tagTxn = new PlacesTagURITransaction(NetUtil.newURI(items[i].uri),
+                                                 [ip.itemId]);
+        transactions.push(tagTxn);
         continue;
       }
 
       // Adjust index to make sure items are pasted in the correct position.
       // If index is DEFAULT_INDEX, items are just appended.
       if (ip.index != PlacesUtils.bookmarks.DEFAULT_INDEX)
         insertionIndex = ip.index + i;
 
       transactions.push(
         PlacesUIUtils.makeTransaction(items[i], type, ip.itemId,
                                       insertionIndex, action == "copy")
       );
     }
  
-    PlacesUtils.transactionManager.doTransaction(
-      new PlacesAggregatedTransaction("Paste", transactions)
-    );
+    let aggregatedTxn = new PlacesAggregatedTransaction("Paste", transactions);
+    PlacesUtils.transactionManager.doTransaction(aggregatedTxn);
 
     // Cut/past operations are not repeatable, so clear the clipboard.
     if (action == "cut") {
       this._clearClipboard();
     }
 
     // Select the pasted items, they should be consecutive.
     let insertedNodeIds = [];
@@ -1543,27 +1545,28 @@ let PlacesControllerDragHelper = {
       if (index != -1 && dragginUp)
         index+= movedCount++;
 
       // If dragging over a tag container we should tag the item.
       if (insertionPoint.isTag &&
           insertionPoint.orientation == Ci.nsITreeView.DROP_ON) {
         let uri = NetUtil.newURI(unwrapped.uri);
         let tagItemId = insertionPoint.itemId;
-        transactions.push(PlacesUIUtils.ptm.tagURI(uri,[tagItemId]));
+        let tagTxn = new PlacesTagURITransaction(uri, [tagItemId]);
+        transactions.push(tagTxn);
       }
       else {
         transactions.push(PlacesUIUtils.makeTransaction(unwrapped,
                           flavor, insertionPoint.itemId,
                           index, doCopy));
       }
     }
 
-    let txn = PlacesUIUtils.ptm.aggregateTransactions("DropItems", transactions);
-    PlacesUIUtils.ptm.doTransaction(txn);
+    let txn = new PlacesAggregatedTransaction("DropItems", transactions);
+    PlacesUtils.transactionManager.doTransaction(txn);
   },
 
   /**
    * Checks if we can insert into a container.
    * @param   aContainer
    *          The container were we are want to drop
    */
   disallowInsertion: function(aContainer) {
--- a/browser/components/places/content/editBookmarkOverlay.js
+++ b/browser/components/places/content/editBookmarkOverlay.js
@@ -430,25 +430,28 @@ var gEditItemOverlay = {
         if (tags.indexOf(currentTags[i]) == -1)
           tagsToRemove.push(currentTags[i]);
       }
       for (var i = 0; i < tags.length; i++) {
         if (currentTags.indexOf(tags[i]) == -1)
           tagsToAdd.push(tags[i]);
       }
 
-      if (tagsToRemove.length > 0)
-        txns.push(PlacesUIUtils.ptm.untagURI(this._uri, tagsToRemove));
-      if (tagsToAdd.length > 0)
-        txns.push(PlacesUIUtils.ptm.tagURI(this._uri, tagsToAdd));
+      if (tagsToRemove.length > 0) {
+        let untagTxn = new PlacesUntagURITransaction(this._uri, tagsToRemove);
+        txns.push(untagTxn);
+      }
+      if (tagsToAdd.length > 0) {
+        let tagTxn = new PlacesTagURITransaction(this._uri, tagsToAdd);
+        txns.push(tagTxn);
+      }
 
       if (txns.length > 0) {
-        var aggregate = PlacesUIUtils.ptm.aggregateTransactions("Update tags",
-                                                                txns);
-        PlacesUIUtils.ptm.doTransaction(aggregate);
+        let aggregate = new PlacesAggregatedTransaction("Update tags", txns);
+        PlacesUtils.transactionManager.doTransaction(aggregate);
 
         // Ensure the tagsField is in sync, clean it up from empty tags
         var tags = PlacesUtils.tagging.getTagsForURI(this._uri).join(", ");
         this._initTextField("tagsField", tags, false);
         return true;
       }
     }
     return false;
@@ -490,105 +493,116 @@ var gEditItemOverlay = {
         tagsToAdd[i] = [];
         for (var j = 0; j < tags.length; j++) {
           if (this._tags[i].indexOf(tags[j]) == -1)
             tagsToAdd[i].push(tags[j]);
         }
       }
 
       if (tagsToAdd.length > 0) {
-        for (i = 0; i < this._uris.length; i++) {
-          if (tagsToAdd[i].length > 0)
-            txns.push(PlacesUIUtils.ptm.tagURI(this._uris[i], tagsToAdd[i]));
+        for (let i = 0; i < this._uris.length; i++) {
+          if (tagsToAdd[i].length > 0) {
+            let tagTxn = new PlacesTagURITransaction(this._uris[i],
+                                                     tagsToAdd[i]);
+            txns.push(tagTxn);
+          }
         }
       }
       if (tagsToRemove.length > 0) {
-        for (var i = 0; i < this._uris.length; i++)
-          txns.push(PlacesUIUtils.ptm.untagURI(this._uris[i], tagsToRemove));
+        for (let i = 0; i < this._uris.length; i++) {
+          let untagTxn = new PlacesUntagURITransaction(this._uris[i],
+                                                       tagsToRemove);
+          txns.push(untagTxn);
+        }
       }
 
       if (txns.length > 0) {
-        var aggregate = PlacesUIUtils.ptm.aggregateTransactions("Update tags",
-                                                                txns);
-        PlacesUIUtils.ptm.doTransaction(aggregate);
+        let aggregate = new PlacesAggregatedTransaction("Update tags", txns);
+        PlacesUtils.transactionManager.doTransaction(aggregate);
 
         this._allTags = tags;
         this._tags = [];
-        for (i = 0; i < this._uris.length; i++)
+        for (let i = 0; i < this._uris.length; i++) {
           this._tags[i] = PlacesUtils.tagging.getTagsForURI(this._uris[i]);
+        }
 
         // Ensure the tagsField is in sync, clean it up from empty tags
         this._initTextField("tagsField", tags, false);
         return true;
       }
     }
     return false;
   },
 
   onNamePickerChange: function EIO_onNamePickerChange() {
     if (this._itemId == -1)
       return;
 
     var namePicker = this._element("namePicker")
-    var txns = [];
-    const ptm = PlacesUIUtils.ptm;
 
     // Here we update either the item title or its cached static title
     var newTitle = namePicker.value;
     if (!newTitle &&
         PlacesUtils.bookmarks.getFolderIdForItem(this._itemId) == PlacesUtils.tagsFolderId) {
       // We don't allow setting an empty title for a tag, restore the old one.
       this._initNamePicker();
     }
     else if (this._getItemStaticTitle() != newTitle) {
       this._mayUpdateFirstEditField("namePicker");
-      txns.push(ptm.editItemTitle(this._itemId, newTitle));
+      let txn = new PlacesEditItemTitleTransaction(this._itemId, newTitle);
+      PlacesUtils.transactionManager.doTransaction(txn);
     }
-
-    var aggregate = ptm.aggregateTransactions("Edit Item Title", txns);
-    ptm.doTransaction(aggregate);
   },
 
   onDescriptionFieldBlur: function EIO_onDescriptionFieldBlur() {
     var description = this._element("descriptionField").value;
     if (description != PlacesUIUtils.getItemDescription(this._itemId)) {
-      var txn = PlacesUIUtils.ptm
-                             .editItemDescription(this._itemId, description);
-      PlacesUIUtils.ptm.doTransaction(txn);
+      var annoObj = { name   : PlacesUIUtils.DESCRIPTION_ANNO,
+                      type   : Ci.nsIAnnotationService.TYPE_STRING,
+                      flags  : 0,
+                      value  : description,
+                      expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
+      var txn = new PlacesSetItemAnnotationTransaction(this._itemId, annoObj);
+      PlacesUtils.transactionManager.doTransaction(txn);
     }
   },
 
   onLocationFieldBlur: function EIO_onLocationFieldBlur() {
     var uri;
     try {
       uri = PlacesUIUtils.createFixedURI(this._element("locationField").value);
     }
     catch(ex) { return; }
 
     if (!this._uri.equals(uri)) {
-      var txn = PlacesUIUtils.ptm.editBookmarkURI(this._itemId, uri);
-      PlacesUIUtils.ptm.doTransaction(txn);
+      var txn = new PlacesEditBookmarkURITransaction(this._itemId, uri);
+      PlacesUtils.transactionManager.doTransaction(txn);
       this._uri = uri;
     }
   },
 
   onKeywordFieldBlur: function EIO_onKeywordFieldBlur() {
     var keyword = this._element("keywordField").value;
     if (keyword != PlacesUtils.bookmarks.getKeywordForBookmark(this._itemId)) {
-      var txn = PlacesUIUtils.ptm.editBookmarkKeyword(this._itemId, keyword);
-      PlacesUIUtils.ptm.doTransaction(txn);
+      var txn = new PlacesEditBookmarkKeywordTransaction(this._itemId, keyword);
+      PlacesUtils.transactionManager.doTransaction(txn);
     }
   },
 
   onLoadInSidebarCheckboxCommand:
   function EIO_onLoadInSidebarCheckboxCommand() {
     var loadInSidebarChecked = this._element("loadInSidebarCheckbox").checked;
-    var txn = PlacesUIUtils.ptm.setLoadInSidebar(this._itemId,
-                                                 loadInSidebarChecked);
-    PlacesUIUtils.ptm.doTransaction(txn);
+    var annoObj = { name   : PlacesUIUtils.LOAD_IN_SIDEBAR_ANNO,
+                    type   : Ci.nsIAnnotationService.TYPE_INT32,
+                    flags  : 0,
+                    value  : loadInSidebarChecked,
+                    expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
+    var txn = new PlacesSetItemAnnotationTransaction(this._itemId,
+                                                     annoObj);
+    PlacesUtils.transactionManager.doTransaction(txn);
   },
 
   toggleFolderTreeVisibility: function EIO_toggleFolderTreeVisibility() {
     var expander = this._element("foldersExpander");
     var folderTreeRow = this._element("folderTreeRow");
     if (!folderTreeRow.collapsed) {
       expander.className = "expander-down";
       expander.setAttribute("tooltiptext",
@@ -667,18 +681,20 @@ var gEditItemOverlay = {
       // menulist right away
       setTimeout(function(self) self.toggleFolderTreeVisibility(), 100, this);
       return;
     }
 
     // Move the item
     var container = this._getFolderIdFromMenuList();
     if (PlacesUtils.bookmarks.getFolderIdForItem(this._itemId) != container) {
-      var txn = PlacesUIUtils.ptm.moveItem(this._itemId, container, -1);
-      PlacesUIUtils.ptm.doTransaction(txn);
+      var txn = new PlacesMoveItemTransaction(this._itemId, 
+                                              container, 
+                                              PlacesUtils.bookmarks.DEFAULT_INDEX);
+      PlacesUtils.transactionManager.doTransaction(txn);
 
       // Mark the containing folder as recently-used if it isn't in the
       // static list
       if (container != PlacesUtils.unfiledBookmarksFolderId &&
           container != PlacesUtils.toolbarFolderId &&
           container != PlacesUtils.bookmarksMenuFolderId)
         this._markFolderAsRecentlyUsed(container);
     }
@@ -715,25 +731,27 @@ var gEditItemOverlay = {
   _markFolderAsRecentlyUsed:
   function EIO__markFolderAsRecentlyUsed(aFolderId) {
     var txns = [];
 
     // Expire old unused recent folders
     var anno = this._getLastUsedAnnotationObject(false);
     while (this._recentFolders.length > MAX_FOLDER_ITEM_IN_MENU_LIST) {
       var folderId = this._recentFolders.pop().folderId;
-      txns.push(PlacesUIUtils.ptm.setItemAnnotation(folderId, anno));
+      let annoTxn = new PlacesSetItemAnnotationTransaction(folderId, anno);
+      txns.push(annoTxn);
     }
 
     // Mark folder as recently used
     anno = this._getLastUsedAnnotationObject(true);
-    txns.push(PlacesUIUtils.ptm.setItemAnnotation(aFolderId, anno));
+    let annoTxn = new PlacesSetItemAnnotationTransaction(aFolderId, anno);
+    txns.push(annoTxn);
 
-    var aggregate = PlacesUIUtils.ptm.aggregateTransactions("Update last used folders", txns);
-    PlacesUIUtils.ptm.doTransaction(aggregate);
+    let aggregate = new PlacesAggregatedTransaction("Update last used folders", txns);
+    PlacesUtils.transactionManager.doTransaction(aggregate);
   },
 
   /**
    * Returns an object which could then be used to set/unset the
    * LAST_USED_ANNO annotation for a folder.
    *
    * @param aLastUsed
    *        Whether to set or unset the LAST_USED_ANNO annotation.
@@ -835,18 +853,18 @@ var gEditItemOverlay = {
     if (!ip || ip.itemId == PlacesUIUtils.allBookmarksFolderId) {
         ip = new InsertionPoint(PlacesUtils.bookmarksMenuFolderId,
                                 PlacesUtils.bookmarks.DEFAULT_INDEX,
                                 Ci.nsITreeView.DROP_ON);
     }
 
     // XXXmano: add a separate "New Folder" string at some point...
     var defaultLabel = this._element("newFolderButton").label;
-    var txn = PlacesUIUtils.ptm.createFolder(defaultLabel, ip.itemId, ip.index);
-    PlacesUIUtils.ptm.doTransaction(txn);
+    var txn = new PlacesCreateFolderTransaction(defaultLabel, ip.itemId, ip.index);
+    PlacesUtils.transactionManager.doTransaction(txn);
     this._folderTree.focus();
     this._folderTree.selectItems([this._lastNewItem]);
     this._folderTree.startEditing(this._folderTree.view.selection.currentIndex,
                                   this._folderTree.columns.getFirstColumn());
   },
 
   // nsIDOMEventListener
   handleEvent: function EIO_nsIDOMEventListener(aEvent) {
--- a/browser/components/places/content/moveBookmarks.js
+++ b/browser/components/places/content/moveBookmarks.js
@@ -62,23 +62,25 @@ var gMoveBookmarksDialog = {
     var selectedFolderID = PlacesUtils.getConcreteItemId(selectedNode);
 
     var transactions = [];
     for (var i=0; i < this._nodes.length; i++) {
       // Nothing to do if the node is already under the selected folder
       if (this._nodes[i].parent.itemId == selectedFolderID)
         continue;
 
-      transactions.push(new
-        PlacesUIUtils.ptm.moveItem(this._nodes[i].itemId, selectedFolderID, -1));
+      let txn = new PlacesMoveItemTransaction(this._nodes[i].itemId,
+                                              selectedFolderID,
+                                              PlacesUtils.bookmarks.DEFAULT_INDEX);
+      transactions.push(txn);
     }
 
     if (transactions.length != 0) {
-      var txn = PlacesUIUtils.ptm.aggregateTransactions("Move Items", transactions);
-      PlacesUIUtils.ptm.doTransaction(txn);
+      let txn = new PlacesAggregatedTransaction("Move Items", transactions);
+      PlacesUtils.transactionManager.doTransaction(txn);
     }
   },
 
   newFolder: function MBD_newFolder() {
     // The command is disabled when the tree is not focused
     this.foldersTree.focus();
     goDoCommand("placesCmd_new:folder");
   }
--- a/browser/components/places/content/places.js
+++ b/browser/components/places/content/places.js
@@ -823,21 +823,21 @@ var PlacesOrganizer = {
     var input = {value: defaultText};
     var save = prompts.prompt(null, title, inputLabel, input, null, check);
 
     // Don't add the query if the user cancels or clears the seach name.
     if (!save || input.value == "")
      return;
 
     // Add the place: uri as a bookmark under the bookmarks root.
-    var txn = PlacesUIUtils.ptm.createItem(placeURI,
-                                           PlacesUtils.bookmarksMenuFolderId,
-                                           PlacesUtils.bookmarks.DEFAULT_INDEX,
-                                           input.value);
-    PlacesUIUtils.ptm.doTransaction(txn);
+    var txn = new PlacesCreateBookmarkTransaction(placeURI,
+                                                  PlacesUtils.bookmarksMenuFolderId,
+                                                  PlacesUtils.bookmarks.DEFAULT_INDEX,
+                                                  input.value);
+    PlacesUtils.transactionManager.doTransaction(txn);
 
     // select and load the new query
     this._places.selectPlaceURI(placeSpec);
   }
 };
 
 /**
  * A set of utilities relating to search within Bookmarks and History.
--- a/browser/components/places/content/treeView.js
+++ b/browser/components/places/content/treeView.js
@@ -1655,18 +1655,18 @@ PlacesTreeView.prototype = {
 
     return true;
   },
 
   setCellText: function PTV_setCellText(aRow, aColumn, aText) {
     // We may only get here if the cell is editable.
     let node = this._rows[aRow];
     if (node.title != aText) {
-      let txn = PlacesUIUtils.ptm.editItemTitle(node.itemId, aText);
-      PlacesUIUtils.ptm.doTransaction(txn);
+      let txn = new PlacesEditItemTitleTransaction(node.itemId, aText);
+      PlacesUtils.transactionManager.doTransaction(txn);
     }
   },
 
   selectionChanged: function() { },
   cycleCell: function(aRow, aColumn) { },
   isSelectable: function(aRow, aColumn) { return false; },
   performAction: function(aAction) { },
   performActionOnRow: function(aAction, aRow) { },
--- a/browser/components/places/tests/browser/browser_425884.js
+++ b/browser/components/places/tests/browser/browser_425884.js
@@ -81,40 +81,40 @@ function test() {
   folderANode.containerOpen = false;
 
   var transaction = PlacesUIUtils.makeTransaction(rawNode,
                                                   PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER,
                                                   testRootId,
                                                   -1,
                                                   true);
   ok(transaction, "create transaction");
-  PlacesUIUtils.ptm.doTransaction(transaction);
+  PlacesUtils.transactionManager.doTransaction(transaction);
   // confirm copy
   is(testRootNode.childCount, 2, "create test folder via copy");
 
   // validate the copy
   var folderBNode = testRootNode.getChild(1);
   validate(folderBNode);
 
   // undo the transaction, confirm the removal
-  PlacesUIUtils.ptm.undoTransaction();
+  PlacesUtils.transactionManager.undoTransaction();
   is(testRootNode.childCount, 1, "confirm undo removed the copied folder");
 
   // redo the transaction
-  PlacesUIUtils.ptm.redoTransaction();
+  PlacesUtils.transactionManager.redoTransaction();
   is(testRootNode.childCount, 2, "confirm redo re-copied the folder");
   folderBNode = testRootNode.getChild(1);
   validate(folderBNode);
 
   // Close containers, cleaning up their observers.
   testRootNode.containerOpen = false;
   toolbarNode.containerOpen = false;
 
   // clean up
-  PlacesUIUtils.ptm.undoTransaction();
+  PlacesUtils.transactionManager.undoTransaction();
   PlacesUtils.bookmarks.removeItem(folderAId);
 }
 
 function populate(aFolderId) {
   var folderId = PlacesUtils.bookmarks.createFolder(aFolderId, "test folder", -1);
   PlacesUtils.bookmarks.insertBookmark(folderId, PlacesUtils._uri("http://foo"), -1, "test bookmark");
   PlacesUtils.bookmarks.insertSeparator(folderId, -1);
 }
--- a/browser/components/places/tests/browser/browser_457473_no_copy_guid.js
+++ b/browser/components/places/tests/browser/browser_457473_no_copy_guid.js
@@ -80,43 +80,43 @@ function test() {
   // Create a copy transaction from the serialization.
   // this exercises the guid-filtering
   var transaction = PlacesUIUtils.makeTransaction(rawNode,
                                                   PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER,
                                                   testRootId, -1, true);
   ok(transaction, "create transaction");
 
   // execute it, copying to the test root folder
-  PlacesUIUtils.ptm.doTransaction(transaction);
+  PlacesUtils.transactionManager.doTransaction(transaction);
   is(testRootNode.childCount, 2, "create test folder via copy");
 
   // check GUIDs are different
   var folderBNode = testRootNode.getChild(1);
   ok(checkGUIDs(folderBNode, folderAGUIDs, false), "confirm folder A GUIDs don't match folder B GUIDs");
   var folderBGUIDs = getGUIDs(folderBNode);
   ok(checkGUIDs(folderBNode, folderBGUIDs, true), "confirm test of new GUIDs");
 
   // undo the transaction, confirm the removal
-  PlacesUIUtils.ptm.undoTransaction();
+  PlacesUtils.transactionManager.undoTransaction();
   is(testRootNode.childCount, 1, "confirm undo removed the copied folder");
 
   // redo the transaction
   // confirming GUIDs persist through undo/redo
-  PlacesUIUtils.ptm.redoTransaction();
+  PlacesUtils.transactionManager.redoTransaction();
   is(testRootNode.childCount, 2, "confirm redo re-copied the folder");
   folderBNode = testRootNode.getChild(1);
   ok(checkGUIDs(folderBNode, folderAGUIDs, false), "folder B GUIDs after undo/redo don't match folder A GUIDs"); // sanity check
   ok(checkGUIDs(folderBNode, folderBGUIDs, true), "folder B GUIDs after under/redo should match pre-undo/redo folder B GUIDs");
 
   // Close containers, cleaning up their observers.
   testRootNode.containerOpen = false;
   toolbarNode.containerOpen = false;
 
   // clean up
-  PlacesUIUtils.ptm.undoTransaction();
+  PlacesUtils.transactionManager.undoTransaction();
   PlacesUtils.bookmarks.removeItem(testRootId);
 }
 
 function getGUIDs(aNode) {
   PlacesUtils.asContainer(aNode);
   aNode.containerOpen = true;
   var GUIDs = {
     folder: PlacesUtils.bookmarks.getItemGUID(aNode.itemId),
--- a/browser/components/places/tests/unit/xpcshell.ini
+++ b/browser/components/places/tests/unit/xpcshell.ini
@@ -14,11 +14,9 @@ tail =
 [test_browserGlue_distribution.js]
 [test_browserGlue_migrate.js]
 [test_browserGlue_prefs.js]
 [test_browserGlue_restore.js]
 [test_browserGlue_shutdown.js]
 [test_browserGlue_smartBookmarks.js]
 [test_clearHistory_shutdown.js]
 [test_leftpane_corruption_handling.js]
-[test_placesTxn.js]
 [test_PUIU_makeTransaction.js]
-[test_txnGUIDs.js]
--- a/browser/components/preferences/sync.js
+++ b/browser/components/preferences/sync.js
@@ -152,40 +152,40 @@ let gSyncPane = {
    *          "pair"  -- pair a device first
    *          "reset" -- reset sync
    */
   openSetup: function (wizardType) {
     var win = Services.wm.getMostRecentWindow("Weave:AccountSetup");
     if (win)
       win.focus();
     else {
-      window.openDialog("chrome://browser/content/syncSetup.xul",
+      window.openDialog("chrome://browser/content/sync/setup.xul",
                         "weaveSetup", "centerscreen,chrome,resizable=no",
                         wizardType);
     }
   },
 
   openQuotaDialog: function () {
     let win = Services.wm.getMostRecentWindow("Sync:ViewQuota");
     if (win)
       win.focus();
     else 
-      window.openDialog("chrome://browser/content/syncQuota.xul", "",
+      window.openDialog("chrome://browser/content/sync/quota.xul", "",
                         "centerscreen,chrome,dialog,modal");
   },
 
   openAddDevice: function () {
     if (!Weave.Utils.ensureMPUnlocked())
       return;
     
     let win = Services.wm.getMostRecentWindow("Sync:AddDevice");
     if (win)
       win.focus();
     else 
-      window.openDialog("chrome://browser/content/syncAddDevice.xul",
+      window.openDialog("chrome://browser/content/sync/addDevice.xul",
                         "syncAddDevice", "centerscreen,chrome,resizable=no");
   },
 
   resetSync: function () {
     this.openSetup("reset");
   }
 }
 
--- a/browser/components/preferences/sync.xul
+++ b/browser/components/preferences/sync.xul
@@ -64,17 +64,17 @@
       <preference id="engine.prefs"     name="services.sync.engine.prefs"     type="bool"/>
       <preference id="engine.passwords" name="services.sync.engine.passwords" type="bool"/>
     </preferences>
 
 
     <script type="application/javascript"
             src="chrome://browser/content/preferences/sync.js"/>
     <script type="application/javascript"
-            src="chrome://browser/content/syncUtils.js"/>
+            src="chrome://browser/content/sync/utils.js"/>
 
 
       <deck id="weavePrefsDeck">
         <vbox id="noAccount" align="center">
           <spacer flex="1"/>
           <description id="syncDesc">
             &weaveDesc.label;
           </description>
--- a/browser/confvars.sh
+++ b/browser/confvars.sh
@@ -37,30 +37,35 @@
 # ***** END LICENSE BLOCK *****
 
 MOZ_APP_BASENAME=Firefox
 MOZ_APP_VENDOR=Mozilla
 MOZ_UPDATER=1
 MOZ_PHOENIX=1
 
 if test "$OS_ARCH" = "WINNT"; then
-  MOZ_VERIFY_MAR_SIGNATURE=1
   if ! test "$HAVE_64BIT_OS"; then
+    MOZ_VERIFY_MAR_SIGNATURE=1
     MOZ_MAINTENANCE_SERVICE=1
   fi
 fi
 
 MOZ_CHROME_FILE_FORMAT=omni
 MOZ_SAFE_BROWSING=1
 MOZ_SERVICES_SYNC=1
 MOZ_APP_VERSION=$FIREFOX_VERSION
 MOZ_EXTENSIONS_DEFAULT=" gnomevfs"
 # MOZ_APP_DISPLAYNAME will be set by branding/configure.sh
-# Changing either of these values requires a clobber to ensure correct results,
+# Changing MOZ_*BRANDING_DIRECTORY requires a clobber to ensure correct results,
 # because branding dependencies are broken.
+# MOZ_BRANDING_DIRECTORY is the default branding directory used when none is
+# specified. It should never point to the "official" branding directory.
+# For mozilla-beta, mozilla-release, or mozilla-central repositories, use
+# "nightly" branding (until bug 659568 is fixed).
+# For the mozilla-aurora repository, use "aurora".
 MOZ_BRANDING_DIRECTORY=browser/branding/nightly
 MOZ_OFFICIAL_BRANDING_DIRECTORY=browser/branding/official
 MOZ_APP_ID={ec8030f7-c20a-464f-9b0e-13a3a9e97384}
 # This should usually be the same as the value MAR_CHANNEL_ID.
 # If more than one ID is needed, then you should use a comma separated list
 # of values.
 ACCEPTED_MAR_CHANNEL_IDS=firefox-mozilla-central
 # The MAR_CHANNEL_ID must not contain the following 3 characters: ",\t "
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -150,16 +150,17 @@
 @BINPATH@/components/dom_wifi.xpt
 @BINPATH@/components/dom_system_b2g.xpt
 #endif
 @BINPATH@/components/dom_battery.xpt
 #ifdef MOZ_B2G_BT
 @BINPATH@/components/dom_bluetooth.xpt
 #endif
 @BINPATH@/components/dom_canvas.xpt
+@BINPATH@/components/dom_contacts.xpt
 @BINPATH@/components/dom_core.xpt
 @BINPATH@/components/dom_css.xpt
 @BINPATH@/components/dom_events.xpt
 @BINPATH@/components/dom_geolocation.xpt
 @BINPATH@/components/dom_network.xpt
 @BINPATH@/components/dom_notification.xpt
 @BINPATH@/components/dom_html.xpt
 @BINPATH@/components/dom_indexeddb.xpt
@@ -404,16 +405,19 @@
 @BINPATH@/components/SyncComponents.manifest
 @BINPATH@/components/Weave.js
 #endif
 @BINPATH@/components/TelemetryPing.js
 @BINPATH@/components/TelemetryPing.manifest
 @BINPATH@/components/messageWakeupService.js
 @BINPATH@/components/messageWakeupService.manifest
 
+@BINPATH@/components/ContactManager.js
+@BINPATH@/components/ContactManager.manifest
+
 ; Modules
 @BINPATH@/modules/*
 
 ; Safe Browsing
 @BINPATH@/components/nsSafebrowsingApplication.manifest
 @BINPATH@/components/nsSafebrowsingApplication.js
 @BINPATH@/components/nsURLClassifier.manifest
 @BINPATH@/components/nsUrlClassifierHashCompleter.js
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -328,8 +328,12 @@ syncPromoNotification.learnMoreLinkText=
 # LOCALIZATION NOTE (telemetryPrompt): %1$S will be replaced by brandFullName,
 # and %2$S by the value of the toolkit.telemetry.server_owner preference.
 telemetryPrompt = Will you help improve %1$S by sending anonymous information about performance, hardware characteristics, feature usage, and browser customizations to %2$S?
 telemetryLinkLabel = Learn More
 telemetryYesButtonLabel2 = Yes, I want to help
 telemetryYesButtonAccessKey = Y
 telemetryNoButtonLabel = No
 telemetryNoButtonAccessKey = N
+# Telemetry opt-out prompt for Aurora and Nightly
+# LOCALIZATION NOTE (telemetryOptOutPrompt): %1$S and %3$S will be replaced by
+# brandFullName, and %2$S by the value of the toolkit.telemetry.server_owner preference.
+telemetryOptOutPrompt = %1$S sends information about performance, hardware, usage and customizations back to %2$S to help improve %3$S.
--- a/browser/themes/gnomestripe/syncCommon.css
+++ b/browser/themes/gnomestripe/syncCommon.css
@@ -1,9 +1,9 @@
-/* The following are used by both syncSetup.xul and syncGenericChange.xul */
+/* The following are used by both sync/setup.xul and sync/genericChange.xul */
 .status {
   color: -moz-dialogtext;
 }
 
 .statusIcon {
   -moz-margin-start: 4px;
   max-height: 16px;
   max-width: 16px;
@@ -16,17 +16,17 @@
 .statusIcon[status="error"] {
   list-style-image: url("moz-icon://stock/gtk-dialog-error?size=menu");
 }
 
 .statusIcon[status="success"] {
   list-style-image: url("moz-icon://stock/gtk-dialog-info?size=menu");
 }
 
-/* .data is only used by syncGenericChange.xul, but it seems unnecessary to have
+/* .data is only used by sync/genericChange.xul, but it seems unnecessary to have
    a separate stylesheet for it. */
 .data {
   font-size: 90%;
   font-weight: bold;
 }
 
 dialog#change-dialog {
   width: 40em;
--- a/browser/themes/pinstripe/syncCommon.css
+++ b/browser/themes/pinstripe/syncCommon.css
@@ -1,9 +1,9 @@
-/* The following are used by both syncSetup.xul and syncGenericChange.xul */
+/* The following are used by both sync/setup.xul and sync/genericChange.xul */
 .status {
   color: -moz-dialogtext;
 }
 
 .statusIcon {
   -moz-margin-start: 4px;
   max-height: 16px;
   max-width: 16px;
@@ -16,17 +16,17 @@
 .statusIcon[status="error"] {
   list-style-image: url("chrome://global/skin/icons/error-16.png");
 }
 
 .statusIcon[status="success"] {
   list-style-image: url("chrome://global/skin/icons/information-16.png");
 }
 
-/* .data is only used by syncGenericChange.xul, but it seems unnecessary to have
+/* .data is only used by sync/genericChange.xul, but it seems unnecessary to have
    a separate stylesheet for it. */
 .data {
   font-size: 90%;
   font-weight: bold;
 }
 
 dialog#change-dialog {
   width: 40em;
--- a/browser/themes/winstripe/syncCommon.css
+++ b/browser/themes/winstripe/syncCommon.css
@@ -1,9 +1,9 @@
-/* The following are used by both syncSetup.xul and syncGenericChange.xul */
+/* The following are used by both sync/setup.xul and sync/genericChange.xul */
 .status {
   color: -moz-dialogtext;
 }
 
 .statusIcon {
   -moz-margin-start: 4px;
   max-height: 16px;
   max-width: 16px;
@@ -16,17 +16,17 @@
 .statusIcon[status="error"] {
   list-style-image: url("chrome://global/skin/icons/error-16.png");
 }
 
 .statusIcon[status="success"] {
   list-style-image: url("chrome://global/skin/icons/information-16.png");
 }
 
-/* .data is only used by syncGenericChange.xul, but it seems unnecessary to have
+/* .data is only used by sync/genericChange.xul, but it seems unnecessary to have
    a separate stylesheet for it. */
 .data {
   font-size: 90%;
   font-weight: bold;
 }
 
 dialog#change-dialog {
   width: 40em;
deleted file mode 100644
--- a/build/mobile/devicemanager-run-test.py
+++ /dev/null
@@ -1,89 +0,0 @@
-# ***** BEGIN LICENSE BLOCK *****
-# Version: MPL 1.1/GPL 2.0/LGPL 2.1
-#
-# The contents of this file are subject to the Mozilla Public License Version
-# 1.1 (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS IS" basis,
-# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-# for the specific language governing rights and limitations under the
-# License.
-#
-# The Original Code is remote test framework.
-#
-# The Initial Developer of the Original Code is
-# the Mozilla Corporation.
-# Portions created by the Initial Developer are Copyright (C) 2010
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#
-# Alternatively, the contents of this file may be used under the terms of
-# either the GNU General Public License Version 2 or later (the "GPL"), or
-# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-# in which case the provisions of the GPL or the LGPL are applicable instead
-# of those above. If you wish to allow use of your version of this file only
-# under the terms of either the GPL or the LGPL, and not to allow others to
-# use your version of this file under the terms of the MPL, indicate your
-# decision by deleting the provisions above and replace them with the notice
-# and other provisions required by the GPL or the LGPL. If you do not delete
-# the provisions above, a recipient may use your version of this file under
-# the terms of any one of the MPL, the GPL or the LGPL.
-#
-# ***** END LICENSE BLOCK *****
-
-import devicemanager
-import devicemanagerUtils
-import sys
-import os
-
-def main():
-    ip_addr = os.environ.get("DEVICE_IP")
-    port = os.environ.get("DEVICE_PORT")
-    gre_path = os.environ.get("REMOTE_GRE_PATH").replace('\\','/')
-
-    if ip_addr == None:
-        print "Error: please define the environment variable DEVICE_IP before running this test"
-        sys.exit(1)
-
-    if port == None:
-        print "Error: please define the environment variable DEVICE_PORT before running this test"
-        sys.exit(1)
-
-    if gre_path == None:
-        print "Error: please define the environment variable REMOTE_GRE_PATH before running this test"
-        sys.exit(1)
-
-    dm = devicemanagerUtils.getDeviceManager(ip_addr, int(port))
-    if len(sys.argv) < 2:
-        print "usage python devicemanager-run-test.py <test program> [args1 [arg2..]]"
-        sys.exit(1)
-
-    cmd = sys.argv[1]
-    args = ' '
-    if len(sys.argv) > 2:
-        args = ' ' + ' '.join(sys.argv[2:])
-
-    dm.debug = 0
-    lastslash = cmd.rfind('/');
-    if lastslash == -1:
-        lastslash = 0
-    dm.pushFile(cmd, gre_path + cmd[lastslash:])
-    process = dm.launchProcess([gre_path  + cmd[lastslash:] + args])
-    output_list = dm.communicate(process)
-    ret = -1
-    if (output_list != None and output_list[0] != None):
-        try:
-            output = output_list[0]
-            index = output.find('exited with return code')
-            print output[0:index]
-            retstr = (output[index + 24 : output.find('\n', index)])
-            ret = int(retstr)
-        except ValueError:
-            ret = -1
-    sys.exit(ret)
-
-if __name__ == '__main__':
-    main()
--- a/build/mobile/devicemanager.py
+++ b/build/mobile/devicemanager.py
@@ -192,41 +192,16 @@ class DeviceManager:
     """
     external function
     DEPRECATED: Use shell() or launchApplication() for new code
     returns:
     success: output filename
     failure: None
     """
 
-  def communicate(self, process, timeout = 600, interval = 5):
-    """
-    loops until 'process' has exited or 'timeout' seconds is reached
-    loop sleeps for 'interval' seconds between iterations
-    external function
-    returns:
-    success: [file contents, None]
-    failure: [None, None]
-    """
-    
-    timed_out = True
-    if (timeout > 0):
-      total_time = 0
-      while total_time < timeout:
-        time.sleep(interval)
-        if self.processExist(process) == None:
-          timed_out = False
-          break
-        total_time += interval
-
-    if (timed_out == True):
-      return [None, None]
-
-    return [self.getFile(process, "temp.txt"), None]
-
   def processExist(self, appname):
     """
     iterates process list and returns pid if exists, otherwise None
     external function
     returns:
     success: pid
     failure: None
     """
@@ -596,24 +571,24 @@ def _pop_last_line(file):
   '''
   Utility function to get the last line from a file (shared between ADB and
   SUT device managers). Function also removes it from the file. Intended to
   strip off the return code from a shell command.
   '''
   bytes_from_end = 1
   file.seek(0, 2)
   length = file.tell() + 1
-  while bytes_from_end <= length:
+  while bytes_from_end < length:
     file.seek((-1)*bytes_from_end, 2)
     data = file.read()
 
-    if bytes_from_end == length and len(data) == 0: # no data, return None
+    if bytes_from_end == length-1 and len(data) == 0: # no data, return None
       return None
 
-    if data[0] == '\n' or bytes_from_end == length:
+    if data[0] == '\n' or bytes_from_end == length-1:
       # found the last line, which should have the return value
       if data[0] == '\n':
         data = data[1:]
 
       # truncate off the return code line
       file.truncate(length - bytes_from_end)
       file.seek(0,2)
       file.write('\0')
--- a/build/mobile/devicemanagerADB.py
+++ b/build/mobile/devicemanagerADB.py
@@ -20,21 +20,27 @@ class DeviceManagerADB(DeviceManager):
     self.tempDir = None
     if packageName == None:
       if os.getenv('USER'):
         packageName = 'org.mozilla.fennec_' + os.getenv('USER')
       else:
         packageName = 'org.mozilla.fennec_'
     self.Init(packageName)
 
+  def __del__(self):
+    if self.host:
+      self.disconnectRemoteADB()
+
   def Init(self, packageName):
     # Initialization code that may fail: Catch exceptions here to allow
     # successful initialization even if, for example, adb is not installed.
     try:
       self.verifyADB()
+      if self.host:
+        self.connectRemoteADB()
       self.verifyRunAs(packageName)
     except:
       self.useRunAs = False
       self.packageName = packageName
     try:
       self.verifyZip()
     except:
       self.useZip = False
@@ -73,17 +79,17 @@ class DeviceManagerADB(DeviceManager):
       if arg.find(" ") or arg.find("(") or arg.find(")") or arg.find("\""):
         cmd[index] = '\'%s\'' % arg
 
     # This is more complex than you'd think because adb doesn't actually
     # return the return code from a process, so we have to capture the output
     # to get it
     # FIXME: this function buffers all output of the command into memory,
     # always. :(
-    cmdline = subprocess.list2cmdline(cmd) + "; echo $?"
+    cmdline = " ".join(cmd) + "; echo $?"
 
     # prepend cwd and env to command if necessary
     if cwd:
       cmdline = "cd %s; %s" % (cwd, cmdline)
     if env:
       envstr = '; '.join(map(lambda x: 'export %s=%s' % (x[0], x[1]), env.iteritems()))
       cmdline = envstr + "; " + cmdline
 
@@ -99,16 +105,22 @@ class DeviceManagerADB(DeviceManager):
       if m:
         return_code = m.group(1)
         outputfile.seek(-2, 2)
         outputfile.truncate() # truncate off the return code
         return return_code
 
     return None
 
+  def connectRemoteADB(self):
+    self.checkCmd(["connect", self.host + ":" + str(self.port)])
+
+  def disconnectRemoteADB(self):
+    self.checkCmd(["disconnect", self.host + ":" + str(self.port)])
+
   # external function
   # returns:
   #  success: True
   #  failure: False
   def pushFile(self, localname, destname):
     try:
       if (os.name == "nt"):
         destname = destname.replace('\\', '/')
--- a/build/mobile/droid.py
+++ b/build/mobile/droid.py
@@ -34,16 +34,17 @@
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
 from devicemanagerADB import DeviceManagerADB
 from devicemanagerSUT import DeviceManagerSUT
+import StringIO
 
 class DroidMixin(object):
   """Mixin to extend DeviceManager with Android-specific functionality"""
 
   def launchApplication(self, app, activity="App",
                         intent="android.intent.action.VIEW", env=None,
                         url=None, extra_args=None):
     """
@@ -54,27 +55,27 @@ class DroidMixin(object):
     """
     # only one instance of an application may be running at once
     if self.processExist(app):
       return False
 
     acmd = [ "am", "start", "-a", intent, "-W", "-n", "%s/.%s" % (app, activity)]
 
     if extra_args:
-      acmd.extend(["--es", "args", " ".join(args)])
+      acmd.extend(["--es", "args", " ".join(extra_args)])
 
     if env:
       envCnt = 0
       # env is expected to be a dict of environment variables
       for envkey, envval in env.iteritems():
         acmd.extend(["--es", "env" + str(envCnt), envkey + "=" + envval])
         envCnt += 1
 
     if url:
-      acmd.extend(["-d", ''.join(['"', url, '"'])])
+      acmd.extend(["-d", ''.join(["'", url, "'"])])
 
     # shell output not that interesting and debugging logs should already
     # show what's going on here... so just create an empty memory buffer
     # and ignore
     shellOutput = StringIO.StringIO()
     if self.shell(acmd, shellOutput) == 0:
       return True
 
--- a/build/mobile/remoteautomation.py
+++ b/build/mobile/remoteautomation.py
@@ -136,27 +136,27 @@ class RemoteAutomation(Automation):
 #TODO: figure out which platform require NO_EM_RESTART
 #        return app, ['--environ:NO_EM_RESTART=1'] + args
         return app, args
 
     def getLanIp(self):
         nettools = NetworkTools()
         return nettools.getLanIp()
 
-    def Process(self, cmd, stdout = None, stderr = None, env = None, cwd = '.'):
+    def Process(self, cmd, stdout = None, stderr = None, env = None, cwd = None):
         if stdout == None or stdout == -1 or stdout == subprocess.PIPE:
           stdout = self._remoteLog
 
         return self.RProcess(self._devicemanager, cmd, stdout, stderr, env, cwd)
 
     # be careful here as this inner class doesn't have access to outer class members    
     class RProcess(object):
         # device manager process
         dm = None
-        def __init__(self, dm, cmd, stdout = None, stderr = None, env = None, cwd = '.'):
+        def __init__(self, dm, cmd, stdout = None, stderr = None, env = None, cwd = None):
             self.dm = dm
             self.stdoutlen = 0
             self.proc = dm.launchProcess(cmd, stdout, cwd, env, True)
             if (self.proc is None):
               if cmd[0] == 'am':
                 self.proc = stdout
               else:
                 raise Exception("unable to launch process")
--- a/build/mobile/sutagent/android/DoCommand.java
+++ b/build/mobile/sutagent/android/DoCommand.java
@@ -62,16 +62,17 @@ import java.security.NoSuchAlgorithmExce
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.GregorianCalendar;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.StringTokenizer;
 import java.util.TimeZone;
 import java.util.zip.Adler32;
 import java.util.zip.CheckedInputStream;
 import java.util.zip.CheckedOutputStream;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 import java.util.zip.ZipInputStream;
 import java.util.zip.ZipOutputStream;
@@ -131,17 +132,17 @@ public class DoCommand {
 
     String    currentDir = "/";
     String    sErrorPrefix = "##AGENT-WARNING## ";
     boolean bTraceOn = false;
 
     String ffxProvider = "org.mozilla.ffxcp";
     String fenProvider = "org.mozilla.fencp";
 
-    private final String prgVersion = "SUTAgentAndroid Version 1.06";
+    private final String prgVersion = "SUTAgentAndroid Version 1.07";
 
     public enum Command
         {
         RUN ("run"),
         EXEC ("exec"),
         EXECCWD ("execcwd"),
         ENVRUN ("envrun"),
         KILL ("kill"),
@@ -2444,16 +2445,58 @@ private void CancelNotification()
                 {
                 if (lProcesses.get(lcv).processName.contains(sProcName))
                     {
                     sRet = sErrorPrefix + "Unable to kill " + nPID + " " + strProcName + "\n";
                     break;
                     }
                 }
             }
+        else
+            {
+            // To kill processes other than Java applications - processes
+            // like xpcshell - a different strategy is necessary: use ps
+            // to find the process' PID.
+            try
+                {
+                pProc = Runtime.getRuntime().exec("ps");
+                RedirOutputThread outThrd = new RedirOutputThread(pProc, null);
+                outThrd.start();
+                outThrd.join(10000);
+                sTmp = outThrd.strOutput;
+                StringTokenizer stokLines = new StringTokenizer(sTmp, "\n");
+                while(stokLines.hasMoreTokens())
+                    {
+                    String sLine = stokLines.nextToken();
+                    StringTokenizer stokColumns = new StringTokenizer(sLine, " \t\n");
+                    stokColumns.nextToken();
+                    String sPid = stokColumns.nextToken();
+                    stokColumns.nextToken();
+                    stokColumns.nextToken();
+                    stokColumns.nextToken();
+                    stokColumns.nextToken();
+                    stokColumns.nextToken();
+                    stokColumns.nextToken();
+                    String sName = null;
+                    if (stokColumns.hasMoreTokens())
+                        {
+                        sName = stokColumns.nextToken();
+                        if (sName.contains(sProcName))
+                            {
+                            NewKillProc(sPid, out);
+                            sRet = "Successfully killed " + sPid + " " + sName + "\n";
+                            }
+                        }
+                    }
+                }
+            catch (Exception e)
+                {
+                e.printStackTrace();
+                }
+            }
 
         return (sRet);
         }
 
     public boolean IsProcessDead(String sProcName)
         {
         boolean bRet = false;
         ActivityManager aMgr = (ActivityManager) contextWrapper.getSystemService(Activity.ACTIVITY_SERVICE);
@@ -2867,25 +2910,20 @@ private void CancelNotification()
             }
 
         return (sRet);
         }
 
     public String NewKillProc(String sProcId, OutputStream out)
         {
         String sRet = "";
-        String [] theArgs = new String [3];
-
-        theArgs[0] = "su";
-        theArgs[1] = "-c";
-        theArgs[2] = "kill " + sProcId;
 
         try
             {
-            pProc = Runtime.getRuntime().exec(theArgs);
+            pProc = Runtime.getRuntime().exec("kill "+sProcId);
             RedirOutputThread outThrd = new RedirOutputThread(pProc, out);
             outThrd.start();
             outThrd.join(5000);
             }
         catch (IOException e)
             {
             sRet = e.getMessage();
             e.printStackTrace();
--- a/build/unix/build-toolchain/build-gcc.py
+++ b/build/unix/build-toolchain/build-gcc.py
@@ -245,16 +245,18 @@ if not os.path.exists(source_dir):
     extract(unifdef_source_tar, source_dir)
     extract(mpc_source_tar, source_dir)
     extract(mpfr_source_tar, source_dir)
     extract(gmp_source_tar, source_dir)
     extract(gcc_source_tar, source_dir)
     patch('plugin_finish_decl.diff', 0, gcc_source_dir)
     patch('pr49911.diff', 1, gcc_source_dir)
     patch('r159628-r163231-r171807.patch', 1, gcc_source_dir)
+    patch('gcc-fixinc.patch', 1, gcc_source_dir)
+    patch('gcc-include.patch', 1, gcc_source_dir)
 
 if os.path.exists(build_dir):
     shutil.rmtree(build_dir)
 os.makedirs(build_dir)
 
 build_aux_tools(build_dir)
 
 stage1_dir = build_dir + '/stage1'
new file mode 100644
--- /dev/null
+++ b/build/unix/build-toolchain/gcc-fixinc.patch
@@ -0,0 +1,12 @@
+diff -ru a/fixincludes/Makefile.in b/fixincludes/Makefile.in
+--- a/fixincludes/Makefile.in	2009-07-30 18:33:49.000000000 -0400
++++ b/fixincludes/Makefile.in	2012-02-27 14:59:09.371875951 -0500
+@@ -126,7 +126,7 @@
+ fixlib.o    : fixlib.c
+ 
+ fixinc.sh : fixinc.in mkfixinc.sh Makefile
+-	srcdir="$(srcdir)" $(SHELL) $(srcdir)/mkfixinc.sh $(target)
++	echo "#!/bin/sh" > $@
+ 
+ $(srcdir)/fixincl.x: @MAINT@ fixincl.tpl inclhack.def
+ 	cd $(srcdir) ; $(SHELL) ./genfixes
new file mode 100644
--- /dev/null
+++ b/build/unix/build-toolchain/gcc-include.patch
@@ -0,0 +1,24 @@
+diff -ru a/configure b/configure
+--- a/configure	2010-10-06 06:29:55.000000000 -0400
++++ b/configure	2012-02-27 20:46:26.303460301 -0500
+@@ -8047,7 +8047,7 @@
+ # being built; programs in there won't even run.
+ if test "${build}" = "${host}" && test -d ${srcdir}/gcc; then
+   # Search for pre-installed headers if nothing else fits.
+-  FLAGS_FOR_TARGET=$FLAGS_FOR_TARGET' -B$(build_tooldir)/bin/ -B$(build_tooldir)/lib/ -isystem $(build_tooldir)/include -isystem $(build_tooldir)/sys-include'
++  FLAGS_FOR_TARGET=$FLAGS_FOR_TARGET' -B$(exec_prefix)/bin/ -B$(exec_prefix)/lib/ -isystem $(exec_prefix)/include -isystem $(exec_prefix)/sys-include'
+ fi
+ 
+ if test "x${use_gnu_ld}" = x &&
+diff -ru a/configure.ac b/configure.ac
+--- a/configure.ac	2010-10-06 06:29:55.000000000 -0400
++++ b/configure.ac	2012-02-27 20:46:22.587442745 -0500
+@@ -3100,7 +3100,7 @@
+ # being built; programs in there won't even run.
+ if test "${build}" = "${host}" && test -d ${srcdir}/gcc; then
+   # Search for pre-installed headers if nothing else fits.
+-  FLAGS_FOR_TARGET=$FLAGS_FOR_TARGET' -B$(build_tooldir)/bin/ -B$(build_tooldir)/lib/ -isystem $(build_tooldir)/include -isystem $(build_tooldir)/sys-include'
++  FLAGS_FOR_TARGET=$FLAGS_FOR_TARGET' -B$(exec_prefix)/bin/ -B$(exec_prefix)/lib/ -isystem $(exec_prefix)/include -isystem $(exec_prefix)/sys-include'
+ fi
+ 
+ if test "x${use_gnu_ld}" = x &&
--- a/caps/src/nsSecurityManagerFactory.cpp
+++ b/caps/src/nsSecurityManagerFactory.cpp
@@ -68,41 +68,41 @@ nsSecurityNameSet::nsSecurityNameSet()
 
 nsSecurityNameSet::~nsSecurityNameSet()
 {
 }
 
 NS_IMPL_ISUPPORTS1(nsSecurityNameSet, nsIScriptExternalNameSet)
 
 static JSString *
-getStringArgument(JSContext *cx, JSObject *obj, PRUint16 argNum, uintN argc, jsval *argv)
+getStringArgument(JSContext *cx, JSObject *obj, PRUint16 argNum, unsigned argc, jsval *argv)
 {
     if (argc <= argNum || !JSVAL_IS_STRING(argv[argNum])) {
         JS_ReportError(cx, "String argument expected");
         return nsnull;
     }
 
     /*
      * We don't want to use JS_ValueToString because we want to be able
      * to have an object to represent a target in subsequent versions.
      */
     return JSVAL_TO_STRING(argv[argNum]);
 }
 
 static bool
-getBytesArgument(JSContext *cx, JSObject *obj, PRUint16 argNum, uintN argc, jsval *argv,
+getBytesArgument(JSContext *cx, JSObject *obj, PRUint16 argNum, unsigned argc, jsval *argv,
                  JSAutoByteString *bytes)
 {
     JSString *str = getStringArgument(cx, obj, argNum, argc, argv);
     return str && bytes->encode(cx, str);
 }
 
 static void
 getUTF8StringArgument(JSContext *cx, JSObject *obj, PRUint16 argNum,
-                      uintN argc, jsval *argv, nsCString& aRetval)
+                      unsigned argc, jsval *argv, nsCString& aRetval)
 {
     aRetval.Truncate();
 
     if (argc <= argNum || !JSVAL_IS_STRING(argv[argNum])) {
         JS_ReportError(cx, "String argument expected");
         return;
     }
 
@@ -117,17 +117,17 @@ getUTF8StringArgument(JSContext *cx, JSO
     const PRUnichar *data = JS_GetStringCharsZ(cx, str);
     if (!data)
         return;
 
     CopyUTF16toUTF8(data, aRetval);
 }
 
 static JSBool
-netscape_security_isPrivilegeEnabled(JSContext *cx, uintN argc, jsval *vp)
+netscape_security_isPrivilegeEnabled(JSContext *cx, unsigned argc, jsval *vp)
 {
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     bool result = false;
     if (JSString *str = getStringArgument(cx, obj, 0, argc, JS_ARGV(cx, vp))) {
         JSAutoByteString cap(cx, str);
@@ -148,17 +148,17 @@ netscape_security_isPrivilegeEnabled(JSC
         return JS_FALSE;
     }
     JS_SET_RVAL(cx, vp, BOOLEAN_TO_JSVAL(result));
     return JS_TRUE;
 }
 
 
 static JSBool
-netscape_security_enablePrivilege(JSContext *cx, uintN argc, jsval *vp)
+netscape_security_enablePrivilege(JSContext *cx, unsigned argc, jsval *vp)
 {
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     JSAutoByteString cap;
     if (!getBytesArgument(cx, obj, 0, argc, JS_ARGV(cx, vp), &cap))
         return JS_FALSE;
@@ -191,17 +191,17 @@ netscape_security_enablePrivilege(JSCont
     rv = securityManager->EnableCapability(cap.ptr());
     if (NS_FAILED(rv))
         return JS_FALSE;
     JS_SET_RVAL(cx, vp, JSVAL_VOID);
     return JS_TRUE;
 }
 
 static JSBool
-netscape_security_disablePrivilege(JSContext *cx, uintN argc, jsval *vp)
+netscape_security_disablePrivilege(JSContext *cx, unsigned argc, jsval *vp)
 {
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     JSAutoByteString cap;
     if (!getBytesArgument(cx, obj, 0, argc, JS_ARGV(cx, vp), &cap))
         return JS_FALSE;
@@ -217,17 +217,17 @@ netscape_security_disablePrivilege(JSCon
     rv = securityManager->DisableCapability(cap.ptr());
     if (NS_FAILED(rv))
         return JS_FALSE;
     JS_SET_RVAL(cx, vp, JSVAL_VOID);
     return JS_TRUE;
 }
 
 static JSBool
-netscape_security_revertPrivilege(JSContext *cx, uintN argc, jsval *vp)
+netscape_security_revertPrivilege(JSContext *cx, unsigned argc, jsval *vp)
 {
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     JSAutoByteString cap;
     if (!getBytesArgument(cx, obj, 0, argc, JS_ARGV(cx, vp), &cap))
         return JS_FALSE;
@@ -243,17 +243,17 @@ netscape_security_revertPrivilege(JSCont
     rv = securityManager->RevertCapability(cap.ptr());
     if (NS_FAILED(rv))
         return JS_FALSE;
     JS_SET_RVAL(cx, vp, JSVAL_VOID);
     return JS_TRUE;
 }
 
 static JSBool
-netscape_security_setCanEnablePrivilege(JSContext *cx, uintN argc, jsval *vp)
+netscape_security_setCanEnablePrivilege(JSContext *cx, unsigned argc, jsval *vp)
 {
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     if (argc < 2) return JS_FALSE;
     nsCAutoString principalFingerprint;
     getUTF8StringArgument(cx, obj, 0, argc, JS_ARGV(cx, vp), principalFingerprint);
@@ -275,17 +275,17 @@ netscape_security_setCanEnablePrivilege(
                                                  nsIPrincipal::ENABLE_GRANTED);
     if (NS_FAILED(rv))
         return JS_FALSE;
     JS_SET_RVAL(cx, vp, JSVAL_VOID);
     return JS_TRUE;
 }
 
 static JSBool
-netscape_security_invalidate(JSContext *cx, uintN argc, jsval *vp)
+netscape_security_invalidate(JSContext *cx, unsigned argc, jsval *vp)
 {
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsCAutoString principalFingerprint;
     getUTF8StringArgument(cx, obj, 0, argc, JS_ARGV(cx, vp), principalFingerprint);
     if (principalFingerprint.IsEmpty())
--- a/content/base/public/nsIObjectLoadingContent.idl
+++ b/content/base/public/nsIObjectLoadingContent.idl
@@ -37,26 +37,27 @@
 
 #include "nsISupports.idl"
 
 interface nsIFrame;
 interface nsIObjectFrame;
 interface nsIPluginTag;
 interface nsIDOMElement;
 interface nsIDOMClientRect;
+interface nsIURI;
 
 %{C++
 #include "nsNPAPIPluginInstance.h"
 %}
 [ptr] native nsNPAPIPluginInstancePtr(nsNPAPIPluginInstance);
 
 /**
  * This interface represents a content node that loads objects.
  */
-[scriptable, uuid(6D8914C7-0E22-4452-8962-11B69BBE84D7)]
+[scriptable, uuid(3FF07AB3-5BAC-4D98-9549-5BD15CCEBCD3)]
 interface nsIObjectLoadingContent : nsISupports
 {
   const unsigned long TYPE_LOADING  = 0;
   const unsigned long TYPE_IMAGE    = 1;
   const unsigned long TYPE_PLUGIN   = 2;
   const unsigned long TYPE_DOCUMENT = 3;
   const unsigned long TYPE_NULL     = 4;
 
@@ -75,16 +76,24 @@ interface nsIObjectLoadingContent : nsIS
   /**
    * Gets the content type that corresponds to the give MIME type.  See the
    * constants above for the list of possible values.  If nothing else fits,
    * TYPE_NULL will be returned.
    */
   unsigned long getContentTypeForMIMEType(in AUTF8String aMimeType);
 
   /**
+  * Gets the base URI to be used for this object. This differs from
+  * nsIContent::GetBaseURI in that it takes codebase attributes into
+  * account. The MIME type is required as some plugins (java) calculate
+  * this differently.
+  */
+  nsIURI GetObjectBaseURI(in ACString aMimeType);
+
+  /**
    * Returns the plugin instance if it has already been instantiated. This
    * will never instantiate the plugin and so is safe to call even when
    * content script must not execute.
    */
   [noscript] readonly attribute nsNPAPIPluginInstancePtr pluginInstance;
 
   /**
    * Tells the content about an associated object frame.
--- a/content/base/src/nsContentAreaDragDrop.cpp
+++ b/content/base/src/nsContentAreaDragDrop.cpp
@@ -403,19 +403,20 @@ DragDataProducer::Produce(nsDOMDataTrans
   nsCOMPtr<nsISelection> selection;
   nsIContent* editingElement = mSelectionTargetNode->IsEditable() ?
                                mSelectionTargetNode->GetEditingHost() : nsnull;
   nsCOMPtr<nsITextControlElement> textControl(do_QueryInterface(editingElement));
   if (textControl) {
     nsISelectionController* selcon = textControl->GetSelectionController();
     if (selcon) {
       selcon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection));
-      if (!selection)
-        return NS_OK;
     }
+
+    if (!selection)
+      return NS_OK;
   }
   else {
     mWindow->GetSelection(getter_AddRefs(selection));
     if (!selection)
       return NS_OK;
 
     // Check if the node is inside a form control. Don't set aCanDrag to false
     //however, as we still want to allow the drag.
@@ -444,21 +445,24 @@ DragDataProducer::Produce(nsDOMDataTrans
     }
   }
 
   // In chrome shells, only allow dragging inside editable areas.
   if (isChromeShell && !editingElement)
     return NS_OK;
 
   if (isChromeShell && textControl) {
-    // Only use the selection if it isn't collapsed.
-    bool isCollapsed = false;
-    selection->GetIsCollapsed(&isCollapsed);
-    if (!isCollapsed)
-      selection.swap(*aSelection);
+    // Only use the selection if the target node is in the selection.
+    bool selectionContainsTarget = false;
+    nsCOMPtr<nsIDOMNode> targetNode = do_QueryInterface(mSelectionTargetNode);
+    selection->ContainsNode(targetNode, false, &selectionContainsTarget);
+    if (!selectionContainsTarget)
+      return NS_OK;
+
+    selection.swap(*aSelection);
   }
   else {
     // In content shells, a number of checks are made below to determine
     // whether an image or a link is being dragged. If so, add additional
     // data to the data transfer. This is also done for chrome shells, but
     // only when in a non-textbox editor.
 
     bool haveSelectedContent = false;
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -171,17 +171,17 @@ nsresult NS_NewContentIterator(nsIConten
 
 void
 nsWrapperCache::RemoveExpandoObject()
 {
   JSObject *expando = GetExpandoObjectPreserveColor();
   if (expando) {
     JSCompartment *compartment = js::GetObjectCompartment(expando);
     xpc::CompartmentPrivate *priv =
-      static_cast<xpc::CompartmentPrivate *>(js_GetCompartmentPrivate(compartment));
+      static_cast<xpc::CompartmentPrivate *>(JS_GetCompartmentPrivate(compartment));
     priv->RemoveDOMExpandoObject(expando);
   }
 }
 
 //----------------------------------------------------------------------
 
 nsINode::nsSlots::~nsSlots()
 {
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -593,17 +593,17 @@ nsObjectLoadingContent::InstantiatePlugi
   // of this method.
   nsCOMPtr<nsIObjectLoadingContent> kungFuDeathGrip = this;
   nsCOMPtr<nsIContent> thisContent = do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
 
   nsCOMPtr<nsIURI> baseURI;
   if (!aURI) {
     // We need some URI. If we have nothing else, use the base URI.
     // XXX(biesi): The code used to do this. Not sure why this is correct...
-    GetObjectBaseURI(thisContent, getter_AddRefs(baseURI));
+    GetObjectBaseURI(nsCString(aMimeType), getter_AddRefs(baseURI));
     aURI = baseURI;
   }
 
   // Flush layout so that the plugin is initialized with the latest information.
   nsIDocument* doc = thisContent->GetCurrentDoc();
   if (!doc) {
     return NS_ERROR_FAILURE;
   }
@@ -1158,17 +1158,17 @@ nsObjectLoadingContent::LoadObject(const
 
   // Avoid StringToURI in order to use the codebase attribute as base URI
   nsCOMPtr<nsIContent> thisContent = 
     do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
   NS_ASSERTION(thisContent, "must be a content");
 
   nsIDocument* doc = thisContent->OwnerDoc();
   nsCOMPtr<nsIURI> baseURI;
-  GetObjectBaseURI(thisContent, getter_AddRefs(baseURI));
+  GetObjectBaseURI(aTypeHint, getter_AddRefs(baseURI));
 
   nsCOMPtr<nsIURI> uri;
   nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(uri),
                                             aURI, doc,
                                             baseURI);
   // If URI creation failed, fallback immediately - this only happens for
   // malformed URIs
   if (!uri) {
@@ -1189,16 +1189,61 @@ nsObjectLoadingContent::UpdateFallbackSt
   // Notify the UI and update the fallback state
   PluginSupportState state = GetPluginSupportState(aContent, aTypeHint);
   if (state != ePluginOtherState) {
     fallback.SetPluginState(state);
     FirePluginError(aContent, state);
   }
 }
 
+bool
+nsObjectLoadingContent::IsFileCodebaseAllowable(nsIURI* aBaseURI, nsIURI* aOriginURI)
+{
+  nsCOMPtr<nsIFileURL> baseFileURL(do_QueryInterface(aBaseURI));
+  nsCOMPtr<nsIFileURL> originFileURL(do_QueryInterface(aOriginURI));
+
+  // get IFile handles and normalize
+  nsCOMPtr<nsIFile> originFile;
+  nsCOMPtr<nsIFile> baseFile;
+  if (!originFileURL || !baseFileURL ||
+      NS_FAILED(originFileURL->GetFile(getter_AddRefs(originFile))) ||
+      NS_FAILED(baseFileURL->GetFile(getter_AddRefs(baseFile))) ||
+      NS_FAILED(baseFile->Normalize()) ||
+      NS_FAILED(originFile->Normalize())) {
+    return false;
+  }
+
+  // If the origin is a directory, it should contain/equal baseURI
+  // Otherwise, its parent directory should contain/equal baseURI
+  bool origin_is_dir;
+  bool contained = false;
+  nsresult rv = originFile->IsDirectory(&origin_is_dir);
+  NS_ENSURE_SUCCESS(rv, false);
+
+  if (origin_is_dir) {
+    // originURI is a directory, ensure it contains the baseURI
+    rv = originFile->Contains(baseFile, true, &contained);
+    if (NS_SUCCEEDED(rv) && !contained) {
+      rv = originFile->Equals(baseFile, &contained);
+    }
+  } else {
+    // originURI is a file, ensure its parent contains the baseURI
+    nsCOMPtr<nsIFile> originParent;
+    rv = originFile->GetParent(getter_AddRefs(originParent));
+    if (NS_SUCCEEDED(rv) && originParent) {
+      rv = originParent->Contains(baseFile, true, &contained);
+      if (NS_SUCCEEDED(rv) && !contained) {
+        rv = originParent->Equals(baseFile, &contained);
+      }
+    }
+  }
+
+  return NS_SUCCEEDED(rv) && contained;
+}
+
 nsresult
 nsObjectLoadingContent::LoadObject(nsIURI* aURI,
                                    bool aNotify,
                                    const nsCString& aTypeHint,
                                    bool aForceLoad)
 {
   // Only do a URI equality check for things that aren't stopped plugins.
   // This is because we still need to load again if the plugin has been stopped.
@@ -1286,16 +1331,38 @@ nsObjectLoadingContent::LoadObject(nsIUR
                                 nsnull, //extra
                                 &shouldLoad,
                                 nsContentUtils::GetContentPolicy(),
                                 secMan);
     if (NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad)) {
       HandleBeingBlockedByContentPolicy(rv, shouldLoad);
       return NS_OK;
     }
+
+    // If this is a file:// URI, require that the codebase (baseURI)
+    // is contained within the same folder as the document origin (originURI)
+    // or within the document origin, if it is a folder.
+    // No originURI implies chrome, which bypasses the check
+    // -- bug 406541
+    nsCOMPtr<nsIURI> originURI;
+    nsCOMPtr<nsIURI> baseURI;
+    GetObjectBaseURI(aTypeHint, getter_AddRefs(baseURI));
+    rv = thisContent->NodePrincipal()->GetURI(getter_AddRefs(originURI));
+    if (NS_FAILED(rv)) {
+      Fallback(aNotify);
+      return NS_OK;
+    }
+    if (originURI) {
+      bool isfile;
+      if (NS_FAILED(originURI->SchemeIs("file", &isfile)) ||
+          (isfile && !IsFileCodebaseAllowable(baseURI, originURI))) {
+        Fallback(aNotify);
+        return NS_OK;
+      }
+    }
   }
 
   nsresult rv = NS_ERROR_UNEXPECTED;
   // This fallback variable MUST be declared after the notifier variable. Do NOT
   // change the order of the declarations!
   AutoFallback fallback(this, &rv);
 
   PRUint32 caps = GetCapabilities();
@@ -1403,17 +1470,17 @@ nsObjectLoadingContent::LoadObject(nsIUR
 
     if (isSupportedClassID) {
       // Use the classid's type
       NS_ASSERTION(!typeForID.IsEmpty(), "Must have a real type!");
       mContentType = typeForID;
       // XXX(biesi). The plugin instantiation code used to pass the base URI
       // here instead of the plugin URI for instantiation via class ID, so I
       // continue to do so. Why that is, no idea...
-      GetObjectBaseURI(thisContent, getter_AddRefs(mURI));
+      GetObjectBaseURI(mContentType, getter_AddRefs(mURI));
       if (!mURI) {
         mURI = aURI;
       }
     }
 
     // rv is references by a stack-based object, need to assign here
     rv = AsyncStartPluginInstance();
 
@@ -1780,35 +1847,39 @@ nsObjectLoadingContent::TypeForClassID(c
       aType.AssignLiteral("application/oleobject");
       return NS_OK;
     }
   }
 
   return NS_ERROR_NOT_AVAILABLE;
 }
 
-void
-nsObjectLoadingContent::GetObjectBaseURI(nsIContent* thisContent, nsIURI** aURI)
+NS_IMETHODIMP
+nsObjectLoadingContent::GetObjectBaseURI(const nsACString & aMimeType, nsIURI** aURI)
 {
-  // We want to use swap(); since this is just called from this file,
-  // we can assert this (callers use comptrs)
-  NS_PRECONDITION(*aURI == nsnull, "URI must be inited to zero");
+  nsCOMPtr<nsIContent> thisContent =
+    do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
 
   // For plugins, the codebase attribute is the base URI
   nsCOMPtr<nsIURI> baseURI = thisContent->GetBaseURI();
   nsAutoString codebase;
   thisContent->GetAttr(kNameSpaceID_None, nsGkAtoms::codebase,
                        codebase);
-  if (!codebase.IsEmpty()) {
-    nsContentUtils::NewURIWithDocumentCharset(aURI, codebase,
-                                              thisContent->OwnerDoc(),
-                                              baseURI);
-  } else {
-    baseURI.swap(*aURI);
+
+  if (codebase.IsEmpty() && aMimeType.Equals("application/x-java-vm")) {
+    // bug 406541
+    // Java resolves codebase="" as "/" -- so we replicate that quirk, to ensure
+    // we run security checks against the same path.
+    codebase.AssignLiteral("/");
   }
+
+  nsContentUtils::NewURIWithDocumentCharset(aURI, codebase,
+                                            thisContent->OwnerDoc(),
+                                            baseURI);
+  return NS_OK;
 }
 
 nsObjectFrame*
 nsObjectLoadingContent::GetExistingFrame()
 {
   nsCOMPtr<nsIContent> thisContent = do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
   nsIFrame* frame = thisContent->GetPrimaryFrame();
   nsIObjectFrame* objFrame = do_QueryFrame(frame);
--- a/content/base/src/nsObjectLoadingContent.h
+++ b/content/base/src/nsObjectLoadingContent.h
@@ -249,16 +249,22 @@ class nsObjectLoadingContent : public ns
     void NotifyContentObjectWrapper();
 
     /**
      * Check whether the given request represents a successful load.
      */
     static bool IsSuccessfulRequest(nsIRequest* aRequest);
 
     /**
+     * Check if the given baseURI is contained in the same directory as the
+     * aOriginURI (or a child thereof)
+     */
+    static bool IsFileCodebaseAllowable(nsIURI* aBaseURI, nsIURI* aOriginURI);
+
+    /**
      * Check whether the URI can be handled internally.
      */
     static bool CanHandleURI(nsIURI* aURI);
 
     /**
      * Checks whether the given type is a supported document type.
      */
     bool IsSupportedDocument(const nsCString& aType);
@@ -295,24 +301,16 @@ class nsObjectLoadingContent : public ns
      * For a classid, returns the MIME type that can be used to instantiate
      * a plugin for this ID.
      *
      * @return NS_ERROR_NOT_AVAILABLE Unsupported class ID.
      */
     nsresult TypeForClassID(const nsAString& aClassID, nsACString& aType);
 
     /**
-     * Gets the base URI to be used for this object. This differs from
-     * nsIContent::GetBaseURI in that it takes codebase attributes into
-     * account.
-     */
-    void GetObjectBaseURI(nsIContent* thisContent, nsIURI** aURI);
-
-
-    /**
      * Gets the frame that's associated with this content node.
      * Does not flush.
      */
     nsObjectFrame* GetExistingFrame();
 
     /**
      * Handle being blocked by a content policy.  aStatus is the nsresult
      * return value of the Should* call, while aRetval is what it returned in
--- a/content/canvas/src/CustomQS_Canvas2D.h
+++ b/content/canvas/src/CustomQS_Canvas2D.h
@@ -241,17 +241,17 @@ GetImageDataDimensions(JSContext *cx, JS
         return xpc_qsThrow(cx, NS_ERROR_DOM_INDEX_SIZE_ERR);
 
     *width = uint32_t(wi);
     *height = uint32_t(hi);
     return true;
 }
 
 static JSBool
-nsIDOMCanvasRenderingContext2D_CreateImageData(JSContext *cx, uintN argc, jsval *vp)
+nsIDOMCanvasRenderingContext2D_CreateImageData(JSContext *cx, unsigned argc, jsval *vp)
 {
     XPC_QS_ASSERT_CONTEXT_OK(cx);
 
     /* Note: this doesn't need JS_THIS_OBJECT */
 
     if (argc < 1)
         return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
 
@@ -287,17 +287,17 @@ nsIDOMCanvasRenderingContext2D_CreateIma
     int32_t hi = JS_DoubleToInt32(height);
 
     uint32_t w = NS_ABS(wi);
     uint32_t h = NS_ABS(hi);
     return CreateImageData(cx, w, h, NULL, 0, 0, vp);
 }
 
 static JSBool
-nsIDOMCanvasRenderingContext2D_GetImageData(JSContext *cx, uintN argc, jsval *vp)
+nsIDOMCanvasRenderingContext2D_GetImageData(JSContext *cx, unsigned argc, jsval *vp)
 {
     XPC_QS_ASSERT_CONTEXT_OK(cx);
 
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsIDOMCanvasRenderingContext2D *self;
@@ -344,17 +344,17 @@ nsIDOMCanvasRenderingContext2D_GetImageD
         y -= h;
     } else {
         h = hi;
     }
     return CreateImageData(cx, w, h, self, x, y, vp);
 }
 
 static JSBool
-nsIDOMCanvasRenderingContext2D_PutImageData(JSContext *cx, uintN argc, jsval *vp)
+nsIDOMCanvasRenderingContext2D_PutImageData(JSContext *cx, unsigned argc, jsval *vp)
 {
     XPC_QS_ASSERT_CONTEXT_OK(cx);
 
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsresult rv;
--- a/content/canvas/src/CustomQS_WebGL.h
+++ b/content/canvas/src/CustomQS_WebGL.h
@@ -78,17 +78,17 @@ helper_isFloat32Array(JSObject *obj) {
 
 /*
  * BufferData takes:
  *    BufferData (int, int, int)
  *    BufferData_buf (int, js::ArrayBuffer *, int)
  *    BufferData_array (int, js::TypedArray *, int)
  */
 static JSBool
-nsIDOMWebGLRenderingContext_BufferData(JSContext *cx, uintN argc, jsval *vp)
+nsIDOMWebGLRenderingContext_BufferData(JSContext *cx, unsigned argc, jsval *vp)
 {
     XPC_QS_ASSERT_CONTEXT_OK(cx);
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsIDOMWebGLRenderingContext *self;
     xpc_qsSelfRef selfref;
@@ -151,17 +151,17 @@ nsIDOMWebGLRenderingContext_BufferData(J
 }
 
 /*
  * BufferSubData takes:
  *    BufferSubData (int, int, js::ArrayBuffer *)
  *    BufferSubData_array (int, int, js::TypedArray *)
  */
 static JSBool
-nsIDOMWebGLRenderingContext_BufferSubData(JSContext *cx, uintN argc, jsval *vp)
+nsIDOMWebGLRenderingContext_BufferSubData(JSContext *cx, unsigned argc, jsval *vp)
 {
     XPC_QS_ASSERT_CONTEXT_OK(cx);
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsIDOMWebGLRenderingContext *self;
     xpc_qsSelfRef selfref;
@@ -223,17 +223,17 @@ nsIDOMWebGLRenderingContext_BufferSubDat
     return JS_TRUE;
 }
 
 /*
  * CompressedTexImage2D takes:
  *    CompressedTexImage2D(uint, int, uint, int, int, int, ArrayBufferView)
  */
 static JSBool
-nsIDOMWebGLRenderingContext_CompressedTexImage2D(JSContext *cx, uintN argc, jsval *vp)
+nsIDOMWebGLRenderingContext_CompressedTexImage2D(JSContext *cx, unsigned argc, jsval *vp)
 {
     XPC_QS_ASSERT_CONTEXT_OK(cx);
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsresult rv;
 
@@ -273,17 +273,17 @@ nsIDOMWebGLRenderingContext_CompressedTe
     return JS_TRUE;
 }
 
 /*
  * CompressedTexSubImage2D takes:
  *    CompressedTexSubImage2D(uint, int, int, int, int, int, uint, ArrayBufferView)
  */
 static JSBool
-nsIDOMWebGLRenderingContext_CompressedTexSubImage2D(JSContext *cx, uintN argc, jsval *vp)
+nsIDOMWebGLRenderingContext_CompressedTexSubImage2D(JSContext *cx, unsigned argc, jsval *vp)
 {
     XPC_QS_ASSERT_CONTEXT_OK(cx);
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsresult rv;
 
@@ -324,17 +324,17 @@ nsIDOMWebGLRenderingContext_CompressedTe
     return JS_TRUE;
 }
 
 /*
  * ReadPixels takes:
  *    ReadPixels(int, int, int, int, uint, uint, ArrayBufferView)
  */
 static JSBool
-nsIDOMWebGLRenderingContext_ReadPixels(JSContext *cx, uintN argc, jsval *vp)
+nsIDOMWebGLRenderingContext_ReadPixels(JSContext *cx, unsigned argc, jsval *vp)
 {
     XPC_QS_ASSERT_CONTEXT_OK(cx);
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsresult rv;
 
@@ -384,17 +384,17 @@ nsIDOMWebGLRenderingContext_ReadPixels(J
 
 /*
  * TexImage2D takes:
  *    TexImage2D(uint, int, uint, int, int, int, uint, uint, ArrayBufferView)
  *    TexImage2D(uint, int, uint, uint, uint, nsIDOMElement)
  *    TexImage2D(uint, int, uint, uint, uint, ImageData)
  */
 static JSBool
-nsIDOMWebGLRenderingContext_TexImage2D(JSContext *cx, uintN argc, jsval *vp)
+nsIDOMWebGLRenderingContext_TexImage2D(JSContext *cx, unsigned argc, jsval *vp)
 {
     XPC_QS_ASSERT_CONTEXT_OK(cx);
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsresult rv;
 
@@ -505,17 +505,17 @@ nsIDOMWebGLRenderingContext_TexImage2D(J
 }
 
 /* TexSubImage2D takes:
  *    TexSubImage2D(uint, int, int, int, int, int, uint, uint, ArrayBufferView)
  *    TexSubImage2D(uint, int, int, int, uint, uint, nsIDOMElement)
  *    TexSubImage2D(uint, int, int, int, uint, uint, ImageData)
  */
 static JSBool
-nsIDOMWebGLRenderingContext_TexSubImage2D(JSContext *cx, uintN argc, jsval *vp)
+nsIDOMWebGLRenderingContext_TexSubImage2D(JSContext *cx, unsigned argc, jsval *vp)
 {
     XPC_QS_ASSERT_CONTEXT_OK(cx);
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsresult rv;
 
@@ -616,17 +616,17 @@ nsIDOMWebGLRenderingContext_TexSubImage2
         return xpc_qsThrowMethodFailed(cx, rv, vp);
 
     *vp = JSVAL_VOID;
     return JS_TRUE;
 }
 
 /* NOTE: There is a TN version of this below, update it as well */
 static inline JSBool
-helper_nsIDOMWebGLRenderingContext_Uniform_x_iv(JSContext *cx, uintN argc, jsval *vp, int nElements)
+helper_nsIDOMWebGLRenderingContext_Uniform_x_iv(JSContext *cx, unsigned argc, jsval *vp, int nElements)
 {
     XPC_QS_ASSERT_CONTEXT_OK(cx);
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsresult rv;
 
@@ -690,17 +690,17 @@ helper_nsIDOMWebGLRenderingContext_Unifo
         return xpc_qsThrowMethodFailed(cx, rv, vp);
 
     *vp = JSVAL_VOID;
     return JS_TRUE;
 }
 
 /* NOTE: There is a TN version of this below, update it as well */
 static inline JSBool
-helper_nsIDOMWebGLRenderingContext_Uniform_x_fv(JSContext *cx, uintN argc, jsval *vp, int nElements)
+helper_nsIDOMWebGLRenderingContext_Uniform_x_fv(JSContext *cx, unsigned argc, jsval *vp, int nElements)
 {
     XPC_QS_ASSERT_CONTEXT_OK(cx);
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsresult rv;
 
@@ -764,17 +764,17 @@ helper_nsIDOMWebGLRenderingContext_Unifo
         return xpc_qsThrowMethodFailed(cx, rv, vp);
 
     *vp = JSVAL_VOID;
     return JS_TRUE;
 }
 
 /* NOTE: There is a TN version of this below, update it as well */
 static inline JSBool
-helper_nsIDOMWebGLRenderingContext_UniformMatrix_x_fv(JSContext *cx, uintN argc, jsval *vp, int nElements)
+helper_nsIDOMWebGLRenderingContext_UniformMatrix_x_fv(JSContext *cx, unsigned argc, jsval *vp, int nElements)
 {
     XPC_QS_ASSERT_CONTEXT_OK(cx);
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsIDOMWebGLRenderingContext *self;
     xpc_qsSelfRef selfref;
@@ -837,17 +837,17 @@ helper_nsIDOMWebGLRenderingContext_Unifo
     if (NS_FAILED(rv))
         return xpc_qsThrowMethodFailed(cx, rv, vp);
 
     *vp = JSVAL_VOID;
     return JS_TRUE;
 }
 
 static inline JSBool
-helper_nsIDOMWebGLRenderingContext_VertexAttrib_x_fv(JSContext *cx, uintN argc, jsval *vp, int nElements)
+helper_nsIDOMWebGLRenderingContext_VertexAttrib_x_fv(JSContext *cx, unsigned argc, jsval *vp, int nElements)
 {
     XPC_QS_ASSERT_CONTEXT_OK(cx);
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsIDOMWebGLRenderingContext *self;
     xpc_qsSelfRef selfref;
@@ -905,96 +905,96 @@ helper_nsIDOMWebGLRenderingContext_Verte
     if (NS_FAILED(rv))
         return xpc_qsThrowMethodFailed(cx, rv, vp);
 
     *vp = JSVAL_VOID;
     return JS_TRUE;
 }
 
 static JSBool
-nsIDOMWebGLRenderingContext_Uniform1iv(JSContext *cx, uintN argc, jsval *vp)
+nsIDOMWebGLRenderingContext_Uniform1iv(JSContext *cx, unsigned argc, jsval *vp)
 {
     return helper_nsIDOMWebGLRenderingContext_Uniform_x_iv(cx, argc, vp, 1);
 }
 
 static JSBool
-nsIDOMWebGLRenderingContext_Uniform2iv(JSContext *cx, uintN argc, jsval *vp)
+nsIDOMWebGLRenderingContext_Uniform2iv(JSContext *cx, unsigned argc, jsval *vp)
 {
     return helper_nsIDOMWebGLRenderingContext_Uniform_x_iv(cx, argc, vp, 2);
 }
 
 static JSBool
-nsIDOMWebGLRenderingContext_Uniform3iv(JSContext *cx, uintN argc, jsval *vp)
+nsIDOMWebGLRenderingContext_Uniform3iv(JSContext *cx, unsigned argc, jsval *vp)
 {
     return helper_nsIDOMWebGLRenderingContext_Uniform_x_iv(cx, argc, vp, 3);
 }
 
 static JSBool
-nsIDOMWebGLRenderingContext_Uniform4iv(JSContext *cx, uintN argc, jsval *vp)
+nsIDOMWebGLRenderingContext_Uniform4iv(JSContext *cx, unsigned argc, jsval *vp)
 {
     return helper_nsIDOMWebGLRenderingContext_Uniform_x_iv(cx, argc, vp, 4);
 }
 
 static JSBool
-nsIDOMWebGLRenderingContext_Uniform1fv(JSContext *cx, uintN argc, jsval *vp)
+nsIDOMWebGLRenderingContext_Uniform1fv(JSContext *cx, unsigned argc, jsval *vp)
 {
     return helper_nsIDOMWebGLRenderingContext_Uniform_x_fv(cx, argc, vp, 1);
 }
 
 static JSBool
-nsIDOMWebGLRenderingContext_Uniform2fv(JSContext *cx, uintN argc, jsval *vp)
+nsIDOMWebGLRenderingContext_Uniform2fv(JSContext *cx, unsigned argc, jsval *vp)
 {
     return helper_nsIDOMWebGLRenderingContext_Uniform_x_fv(cx, argc, vp, 2);
 }
 
 static JSBool
-nsIDOMWebGLRenderingContext_Uniform3fv(JSContext *cx, uintN argc, jsval *vp)
+nsIDOMWebGLRenderingContext_Uniform3fv(JSContext *cx, unsigned argc, jsval *vp)
 {
     return helper_nsIDOMWebGLRenderingContext_Uniform_x_fv(cx, argc, vp, 3);
 }
 
 static JSBool
-nsIDOMWebGLRenderingContext_Uniform4fv(JSContext *cx, uintN argc, jsval *vp)
+nsIDOMWebGLRenderingContext_Uniform4fv(JSContext *cx, unsigned argc, jsval *vp)
 {
     return helper_nsIDOMWebGLRenderingContext_Uniform_x_fv(cx, argc, vp, 4);
 }
 
 static JSBool
-nsIDOMWebGLRenderingContext_UniformMatrix2fv(JSContext *cx, uintN argc, jsval *vp)
+nsIDOMWebGLRenderingContext_UniformMatrix2fv(JSContext *cx, unsigned argc, jsval *vp)
 {
     return helper_nsIDOMWebGLRenderingContext_UniformMatrix_x_fv(cx, argc, vp, 2);
 }
 
 static JSBool
-nsIDOMWebGLRenderingContext_UniformMatrix3fv(JSContext *cx, uintN argc, jsval *vp)
+nsIDOMWebGLRenderingContext_UniformMatrix3fv(JSContext *cx, unsigned argc, jsval *vp)
 {
     return helper_nsIDOMWebGLRenderingContext_UniformMatrix_x_fv(cx, argc, vp, 3);
 }
 
 static JSBool
-nsIDOMWebGLRenderingContext_UniformMatrix4fv(JSContext *cx, uintN argc, jsval *vp)
+nsIDOMWebGLRenderingContext_UniformMatrix4fv(JSContext *cx, unsigned argc, jsval *vp)
 {
     return helper_nsIDOMWebGLRenderingContext_UniformMatrix_x_fv(cx, argc, vp, 4);
 }
 
 static JSBool
-nsIDOMWebGLRenderingContext_VertexAttrib1fv(JSContext *cx, uintN argc, jsval *vp)
+nsIDOMWebGLRenderingContext_VertexAttrib1fv(JSContext *cx, unsigned argc, jsval *vp)
 {
     return helper_nsIDOMWebGLRenderingContext_VertexAttrib_x_fv(cx, argc, vp, 1);
 }
 
 static JSBool
-nsIDOMWebGLRenderingContext_VertexAttrib2fv(JSContext *cx, uintN argc, jsval *vp)
+nsIDOMWebGLRenderingContext_VertexAttrib2fv(JSContext *cx, unsigned argc, jsval *vp)
 {
     return helper_nsIDOMWebGLRenderingContext_VertexAttrib_x_fv(cx, argc, vp, 2);
 }
 
 static JSBool
-nsIDOMWebGLRenderingContext_VertexAttrib3fv(JSContext *cx, uintN argc, jsval *vp)
+nsIDOMWebGLRenderingContext_VertexAttrib3fv(JSContext *cx, unsigned argc, jsval *vp)
 {
     return helper_nsIDOMWebGLRenderingContext_VertexAttrib_x_fv(cx, argc, vp, 3);
 }
 
 static JSBool
-nsIDOMWebGLRenderingContext_VertexAttrib4fv(JSContext *cx, uintN argc, jsval *vp)
+nsIDOMWebGLRenderingContext_VertexAttrib4fv(JSContext *cx, unsigned argc, jsval *vp)
 {
     return helper_nsIDOMWebGLRenderingContext_VertexAttrib_x_fv(cx, argc, vp, 4);
 }
--- a/content/canvas/test/webgl/test_webgl_conformance_test_suite.html
+++ b/content/canvas/test/webgl/test_webgl_conformance_test_suite.html
@@ -59,16 +59,44 @@ function start() {
   var kIsWindowsVistaOrHigher = false;
   if (kIsWindows) {
     // code borrowed from browser/modules/test/browser_taskbar_preview.js
     netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
     var version = Components.classes["@mozilla.org/system-info;1"]
                             .getService(Components.interfaces.nsIPropertyBag2)
                             .getProperty("version");
     kIsWindowsVistaOrHigher = (parseFloat(version) >= 6.0);
+    // Workaround for Windows 2000 (driver?) which may crash itself.
+    if (parseFloat(version) <= 5.0) {
+      todo(false, "Test disabled on Windows 2000 and older. (To prevent possible system crash.)");
+      SimpleTest.finish();
+      return;
+    }
+  }
+
+  // we currently disable this test on version of Mac OSX older than 10.6,
+  // due to various weird failures, including one making getRenderbufferParameter tests
+  // on DEPTH_STENCIL fail
+  var kDarwinVersion = 0;
+  if (kIsMac) {
+    // code borrowed from browser/modules/test/browser_taskbar_preview.js
+    var is106orHigher = false;
+    netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+    kDarwinVersion = parseFloat(Components.classes["@mozilla.org/system-info;1"]
+                                          .getService(Components.interfaces.nsIPropertyBag2)
+                                          .getProperty("version"));
+    // the next line is correct: Mac OS 10.6 corresponds to Darwin version 10 !
+    // Mac OS 10.5 would be Darwin version 9. the |version| string we've got here
+    // is the Darwin version.
+    is106orHigher = (kDarwinVersion >= 10.0);
+    if (!is106orHigher) {
+      dump("WebGL mochitest disabled on Mac OSX versions older than 10.6\n");
+      SimpleTest.finish();
+      return;
+    }
   }
 
   // we currently disable this test on version of Mac OSX older than 10.6,
   // due to various weird failures, including one making getRenderbufferParameter tests
   // on DEPTH_STENCIL fail
   var kDarwinVersion = 0;
   if (kIsMac) {
     // code borrowed from browser/modules/test/browser_taskbar_preview.js
@@ -399,16 +427,17 @@ function start() {
     } else {
         var errmsg = "Can't create a WebGL context";
         reporter.fullResultsNode.textContent = errmsg;
         // Workaround for SeaMonkey tinderboxes which don't support WebGL.
         if (navigator.userAgent.match(/ SeaMonkey\//))
           todo(false, errmsg + " (This is expected on SeaMonkey (tinderboxes).)");
         else
           ok(false, errmsg);
+        dump("WebGL mochitest failed: " + errmsg + "\n");
         reporter.finishedTestSuite();
     }
   };
 
   SimpleTest.requestLongerTimeout(3);
 
   var statusElem = document.getElementById("status");
   var statusTextNode = document.createTextNode('');
--- a/content/media/nsMediaCache.cpp
+++ b/content/media/nsMediaCache.cpp
@@ -2155,26 +2155,28 @@ nsMediaCacheStream::Read(char* aBuffer, 
     return NS_ERROR_FAILURE;
 
   PRUint32 count = 0;
   // Read one block (or part of a block) at a time
   while (count < aCount) {
     PRUint32 streamBlock = PRUint32(mStreamOffset/BLOCK_SIZE);
     PRUint32 offsetInStreamBlock =
       PRUint32(mStreamOffset - streamBlock*BLOCK_SIZE);
-    PRInt32 size = NS_MIN(aCount - count, BLOCK_SIZE - offsetInStreamBlock);
+    PRInt64 size = NS_MIN(aCount - count, BLOCK_SIZE - offsetInStreamBlock);
 
     if (mStreamLength >= 0) {
       // Don't try to read beyond the end of the stream
       PRInt64 bytesRemaining = mStreamLength - mStreamOffset;
       if (bytesRemaining <= 0) {
         // Get out of here and return NS_OK
         break;
       }
-      size = NS_MIN(size, PRInt32(bytesRemaining));
+      size = NS_MIN(size, bytesRemaining);
+      // Clamp size until 64-bit file size issues (bug 500784) are fixed.
+      size = NS_MIN(size, PRInt64(PR_INT32_MAX));
     }
 
     PRInt32 bytes;
     PRInt32 cacheBlock = streamBlock < mBlocks.Length() ? mBlocks[streamBlock] : -1;
     if (cacheBlock < 0) {
       // We don't have a complete cached block here.
 
       if (count > 0) {
@@ -2219,17 +2221,18 @@ nsMediaCacheStream::Read(char* aBuffer, 
         return NS_ERROR_FAILURE;
       }
       continue;
     }
 
     gMediaCache->NoteBlockUsage(this, cacheBlock, mCurrentMode, TimeStamp::Now());
 
     PRInt64 offset = cacheBlock*BLOCK_SIZE + offsetInStreamBlock;
-    nsresult rv = gMediaCache->ReadCacheFile(offset, aBuffer + count, size, &bytes);
+    NS_ASSERTION(size >= 0 && size <= PR_INT32_MAX, "Size out of range.");
+    nsresult rv = gMediaCache->ReadCacheFile(offset, aBuffer + count, PRInt32(size), &bytes);
     if (NS_FAILED(rv)) {
       if (count == 0)
         return rv;
       // If we did successfully read some data, may as well return it
       break;
     }
     mStreamOffset += bytes;
     count += bytes;
--- a/content/xbl/src/nsXBLBinding.cpp
+++ b/content/xbl/src/nsXBLBinding.cpp
@@ -111,17 +111,17 @@ XBLFinalize(JSContext *cx, JSObject *obj
     static_cast<nsXBLDocumentInfo*>(::JS_GetPrivate(obj));
   NS_RELEASE(docInfo);
   
   nsXBLJSClass* c = static_cast<nsXBLJSClass*>(::JS_GetClass(obj));
   c->Drop();
 }
 
 static JSBool
-XBLResolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
+XBLResolve(JSContext *cx, JSObject *obj, jsid id, unsigned flags,
            JSObject **objp)
 {
   // Note: if we get here, that means that the implementation for some binding
   // was installed, which means that AllowScripts() tested true.  Hence no need
   // to do checks like that here.
   
   // Default to not resolving things.
   NS_ASSERTION(*objp, "Must have starting object");
--- a/content/xbl/src/nsXBLProtoImplField.h
+++ b/content/xbl/src/nsXBLProtoImplField.h
@@ -75,12 +75,12 @@ public:
   const PRUnichar* GetName() const { return mName; }
 
 protected:
   nsXBLProtoImplField* mNext;
   PRUnichar* mName;
   PRUnichar* mFieldText;
   PRUint32 mFieldTextLength;
   PRUint32 mLineNumber;
-  uintN mJSAttributes;
+  unsigned mJSAttributes;
 };
 
 #endif // nsXBLProtoImplField_h__
--- a/content/xbl/src/nsXBLProtoImplProperty.h
+++ b/content/xbl/src/nsXBLProtoImplProperty.h
@@ -92,16 +92,16 @@ protected:
 
   union {
     // The raw text for the setter (prior to compilation).
     nsXBLTextWithLineNumber* mSetterText;
     // The JS object for the setter (after compilation)
     JSObject *               mJSSetterObject;
   };
   
-  uintN mJSAttributes;          // A flag for all our JS properties (getter/setter/readonly/shared/enum)
+  unsigned mJSAttributes;          // A flag for all our JS properties (getter/setter/readonly/shared/enum)
 
 #ifdef DEBUG
   bool mIsCompiled;
 #endif
 };
 
 #endif // nsXBLProtoImplProperty_h__
--- a/dom/Makefile.in
+++ b/dom/Makefile.in
@@ -42,16 +42,17 @@ VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= dom
 
 DIRS = \
   interfaces/base \
   interfaces/canvas \
+  interfaces/contacts \
   interfaces/core \
   interfaces/html \
   interfaces/events \
   interfaces/stylesheets \
   interfaces/sidebar \
   interfaces/css \
   interfaces/traversal \
   interfaces/range \
@@ -72,16 +73,17 @@ ifeq (gonk,$(MOZ_WIDGET_TOOLKIT))
 DIRS += \
   interfaces/apps \
   $(NULL)
 endif
 
 DIRS += \
   base \
   battery \
+  contacts \
   power \
   sms \
   src \
   locales \
   network \
   plugins/base \
   plugins/ipc \
   indexedDB \
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -679,21 +679,16 @@ protected:
 
   virtual ~IDBEventTargetSH()
   { }
 
 public:
   NS_IMETHOD PreCreate(nsISupports *aNativeObj, JSContext *aCx,
                        JSObject *aGlobalObj, JSObject **aParentObj);
 
-  NS_IMETHOD AddProperty(nsIXPConnectWrappedNative *aWrapper, JSContext *aCx,
-                         JSObject *aObj, jsid aId, jsval *aVp, bool *aRetval);
-
-  virtual void PreserveWrapper(nsISupports *aNative);
-
   static nsIClassInfo *doCreate(nsDOMClassInfoData *aData)
   {
     return new IDBEventTargetSH(aData);
   }
 };
 
 } // anonymous namespace
 
@@ -5235,17 +5230,17 @@ GetDocument(JSObject *obj)
 {
   return static_cast<nsHTMLDocument*>(
     static_cast<nsIHTMLDocument*>(::JS_GetPrivate(obj)));
 }
 
 // static
 JSBool
 nsWindowSH::GlobalScopePolluterNewResolve(JSContext *cx, JSObject *obj,
-                                          jsid id, uintN flags,
+                                          jsid id, unsigned flags,
                                           JSObject **objp)
 {
   if (flags & (JSRESOLVE_ASSIGNING | JSRESOLVE_DECLARING |
                JSRESOLVE_CLASSNAME | JSRESOLVE_QUALIFIED) ||
       !JSID_IS_STRING(id)) {
     // Nothing to do here if we're either assigning or declaring,
     // resolving a class name, doing a qualified resolve, or
     // resolving a number.
@@ -5541,17 +5536,17 @@ FindConstructorFunc(const nsDOMClassInfo
     }
   }
   return nsnull;
 }
 
 static nsresult
 BaseStubConstructor(nsIWeakReference* aWeakOwner,
                     const nsGlobalNameStruct *name_struct, JSContext *cx,
-                    JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+                    JSObject *obj, unsigned argc, jsval *argv, jsval *rval)
 {
   nsresult rv;
   nsCOMPtr<nsISupports> native;
   if (name_struct->mType == nsGlobalNameStruct::eTypeClassConstructor) {
     const nsDOMClassInfoData* ci_data =
       &sClassInfoData[name_struct->mDOMClassInfoID];
     const char *contractid = FindConstructorContractID(ci_data);
     if (contractid) {
@@ -6635,17 +6630,17 @@ nsWindowSH::GlobalResolve(nsGlobalWindow
   }
 
   return rv;
 }
 
 // Native code for window._content getter, this simply maps
 // window._content to window.content for backwards compatibility only.
 static JSBool
-ContentWindowGetter(JSContext *cx, uintN argc, jsval *vp)
+ContentWindowGetter(JSContext *cx, unsigned argc, jsval *vp)
 {
   JSObject *obj = JS_THIS_OBJECT(cx, vp);
   if (!obj)
     return JS_FALSE;
 
   return ::JS_GetProperty(cx, obj, "content", vp);
 }
 
@@ -7695,35 +7690,16 @@ IDBEventTargetSH::PreCreate(nsISupports 
                             JSObject *aGlobalObj, JSObject **aParentObj)
 {
   IDBWrapperCache *target = IDBWrapperCache::FromSupports(aNativeObj);
   JSObject *parent = target->GetParentObject();
   *aParentObj = parent ? parent : aGlobalObj;
   return NS_OK;
 }
 
-NS_IMETHODIMP
-IDBEventTargetSH::AddProperty(nsIXPConnectWrappedNative *aWrapper,
-                              JSContext *aCx, JSObject *aObj, jsid aId,
-                              jsval *aVp, bool *aRetval)
-{
-  if (aId != sAddEventListener_id) {
-    IDBEventTargetSH::PreserveWrapper(GetNative(aWrapper, aObj));
-  }
-
-  return NS_OK;
-}
-
-void
-IDBEventTargetSH::PreserveWrapper(nsISupports *aNative)
-{
-  IDBWrapperCache *target = IDBWrapperCache::FromSupports(aNative);
-  nsContentUtils::PreserveWrapper(aNative, target);
-}
-
 // Element helper
 
 static bool
 GetBindingURL(Element *aElement, nsIDocument *aDocument,
               nsCSSValue::URL **aResult)
 {
   // If we have a frame the frame has already loaded the binding.  And
   // otherwise, don't do anything else here unless we're dealing with
@@ -8896,17 +8872,17 @@ nsHTMLDocumentSH::DocumentAllGetProperty
     *vp = JSVAL_VOID;
   }
 
   return JS_TRUE;
 }
 
 JSBool
 nsHTMLDocumentSH::DocumentAllNewResolve(JSContext *cx, JSObject *obj, jsid id,
-                                        uintN flags, JSObject **objp)
+                                        unsigned flags, JSObject **objp)
 {
   if (flags & JSRESOLVE_ASSIGNING) {
     // Nothing to do here if we're assigning
 
     return JS_TRUE;
   }
 
   jsval v = JSVAL_VOID;
@@ -8966,17 +8942,17 @@ void
 nsHTMLDocumentSH::ReleaseDocument(JSContext *cx, JSObject *obj)
 {
   nsIHTMLDocument *doc = (nsIHTMLDocument *)::JS_GetPrivate(obj);
 
   NS_IF_RELEASE(doc);
 }
 
 JSBool
-nsHTMLDocumentSH::CallToGetPropMapper(JSContext *cx, uintN argc, jsval *vp)
+nsHTMLDocumentSH::CallToGetPropMapper(JSContext *cx, unsigned argc, jsval *vp)
 {
   // Handle document.all("foo") style access to document.all.
 
   if (argc != 1) {
     // XXX: Should throw NS_ERROR_XPC_NOT_ENOUGH_ARGS for argc < 1,
     // and create a new NS_ERROR_XPC_TOO_MANY_ARGS for argc > 1? IE
     // accepts nothing other than one arg.
     nsDOMClassInfo::ThrowJSException(cx, NS_ERROR_INVALID_ARG);
@@ -9092,17 +9068,17 @@ nsHTMLDocumentSH::DocumentAllHelperGetPr
     }
   }
 
   return JS_TRUE;
 }
 
 JSBool
 nsHTMLDocumentSH::DocumentAllHelperNewResolve(JSContext *cx, JSObject *obj,
-                                              jsid id, uintN flags,
+                                              jsid id, unsigned flags,
                                               JSObject **objp)
 {
   if (id == nsDOMClassInfo::sAll_id) {
     // document.all is resolved for the first time. Define it.
     JSObject *helper = GetDocumentAllHelper(obj);
 
     if (helper) {
       if (!::JS_DefineProperty(cx, helper, "all", JSVAL_VOID, nsnull, nsnull,
@@ -9115,17 +9091,17 @@ nsHTMLDocumentSH::DocumentAllHelperNewRe
   }
 
   return JS_TRUE;
 }
 
 
 JSBool
 nsHTMLDocumentSH::DocumentAllTagsNewResolve(JSContext *cx, JSObject *obj,
-                                            jsid id, uintN flags,
+                                            jsid id, unsigned flags,
                                             JSObject **objp)
 {
   if (JSID_IS_STRING(id)) {
     nsDocument *doc = GetDocument(obj);
 
     JSObject *proto = ::JS_GetPrototype(obj);
     if (NS_UNLIKELY(!proto)) {
       return JS_TRUE;
--- a/dom/base/nsDOMClassInfo.h
+++ b/dom/base/nsDOMClassInfo.h
@@ -420,17 +420,17 @@ public:
                         JSObject *obj, jsid id, PRUint32 flags,
                         JSObject **objp, bool *_retval);
   NS_IMETHOD Finalize(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
                       JSObject *obj);
   NS_IMETHOD OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
                          JSObject * obj, JSObject * *_retval);
 
   static JSBool GlobalScopePolluterNewResolve(JSContext *cx, JSObject *obj,
-                                              jsid id, uintN flags,
+                                              jsid id, unsigned flags,
                                               JSObject **objp);
   static JSBool GlobalScopePolluterGetProperty(JSContext *cx, JSObject *obj,
                                                jsid id, jsval *vp);
   static JSBool SecurityCheckOnAddDelProp(JSContext *cx, JSObject *obj, jsid id,
                                           jsval *vp);
   static JSBool SecurityCheckOnSetProp(JSContext *cx, JSObject *obj, jsid id,
                                        JSBool strict, jsval *vp);
   static void InvalidateGlobalScopePolluter(JSContext *cx, JSObject *obj);
@@ -858,26 +858,26 @@ protected:
   static JSBool GetDocumentAllNodeList(JSContext *cx, JSObject *obj,
                                        nsDocument *doc,
                                        nsContentList **nodeList);
 
 public:
   static JSBool DocumentAllGetProperty(JSContext *cx, JSObject *obj, jsid id,
                                        jsval *vp);
   static JSBool DocumentAllNewResolve(JSContext *cx, JSObject *obj, jsid id,
-                                      uintN flags, JSObject **objp);
+                                      unsigned flags, JSObject **objp);
   static void ReleaseDocument(JSContext *cx, JSObject *obj);
-  static JSBool CallToGetPropMapper(JSContext *cx, uintN argc, jsval *vp);
+  static JSBool CallToGetPropMapper(JSContext *cx, unsigned argc, jsval *vp);
   static JSBool DocumentAllHelperGetProperty(JSContext *cx, JSObject *obj,
                                              jsid id, jsval *vp);
   static JSBool DocumentAllHelperNewResolve(JSContext *cx, JSObject *obj,
-                                            jsid id, uintN flags,
+                                            jsid id, unsigned flags,
                                             JSObject **objp);
   static JSBool DocumentAllTagsNewResolve(JSContext *cx, JSObject *obj,
-                                          jsid id, uintN flags,
+                                          jsid id, unsigned flags,
                                           JSObject **objp);
 
   NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
                         JSObject *obj, jsid id, PRUint32 flags,
                         JSObject **objp, bool *_retval);
   NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
                          JSObject *obj, jsid id, jsval *vp, bool *_retval);
 
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -1222,58 +1222,18 @@ nsGlobalWindow::ClearControllers()
       if (context)
         context->SetCommandContext(nsnull);
     }
 
     mControllers = nsnull;
   }
 }
 
-// static
 void
-nsGlobalWindow::TryClearWindowScope(nsISupports *aWindow)
-{
-  nsGlobalWindow *window =
-          static_cast<nsGlobalWindow *>(static_cast<nsIDOMWindow*>(aWindow));
-
-  // This termination function might be called when any script evaluation in our
-  // context terminated, even if there are other scripts in the stack. Thus, we
-  // have to check again if a script is executing and post a new termination
-  // function if necessary.
-  window->ClearScopeWhenAllScriptsStop();
-}
-
-void
-nsGlobalWindow::ClearScopeWhenAllScriptsStop()
-{
-  NS_ASSERTION(IsInnerWindow(), "Must be an inner window");
-
-  // We cannot clear scope safely until all the scripts in our script context
-  // stopped. This might be a long wait, for example if one script is busy
-  // because it started a nested event loop for a modal dialog.
-  nsIScriptContext *jsscx = GetContextInternal();
-  if (jsscx && jsscx->GetExecutingScript()) {
-    // We ignore the return value because the only reason that we clear scope
-    // here is to try to prevent leaks. Failing to clear scope might mean that
-    // we'll leak more but if we don't have enough memory to allocate a
-    // termination function we probably don't have to worry about this anyway.
-    jsscx->SetTerminationFunction(TryClearWindowScope,
-                                  static_cast<nsIDOMWindow *>(this));
-    return;
-  }
-
-  NotifyWindowIDDestroyed("inner-window-destroyed");
-  nsIScriptContext *scx = GetContextInternal();
-  if (scx) {
-    scx->ClearScope(mJSObject, true);
-  }
-}
-
-void
-nsGlobalWindow::FreeInnerObjects(bool aClearScope)
+nsGlobalWindow::FreeInnerObjects()
 {
   NS_ASSERTION(IsInnerWindow(), "Don't free inner objects on an outer window");
 
   // Make sure that this is called before we null out the document and
   // other members that the window destroyed observers could
   // re-create.
   NotifyDOMWindowDestroyed(this);
 
@@ -1325,19 +1285,17 @@ nsGlobalWindow::FreeInnerObjects(bool aC
 
   if (mApplicationCache) {
     static_cast<nsDOMOfflineResourceList*>(mApplicationCache.get())->Disconnect();
     mApplicationCache = nsnull;
   }
 
   mIndexedDB = nsnull;
 
-  if (aClearScope) {
-    ClearScopeWhenAllScriptsStop();
-  }
+  NotifyWindowIDDestroyed("inner-window-destroyed");
 
   if (mDummyJavaPluginOwner) {
     // Tear down the dummy java plugin.
 
     // XXXjst: On a general note, should windows with java stuff in
     // them ever even make it into the fast-back cache?
 
     mDummyJavaPluginOwner->Destroy();
@@ -1661,17 +1619,16 @@ nsGlobalWindow::WouldReuseInnerWindow(ns
   }
   
   NS_ASSERTION(NS_IsAboutBlank(mDoc->GetDocumentURI()),
                "How'd this happen?");
   
   // Great, we're the original document, check for one of the other
   // conditions.
   if (mDoc == aNewDocument) {
-    // aClearScopeHint is false.
     return true;
   }
 
   bool equal;
   if (NS_SUCCEEDED(mDoc->NodePrincipal()->Equals(aNewDocument->NodePrincipal(),
                                                  &equal)) &&
       equal) {
     // The origin is the same.
@@ -1835,20 +1792,18 @@ WindowStateHolder::WindowStateHolder(nsG
 
 WindowStateHolder::~WindowStateHolder()
 {
   if (mInnerWindow) {
     // This window was left in the bfcache and is now going away. We need to
     // free it up.
     // Note that FreeInnerObjects may already have been called on the
     // inner window if its outer has already had SetDocShell(null)
-    // called.  In this case the contexts will all be null and the
-    // true for aClearScope won't do anything; this is OK since
-    // SetDocShell(null) already did it.
-    mInnerWindow->FreeInnerObjects(true);
+    // called.
+    mInnerWindow->FreeInnerObjects();
   }
 }
 
 NS_IMPL_ISUPPORTS1(WindowStateHolder, WindowStateHolder)
 
 
 struct ReparentWaiverClosure
 {
@@ -2001,22 +1956,16 @@ nsGlobalWindow::SetNewDocument(nsIDocume
     return NS_ERROR_FAILURE;
   }
 
   JSAutoRequest ar(cx);
 
   nsCOMPtr<WindowStateHolder> wsh = do_QueryInterface(aState);
   NS_ASSERTION(!aState || wsh, "What kind of weird state are you giving me here?");
 
-  // Make sure to clear scope on the outer window *before* we
-  // initialize the new inner window. If we don't, things
-  // (Object.prototype etc) could leak from the old outer to the new
-  // inner scope.
-  mContext->ClearScope(mJSObject, false);
-
   if (reUseInnerWindow) {
     // We're reusing the current inner window.
     NS_ASSERTION(!currentInner->IsFrozen(),
                  "We should never be reusing a shared inner window");
     newInnerWindow = currentInner;
 
     if (aDocument != oldDoc) {
       nsWindowSH::InvalidateGlobalScopePolluter(cx, currentInner->mJSObject);
@@ -2076,66 +2025,31 @@ nsGlobalWindow::SetNewDocument(nsIDocume
 
       mCreatingInnerWindow = false;
       Thaw();
 
       NS_ENSURE_SUCCESS(rv, rv);
     }
 
     if (currentInner && currentInner->mJSObject) {
-      bool termFuncSet = false;
-
       if (oldDoc == aDocument) {
         // Move the navigator from the old inner window to the new one since
         // this is a document.write. This is safe from a same-origin point of
         // view because document.write can only be used by the same origin.
         newInnerWindow->mNavigator = currentInner->mNavigator;
         currentInner->mNavigator = nsnull;
         if (newInnerWindow->mNavigator) {
           newInnerWindow->mNavigator->SetWindow(newInnerWindow);
         }
-
-        // Suspend the current context's request before Pop() resumes the old
-        // context's request.
-        JSAutoSuspendRequest asr(cx);
-
-        // Pop our context here so that we get the correct one for the
-        // termination function.
-        cxPusher.Pop();
-
-        JSContext *oldCx = nsContentUtils::GetCurrentJSContext();
-
-        nsIScriptContext *callerScx;
-        if (oldCx && (callerScx = GetScriptContextFromJSContext(oldCx))) {
-          // We're called from document.open() (and document.open() is
-          // called from JS), clear the scope etc in a termination
-          // function on the calling context to prevent clearing the
-          // calling scope.
-          NS_ASSERTION(!currentInner->IsFrozen(),
-              "How does this opened window get into session history");
-
-          JSAutoRequest ar(oldCx);
-
-          callerScx->SetTerminationFunction(ClearWindowScope,
-                                            static_cast<nsIDOMWindow *>
-                                                       (currentInner));
-
-          termFuncSet = true;
-        }
-
-        // Re-push our context.
-        cxPusher.Push(cx);
       }
 
-      // Don't clear scope on our current inner window if it's going to be
+      // Don't free objects on our current inner window if it's going to be
       // held in the bfcache.
       if (!currentInner->IsFrozen()) {
-        // Skip the ClearScope if we set a termination function to do
-        // it ourselves, later.
-        currentInner->FreeInnerObjects(!termFuncSet);
+        currentInner->FreeInnerObjects();
       }
     }
 
     mInnerWindow = newInnerWindow;
 
     if (!mJSObject) {
       mContext->CreateOuterObject(this, newInnerWindow);
       mContext->DidInitializeContext();
@@ -2172,17 +2086,17 @@ nsGlobalWindow::SetNewDocument(nsIDocume
         }
 
         JS_SetParent(cx, mJSObject, newInnerWindow->mJSObject);
 
         mContext->SetOuterObject(mJSObject);
 
         JSCompartment *compartment = js::GetObjectCompartment(mJSObject);
         xpc::CompartmentPrivate *priv =
-          static_cast<xpc::CompartmentPrivate*>(JS_GetCompartmentPrivate(cx, compartment));
+          static_cast<xpc::CompartmentPrivate*>(JS_GetCompartmentPrivate(compartment));
         if (priv && priv->waiverWrapperMap) {
           NS_ASSERTION(!JS_IsExceptionPending(cx),
                        "We might overwrite a pending exception!");
           ReparentWaiverClosure closure = {
             cx,
             newInnerWindow->mJSObject
           };
           priv->waiverWrapperMap->Enumerate(ReparentWaiverWrappers, &closure);
@@ -2428,17 +2342,17 @@ nsGlobalWindow::SetDocShell(nsIDocShell*
     // Call FreeInnerObjects on all inner windows, not just the current
     // one, since some could be held by WindowStateHolder objects that
     // are GC-owned.
     for (nsRefPtr<nsGlobalWindow> inner = (nsGlobalWindow *)PR_LIST_HEAD(this);
          inner != this;
          inner = (nsGlobalWindow*)PR_NEXT_LINK(inner)) {
       NS_ASSERTION(!inner->mOuterWindow || inner->mOuterWindow == this,
                    "bad outer window pointer");
-      inner->FreeInnerObjects(true);
+      inner->FreeInnerObjects();
     }
 
     // Make sure that this is called before we null out the document.
     NotifyDOMWindowDestroyed(this);
 
     NotifyWindowIDDestroyed("outer-window-destroyed");
 
     nsGlobalWindow *currentInner = GetCurrentInnerWindowInternal();
@@ -2450,20 +2364,16 @@ nsGlobalWindow::SetDocShell(nsIDocShell*
       mDocumentPrincipal = mDoc->NodePrincipal();
 
       // Release our document reference
       mDocument = nsnull;
       mDoc = nsnull;
       mFocusedNode = nsnull;
     }
 
-    if (mContext) {
-      mContext->ClearScope(mJSObject, true);
-    }
-
     ClearControllers();
 
     mChromeEventHandler = nsnull; // force release now
 
     if (mArguments) { 
       // We got no new document after someone called
       // SetArguments(), drop our reference to the arguments.
       mArguments = nsnull;
@@ -8980,27 +8890,16 @@ nsGlobalWindow::CloseWindow(nsISupports 
                (static_cast<nsPIDOMWindow*>(win));
 
   // Need to post an event for closing, otherwise window and 
   // presshell etc. may get destroyed while creating frames, bug 338897.
   nsCloseEvent::PostCloseEvent(globalWin);
   // else if OOM, better not to close. That might cause a crash.
 }
 
-// static
-void
-nsGlobalWindow::ClearWindowScope(nsISupports *aWindow)
-{
-  nsCOMPtr<nsIScriptGlobalObject> sgo(do_QueryInterface(aWindow));
-  nsIScriptContext *scx = sgo->GetContext();
-  if (scx) {
-    scx->ClearScope(sgo->GetGlobalJSObject(), true);
-  }
-}
-
 //*****************************************************************************
 // nsGlobalWindow: Timeout Functions
 //*****************************************************************************
 
 PRUint32 sNestingLevel;
 
 nsresult
 nsGlobalWindow::SetTimeoutOrInterval(nsIScriptTimeoutHandler *aHandler,
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -231,17 +231,17 @@ private:
 
 //*****************************************************************************
 // nsOuterWindow: Outer Window Proxy
 //*****************************************************************************
 
 class nsOuterWindowProxy : public js::Wrapper
 {
 public:
-  nsOuterWindowProxy() : js::Wrapper((uintN)0) {}
+  nsOuterWindowProxy() : js::Wrapper((unsigned)0) {}
 
   virtual bool isOuterWindow() {
     return true;
   }
   JSString *obj_toString(JSContext *cx, JSObject *wrapper);
   void finalize(JSContext *cx, JSObject *proxy);
 
   static nsOuterWindowProxy singleton;
@@ -590,21 +590,19 @@ private:
 protected:
   friend class HashchangeCallback;
   friend class nsBarProp;
 
   // Object Management
   virtual ~nsGlobalWindow();
   void CleanUp(bool aIgnoreModalDialog);
   void ClearControllers();
-  static void TryClearWindowScope(nsISupports* aWindow);
-  void ClearScopeWhenAllScriptsStop();
   nsresult FinalClose();
 
-  void FreeInnerObjects(bool aClearScope);
+  void FreeInnerObjects();
   nsGlobalWindow *CallerInnerWindow();
 
   nsresult InnerSetNewDocument(nsIDocument* aDocument);
 
   nsresult DefineArgumentsProperty(nsIArray *aArguments);
 
   // Get the parent, returns null if this is a toplevel window
   nsIDOMWindow* GetParentInternal();
@@ -672,17 +670,16 @@ protected:
                                     bool aDoJSFixups,
                                     nsIArray *argv,
                                     nsISupports *aExtraArgument,
                                     nsIPrincipal *aCalleePrincipal,
                                     JSContext *aJSCallerContext,
                                     nsIDOMWindow **aReturn);
 
   static void CloseWindow(nsISupports* aWindow);
-  static void ClearWindowScope(nsISupports* aWindow);
 
   // Timeout Functions
   // Language agnostic timeout function (all args passed).
   // |interval| is in milliseconds.
   nsresult SetTimeoutOrInterval(nsIScriptTimeoutHandler *aHandler,
                                 PRInt32 interval,
                                 bool aIsInterval, PRInt32 *aReturn);
   nsresult ClearTimeoutOrInterval(PRInt32 aTimerID);
--- a/dom/base/nsIScriptContext.h
+++ b/dom/base/nsIScriptContext.h
@@ -70,18 +70,18 @@ public:
 
   virtual nsIScriptObjectPrincipal* GetObjectPrincipal() = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIScriptContextPrincipal,
                               NS_ISCRIPTCONTEXTPRINCIPAL_IID)
 
 #define NS_ISCRIPTCONTEXT_IID \
-{ 0xf3840057, 0x4fe5, 0x4f92, \
- { 0xa3, 0xb8, 0x27, 0xd7, 0x44, 0x6f, 0x72, 0x4d } }
+{ 0x6d69fbee, 0x0723, 0x48f5, \
+ { 0x82, 0x48, 0xcd, 0xcf, 0x88, 0xac, 0x25, 0x74 } }
 
 /* This MUST match JSVERSION_DEFAULT.  This version stuff if we don't
    know what language we have is a little silly... */
 #define SCRIPTVERSION_DEFAULT JSVERSION_DEFAULT
 
 /**
  * It is used by the application to initialize a runtime and run scripts.
  * A script runtime would implement this interface.
@@ -423,30 +423,16 @@ public:
    * Initialize DOM classes on aGlobalObj, always call
    * WillInitializeContext() before calling InitContext(), and always
    * call DidInitializeContext() when a context is fully
    * (successfully) initialized.
    */
   virtual nsresult InitClasses(JSObject* aGlobalObj) = 0;
 
   /**
-   * Clear the scope object - may be called either as we are being torn down,
-   * or before we are attached to a different document.
-   *
-   * aClearFromProtoChain is probably somewhat JavaScript specific.  It
-   * indicates that the global scope polluter should be removed from the
-   * prototype chain and that the objects in the prototype chain should
-   * also have their scopes cleared.  We don't do this all the time
-   * because the prototype chain is shared between inner and outer
-   * windows, and needs to stay with inner windows that we're keeping
-   * around.
-   */
-  virtual void ClearScope(void* aGlobalObj, bool aClearFromProtoChain) = 0;
-
-  /**
    * Tell the context we're about to be reinitialize it.
    */
   virtual void WillInitializeContext() = 0;
 
   /**
    * Tell the context we're done reinitializing it.
    */
   virtual void DidInitializeContext() = 0;
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -2717,39 +2717,39 @@ CheckUniversalXPConnectForTraceMalloc(JS
                     IsCapabilityEnabled("UniversalXPConnect", &hasCap);
     if (NS_SUCCEEDED(rv) && hasCap)
         return JS_TRUE;
     JS_ReportError(cx, "trace-malloc functions require UniversalXPConnect");
     return JS_FALSE;
 }
 
 static JSBool
-TraceMallocDisable(JSContext *cx, uintN argc, jsval *vp)
+TraceMallocDisable(JSContext *cx, unsigned argc, jsval *vp)
 {
     if (!CheckUniversalXPConnectForTraceMalloc(cx))
         return JS_FALSE;
 
     NS_TraceMallocDisable();
     JS_SET_RVAL(cx, vp, JSVAL_VOID);
     return JS_TRUE;
 }
 
 static JSBool
-TraceMallocEnable(JSContext *cx, uintN argc, jsval *vp)
+TraceMallocEnable(JSContext *cx, unsigned argc, jsval *vp)
 {
     if (!CheckUniversalXPConnectForTraceMalloc(cx))
         return JS_FALSE;
 
     NS_TraceMallocEnable();
     JS_SET_RVAL(cx, vp, JSVAL_VOID);
     return JS_TRUE;
 }
 
 static JSBool
-TraceMallocOpenLogFile(JSContext *cx, uintN argc, jsval *vp)
+TraceMallocOpenLogFile(JSContext *cx, unsigned argc, jsval *vp)
 {
     int fd;
     JSString *str;
 
     if (!CheckUniversalXPConnectForTraceMalloc(cx))
         return JS_FALSE;
 
     if (argc == 0) {
@@ -2767,17 +2767,17 @@ TraceMallocOpenLogFile(JSContext *cx, ui
             return JS_FALSE;
         }
     }
     JS_SET_RVAL(cx, vp, INT_TO_JSVAL(fd));
     return JS_TRUE;
 }
 
 static JSBool
-TraceMallocChangeLogFD(JSContext *cx, uintN argc, jsval *vp)
+TraceMallocChangeLogFD(JSContext *cx, unsigned argc, jsval *vp)
 {
     if (!CheckUniversalXPConnectForTraceMalloc(cx))
         return JS_FALSE;
 
     int32_t fd, oldfd;
     if (argc == 0) {
         oldfd = -1;
     } else {
@@ -2789,50 +2789,50 @@ TraceMallocChangeLogFD(JSContext *cx, ui
             return JS_FALSE;
         }
     }
     JS_SET_RVAL(cx, vp, INT_TO_JSVAL(oldfd));
     return JS_TRUE;
 }
 
 static JSBool
-TraceMallocCloseLogFD(JSContext *cx, uintN argc, jsval *vp)
+TraceMallocCloseLogFD(JSContext *cx, unsigned argc, jsval *vp)
 {
     if (!CheckUniversalXPConnectForTraceMalloc(cx))
         return JS_FALSE;
 
     int32_t fd;
     JS_SET_RVAL(cx, vp, JSVAL_VOID);
     if (argc == 0)
         return JS_TRUE;
     if (!JS_ValueToECMAInt32(cx, JS_ARGV(cx, vp)[0], &fd))
         return JS_FALSE;
     NS_TraceMallocCloseLogFD((int) fd);
     return JS_TRUE;
 }
 
 static JSBool
-TraceMallocLogTimestamp(JSContext *cx, uintN argc, jsval *vp)
+TraceMallocLogTimestamp(JSContext *cx, unsigned argc, jsval *vp)
 {
     if (!CheckUniversalXPConnectForTraceMalloc(cx))
         return JS_FALSE;
 
     JSString *str = JS_ValueToString(cx, argc ? JS_ARGV(cx, vp)[0] : JSVAL_VOID);
     if (!str)
         return JS_FALSE;
     JSAutoByteString caption(cx, str);
     if (!caption)
         return JS_FALSE;
     NS_TraceMallocLogTimestamp(caption.ptr());
     JS_SET_RVAL(cx, vp, JSVAL_VOID);
     return JS_TRUE;
 }
 
 static JSBool
-TraceMallocDumpAllocations(JSContext *cx, uintN argc, jsval *vp)
+TraceMallocDumpAllocations(JSContext *cx, unsigned argc, jsval *vp)
 {
     if (!CheckUniversalXPConnectForTraceMalloc(cx))
         return JS_FALSE;
 
     JSString *str = JS_ValueToString(cx, argc ? JS_ARGV(cx, vp)[0] : JSVAL_VOID);
     if (!str)
         return JS_FALSE;
     JSAutoByteString pathname(cx, str);
@@ -2870,17 +2870,17 @@ IsJProfAction(struct sigaction *action)
             (action->sa_flags & (SA_RESTART | SA_SIGINFO)) == (SA_RESTART | SA_SIGINFO));
 }
 
 void NS_JProfStartProfiling();
 void NS_JProfStopProfiling();
 void NS_JProfClearCircular();
 
 static JSBool
-JProfStartProfilingJS(JSContext *cx, uintN argc, jsval *vp)
+JProfStartProfilingJS(JSContext *cx, unsigned argc, jsval *vp)
 {
   NS_JProfStartProfiling();
   return JS_TRUE;
 }
 
 void NS_JProfStartProfiling()
 {
     // Figure out whether we're dealing with SIGPROF, SIGALRM, or
@@ -2912,45 +2912,45 @@ void NS_JProfStartProfiling()
         raise(SIGPOLL);
         return;
     }
 
     printf("Could not start jprof-profiling since JPROF_FLAGS was not set.\n");
 }
 
 static JSBool
-JProfStopProfilingJS(JSContext *cx, uintN argc, jsval *vp)
+JProfStopProfilingJS(JSContext *cx, unsigned argc, jsval *vp)
 {
   NS_JProfStopProfiling();
   return JS_TRUE;
 }
 
 void
 NS_JProfStopProfiling()
 {
     raise(SIGUSR1);
     //printf("Stopped jprof profiling.\n");
 }
 
 static JSBool
-JProfClearCircularJS(JSContext *cx, uintN argc, jsval *vp)
+JProfClearCircularJS(JSContext *cx, unsigned argc, jsval *vp)
 {
   NS_JProfClearCircular();
   return JS_TRUE;
 }
 
 void
 NS_JProfClearCircular()
 {
     raise(SIGUSR2);
     //printf("cleared jprof buffer\n");
 }
 
 static JSBool
-JProfSaveCircularJS(JSContext *cx, uintN argc, jsval *vp)
+JProfSaveCircularJS(JSContext *cx, unsigned argc, jsval *vp)
 {
   // Not ideal...
   NS_JProfStopProfiling();
   NS_JProfStartProfiling();
   return JS_TRUE;
 }
 
 static JSFunctionSpec JProfFunctions[] = {
@@ -2964,17 +2964,17 @@ static JSFunctionSpec JProfFunctions[] =
 #endif /* defined(MOZ_JPROF) */
 
 #ifdef MOZ_DMD
 
 // See https://wiki.mozilla.org/Performance/MemShrink/DMD for instructions on
 // how to use DMD.
 
 static JSBool
-DMDCheckJS(JSContext *cx, uintN argc, jsval *vp)
+DMDCheckJS(JSContext *cx, unsigned argc, jsval *vp)
 {
   mozilla::DMDCheckAndDump();
   return JS_TRUE;
 }
 
 static JSFunctionSpec DMDFunctions[] = {
     {"DMD",                        DMDCheckJS,                 0, 0},
     {nsnull,                       nsnull,                     0, 0}
@@ -3011,92 +3011,16 @@ nsJSContext::InitClasses(JSObject* aGlob
 #endif
 
   JSOptionChangedCallback(js_options_dot_str, this);
 
   return rv;
 }
 
 void
-nsJSContext::ClearScope(void *aGlobalObj, bool aClearFromProtoChain)
-{
-  // Push our JSContext on our thread's context stack.
-  nsCOMPtr<nsIJSContextStack> stack =
-    do_GetService("@mozilla.org/js/xpc/ContextStack;1");
-  if (stack && NS_FAILED(stack->Push(mContext))) {
-    stack = nsnull;
-  }
-
-  if (aGlobalObj) {
-    JSObject *obj = (JSObject *)aGlobalObj;
-    JSAutoRequest ar(mContext);
-
-    JSAutoEnterCompartment ac;
-    ac.enterAndIgnoreErrors(mContext, obj);
-
-    // Grab a reference to the window property, which is the outer
-    // window, so that we can re-define it once we've cleared
-    // scope. This is what keeps the outer window alive in cases where
-    // nothing else does.
-    jsval window;
-    if (!JS_GetProperty(mContext, obj, "window", &window)) {
-      window = JSVAL_VOID;
-
-      JS_ClearPendingException(mContext);
-    }
-
-    JS_ClearScope(mContext, obj);
-
-    NS_ABORT_IF_FALSE(!xpc::WrapperFactory::IsXrayWrapper(obj), "unexpected wrapper");
-
-    if (window != JSVAL_VOID) {
-      if (!JS_DefineProperty(mContext, obj, "window", window,
-                             JS_PropertyStub, JS_StrictPropertyStub,
-                             JSPROP_ENUMERATE | JSPROP_READONLY |
-                             JSPROP_PERMANENT)) {
-        JS_ClearPendingException(mContext);
-      }
-    }
-
-    if (!js::GetObjectParent(obj)) {
-      JS_ClearRegExpStatics(mContext, obj);
-    }
-
-    // Always clear watchpoints, to deal with two cases:
-    // 1.  The first document for this window is loading, and a miscreant has
-    //     preset watchpoints on the window object in order to attack the new
-    //     document's privileged information.
-    // 2.  A document loaded and used watchpoints on its own window, leaving
-    //     them set until the next document loads. We must clean up window
-    //     watchpoints here.
-    // Watchpoints set on document and subordinate objects are all cleared
-    // when those sub-window objects are finalized, after JS_ClearScope and
-    // a GC run that finds them to be garbage.
-    ::JS_ClearWatchPointsForObject(mContext, obj);
-
-    // Since the prototype chain is shared between inner and outer (and
-    // stays with the inner), we don't clear things from the prototype
-    // chain when we're clearing an outer window whose current inner we
-    // still want.
-    if (aClearFromProtoChain) {
-      nsWindowSH::InvalidateGlobalScopePolluter(mContext, obj);
-
-      // Clear up obj's prototype chain, but not Object.prototype.
-      for (JSObject *o = ::JS_GetPrototype(obj), *next;
-           o && (next = ::JS_GetPrototype(o)); o = next)
-        ::JS_ClearScope(mContext, o);
-    }
-  }
-
-  if (stack) {
-    stack->Pop(nsnull);
-  }
-}
-
-void
 nsJSContext::WillInitializeContext()
 {
   mIsInitialized = false;
 }
 
 void
 nsJSContext::DidInitializeContext()
 {
--- a/dom/base/nsJSEnvironment.h
+++ b/dom/base/nsJSEnvironment.h
@@ -156,17 +156,16 @@ public:
   virtual bool GetProcessingScriptTag();
   virtual void SetProcessingScriptTag(bool aResult);
 
   virtual bool GetExecutingScript();
 
   virtual void SetGCOnDestruction(bool aGCOnDestruction);
 
   virtual nsresult InitClasses(JSObject* aGlobalObj);
-  virtual void ClearScope(void* aGlobalObj, bool bClearPolluters);
 
   virtual void WillInitializeContext();
   virtual void DidInitializeContext();
 
   virtual nsresult Serialize(nsIObjectOutputStream* aStream, JSScript* aScriptObject);
   virtual nsresult Deserialize(nsIObjectInputStream* aStream,
                                nsScriptObjectHolder<JSScript>& aResult);
 
new file mode 100644
--- /dev/null
+++ b/dom/contacts/ContactManager.js
@@ -0,0 +1,404 @@
+/* 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/. */
+
+"use strict"
+
+/* static functions */
+let DEBUG = 0;
+if (DEBUG)
+  debug = function (s) { dump("-*- ContactManager: " + s + "\n"); }
+else
+  debug = function (s) {}
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+
+const nsIClassInfo            = Ci.nsIClassInfo;
+const CONTACTPROPERTIES_CID   = Components.ID("{53ed7c20-ceda-11e0-9572-0800200c9a66}");
+const nsIDOMContactProperties = Ci.nsIDOMContactProperties;
+
+// ContactProperties is not directly instantiated. It is used as interface.
+
+ContactProperties.prototype = {
+
+  classID : CONTACTPROPERTIES_CID,
+  classInfo : XPCOMUtils.generateCI({classID: CONTACTPROPERTIES_CID,
+                                     contractID:"@mozilla.org/contactProperties;1",
+                                     classDescription: "ContactProperties",
+                                     interfaces: [nsIDOMContactProperties],
+                                     flags: nsIClassInfo.DOM_OBJECT}),
+
+  QueryInterface : XPCOMUtils.generateQI([nsIDOMContactProperties])
+}
+
+//ContactAddress
+
+const CONTACTADDRESS_CONTRACTID = "@mozilla.org/contactAddress;1";
+const CONTACTADDRESS_CID        = Components.ID("{27a568b0-cee1-11e0-9572-0800200c9a66}");
+const nsIDOMContactAddress      = Components.interfaces.nsIDOMContactAddress;
+
+function ContactAddress(aStreetAddress, aLocality, aRegion, aPostalCode, aCountryName) {
+  this.streetAddress = aStreetAddress || null;
+  this.locality = aLocality || null;
+  this.region = aRegion || null;
+  this.postalCode = aPostalCode || null;
+  this.countryName = aCountryName || null;
+};
+
+function ContactProperties(aProp) { debug("ContactProperties Constructor"); }
+
+ContactAddress.prototype = {
+
+  classID : CONTACTADDRESS_CID,
+  classInfo : XPCOMUtils.generateCI({classID: CONTACTADDRESS_CID,
+                                     contractID: CONTACTADDRESS_CONTRACTID,
+                                     classDescription: "ContactAddress",
+                                     interfaces: [nsIDOMContactAddress],
+                                     flags: nsIClassInfo.DOM_OBJECT}),
+
+  QueryInterface : XPCOMUtils.generateQI([nsIDOMContactAddress])
+}
+
+//ContactFindOptions
+
+const CONTACTFINDOPTIONS_CONTRACTID = "@mozilla.org/contactFindOptions;1";
+const CONTACTFINDOPTIONS_CID        = Components.ID("{e31daea0-0cb6-11e1-be50-0800200c9a66}");
+const nsIDOMContactFindOptions      = Components.interfaces.nsIDOMContactFindOptions;
+
+function ContactFindOptions(aFilterValue, aFilterBy, aFilterOp, aFilterLimit) {
+  this.filterValue = aFilterValue || '';
+
+  this.filterBy = new Array();
+  for (let field in aFilterBy)
+    this.filterBy.push(field);
+
+  this.filterOp = aFilterOp || '';
+  this.filterLimit = aFilterLimit || 0;
+};
+
+ContactFindOptions.prototype = {
+
+  classID : CONTACTFINDOPTIONS_CID,
+  classInfo : XPCOMUtils.generateCI({classID: CONTACTFINDOPTIONS_CID,
+                                     contractID: CONTACTFINDOPTIONS_CONTRACTID,
+                                     classDescription: "ContactFindOptions",
+                                     interfaces: [nsIDOMContactFindOptions],
+                                     flags: nsIClassInfo.DOM_OBJECT}),
+              
+  QueryInterface : XPCOMUtils.generateQI([nsIDOMContactFindOptions])
+}
+
+//Contact
+
+const CONTACT_CONTRACTID = "@mozilla.org/contact;1";
+const CONTACT_CID        = Components.ID("{da0f7040-388b-11e1-b86c-0800200c9a66}");
+const nsIDOMContact      = Components.interfaces.nsIDOMContact;
+
+function Contact() { debug("Contact constr: "); };
+
+Contact.prototype = {
+  
+  init: function init(aProp) {
+    // Accept non-array strings for DOMString[] properties and convert them.
+    function _create(aField) {
+      if (typeof aField == "string")
+        return new Array(aField);
+      return aField;
+    };
+
+    this.name =            _create(aProp.name) || null;
+    this.honorificPrefix = _create(aProp.honorificPrefix) || null;
+    this.givenName =       _create(aProp.givenName) || null;
+    this.additionalName =  _create(aProp.additionalName) || null;
+    this.familyName =      _create(aProp.familyName) || null;
+    this.honorificSuffix = _create(aProp.honorificSuffix) || null;
+    this.nickname =        _create(aProp.nickname) || null;
+    this.email =           _create(aProp.email) || null;
+    this.photo =           _create(aProp.photo) || null;
+    this.url =             _create(aProp.url) || null;
+    this.category =        _create(aProp.category) || null;
+
+    if (aProp.adr) {
+      // Make sure adr argument is an array. Instanceof doesn't work.
+      aProp.adr = aProp.adr.length == undefined ? [aProp.adr] : aProp.adr;
+
+      this.adr = new Array();
+      for (let i = 0; i < aProp.adr.length; i++)
+        this.adr.push(new ContactAddress(aProp.adr[i].streetAddress, aProp.adr[i].locality,
+                                         aProp.adr[i].region, aProp.adr[i].postalCode,
+                                         aProp.adr[i].countryName));
+    } else {
+      this.adr = null;
+    }
+
+    this.tel =             _create(aProp.tel) || null;
+    this.org =             _create(aProp.org) || null;
+    this.bday =            (aProp.bday == "undefined" || aProp.bday == null) ? null : new Date(aProp.bday);
+    this.note =            _create(aProp.note) || null;
+    this.impp =            _create(aProp.impp) || null;
+    this.anniversary =     (aProp.anniversary == "undefined" || aProp.anniversary == null) ? null : new Date(aProp.anniversary);
+    this.sex =             (aProp.sex != "undefined") ? aProp.sex : null;
+    this.genderIdentity =  (aProp.genderIdentity != "undefined") ? aProp.genderIdentity : null;
+  },
+
+  get published () {
+    return this._published;
+  },
+
+  set published(aPublished) {
+    this._published = aPublished;
+  },
+
+  get updated () {
+    return this._updated;
+  },
+ 
+  set updated(aUpdated) {
+    this._updated = aUpdated;
+  },
+
+  classID : CONTACT_CID,
+  classInfo : XPCOMUtils.generateCI({classID: CONTACT_CID,
+                                     contractID: CONTACT_CONTRACTID,
+                                     classDescription: "Contact",
+                                     interfaces: [nsIDOMContact, nsIDOMContactProperties],
+                                     flags: nsIClassInfo.DOM_OBJECT}),
+
+  QueryInterface : XPCOMUtils.generateQI([nsIDOMContact, nsIDOMContactProperties])
+}
+
+// ContactManager
+
+const CONTACTMANAGER_CONTRACTID = "@mozilla.org/contactManager;1";
+const CONTACTMANAGER_CID        = Components.ID("{50a820b0-ced0-11e0-9572-0800200c9a66}");
+const nsIDOMContactManager      = Components.interfaces.nsIDOMContactManager;
+
+function ContactManager()
+{
+  debug("Constructor");
+}
+
+ContactManager.prototype = {
+
+  save: function save(aContact) {
+    let request;
+    if (this.hasPrivileges) {
+      debug("save: " + JSON.stringify(aContact) + " :" + aContact.id);
+      let newContact = {};
+      newContact.properties = {
+        name:            [],
+        honorificPrefix: [],
+        givenName:       [],
+        additionalName:  [],
+        familyName:      [],
+        honorificSuffix: [],
+        nickname:        [],
+        email:           [],
+        photo:           [],
+        url:             [],
+        category:        [],
+        adr:             [],
+        tel:             [],
+        org:             [],
+        bday:            null,
+        note:            [],
+        impp:            [],
+        anniversary:     null,
+        sex:             null,
+        genderIdentity:  null
+      };
+      for (let field in newContact.properties)
+        newContact.properties[field] = aContact[field];
+
+      if (aContact.id == "undefined") {
+        debug("Create id!");
+        aContact.id = this._getRandomId();
+      }
+
+      this._setMetaData(newContact, aContact);
+      debug("send: " + JSON.stringify(newContact));
+      request = this._rs.createRequest(this._window);
+      this._mm.sendAsyncMessage("Contact:Save", {contact: newContact,
+                                                 requestID: this.getRequestId({ request: request })});
+      return request;
+    } else {
+      throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
+    }
+  },
+
+  remove: function removeContact(aRecord) {
+    let request;
+    if (this.hasPrivileges) {
+      request = this._rs.createRequest(this._window);
+      this._mm.sendAsyncMessage("Contact:Remove", {id: aRecord.id,
+                                                   requestID: this.getRequestId({ request: request })});
+      return request;
+    } else {
+      throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
+    }
+  },
+
+  _setMetaData: function(aNewContact, aRecord) {
+    aNewContact.id = aRecord.id;
+    aNewContact.published = aRecord.published;
+    aNewContact.updated = aRecord.updated;
+  },
+
+  _convertContactsArray: function(aContacts) {
+    let contacts = new Array();
+    for (let i in aContacts) {
+      let newContact = new Contact();
+      newContact.init(aContacts[i].properties);
+      this._setMetaData(newContact, aContacts[i]);
+      contacts.push(newContact);
+    }
+    return contacts;
+  },
+
+  getRequestId: function(aRequest) {
+    let id = "id" + this._getRandomId();
+    this._requests[id] = aRequest;
+    return id;
+  },
+
+  getRequest: function(aId) {
+    if (this._requests[aId])
+      return this._requests[aId].request;
+  },
+
+  removeRequest: function(aId) {
+    if (this._requests[aId])
+      delete this._requests[aId];
+  },
+  
+  _getRandomId: function() {
+    return Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID().toString();
+  },
+
+  receiveMessage: function(aMessage) {
+    debug("Contactmanager::receiveMessage: " + aMessage.name);
+    let msg = aMessage.json;
+    let contacts = msg.contacts;
+
+    switch (aMessage.name) {
+      case "Contacts:Find:Return:OK":
+        let req = this.getRequest(msg.requestID);
+        if (req) {
+          let result = this._convertContactsArray(contacts);
+          debug("result: " + JSON.stringify(result));
+          this._rs.fireSuccess(req, result);
+        } else {
+          debug("no request stored!" + msg.requestID);
+        }
+        break;
+      case "Contact:Save:Return:OK":
+      case "Contacts:Clear:Return:OK":
+      case "Contact:Remove:Return:OK":
+        req = this.getRequest(msg.requestID);
+        if (req)
+          this._rs.fireSuccess(req, 0);
+        break;
+      case "Contacts:Find:Return:KO":
+      case "Contact:Save:Return:KO":
+      case "Contact:Remove:Return:KO":
+      case "Contacts:Clear:Return:KO":
+        req = this.getRequest(msg.requestID);
+        if (req)
+          this._rs.fireError(req, msg.errorMsg);
+        break;
+      default: 
+        debug("Wrong message: " + aMessage.name);
+    }
+    this.removeRequest(msg.requestID);
+  },
+
+  find: function(aOptions) {
+    let request;
+    if (this.hasPrivileges) {
+      request = this._rs.createRequest(this._window);
+      this._mm.sendAsyncMessage("Contacts:Find", {findOptions: aOptions, 
+                                                  requestID: this.getRequestId({ request: request })});
+      return request;
+    } else {
+      debug("find not allowed");
+      throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
+    }
+  },
+
+  clear: function() {
+    let request;
+    if (this.hasPrivileges) {
+      request = this._rs.createRequest(this._window);
+      this._mm.sendAsyncMessage("Contacts:Clear", {requestID: this.getRequestId({ request: request })});
+      return request;
+    } else {
+      debug("clear not allowed");
+      throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
+    }
+  },
+
+  init: function(aWindow) {
+    // Set navigator.mozContacts to null.
+    if (!Services.prefs.getBoolPref("dom.mozContacts.enabled"))
+      return null;
+
+    this._window = aWindow;
+    this._messages = ["Contacts:Find:Return:OK", "Contacts:Find:Return:KO",
+                     "Contacts:Clear:Return:OK", "Contacts:Clear:Return:KO",
+                     "Contact:Save:Return:OK", "Contact:Save:Return:KO",
+                     "Contact:Remove:Return:OK", "Contact:Remove:Return:KO"];
+
+    this._mm = Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager);
+    this._messages.forEach((function(msgName) {
+      this._mm.addMessageListener(msgName, this);
+    }).bind(this));
+
+    this._rs = Cc["@mozilla.org/dom/dom-request-service;1"].getService(Ci.nsIDOMRequestService);
+    this._requests = [];
+    Services.obs.addObserver(this, "inner-window-destroyed", false);
+    let util = this._window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
+    this._innerWindowID = util.currentInnerWindowID;
+
+    let principal = aWindow.document.nodePrincipal;
+    let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager);
+
+    let perm = principal == secMan.getSystemPrincipal() ? 
+                 Ci.nsIPermissionManager.ALLOW_ACTION : 
+                 Services.perms.testExactPermission(principal.URI, "webcontacts-manage");
+ 
+    //only pages with perm set can use the contacts
+    this.hasPrivileges = perm == Ci.nsIPermissionManager.ALLOW_ACTION;
+    debug("has privileges :" + this.hasPrivileges);
+  },
+
+  observe: function(aSubject, aTopic, aData) {
+    let wId = aSubject.QueryInterface(Ci.nsISupportsPRUint64).data;
+    if (wId == this.innerWindowID) {
+      Services.obs.removeObserver(this, "inner-window-destroyed");
+      this._messages.forEach((function(msgName) {
+        this._mm.removeMessageListener(msgName, this);
+      }).bind(this));
+      this._mm = null;
+      this._messages = null;
+      this._requests = null;
+      this._window = null;
+      this._innerWindowID = null;
+    }
+  },
+
+  classID : CONTACTMANAGER_CID,
+  QueryInterface : XPCOMUtils.generateQI([nsIDOMContactManager, Ci.nsIDOMGlobalPropertyInitializer]),
+
+  classInfo : XPCOMUtils.generateCI({classID: CONTACTMANAGER_CID,
+                                     contractID: CONTACTMANAGER_CONTRACTID,
+                                     classDescription: "ContactManager",
+                                     interfaces: [nsIDOMContactManager],
+                                     flags: nsIClassInfo.DOM_OBJECT})
+}
+
+const NSGetFactory = XPCOMUtils.generateNSGetFactory([Contact, ContactManager, ContactProperties, ContactAddress, ContactFindOptions])
new file mode 100644
--- /dev/null
+++ b/dom/contacts/ContactManager.manifest
@@ -0,0 +1,16 @@
+component {53ed7c20-ceda-11e0-9572-0800200c9a66} ContactManager.js
+contract @mozilla.org/contactProperties;1 {53ed7c20-ceda-11e0-9572-0800200c9a66}
+
+component {27a568b0-cee1-11e0-9572-0800200c9a66} ContactManager.js
+contract @mozilla.org/contactAddress;1 {27a568b0-cee1-11e0-9572-0800200c9a66}
+
+component {e31daea0-0cb6-11e1-be50-0800200c9a66} ContactManager.js
+contract @mozilla.org/contactFindOptions;1 {e31daea0-0cb6-11e1-be50-0800200c9a66}
+
+component {da0f7040-388b-11e1-b86c-0800200c9a66} ContactManager.js
+contract @mozilla.org/contact;1 {da0f7040-388b-11e1-b86c-0800200c9a66}
+category JavaScript-global-constructor mozContact @mozilla.org/contact;1
+
+component {50a820b0-ced0-11e0-9572-0800200c9a66} ContactManager.js
+contract @mozilla.org/contactManager;1 {50a820b0-ced0-11e0-9572-0800200c9a66}
+category JavaScript-navigator-property mozContacts @mozilla.org/contactManager;1
new file mode 100644
--- /dev/null
+++ b/dom/contacts/Makefile.in
@@ -0,0 +1,47 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this file,
+# You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DEPTH		= ../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH            = \
+  $(srcdir)        \
+  $(NULL)
+
+include $(DEPTH)/config/autoconf.mk
+
+ifeq ($(MOZ_WIDGET_TOOLKIT),gonk)
+VPATH += $(srcdir)/fallback
+endif
+
+MODULE         = dom
+LIBRARY_NAME   = jsdomcontacts_s
+LIBXUL_LIBRARY = 1
+
+EXTRA_COMPONENTS =              \
+  ContactManager.js             \
+  ContactManager.manifest       \
+  $(NULL)
+
+ifeq ($(MOZ_WIDGET_TOOLKIT),gonk)
+EXTRA_JS_MODULES = ContactService.jsm \
+                   $(NULL)
+
+EXTRA_JS_MODULES += ContactDB.jsm \
+                    $(NULL)
+endif
+
+ifdef ENABLE_TESTS
+DIRS += tests
+endif
+
+# Add VPATH to LOCAL_INCLUDES so we are going to include the correct backend
+# subdirectory (and the ipc one).
+LOCAL_INCLUDES += $(VPATH:%=-I%)
+
+include $(topsrcdir)/config/config.mk
+include $(topsrcdir)/ipc/chromium/chromium-config.mk
+include $(topsrcdir)/config/rules.mk
+
+DEFINES += -D_IMPL_NS_LAYOUT
new file mode 100644
--- /dev/null
+++ b/dom/contacts/fallback/ContactDB.jsm
@@ -0,0 +1,410 @@
+/* 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/. */
+
+"use strict";
+
+const EXPORTED_SYMBOLS = ['ContactDB'];
+
+let DEBUG = 0;
+/* static functions */
+if (DEBUG)
+    debug = function (s) { dump("-*- ContactDB component: " + s + "\n"); }
+else
+    debug = function (s) {}
+
+const Cu = Components.utils; 
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+Cu.import("resource://gre/modules/Services.jsm");
+
+const DB_NAME = "contacts";
+const DB_VERSION = 1;
+const STORE_NAME = "contacts";
+
+function ContactDB(aGlobal) {
+  debug("Constructor");
+  this._indexedDB = aGlobal.mozIndexedDB;
+}
+
+ContactDB.prototype = {
+
+  // Cache the DB
+  db: null,
+
+  close: function close() {
+    debug("close");
+    if (this.db)
+      this.db.close();
+  },
+
+  /**
+   * Prepare the database. This may include opening the database and upgrading
+   * it to the latest schema version.
+   * 
+   * @return (via callback) a database ready for use.
+   */
+  ensureDB: function ensureDB(callback, failureCb) {
+    if (this.db) {
+      debug("ensureDB: already have a database, returning early.");
+      callback(this.db);
+      return;
+    }
+
+    let self = this;
+    debug("try to open database:" + DB_NAME + " " + DB_VERSION);
+    let request = this._indexedDB.open(DB_NAME, DB_VERSION);
+    request.onsuccess = function (event) {
+      debug("Opened database:", DB_NAME, DB_VERSION);
+      self.db = event.target.result;
+      self.db.onversionchange = function(event) {
+        debug("WARNING: DB modified from a different window.");
+      }
+      callback(self.db);
+    };
+    request.onupgradeneeded = function (event) {
+      debug("Database needs upgrade:" + DB_NAME + event.oldVersion + event.newVersion);
+      debug("Correct new database version:" + event.newVersion == DB_VERSION);
+
+      let db = event.target.result;
+      switch (event.oldVersion) {
+        case 0:
+          debug("New database");
+          self.createSchema(db);
+          break;
+
+        default:
+          debug("No idea what to do with old database version:" + event.oldVersion);
+          failureCb(event.target.errorMessage);
+          break;
+      }
+    };
+    request.onerror = function (event) {
+      debug("Failed to open database:", DB_NAME);
+      failureCb(event.target.errorMessage);
+    };
+    request.onblocked = function (event) {
+      debug("Opening database request is blocked.");
+    };
+  },
+
+  /**
+   * Create the initial database schema.
+   *
+   * The schema of records stored is as follows:
+   *
+   * {id:            "...",       // UUID
+   *  published:     Date(...),   // First published date.
+   *  updated:       Date(...),   // Last updated date.
+   *  properties:    {...}        // Object holding the ContactProperties
+   * }
+   */
+  createSchema: function createSchema(db) {
+    let objectStore = db.createObjectStore(STORE_NAME, {keyPath: "id"});
+
+    // Metadata indexes
+    objectStore.createIndex("published", "published", { unique: false });
+    objectStore.createIndex("updated",   "updated",   { unique: false });
+
+    // Properties indexes
+    objectStore.createIndex("nickname",   "properties.nickname",   { unique: false, multiEntry: true });
+    objectStore.createIndex("name",       "properties.name",       { unique: false, multiEntry: true });
+    objectStore.createIndex("familyName", "properties.familyName", { unique: false, multiEntry: true });
+    objectStore.createIndex("givenName",  "properties.givenName",  { unique: false, multiEntry: true });
+    objectStore.createIndex("tel",        "properties.tel",        { unique: false, multiEntry: true });
+    objectStore.createIndex("email",      "properties.email",      { unique: false, multiEntry: true });
+    objectStore.createIndex("note",       "properties.note",       { unique: false, multiEntry: true });
+
+    debug("Created object stores and indexes");
+  },
+
+  /**
+   * Start a new transaction.
+   * 
+   * @param txn_type
+   *        Type of transaction (e.g. IDBTransaction.READ_WRITE)
+   * @param callback
+   *        Function to call when the transaction is available. It will
+   *        be invoked with the transaction and the 'contacts' object store.
+   * @param successCb [optional]
+   *        Success callback to call on a successful transaction commit.
+   * @param failureCb [optional]
+   *        Error callback to call when an error is encountered.
+   */
+  newTxn: function newTxn(txn_type, callback, successCb, failureCb) {
+    this.ensureDB(function (db) {
+      debug("Starting new transaction" + txn_type);
+      let txn = db.transaction(STORE_NAME, txn_type);
+      debug("Retrieving object store", STORE_NAME);
+      let store = txn.objectStore(STORE_NAME);
+
+      txn.oncomplete = function (event) {
+        debug("Transaction complete. Returning to callback.");
+        successCb(txn.result);
+      };
+
+      txn.onabort = function (event) {
+        debug("Caught error on transaction" + event.target.errorCode);
+        switch(event.target.errorCode) {
+          case Ci.nsIIDBDatabaseException.ABORT_ERR:
+          case Ci.nsIIDBDatabaseException.CONSTRAINT_ERR:
+          case Ci.nsIIDBDatabaseException.DATA_ERR:
+          case Ci.nsIIDBDatabaseException.TRANSIENT_ERR:
+          case Ci.nsIIDBDatabaseException.NOT_ALLOWED_ERR:
+          case Ci.nsIIDBDatabaseException.NOT_FOUND_ERR:
+          case Ci.nsIIDBDatabaseException.QUOTA_ERR:
+          case Ci.nsIIDBDatabaseException.READ_ONLY_ERR:
+          case Ci.nsIIDBDatabaseException.TIMEOUT_ERR:
+          case Ci.nsIIDBDatabaseException.TRANSACTION_INACTIVE_ERR:
+          case Ci.nsIIDBDatabaseException.VERSION_ERR:
+          case Ci.nsIIDBDatabaseException.UNKNOWN_ERR:
+            failureCb("UnknownError");
+            break;
+          default:
+            debug("Unknown errorCode", event.target.errorCode);
+            failureCb("UnknownError");
+            break;
+        }
+      };
+      callback(txn, store);
+    }, failureCb);
+  },
+
+  // Todo: add searchfields. "Tom" should be a result with T, t, To, to...
+  makeImport: function makeImport(aContact) {
+    let contact = {};
+    contact.properties = {
+      name:            [],
+      honorificPrefix: [],
+      givenName:       [],
+      additionalName:  [],
+      familyName:      [],
+      honorificSuffix: [],
+      nickname:        [],
+      email:           [],
+      photo:           [],
+      url:             [],
+      category:        [],
+      adr:             [],
+      tel:             [],
+      org:             [],
+      bday:            null,
+      note:            [],
+      impp:            [],
+      anniversary:     null,
+      sex:             null,
+      genderIdentity:  null
+    };
+
+    for (let field in aContact.properties) {
+      contact.properties[field] = aContact.properties[field];
+    }
+
+    contact.updated = aContact.updated;
+    contact.published = aContact.published;
+    contact.id = aContact.id;
+
+    return contact;
+  },
+
+  // Needed to remove searchfields
+  makeExport: function makeExport(aRecord) {
+    let contact = {};
+    contact.properties = aRecord.properties;
+
+    for (let field in aRecord.properties)
+      contact.properties[field] = aRecord.properties[field];
+
+    contact.updated = aRecord.updated;
+    contact.published = aRecord.published;
+    contact.id = aRecord.id;
+    return contact;
+  },
+
+  updateRecordMetadata: function updateRecordMetadata(record) {
+    if (!record.id) {
+      Cu.reportError("Contact without ID");
+    }
+    if (!record.published) {
+      record.published = new Date();
+    }
+    record.updated = new Date();
+  },
+
+  saveContact: function saveContact(aContact, successCb, errorCb) {
+    let contact = this.makeImport(aContact);
+    this.newTxn(Ci.nsIIDBTransaction.READ_WRITE, function (txn, store) {
+      debug("Going to update" + JSON.stringify(contact));
+
+      // Look up the existing record and compare the update timestamp.
+      // If no record exists, just add the new entry.
+      let newRequest = store.get(contact.id);
+      newRequest.onsuccess = function (event) {
+        if (!event.target.result) {
+          debug("new record!")
+          this.updateRecordMetadata(contact);
+          store.put(contact);
+        } else {
+          debug("old record!")
+          if (new Date(typeof contact.updated === "undefined" ? 0 : contact.updated) < new Date(event.target.result.updated)) {
+            debug("rev check fail!");
+            txn.abort();
+            return;
+          } else {
+            debug("rev check OK");
+            contact.published = event.target.result.published;
+            contact.updated = new Date();
+            store.put(contact);
+          }
+        }
+      }.bind(this);
+    }.bind(this), successCb, errorCb);
+  },
+
+  removeContact: function removeContact(aId, aSuccessCb, aErrorCb) {
+    this.newTxn(Ci.nsIIDBTransaction.READ_WRITE, function (txn, store) {
+      debug("Going to delete" + aId);
+      store.delete(aId);
+    }, aSuccessCb, aErrorCb);
+  },
+
+  clear: function clear(aSuccessCb, aErrorCb) {
+    this.newTxn(Ci.nsIIDBTransaction.READ_WRITE, function (txn, store) {
+      debug("Going to clear all!");
+      store.clear();
+    }, aSuccessCb, aErrorCb);
+  },
+
+  /**
+   * @param successCb
+   *        Callback function to invoke with result array.
+   * @param failureCb [optional]
+   *        Callback function to invoke when there was an error.
+   * @param options [optional]
+   *        Object specifying search options. Possible attributes:
+   *        - filterBy
+   *        - filterOp
+   *        - filterValue
+   *        - count
+   *        Possibly supported in the future:
+   *        - fields
+   *        - sortBy
+   *        - sortOrder
+   *        - startIndex
+   */
+  find: function find(aSuccessCb, aFailureCb, aOptions) {
+    debug("ContactDB:find val:" + aOptions.filterValue + " by: " + aOptions.filterBy + " op: " + aOptions.filterOp + "\n");
+
+    let self = this;
+    this.newTxn(Ci.nsIIDBTransaction.READ_ONLY, function (txn, store) {
+      if (aOptions && aOptions.filterOp == "equals") {
+        self._findWithIndex(txn, store, aOptions);
+      } else if (aOptions && aOptions.filterBy) {
+        self._findWithSearch(txn, store, aOptions);
+      } else {
+        self._findAll(txn, store, aOptions);
+      }
+    }, aSuccessCb, aFailureCb);
+  },
+
+  _findWithIndex: function _findWithIndex(txn, store, options) {
+    debug("_findWithIndex: " + options.filterValue +" " + options.filterOp + " " + options.filterBy + " ");
+    let fields = options.filterBy;
+    for (let key in fields) {
+      debug("key: " + fields[key]);
+      if (!store.indexNames.contains(fields[key]) && !fields[key] == "id") {
+        debug("Key not valid!" + fields[key] + ", " + store.indexNames);
+        txn.abort();
+        return;
+      }
+    }
+
+    // lookup for all keys
+    if (options.filterBy.length == 0) {
+      debug("search in all fields!" + JSON.stringify(store.indexNames));
+      for(let myIndex = 0; myIndex < store.indexNames.length; myIndex++) {
+        fields = Array.concat(fields, store.indexNames[myIndex])
+      }
+    }
+
+    let filter_keys = fields.slice();
+    for (let key = filter_keys.shift(); key; key = filter_keys.shift()) {
+      let request;
+      if (key == "id") {
+        // store.get would return an object and not an array
+        request = store.getAll(options.filterValue);
+      } else {
+        debug("Getting index: " + key);
+        let index = store.index(key);
+        request = index.getAll(options.filterValue, options.filterLimit);
+      }
+      if (!txn.result)
+        txn.result = {};
+
+      request.onsuccess = function (event) {
+        debug("Request successful. Record count:" + event.target.result.length);
+        for (let i in event.target.result)
+          txn.result[event.target.result[i].id] = this.makeExport(event.target.result[i]);
+      }.bind(this);
+    }
+  },
+
+  // Will be replaced by _findWithIndex once all searchfields are added.
+  _findWithSearch: function _findWithSearch(txn, store, options) {
+    debug("_findWithSearch:" + options.filterValue + options.filterOp)
+    store.getAll().onsuccess = function (event) {
+      debug("Request successful." + event.target.result);
+      txn.result = event.target.result.filter(function (record) {
+        let properties = record.properties;
+        for (let i = 0; i < options.filterBy.length; i++) {
+          let field = options.filterBy[i];
+          if (!properties[field])
+              continue;
+          let value = '';
+          switch (field) {
+            case "name":
+            case "familyName":
+            case "givenName":
+            case "nickname":
+            case "email":
+            case "tel":
+            case "note":
+              value = [f for each (f in [properties[field]])].join("\n") || '';
+              break;
+            default:
+              value = properties[field];
+              debug("unknown field: " + field);
+          }
+          let match = false;
+          switch (options.filterOp) {
+            case "icontains":
+              match = value.toLowerCase().indexOf(options.filterValue.toLowerCase()) != -1;
+              break;
+            case "contains":
+              match = value.indexOf(options.filterValue) != -1;
+              break;
+            case "equals":
+              match = value == options.filterValue;
+              break
+          }
+          if (match)
+            return true;
+        }
+        return false;
+      }).map(this.makeExport.bind(this));
+    }.bind(this);
+  },
+
+  _findAll: function _findAll(txn, store, options) {
+    debug("ContactDB:_findAll:  " + JSON.stringify(options));
+    if (!txn.result)
+      txn.result = {};
+
+    store.getAll(null, options.filterLimit).onsuccess = function (event) {
+      debug("Request successful. Record count:", event.target.result.length);
+      for (let i in event.target.result)
+        txn.result[event.target.result[i].id] = this.makeExport(event.target.result[i]);
+    }.bind(this);
+  }
+};
new file mode 100644
--- /dev/null
+++ b/dom/contacts/fallback/ContactService.jsm
@@ -0,0 +1,96 @@
+/* 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/. */
+
+"use strict"
+
+let DEBUG = 0;
+if (DEBUG)
+  debug = function (s) { dump("-*- Fallback ContactService component: " + s + "\n"); }
+else
+  debug = function (s) {}
+
+const Cu = Components.utils; 
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+let EXPORTED_SYMBOLS = ["DOMContactManager"];
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/ContactDB.jsm");
+
+let myGlobal = this;
+
+let DOMContactManager = {
+
+  init: function() {
+    debug("Init");
+    this._mm = Cc["@mozilla.org/parentprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager);
+    this._messages = ["Contacts:Find", "Contacts:Clear", "Contact:Save", "Contact:Remove"];
+    this._messages.forEach((function(msgName) {
+      this._mm.addMessageListener(msgName, this);
+    }).bind(this));
+
+    var idbManager = Components.classes["@mozilla.org/dom/indexeddb/manager;1"].getService(Ci.nsIIndexedDatabaseManager);
+    idbManager.initWindowless(myGlobal);
+    this._db = new ContactDB(myGlobal);
+
+    Services.obs.addObserver(this, "profile-before-change", false);
+
+    try {
+      let hosts = Services.prefs.getCharPref("dom.mozContacts.whitelist")
+      hosts.split(",").forEach(function(aHost) {
+        debug("Add host: " + JSON.stringify(aHost));
+        if (aHost.length > 0)
+          Services.perms.add(Services.io.newURI(aHost, null, null), "webcontacts-manage",
+                             Ci.nsIPermissionManager.ALLOW_ACTION);
+      });
+    } catch(e) { debug(e); }
+  },
+
+  observe: function(aSubject, aTopic, aData) {
+    myGlobal = null;
+    this._messages.forEach((function(msgName) {
+      this._mm.removeMessageListener(msgName, this);
+    }).bind(this));
+    Services.obs.removeObserver(this, "profile-before-change");
+    this._mm = null;
+    this._messages = null;
+    if (this._db)
+      this._db.close();
+  },
+
+  receiveMessage: function(aMessage) {
+    debug("Fallback DOMContactManager::receiveMessage " + aMessage.name);
+    let msg = aMessage.json;
+    switch (aMessage.name) {
+      case "Contacts:Find":
+        let result = new Array();
+        this._db.find(
+          function(contacts) {
+            for (let i in contacts)
+              result.push(contacts[i]);
+            debug("result:" + JSON.stringify(result));
+            this._mm.sendAsyncMessage("Contacts:Find:Return:OK", {requestID: msg.requestID, contacts: result});
+          }.bind(this),
+          function(aErrorMsg) { this._mm.sendAsyncMessage("Contacts:Find:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }) }.bind(this), 
+          msg.findOptions);
+        break;
+      case "Contact:Save":
+        this._db.saveContact(msg.contact, function() {this._mm.sendAsyncMessage("Contact:Save:Return:OK", { requestID: msg.requestID }); }.bind(this), 
+                             function(aErrorMsg) { this._mm.sendAsyncMessage("Contact:Save:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }); }.bind(this));
+        break;
+      case "Contact:Remove":
+        this._db.removeContact(msg.id, 
+                               function() {this._mm.sendAsyncMessage("Contact:Remove:Return:OK", { requestID: msg.requestID }); }.bind(this), 
+                               function(aErrorMsg) {this._mm.sendAsyncMessage("Contact:Remove:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }); }.bind(this));
+        break;
+      case "Contacts:Clear":
+        this._db.clear(function() { this._mm.sendAsyncMessage("Contacts:Clear:Return:OK", { requestID: msg.requestID }); }.bind(this),
+                       function(aErrorMsg) { this._mm.sendAsyncMessage("Contacts:Clear:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }); }.bind(this));
+    }
+  }
+}
+
+DOMContactManager.init();
new file mode 100644
--- /dev/null
+++ b/dom/contacts/tests/Makefile.in
@@ -0,0 +1,28 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this file,
+# You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DEPTH            = ../../..
+topsrcdir        = @top_srcdir@
+srcdir           = @srcdir@
+VPATH            = @srcdir@
+
+relativesrcdir   = dom/contacts/tests
+
+include $(DEPTH)/config/autoconf.mk
+
+DIRS = \
+  $(NULL)
+
+include $(topsrcdir)/config/rules.mk
+
+_TEST_FILES = \
+  test_contacts_basics.html \
+  $(NULL)
+
+_CHROME_TEST_FILES = \
+  $(NULL)
+
+libs:: $(_TEST_FILES)
+	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
+
new file mode 100644
--- /dev/null
+++ b/dom/contacts/tests/test_contacts_basics.html
@@ -0,0 +1,666 @@
+<!DOCTYPE html>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id={674720}
+-->
+<head>
+  <title>Test for Bug {674720} WebContacts</title>
+  <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id={674720}">Mozilla Bug {674720}</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+"use strict"
+
+netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+Components.classes["@mozilla.org/permissionmanager;1"]
+          .getService(Components.interfaces.nsIPermissionManager)
+          .add(SpecialPowers.getDocumentURIObject(window.document),
+               "webcontacts-manage",
+               Components.interfaces.nsIPermissionManager.ALLOW_ACTION);
+
+var adr1 = {
+  streetAddress: "street 1",
+  locality: "locality 1",
+  region: "region 1",
+  postalCode: "postal code 1",
+  countryName: "country 1"
+};
+
+var adr2 = {
+  streetAddress: "street2",
+  locality: "locality2",
+  region: "region2",
+  postalCode: "postal code2",
+  countryName: "country2"
+};
+
+var properties1 = {
+  name: "Testname1",
+  familyName: "TestFamilyName",
+  givenName: ["Test1","Test2"],
+  nickname: "nicktest",
+  tel: ["123456"],
+  adr: adr1
+};
+
+var properties2 = {
+  name: ["dummyName", "dummyName2"],
+  familyName: "dummyFamilyName",
+  givenName: "dummyGivenName",
+  honorificPrefix: ["dummyHonorificPrefix","dummyHonorificPrefix2"],
+  honorificSuffix: "dummyHonorificSuffix",
+  additionalName: "dummyadditionalName",
+  nickname: "dummyNickname",
+  tel: ["123456789", "234567890"],
+  email: ["a@b.c", "b@c.d"],
+  adr: [adr1, adr2],
+  impp: ["im1", "im2"],
+  org: ["org1", "org2"],
+  bday: new Date("1980, 12, 01"),
+  note: "test note",
+  photo: ["pic1", "pic2"],
+  category: ["cat1", "cat2"],
+  url: ["www.1.com", "www.2.com"],
+  anniversary: new Date("2000, 12, 01"),
+  sex: "male",
+  genderIdentity: "test"
+};
+
+var sample_id1;
+var sample_id2;
+
+var createResult1;
+var createResult2;
+
+var findResult1;
+var findResult2;
+
+function clearTemps() {
+  sample_id1 = null;
+  sample_id2 = null;
+  createResult1 = null;
+  createResult2 = null;
+  findResult1 = null;
+  findResult2 = null;
+}
+
+function onUnwantedSuccess() {
+  ok(false, "onUnwantedSuccess: shouldn't get here");
+}
+
+function onFailure() {
+  ok(false, "in on Failure!");
+}
+
+function checkStr(str1, str2, msg) {
+  if (str1)
+    ok(typeof str1 == "string" ? [str1] : str1, (typeof str2 == "string") ? [str2] : str2, msg);
+}
+
+function checkAddress(adr1, adr2) {
+  checkStr(adr1.streetAddress, adr2.streetAddress, "Same streetAddress");
+  checkStr(adr1.locality, adr2.locality, "Same locality");
+  checkStr(adr1.region, adr2.region, "Same region");
+  checkStr(adr1.postalCode, adr2.postalCode, "Same postalCode");
+  checkStr(adr1.countryName, adr2.countryName, "Same countryName");
+}
+
+function checkContacts(contact1, contact2) {
+  checkStr(contact1.name, contact2.name, "Same name");
+  checkStr(contact1.honorificPrefix, contact2.honorificPrefix, "Same honorificPrefix");
+  checkStr(contact1.givenName, contact2.givenName, "Same givenName");
+  checkStr(contact1.additionalName, contact2.additionalName, "Same additionalName");
+  checkStr(contact1.familyName, contact2.familyName, "Same familyName");
+  checkStr(contact1.honorificSuffix, contact2.honorificSuffix, "Same honorificSuffix");
+  checkStr(contact1.nickname, contact2.nickname, "Same nickname");
+  checkStr(contact1.email, contact2.email, "Same email");
+  checkStr(contact1.photo, contact2.photo, "Same photo");
+  checkStr(contact1.url, contact2.url, "Same url");
+  checkStr(contact1.category, contact2.category, "Same category");
+  is(contact1.bday ? contact1.bday.valueOf() : null, contact2.bday ? contact2.bday.valueOf() : null, "Same birthday");
+  checkStr(contact1.note, contact2.note, "Same note");
+  checkStr(contact1.impp, contact2.impp, "Same impp");
+  is(contact1.anniversary ? contact1.anniversary.valueOf() : null , contact2.anniversary ? contact2.anniversary.valueOf() : null, "Same anniversary");
+  is(contact1.sex, contact2.sex, "Same sex");
+  is(contact1.genderIdentity, contact2.genderIdentity, "Same genderIdentity");
+
+  for (var i in contact1.adr)
+    checkAddress(contact1.adr[i], contact2.adr[i]);
+}
+
+var req;
+var index = 0;
+
+var mozContacts = window.navigator.mozContacts
+
+var steps = [
+  function () {
+    ok(true, "Deleting database");
+    req = mozContacts.clear();
+    req.onsuccess = function () {
+      ok(true, "Deleted the database");
+      next();
+    };
+    req.onerror = onFailure;
+  },
+  function () {
+    ok(true, "Retrieving all contacts");
+    req = mozContacts.find({});
+    req.onsuccess = function () {
+      ok(req.result.length == 0, "Empty database is empty.");
+      next();
+    };
+    req.onerror = onFailure;
+  },
+  function () {
+    ok(true, "Adding empty contact");
+    createResult1 = new mozContact();
+    createResult1.init({});
+    req = navigator.mozContacts.save(createResult1);
+    req.onsuccess = function () {
+      ok(createResult1.id, "The contact now has an ID.");
+      sample_id1 = createResult1.id;
+      next();
+    };
+    req.onerror = onFailure;
+  },
+  function () {
+    ok(true, "Retrieving all contacts");
+    req = mozContacts.find({});
+    req.onsuccess = function () {
+      ok(req.result.length == 1, "One contact.");
+      findResult1 = req.result[0];
+      next();
+    };
+    req.onerror = onFailure;
+  },
+  function () {
+    ok(true, "Deleting empty contact");
+    req = navigator.mozContacts.remove(findResult1);
+    req.onsuccess = function () {
+      var req2 = mozContacts.find({});
+      req2.onsuccess = function () {
+        ok(req2.result.length == 0, "Empty Database.");
+        clearTemps();
+        next();
+      }
+      req2.onerror = onFailure;
+    }
+    req.onerror = onFailure;
+  },
+  function () {
+    ok(true, "Adding a new contact1");
+    createResult1 = new mozContact();
+    createResult1.init(properties1);
+    req = navigator.mozContacts.save(createResult1);
+    req.onsuccess = function () {
+      ok(createResult1.id, "The contact now has an ID.");
+      sample_id1 = createResult1.id;
+      checkContacts(properties1, createResult1);
+      next();
+    };
+    req.onerror = onFailure;
+  },
+  function () {
+    ok(true, "Retrieving all contacts");
+    req = mozContacts.find({});
+    req.onsuccess = function() {
+      ok(req.result.length == 1, "Found exactly 1 contact.");
+      findResult1 = req.result[0];
+      ok(findResult1.id == sample_id1, "Same ID");
+      checkContacts(createResult1, findResult1);
+      ok(findResult1.updated, "Has updated field");
+      ok(findResult1.published, "Has published field");
+      next();
+    }
+    req.onerror = onFailure;
+  },
+  function () {
+    ok(true, "Modifying contact1");
+    findResult1.impp = properties1.impp = (["phil impp"]);
+    req = navigator.mozContacts.save(findResult1);
+    req.onsuccess = function () {
+      var req2 = mozContacts.find({});
+      req2.onsuccess = function() {
+        ok(req2.result.length == 1, "Found exactly 1 contact.");
+        findResult2 = req2.result[0];
+        ok(findResult2.id == sample_id1, "Same ID");
+        checkContacts(findResult2, properties1);
+        ok(findResult2.impp.length == 1, "Found exactly 1 IMS info.");
+        next();
+      };
+      req2.onerror = onFailure;
+    };
+    req.onerror = onFailure;
+  },
+  function() {
+    ok(true, "Saving old contact, should abort!");
+    req = mozContacts.save(createResult1);
+    req.onsuccess = onUnwantedSuccess;
+    req.onerror   = function() { ok(true, "Successfully declined updating old contact!"); next(); };
+  },
+  function() {
+    ok(true, "Saving old contact, should abort!");
+    req = mozContacts.save(findResult1)
+    req.onsuccess = onUnwantedSuccess;
+    req.onerror   = function() { ok(true, "Successfully declined updating old contact!"); next(); };
+  },
+  function () {
+    ok(true, "Retrieving a specific contact by ID");
+    var options = {filterBy: ["id"],
+                   filterOp: "equals",
+                   filterValue: sample_id1};
+    req = mozContacts.find(options);
+    req.onsuccess = function () {
+      ok(req.result.length == 1, "Found exactly 1 contact.");
+      findResult1 = req.result[0];
+      ok(findResult1.id == sample_id1, "Same ID");
+      checkContacts(createResult1, properties1);
+      next();
+    };
+    req.onerror = onFailure;
+  },
+  function () {
+    ok(true, "Retrieving a specific contact by givenName");
+    var options = {filterBy: ["givenName"],
+                   filterOp: "equals",
+                   filterValue: properties1.givenName[0]};
+    req = mozContacts.find(options);
+    req.onsuccess = function () {
+      ok(req.result.length == 1, "Found exactly 1 contact.");
+      findResult1 = req.result[0];
+      ok(findResult1.id == sample_id1, "Same ID");
+      checkContacts(findResult1, createResult1);
+      next();
+    }
+    req.onerror = onFailure;
+  },
+  function () {
+    ok(true, "Modifying contact2");
+    findResult1.impp = properties1.impp = (["phil impp"]);
+    req = mozContacts.save(findResult1);
+    req.onsuccess = function () {
+      var req2 = mozContacts.find({});
+      req2.onsuccess = function () {
+        ok(req2.result.length == 1, "Found exactly 1 contact.");
+        findResult1 = req2.result[0];
+        ok(findResult1.id == sample_id1, "Same ID");
+        checkContacts(findResult1, createResult1);
+        ok(findResult1.impp.length == 1, "Found exactly 1 IMS info.");
+        next();
+      }
+      req2.onerror = onFailure;
+    };
+    req.onerror = onFailure;
+  },
+  function () {
+    ok(true, "Searching contacts by query");
+    var options = {filterBy: ["name", "email"],
+                   filterOp: "icontains",
+                   filterValue: properties1.name[0].substring(0,4)};
+    req = mozContacts.find(options);
+    req.onsuccess = function () {
+      ok(req.result.length == 1, "Found exactly 1 contact.");
+      findResult1 = req.result[0];
+      ok(findResult1.id == sample_id1, "Same ID");
+      checkContacts(findResult1, createResult1);
+      next();
+    };
+    req.onerror = onFailure;
+  },
+  function () {
+    ok(true, "Searching contacts by query");
+    var options = {filterBy: ["nickname", "email"],
+                   filterOp: "icontains",
+                   filterValue: properties1.nickname};
+    req = mozContacts.find(options);
+    req.onsuccess = function () {
+      ok(req.result.length == 1, "Found exactly 1 contact.");
+      findResult1 = req.result[0];
+      ok(findResult1.id == sample_id1, "Same ID");
+      checkContacts(findResult1, createResult1);
+      next();
+    };
+    req.onerror = onFailure;
+  },
+  function () {
+    ok(true, "Searching contacts with multiple indices");
+    var options = {filterBy: ["nickname", "email", "name"],
+                   filterOp: "equals",
+                   filterValue: properties1.nickname};
+    req = mozContacts.find(options);
+    req.onsuccess = function () {
+      ok(req.result.length == 1, "Found exactly 1 contact.");
+      findResult1 = req.result[0];
+      ok(findResult1.id == sample_id1, "Same ID");
+      checkContacts(findResult1, createResult1);
+      next();
+    };
+    req.onerror = onFailure;
+  },
+  function () {
+    ok(true, "Modifying contact3");
+    findResult1.email = (properties1.nickname);
+    findResult1.nickname = "TEST";
+    var newContact = new mozContact();
+    newContact.init(findResult1);
+    req = mozContacts.save(newContact);
+    req.onsuccess = function () {
+      var options = {filterBy: ["nickname", "email", "name"],
+                     filterOp: "equals",
+                     filterValue: properties1.nickname};
+      // One contact has it in nickname and the other in email
+      var req2 = mozContacts.find(options);
+      req2.onsuccess = function () {
+        ok(req2.result.length == 2, "Found exactly 2 contacts.");
+        ok(req2.result[0].id != req2.result[1].id, "Different ID");
+        next();
+      }
+      req2.onerror = onFailure;
+    };
+    req.onerror = onFailure;
+  },
+  function () {
+    ok(true, "Deleting contact" + findResult1.id);
+    req = mozContacts.remove(findResult1);
+    req.onsuccess = function () {
+      var req2 = mozContacts.find({});
+      req2.onsuccess = function () {
+        ok(req2.result.length == 1, "One contact left.");
+        findResult1 = req2.result[0];
+        next();
+      }
+      req2.onerror = onFailure;
+    }
+    req.onerror = onFailure;
+  },
+  function () {
+    ok(true, "Deleting database");
+    req = mozContacts.remove(findResult1);
+    req.onsuccess =  function () {
+      clearTemps();
+      next();
+    };
+    req.onerror = onFailure;
+  },
+  function () {
+    ok(true, "Adding a new contact");
+    createResult1 = new mozContact();
+    createResult1.init(properties1);
+    req = mozContacts.save(createResult1)
+    req.onsuccess = function () {
+      ok(createResult1.id, "The contact now has an ID.");
+      sample_id1 = createResult1.id;
+      next();
+    }
+    req.onerror = onFailure;
+  },
+  function () {
+    ok(true, "Adding a new contact2");
+    createResult2 = new mozContact();
+    createResult2.init(properties2);
+    req = mozContacts.save(createResult2);
+    req.onsuccess = function () {
+      ok(createResult2.id, "The contact now has an ID.");
+      sample_id2 = createResult2.id;
+      next();
+    };
+    req.onerror = onFailure;
+  },
+  function () {
+    ok(true, "Retrieving all contacts");
+    req = mozContacts.find({})
+    req.onsuccess = function () {
+      ok(req.result.length == 2, "Found exactly 2 contact.");
+      next();
+    }
+    req.onerror = onFailure;
+  },
+  function () {
+    console.log("Searching contacts by query1");
+    var options = {filterBy: ["name", "email"],
+                   filterOp: "icontains",
+                   filterValue: properties1.name[0].substring(0, 4)}
+    req = mozContacts.find(options)
+    req.onsuccess = function () {
+      ok(req.result.length == 1, "Found exactly 1 contact.");
+      findResult1 = req.result[0];
+      ok(findResult1.id == sample_id1, "Same ID");
+      checkContacts(findResult1, createResult1);
+      next();
+    }
+    req.onerror = onFailure;
+  },
+  function () {
+    ok(true, "Searching contacts by query2");
+    var options = {filterBy: ["name", "email"],
+                   filterOp: "icontains",
+                   filterValue: properties2.name[0].substring(0, 4)};
+    req = mozContacts.find(options);
+    req.onsuccess = function () {
+      ok(req.result.length == 1, "Found exactly 1 contact.");
+      findResult1 = req.result[0];
+      ok(findResult1.adr.length == 2, "Adr length 2");
+      checkContacts(findResult1, createResult2);
+      next();
+    }
+    req.onerror = onFailure;
+  },
+  function () {
+    ok(true, "Searching contacts by tel");
+    var options = {filterBy: ["tel"],
+                   filterOp: "contains",
+                   filterValue: properties2.tel[0].substring(0, 7)};
+    req = mozContacts.find(options);
+    req.onsuccess = function () {
+      ok(req.result.length == 1, "Found exactly 1 contact.");
+      findResult1 = req.result[0];
+      ok(findResult1.id == sample_id2, "Same ID");
+      checkContacts(findResult1, createResult2);
+      next();
+    }
+    req.onerror = onFailure;
+  },
+  function () {
+    ok(true, "Searching contacts by email");
+    var options = {filterBy: ["email"],
+                   filterOp: "contains",
+                   filterValue: properties2.email[0].substring(0, 4)};
+    req = mozContacts.find(options);
+    req.onsuccess = function () {
+      ok(req.result.length == 1, "Found exactly 1 contact.");
+      findResult1 = req.result[0];
+      ok(findResult1.id == sample_id2, "Same ID");
+      checkContacts(findResult1, createResult2);
+      next();
+    }
+    req.onerror = onFailure;
+  },
+  function () {
+    ok(true, "Deleting database");
+    req = mozContacts.clear();
+    req.onsuccess = function () {
+      clearTemps();
+      next();
+    }
+    req.onerror = onFailure;
+  },
+  function () {
+    ok(true, "Adding 100 contacts");
+    for (var i=0; i<99; i++) {
+      createResult1 = new mozContact();
+      createResult1.init(properties1);
+      req = mozContacts.save(createResult1);
+      req.onsuccess = function () {
+        ok(createResult1.id, "The contact now has an ID.");
+      };
+      req.onerror = onFailure;
+    };
+    createResult1 = new mozContact();
+    createResult1.init(properties1);
+    req = mozContacts.save(createResult1);
+    req.onsuccess = function () {
+      ok(createResult1.id, "The contact now has an ID.");
+      ok(createResult1.name == properties1.name, "Same Name");
+      next();
+    };
+    req.onerror = onFailure;
+  },
+  function () {
+    ok(true, "Retrieving all contacts");
+    req = mozContacts.find({});
+    req.onsuccess = function () {
+      ok(req.result.length == 100, "100 Entries.");
+      next();
+    }
+    req.onerror = onFailure;
+  },
+  function () {
+    ok(true, "Retrieving all contacts with limit 10");
+    var options = { filterLimit: 10 };
+    req = mozContacts.find(options);
+    req.onsuccess = function () {
+      ok(req.result.length == 10, "10 Entries.");
+      next();
+    }
+    req.onerror = onFailure;
+  },
+  function () {
+    ok(true, "Retrieving all contacts2");
+    var options = {filterBy: ["name"],
+                   filterOp: "icontains",
+                   filterValue: properties2.name[0].substring(0, 4)};
+    req = mozContacts.find({});
+    req.onsuccess = function () {
+      ok(req.result.length == 100, "100 Entries.");
+      checkContacts(createResult1, req.result[99]);
+      next();
+    }
+    req.onerror = onFailure;
+  },
+  function () {
+    ok(true, "Deleting database");
+    req = mozContacts.clear();
+    req.onsuccess = function () {
+      clearTemps();
+      next();
+    }
+    req.onerror = onFailure;
+  },
+  function () {
+    ok(true, "Testing clone contact");
+    createResult1 = new mozContact();
+    createResult1.init(properties1);
+    req = mozContacts.save(createResult1);
+    req.onsuccess = function () {
+      ok(createResult1.id, "The contact now has an ID.");
+      ok(createResult1.name == properties1.name, "Same Name");
+      next();
+    }
+    req.onerror = onFailure;
+  },
+  function() {
+    ok(true, "Testing clone contact2");
+    var cloned = new mozContact(createResult1);
+    ok(cloned.id != createResult1.id, "Cloned contact has new ID");
+    cloned.email = "new email!";
+    cloned.givenName = "Tom";
+    req = mozContacts.save(cloned);
+    req.onsuccess = function () {
+      ok(cloned.id, "The contact now has an ID.");
+      ok(cloned.email == "new email!", "Same Email");
+      ok(createResult1.email != cloned.email, "Clone has different email");
+      ok(cloned.givenName == "Tom", "New Name");
+      next();
+    }
+    req.onerror = onFailure;
+  },
+  function () {
+    ok(true, "Retrieving all contacts");
+    var options = {filterBy: ["name"],
+                   filterOp: "icontains",
+                   filterValue: properties2.name[0].substring(0, 4)};
+    req = mozContacts.find({});
+    req.onsuccess = function () {
+      ok(req.result.length == 2, "2 Entries.");
+      next();
+    }
+    req.onerror = onFailure;
+  },
+  function () {
+    ok(true, "Search with redundant fields should only return 1 contact");
+    createResult1 = new mozContact();
+    createResult1.init({name: "XXX", nickname: "XXX", email: "XXX", tel: "XXX"});
+    req = mozContacts.save(createResult1);
+    req.onsuccess = function() {
+      var options = {filterBy: [],
+                     filterOp: "equals",
+                     filterValue: "XXX"};
+      var req2 = mozContacts.find(options);
+      req2.onsuccess = function() {
+        ok(req2.result.length == 1, "1 Entry");
+        next();
+      }
+      req2.onerror = onFailure;
+    }
+    req.onerror = onFailure;
+  },
+  function () {
+    ok(true, "Deleting database");
+    req = mozContacts.clear()
+    req.onsuccess = function () {
+      ok(true, "Deleted the database");
+      next();
+    }
+    req.onerror = onFailure;
+  },
+  function () {
+    ok(true, "all done!\n");
+    clearTemps();
+
+    SimpleTest.finish();
+  }
+];
+
+function next() {
+  ok(true, "Begin!");
+  if (index >= steps.length) {
+    ok(false, "Shouldn't get here!");
+    return;
+  }
+  try {
+    steps[index]();
+  } catch(ex) {
+    ok(false, "Caught exception", ex);
+  }
+  index += 1;
+}
+
+function permissionTest() {
+  if (gContactsEnabled) {
+    next();
+  } else {
+    is(mozContacts, null, "mozContacts is null when not enabled.");
+    SimpleTest.finish();
+  }
+}
+
+var gContactsEnabled = SpecialPowers.getBoolPref("dom.mozContacts.enabled");
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(permissionTest);
+
+ok(true, "test passed");
+</script>
+</pre>
+</body>
+</html>
\ No newline at end of file
--- a/dom/dom-config.mk
+++ b/dom/dom-config.mk
@@ -1,14 +1,15 @@
 DOM_SRCDIRS = \
   dom/base \
   dom/battery \
   dom/power \
   dom/network/src \
   dom/sms/src \
+  dom/contacts \
   dom/src/events \
   dom/src/storage \
   dom/src/offline \
   dom/src/geolocation \
   dom/src/notification \
   dom/workers \
   content/xbl/src \
   content/xul/document/src \
--- a/dom/indexedDB/IDBCursor.cpp
+++ b/dom/indexedDB/IDBCursor.cpp
@@ -261,16 +261,24 @@ IDBCursor::CreateCommon(IDBRequest* aReq
 
   nsRefPtr<IDBCursor> cursor = new IDBCursor();
 
   IDBDatabase* database = aTransaction->Database();
   cursor->mScriptContext = database->GetScriptContext();
   cursor->mOwner = database->GetOwner();
   cursor->mScriptOwner = database->GetScriptOwner();
 
+  if (cursor->mScriptOwner) {
+    if (NS_FAILED(NS_HOLD_JS_OBJECTS(cursor, IDBCursor))) {
+      return nsnull;
+    }
+
+    cursor->mRooted = true;
+  }
+
   cursor->mRequest = aRequest;
   cursor->mTransaction = aTransaction;
   cursor->mObjectStore = aObjectStore;
   cursor->mDirection = aDirection;
   cursor->mContinueQuery = aContinueQuery;
   cursor->mContinueToQuery = aContinueToQuery;
   cursor->mRangeKey = aRangeKey;
 
--- a/dom/indexedDB/IDBDatabase.cpp
+++ b/dom/indexedDB/IDBDatabase.cpp
@@ -159,17 +159,19 @@ IDBDatabase::Create(IDBWrapperCache* aOw
 
   nsRefPtr<DatabaseInfo> databaseInfo(aDatabaseInfo);
   NS_ASSERTION(databaseInfo, "Null pointer!");
 
   nsRefPtr<IDBDatabase> db(new IDBDatabase());
 
   db->mScriptContext = aOwnerCache->GetScriptContext();
   db->mOwner = aOwnerCache->GetOwner();
-  db->mScriptOwner = aOwnerCache->GetScriptOwner();
+  if (!db->SetScriptOwner(aOwnerCache->GetScriptOwner())) {
+    return nsnull;
+  }
 
   db->mDatabaseId = databaseInfo->id;
   db->mName = databaseInfo->name;
   db->mFilePath = databaseInfo->filePath;
   databaseInfo.swap(db->mDatabaseInfo);
   db->mASCIIOrigin = aASCIIOrigin;
   db->mFileManager = aFileManager;
 
--- a/dom/indexedDB/IDBKeyRange.cpp
+++ b/dom/indexedDB/IDBKeyRange.cpp
@@ -133,17 +133,17 @@ GetKeyFromJSValOrThrow(JSContext* aCx,
     ThrowException(aCx, rv);
     return false;
   }
   return true;
 }
 
 JSBool
 MakeOnlyKeyRange(JSContext* aCx,
-                 uintN aArgc,
+                 unsigned aArgc,
                  jsval* aVp)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   jsval val;
   if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "v", &val)) {
     return false;
   }
@@ -154,17 +154,17 @@ MakeOnlyKeyRange(JSContext* aCx,
     return false;
   }
 
   return ReturnKeyRange(aCx, aVp, keyRange);
 }
 
 JSBool
 MakeLowerBoundKeyRange(JSContext* aCx,
-                       uintN aArgc,
+                       unsigned aArgc,
                        jsval* aVp)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   jsval val;
   JSBool open = false;
   if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "v/b", &val, &open)) {
     return false;
@@ -176,17 +176,17 @@ MakeLowerBoundKeyRange(JSContext* aCx,
     return false;
   }
 
   return ReturnKeyRange(aCx, aVp, keyRange);
 }
 
 JSBool
 MakeUpperBoundKeyRange(JSContext* aCx,
-                       uintN aArgc,
+                       unsigned aArgc,
                        jsval* aVp)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   jsval val;
   JSBool open = false;
   if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "v/b", &val, &open)) {
     return false;
@@ -198,17 +198,17 @@ MakeUpperBoundKeyRange(JSContext* aCx,
     return false;
   }
 
   return ReturnKeyRange(aCx, aVp, keyRange);
 }
 
 JSBool
 MakeBoundKeyRange(JSContext* aCx,
-                  uintN aArgc,
+                  unsigned aArgc,
                   jsval* aVp)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   jsval lowerVal, upperVal;
   JSBool lowerOpen = false, upperOpen = false;
   if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "vv/bb", &lowerVal,
                            &upperVal, &lowerOpen, &upperOpen)) {
--- a/dom/indexedDB/IDBRequest.cpp
+++ b/dom/indexedDB/IDBRequest.cpp
@@ -83,17 +83,19 @@ IDBRequest::Create(nsISupports* aSource,
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   nsRefPtr<IDBRequest> request(new IDBRequest());
 
   request->mSource = aSource;
   request->mTransaction = aTransaction;
   request->mScriptContext = aOwnerCache->GetScriptContext();
   request->mOwner = aOwnerCache->GetOwner();
-  request->mScriptOwner = aOwnerCache->GetScriptOwner();
+  if (!request->SetScriptOwner(aOwnerCache->GetScriptOwner())) {
+    return nsnull;
+  }
 
   return request.forget();
 }
 
 void
 IDBRequest::Reset()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
@@ -124,17 +126,17 @@ IDBRequest::NotifyHelperCompleted(Helper
   // If the request failed then set the error code and return.
   if (NS_FAILED(rv)) {
     mErrorCode = NS_ERROR_GET_CODE(rv);
     return NS_OK;
   }
 
   // Otherwise we need to get the result from the helper.
   JSContext* cx;
-  if (mScriptOwner) {
+  if (GetScriptOwner()) {
     nsIThreadJSContextStack* cxStack = nsContentUtils::ThreadJSContextStack();
     NS_ASSERTION(cxStack, "Failed to get thread context stack!");
 
     if (NS_FAILED(cxStack->GetSafeJSContext(&cx))) {
       NS_WARNING("Failed to get safe JSContext!");
       rv = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
       mErrorCode = NS_ERROR_GET_CODE(rv);
       return rv;
@@ -312,17 +314,19 @@ IDBOpenDBRequest::Create(nsIScriptContex
                          nsPIDOMWindow* aOwner,
                          JSObject* aScriptOwner)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   nsRefPtr<IDBOpenDBRequest> request(new IDBOpenDBRequest());
 
   request->mScriptContext = aScriptContext;
   request->mOwner = aOwner;
-  request->mScriptOwner = aScriptOwner;
+  if (!request->SetScriptOwner(aScriptOwner)) {
+    return nsnull;
+  }
 
   return request.forget();
 }
 
 void
 IDBOpenDBRequest::SetTransaction(IDBTransaction* aTransaction)
 {
   mTransaction = aTransaction;
--- a/dom/indexedDB/IDBTransaction.cpp
+++ b/dom/indexedDB/IDBTransaction.cpp
@@ -114,17 +114,19 @@ IDBTransaction::Create(IDBDatabase* aDat
                        bool aDispatchDelayed)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   nsRefPtr<IDBTransaction> transaction = new IDBTransaction();
 
   transaction->mScriptContext = aDatabase->GetScriptContext();
   transaction->mOwner = aDatabase->GetOwner();
-  transaction->mScriptOwner = aDatabase->GetScriptOwner();
+  if (!transaction->SetScriptOwner(aDatabase->GetScriptOwner())) {
+    return nsnull;
+  }
 
   transaction->mDatabase = aDatabase;
   transaction->mMode = aMode;
   
   transaction->mDatabaseInfo = aDatabase->Info();
 
   if (!transaction->mObjectStoreNames.AppendElements(aObjectStoreNames)) {
     NS_ERROR("Out of memory!");
--- a/dom/indexedDB/IDBWrapperCache.cpp
+++ b/dom/indexedDB/IDBWrapperCache.cpp
@@ -1,29 +1,33 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* 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 "IDBWrapperCache.h"
+#include "nsContentUtils.h"
 
 USING_INDEXEDDB_NAMESPACE
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(IDBWrapperCache)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBWrapperCache,
                                                   nsDOMEventTargetHelper)
   // Don't need NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS because
   // nsDOMEventTargetHelper does it for us.
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBWrapperCache,
                                                 nsDOMEventTargetHelper)
-  tmp->mScriptOwner = nsnull;
+  if (tmp->mScriptOwner) {
+    NS_DROP_JS_OBJECTS(tmp, IDBWrapperCache);
+    tmp->mScriptOwner = nsnull;
+  }
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(IDBWrapperCache,
                                                nsDOMEventTargetHelper)
   // Don't need NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER because
   // nsDOMEventTargetHelper does it for us.
   if (tmp->mScriptOwner) {
     NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(tmp->mScriptOwner,
@@ -31,8 +35,41 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INH
   }
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBWrapperCache)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(IDBWrapperCache, nsDOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(IDBWrapperCache, nsDOMEventTargetHelper)
+
+IDBWrapperCache::~IDBWrapperCache()
+{
+  if (mScriptOwner) {
+    NS_DROP_JS_OBJECTS(this, IDBWrapperCache);
+  }
+}
+
+bool
+IDBWrapperCache::SetScriptOwner(JSObject* aScriptOwner)
+{
+  if (!aScriptOwner) {
+    NS_ASSERTION(!mScriptOwner,
+                 "Don't null out existing owner, we need to call "
+                 "DropJSObjects!");
+
+    return true;
+  }
+
+  mScriptOwner = aScriptOwner;
+
+  nsISupports* thisSupports = NS_CYCLE_COLLECTION_UPCAST(this, IDBWrapperCache);
+  nsXPCOMCycleCollectionParticipant* participant;
+  CallQueryInterface(this, &participant);
+  nsresult rv = nsContentUtils::HoldJSObjects(thisSupports, participant);
+  if (NS_FAILED(rv)) {
+    NS_WARNING("nsContentUtils::HoldJSObjects failed.");
+    mScriptOwner = nsnull;
+    return false;
+  }
+
+  return true;
+}
--- a/dom/indexedDB/IDBWrapperCache.h
+++ b/dom/indexedDB/IDBWrapperCache.h
@@ -20,16 +20,17 @@ public:
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(
                                                    IDBWrapperCache,
                                                    nsDOMEventTargetHelper)
 
   JSObject* GetScriptOwner() const
   {
     return mScriptOwner;
   }
+  bool SetScriptOwner(JSObject* aScriptOwner);
 
   nsIScriptContext* GetScriptContext() const
   {
     return mScriptContext;
   }
 
   nsPIDOMWindow* GetOwner() const
   {
@@ -55,17 +56,17 @@ public:
       nsDOMEventTargetHelper::FromSupports(aSupports));
   }
 
 protected:
   IDBWrapperCache()
   : mScriptOwner(nsnull)
   { }
 
-  virtual ~IDBWrapperCache()
-  { }
+  virtual ~IDBWrapperCache();
 
+private:
   JSObject* mScriptOwner;
 };
 
 END_INDEXEDDB_NAMESPACE
 
 #endif // mozilla_dom_indexeddb_idbwrappercache_h__
--- a/dom/indexedDB/OpenDatabaseHelper.cpp
+++ b/dom/indexedDB/OpenDatabaseHelper.cpp
@@ -2318,16 +2318,17 @@ SetVersionHelper::NotifyTransactionCompl
   }
 
   // If the transaction was aborted, we should throw an error message.
   if (aTransaction->IsAborted()) {
     mOpenHelper->SetError(NS_ERROR_DOM_INDEXEDDB_ABORT_ERR);
   }
 
   mOpenRequest->SetTransaction(nsnull);
+  mOpenRequest = nsnull;
 
   rv = mOpenHelper->NotifySetVersionFinished();
   mOpenHelper = nsnull;
 
   return rv;
 }
 
 nsresult
new file mode 100644
--- /dev/null
+++ b/dom/interfaces/contacts/Makefile.in
@@ -0,0 +1,21 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this file,
+# You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DEPTH          = ../../..
+topsrcdir      = @top_srcdir@
+srcdir         = @srcdir@
+VPATH          = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE         = dom
+XPIDL_MODULE   = dom_contacts
+GRE_MODULE     = 1
+
+XPIDLSRCS =                             \
+            nsIDOMContactProperties.idl \
+            nsIDOMContactManager.idl    \
+            $(NULL)
+
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/dom/interfaces/contacts/nsIDOMContactManager.idl
@@ -0,0 +1,33 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "domstubs.idl"
+#include "nsIDOMContactProperties.idl"
+
+interface nsIArray;
+interface nsIDOMContactFindOptions;
+interface nsIDOMContactProperties;
+interface nsIDOMDOMRequest;
+
+[scriptable, uuid(da0f7040-388b-11e1-b86c-0800200c9a66)]
+interface nsIDOMContact : nsIDOMContactProperties
+{
+  attribute DOMString id;
+  readonly attribute jsval     published;
+  readonly attribute jsval     updated;
+  
+  void init(in nsIDOMContactProperties properties);  // Workaround BUG 723206
+};
+
+[scriptable, uuid(50a820b0-ced0-11e0-9572-0800200c9a66)]
+interface nsIDOMContactManager : nsISupports
+{
+  nsIDOMDOMRequest find(in nsIDOMContactFindOptions options);
+
+  nsIDOMDOMRequest clear();
+
+  nsIDOMDOMRequest save(in nsIDOMContact contact);
+  
+  nsIDOMDOMRequest remove(in nsIDOMContact contact);
+};
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/dom/interfaces/contacts/nsIDOMContactProperties.idl
@@ -0,0 +1,52 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "domstubs.idl"
+
+interface nsIArray;
+interface nsIDOMContact;
+
+[scriptable, uuid(27a568b0-cee1-11e0-9572-0800200c9a66)]
+interface nsIDOMContactAddress : nsISupports
+{
+  attribute DOMString streetAddress;
+  attribute DOMString locality;
+  attribute DOMString region;
+  attribute DOMString postalCode;
+  attribute DOMString countryName;
+};
+
+[scriptable, uuid(e31daea0-0cb6-11e1-be50-0800200c9a66)]
+interface nsIDOMContactFindOptions : nsISupports
+{
+  attribute DOMString filterValue;  // e.g. "Tom"
+  attribute DOMString filterOp;     // e.g. "contains"
+  attribute jsval filterBy;         // DOMString[], e.g. ["givenName", "nickname"]
+  attribute unsigned long filterLimit;
+};
+
+[scriptable, uuid(53ed7c20-ceda-11e0-9572-0800200c9a66)]
+interface nsIDOMContactProperties : nsISupports
+{
+  attribute jsval         name;               // DOMString[]
+  attribute jsval         honorificPrefix;    // DOMString[]
+  attribute jsval         givenName;          // DOMString[]
+  attribute jsval         additionalName;     // DOMString[]
+  attribute jsval         familyName;         // DOMString[]
+  attribute jsval         honorificSuffix;    // DOMString[]
+  attribute jsval         nickname;           // DOMString[]
+  attribute jsval         email;              // DOMString[]
+  attribute jsval         photo;              // DOMString[]
+  attribute jsval         url;                // DOMString[]
+  attribute jsval         category;           // DOMString[]
+  attribute jsval         adr;                // ContactAddress[]
+  attribute jsval         tel;                // DOMString[]
+  attribute jsval         org;                // DOMString[]
+  attribute jsval         bday;               // Date
+  attribute jsval         note;               // DOMString[]
+  attribute jsval         impp;               // DOMString[]
+  attribute jsval         anniversary;        // Date
+  attribute jsval         sex;                // DOMString
+  attribute jsval         genderIdentity;     // DOMString
+};
\ No newline at end of file
--- a/dom/plugins/base/nsJSNPRuntime.cpp
+++ b/dom/plugins/base/nsJSNPRuntime.cpp
@@ -152,30 +152,30 @@ NPObjWrapper_SetProperty(JSContext *cx, 
 static JSBool
 NPObjWrapper_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
 
 static JSBool
 NPObjWrapper_newEnumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
                           jsval *statep, jsid *idp);
 
 static JSBool
-NPObjWrapper_NewResolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
+NPObjWrapper_NewResolve(JSContext *cx, JSObject *obj, jsid id, unsigned flags,
                         JSObject **objp);
 
 static JSBool
 NPObjWrapper_Convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp);
 
 static void
 NPObjWrapper_Finalize(JSContext *cx, JSObject *obj);
 
 static JSBool
-NPObjWrapper_Call(JSContext *cx, uintN argc, jsval *vp);
+NPObjWrapper_Call(JSContext *cx, unsigned argc, jsval *vp);
 
 static JSBool
-NPObjWrapper_Construct(JSContext *cx, uintN argc, jsval *vp);
+NPObjWrapper_Construct(JSContext *cx, unsigned argc, jsval *vp);
 
 static JSBool
 CreateNPObjectMember(NPP npp, JSContext *cx, JSObject *obj, NPObject *npobj,
                      jsid id, NPVariant* getPropertyResult, jsval *vp);
 
 static JSClass sNPObjectJSWrapperClass =
   {
     NPRUNTIME_JSCLASS_NAME,
@@ -197,24 +197,24 @@ typedef struct NPObjectMemberPrivate {
 
 static JSBool
 NPObjectMember_Convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp);
 
 static void
 NPObjectMember_Finalize(JSContext *cx, JSObject *obj);
 
 static JSBool
-NPObjectMember_Call(JSContext *cx, uintN argc, jsval *vp);
+NPObjectMember_Call(JSContext *cx, unsigned argc, jsval *vp);
 
 static void
 NPObjectMember_Trace(JSTracer *trc, JSObject *obj);
 
 static JSClass sNPObjectMemberClass =
   {
-    "NPObject Ambiguous Member class", JSCLASS_HAS_PRIVATE,
+    "NPObject Ambiguous Member class", JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS,
     JS_PropertyStub, JS_PropertyStub,
     JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub,
     JS_ResolveStub, NPObjectMember_Convert,
     NPObjectMember_Finalize, nsnull, NPObjectMember_Call,
     nsnull, nsnull, NPObjectMember_Trace
   };
 
 static void
@@ -1384,17 +1384,17 @@ NPObjWrapper_GetProperty(JSContext *cx, 
     if (!ReportExceptionIfPending(cx))
       return JS_FALSE;
   }
 
   return JS_TRUE;
 }
 
 static JSBool
-CallNPMethodInternal(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+CallNPMethodInternal(JSContext *cx, JSObject *obj, unsigned argc, jsval *argv,
                      jsval *rval, bool ctorCall)
 {
   while (obj && JS_GetClass(obj) != &sNPObjectJSWrapperClass) {
     obj = ::JS_GetPrototype(obj);
   }
 
   if (!obj) {
     ThrowJSException(cx, "NPMethod called on non-NPObject wrapped JSObject!");
@@ -1521,17 +1521,17 @@ CallNPMethodInternal(JSContext *cx, JSOb
 
   // *rval now owns the value, release our reference.
   _releasevariantvalue(&v);
 
   return ReportExceptionIfPending(cx);
 }
 
 static JSBool
-CallNPMethod(JSContext *cx, uintN argc, jsval *vp)
+CallNPMethod(JSContext *cx, unsigned argc, jsval *vp)
 {
   JSObject *obj = JS_THIS_OBJECT(cx, vp);
   if (!obj)
       return JS_FALSE;
 
   return CallNPMethodInternal(cx, obj, argc, JS_ARGV(cx, vp), vp, false);
 }
 
@@ -1617,17 +1617,17 @@ NPObjWrapper_newEnumerate(JSContext *cx,
 
     break;
   }
 
   return JS_TRUE;
 }
 
 static JSBool
-NPObjWrapper_NewResolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
+NPObjWrapper_NewResolve(JSContext *cx, JSObject *obj, jsid id, unsigned flags,
                         JSObject **objp)
 {
   NPObject *npobj = GetNPObject(obj);
 
   if (!npobj || !npobj->_class || !npobj->_class->hasProperty ||
       !npobj->_class->hasMethod) {
     ThrowJSException(cx, "Bad NPObject as private data!");
 
@@ -1722,24 +1722,24 @@ NPObjWrapper_Finalize(JSContext *cx, JSO
   }
 
   if (!sDelayedReleases)
     sDelayedReleases = new nsTArray<NPObject*>;
   sDelayedReleases->AppendElement(npobj);
 }
 
 static JSBool
-NPObjWrapper_Call(JSContext *cx, uintN argc, jsval *vp)
+NPObjWrapper_Call(JSContext *cx, unsigned argc, jsval *vp)
 {
   return CallNPMethodInternal(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)), argc,
                               JS_ARGV(cx, vp), vp, false);
 }
 
 static JSBool
-NPObjWrapper_Construct(JSContext *cx, uintN argc, jsval *vp)
+NPObjWrapper_Construct(JSContext *cx, unsigned argc, jsval *vp)
 {
   return CallNPMethodInternal(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)), argc,
                               JS_ARGV(cx, vp), vp, true);
 }
 
 class NPObjWrapperHashEntry : public PLDHashEntryHdr
 {
 public:
@@ -2221,17 +2221,17 @@ NPObjectMember_Finalize(JSContext *cx, J
   memberPrivate = (NPObjectMemberPrivate *)::JS_GetPrivate(obj);
   if (!memberPrivate)
     return;
 
   PR_Free(memberPrivate);
 }
 
 static JSBool
-NPObjectMember_Call(JSContext *cx, uintN argc, jsval *vp)
+NPObjectMember_Call(JSContext *cx, unsigned argc, jsval *vp)
 {
   JSObject *memobj = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
   NS_ENSURE_TRUE(memobj, JS_FALSE);
 
   NPObjectMemberPrivate *memberPrivate =
     (NPObjectMemberPrivate *)::JS_GetInstancePrivate(cx, memobj,
                                                      &sNPObjectMemberClass,
                                                      JS_ARGV(cx, vp));
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -90,16 +90,17 @@ using mozilla::DefaultXDisplay;
 #include "nsIAppShell.h"
 #include "nsIDOMHTMLAppletElement.h"
 #include "nsAttrName.h"
 #include "nsIFocusManager.h"
 #include "nsFocusManager.h"
 #include "nsIDOMDragEvent.h"
 #include "nsIScrollableFrame.h"
 #include "nsIImageLoadingContent.h"
+#include "nsIObjectLoadingContent.h"
 
 #include "nsContentCID.h"
 #include "nsWidgetsCID.h"
 static NS_DEFINE_CID(kWidgetCID, NS_CHILD_CID);
 static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
 
 #ifdef XP_WIN
 #include <wtypes.h>
@@ -1190,16 +1191,41 @@ nsresult nsPluginInstanceOwner::EnsureCa
 
   // "plugins.force.wmode" preference is forcing wmode type for plugins
   // possible values - "opaque", "transparent", "windowed"
   nsAdoptingCString wmodeType = Preferences::GetCString("plugins.force.wmode");
   if (!wmodeType.IsEmpty()) {
     mNumCachedAttrs++;
   }
 
+  // Some plugins (java, bug 406541) don't canonicalize the 'codebase' attribute
+  // in a standard way - codebase="" results in / (domain root), but
+  // codebase="blah" results in ./blah; codebase="file:" results in "file:///".
+  // We canonicalize codebase here to ensure the codebase we run security checks
+  // against is the same codebase java uses.
+  // Note that GetObjectBaseURI mimics some of java's quirks for maximal
+  // compatibility.
+  const char* mime = nsnull;
+  bool addCodebase = false;
+  nsCAutoString codebaseSpec;
+  if (mInstance && NS_SUCCEEDED(mInstance->GetMIMEType(&mime)) && mime &&
+      strcmp(mime, "application/x-java-vm") == 0) {
+    addCodebase = true;
+    nsCOMPtr<nsIObjectLoadingContent> objlContent = do_QueryInterface(mContent);
+    nsCOMPtr<nsIURI> codebaseURI;
+    objlContent->GetObjectBaseURI(nsCString(mime), getter_AddRefs(codebaseURI));
+    nsresult rv = codebaseURI->GetSpec(codebaseSpec);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    // Make space if codebase isn't already set
+    if (!mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::codebase)) {
+      mNumCachedAttrs++;
+    }
+  }
+
   mCachedAttrParamNames  = (char**)NS_Alloc(sizeof(char*) * (mNumCachedAttrs + 1 + mNumCachedParams));
   NS_ENSURE_TRUE(mCachedAttrParamNames,  NS_ERROR_OUT_OF_MEMORY);
   mCachedAttrParamValues = (char**)NS_Alloc(sizeof(char*) * (mNumCachedAttrs + 1 + mNumCachedParams));
   NS_ENSURE_TRUE(mCachedAttrParamValues, NS_ERROR_OUT_OF_MEMORY);
 
   // Some plugins (eg Flash, see bug 234675.) are actually sensitive to the
   // attribute order.  So we want to make sure we give the plugin the
   // attributes in the order they came in in the source, to be compatible with
@@ -1243,22 +1269,32 @@ nsresult nsPluginInstanceOwner::EnsureCa
         0 == PL_strcasecmp(mCachedAttrParamNames[nextAttrParamIndex], "wmode")) {
       mCachedAttrParamValues[nextAttrParamIndex] = ToNewUTF8String(NS_ConvertUTF8toUTF16(wmodeType));
 
       if (!wmodeSet) {
         // We allocated space to add a wmode attr, but we don't need it now.
         mNumCachedAttrs--;
         wmodeSet = true;
       }
+    } else if (addCodebase && 0 == PL_strcasecmp(mCachedAttrParamNames[nextAttrParamIndex], "codebase")) {
+      mCachedAttrParamValues[nextAttrParamIndex] = ToNewUTF8String(NS_ConvertUTF8toUTF16(codebaseSpec));
+      addCodebase = false;
     } else {
       mCachedAttrParamValues[nextAttrParamIndex] = ToNewUTF8String(value);
     }
     nextAttrParamIndex++;
   }
 
+  // Pontentially add CODEBASE attribute
+  if (addCodebase) {
+    mCachedAttrParamNames [nextAttrParamIndex] = ToNewUTF8String(NS_LITERAL_STRING("codebase"));
+    mCachedAttrParamValues[nextAttrParamIndex] = ToNewUTF8String(NS_ConvertUTF8toUTF16(codebaseSpec));
+    nextAttrParamIndex++;
+  }
+
   // Potentially add WMODE attribute.
   if (!wmodeType.IsEmpty() && !wmodeSet) {
     mCachedAttrParamNames [nextAttrParamIndex] = ToNewUTF8String(NS_LITERAL_STRING("wmode"));
     mCachedAttrParamValues[nextAttrParamIndex] = ToNewUTF8String(NS_ConvertUTF8toUTF16(wmodeType));
     nextAttrParamIndex++;
   }
 
   // Potentially add SRC attribute.
--- a/dom/system/b2g/SystemWorkerManager.cpp
+++ b/dom/system/b2g/SystemWorkerManager.cpp
@@ -69,17 +69,17 @@ SystemWorkerManager *gInstance = nsnull;
 
 class ConnectWorkerToRIL : public WorkerTask
 {
 public:
   virtual bool RunTask(JSContext *aCx);
 };
 
 JSBool
-PostToRIL(JSContext *cx, uintN argc, jsval *vp)
+PostToRIL(JSContext *cx, unsigned argc, jsval *vp)
 {
   NS_ASSERTION(!NS_IsMainThread(), "Expecting to be on the worker thread");
 
   if (argc != 1) {
     JS_ReportError(cx, "Expecting a single argument with the RIL message");
     return false;
   }
 
--- a/dom/tests/mochitest/bugs/Makefile.in
+++ b/dom/tests/mochitest/bugs/Makefile.in
@@ -151,12 +151,18 @@ include $(topsrcdir)/config/rules.mk
 		file_window_bar.html \
 		test_resize_move_windows.html \
 		test_devicemotion_multiple_listeners.html \
 		devicemotion_outer.html \
 		devicemotion_inner.html \
 		test_bug698061.html \
 		test_bug707749.html \
 		test_bug691707.html \
+		test_bug304459.html \
+		iframe_bug304459-1.html \
+		iframe_bug304459-2.html \
+		test_bug38959.html \
+		iframe_bug38959-1.html \
+		iframe_bug38959-2.html \
 		$(NULL)
 
 libs:: 	$(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/bugs/iframe_bug304459-1.html
@@ -0,0 +1,12 @@
+<html>
+<head>
+	<title>Iframe test for bug 304459</title>
+</head>
+<body">
+<script>
+
+Object.prototype.x = "oops";
+
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/bugs/iframe_bug304459-2.html
@@ -0,0 +1,18 @@
+<html>
+<head>
+	<title>Iframe test for bug 304459</title>
+</head>
+<body">
+<script>
+
+var result;
+try {
+  x == undefined;
+} catch (e) {
+  result = true;
+}
+window.parent.postMessage(result, "http://mochi.test:8888");
+
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/bugs/iframe_bug38959-1.html
@@ -0,0 +1,14 @@
+<html>
+<head>
+	<title>Iframe test for bug 38959</title>
+</head>
+<body">
+<script>
+
+x = false;
+window.opener.postMessage(1, "http://mochi.test:8888");
+window.close();
+
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/bugs/iframe_bug38959-2.html
@@ -0,0 +1,14 @@
+<html>
+<head>
+	<title>Iframe test for bug 38959</title>
+</head>
+<body">
+<script>
+
+x = true;
+window.opener.postMessage(2, "http://mochi.test:8888");
+window.close();
+
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/bugs/test_bug304459.html
@@ -0,0 +1,47 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=304459
+-->
+<head>
+  <title>Test for Bug 304459</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=304459">Mozilla Bug 304459</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  <iframe id="frame"></iframe>
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 304459 **/
+
+function iframeLoaded()
+{
+  var frame = document.getElementById("frame");
+  frame.onload = undefined;
+  frame.src = "http://example.org/tests/dom/tests/mochitest/bugs/iframe_bug304459-2.html";
+}
+
+function receiveMessage(evt)
+{
+  ok(evt.data, "Prototype leaks across navigation");
+
+  SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+
+window.addEventListener("message", receiveMessage, false);
+
+var frame = document.getElementById("frame");
+frame.onload = iframeLoaded;
+frame.src = "iframe_bug304459-1.html"
+
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/bugs/test_bug38959.html
@@ -0,0 +1,57 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=38959
+-->
+<head>
+  <title>Test for Bug 38959</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=38959">Mozilla Bug 38959</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  <iframe id="frame"></iframe>
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 38959 **/
+
+var newValue;
+
+function watcher(id, ol, ne)
+{
+  newValue = ne;
+  return ne;
+}
+
+function openWindow(url, crossOrigin)
+{
+  newValue = true;
+  var w = window.open(url);
+  w.watch("x", watcher);
+}
+
+function receiveMessage(evt)
+{
+  ok(newValue, "Watchpoints only allowed same-origin.");
+  if (evt.data == 1) {
+    openWindow("/tests/dom/tests/mochitest/bugs/iframe_bug38959-2.html");
+  }
+  else {
+    SimpleTest.finish();
+  }
+}
+
+SimpleTest.waitForExplicitFinish();
+
+window.addEventListener("message", receiveMessage, false);
+
+openWindow("http://example.org/tests/dom/tests/mochitest/bugs/iframe_bug38959-1.html");
+
+</script>
+</pre>
+</body>
+</html>
--- a/dom/workers/EventTarget.cpp
+++ b/dom/workers/EventTarget.cpp
@@ -86,17 +86,17 @@ EnsureObjectIsEventTarget(JSContext* aCx
 inline
 EventTarget*
 GetPrivate(JSObject* aObj)
 {
   return GetJSPrivateSafeish<EventTarget>(aObj);
 }
 
 JSBool
-Construct(JSContext* aCx, uintN aArgc, jsval* aVp)
+Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
 {
   JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL, JSMSG_WRONG_CONSTRUCTOR,
                        gClass.name);
   return false;
 }
 
 JSFunctionSpec gFunctions[] = {
   JS_FN("addEventListener", EventTarget::AddEventListener, 3, JSPROP_ENUMERATE),
@@ -151,17 +151,17 @@ EventTarget::SetEventListenerOnEventTarg
 EventTarget*
 EventTarget::FromJSObject(JSObject* aObj)
 {
   return GetPrivate(aObj);
 }
 
 // static
 JSBool
-EventTarget::AddEventListener(JSContext* aCx, uintN aArgc, jsval* aVp)
+EventTarget::AddEventListener(JSContext* aCx, unsigned aArgc, jsval* aVp)
 {
   JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
   if (!obj) {
     return true;
   }
 
   if (!EnsureObjectIsEventTarget(aCx, obj, "AddEventListener")) {
     return false;
@@ -186,17 +186,17 @@ EventTarget::AddEventListener(JSContext*
 
   return self->mListenerManager.AddEventListener(aCx, type,
                                                  JS_ARGV(aCx, aVp)[1],
                                                  capturing, wantsUntrusted);
 }
 
 // static
 JSBool
-EventTarget::RemoveEventListener(JSContext* aCx, uintN aArgc, jsval* aVp)
+EventTarget::RemoveEventListener(JSContext* aCx, unsigned aArgc, jsval* aVp)
 {
   JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
   if (!obj) {
     return true;
   }
 
   if (!EnsureObjectIsEventTarget(aCx, obj, "RemoveEventListener")) {
     return false;
@@ -221,17 +221,17 @@ EventTarget::RemoveEventListener(JSConte
 
   return self->mListenerManager.RemoveEventListener(aCx, type,
                                                     JS_ARGV(aCx, aVp)[1],
                                                     capturing);
 }
 
 // static
 JSBool
-EventTarget::DispatchEvent(JSContext* aCx, uintN aArgc, jsval* aVp)
+EventTarget::DispatchEvent(JSContext* aCx, unsigned aArgc, jsval* aVp)
 {
   JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
   if (!obj) {
     return true;
   }
 
   if (!EnsureObjectIsEventTarget(aCx, obj, "DispatchEvent")) {
     return false;
--- a/dom/workers/EventTarget.h
+++ b/dom/workers/EventTarget.h
@@ -75,23 +75,23 @@ protected:
   bool
   SetEventListenerOnEventTarget(JSContext* aCx, const char* aType, jsval* aVp);
 
 public:
   static EventTarget*
   FromJSObject(JSObject* aObj);
 
   static JSBool
-  AddEventListener(JSContext* aCx, uintN aArgc, jsval* aVp);
+  AddEventListener(JSContext* aCx, unsigned aArgc, jsval* aVp);
 
   static JSBool
-  RemoveEventListener(JSContext* aCx, uintN aArgc, jsval* aVp);
+  RemoveEventListener(JSContext* aCx, unsigned aArgc, jsval* aVp);
 
   static JSBool
-  DispatchEvent(JSContext* aCx, uintN aArgc, jsval* aVp);
+  DispatchEvent(JSContext* aCx, unsigned aArgc, jsval* aVp);
 
   bool
   HasListeners()
   {
     return mListenerManager.HasListeners();
   }
 
   bool
--- a/dom/workers/Events.cpp
+++ b/dom/workers/Events.cpp
@@ -233,17 +233,17 @@ protected:
     JS_SetReservedSlot(aObj, SLOT_timeStamp, JS::NumberValue(double(JS_Now())));
     JS_SetReservedSlot(aObj, SLOT_defaultPrevented, JSVAL_FALSE);
     JS_SetReservedSlot(aObj, SLOT_isTrusted,
                        aIsTrusted ? JSVAL_TRUE : JSVAL_FALSE);
   }
 
 private:
   static JSBool
-  Construct(JSContext* aCx, uintN aArgc, jsval* aVp)
+  Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL, JSMSG_WRONG_CONSTRUCTOR,
                          sClass.name);
     return false;
   }
 
   static void
   Finalize(JSContext* aCx, JSObject* aObj)
@@ -275,17 +275,17 @@ private:
     JS_ASSERT(JSID_TO_INT(idval) >= CAPTURING_PHASE &&
               JSID_TO_INT(idval) <= BUBBLING_PHASE);
 
     *aVp = INT_TO_JSVAL(JSID_TO_INT(idval));
     return true;
   }
 
   static JSBool
-  StopPropagation(JSContext* aCx, uintN aArgc, jsval* aVp)
+  StopPropagation(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     Event* event = GetInstancePrivate(aCx, obj, sFunctions[0].name);
     if (!event) {
@@ -293,17 +293,17 @@ private:
     }
 
     event->mStopPropagationCalled = true;
 
     return true;
   }
 
   static JSBool
-  StopImmediatePropagation(JSContext* aCx, uintN aArgc, jsval* aVp)
+  StopImmediatePropagation(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     Event* event = GetInstancePrivate(aCx, obj, sFunctions[3].name);
     if (!event) {
@@ -311,17 +311,17 @@ private:
     }
 
     event->mStopImmediatePropagationCalled = true;
 
     return true;
   }
   
   static JSBool
-  PreventDefault(JSContext* aCx, uintN aArgc, jsval* aVp)
+  PreventDefault(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     Event* event = GetInstancePrivate(aCx, obj, sFunctions[1].name);
     if (!event) {
@@ -331,17 +331,17 @@ private:
     jsval cancelableVal = JS_GetReservedSlot(obj, SLOT_cancelable);
 
     if (JSVAL_TO_BOOLEAN(cancelableVal))
       JS_SetReservedSlot(obj, SLOT_defaultPrevented, cancelableVal);
     return true;
   }
 
   static JSBool
-  InitEvent(JSContext* aCx, uintN aArgc, jsval* aVp)
+  InitEvent(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     Event* event = GetInstancePrivate(aCx, obj, sFunctions[2].name);
     if (!event) {
@@ -517,17 +517,17 @@ private:
     JS_SetReservedSlot(aObj, SLOT_data,
                        aData ? STRING_TO_JSVAL(aData) : emptyString);
     JS_SetReservedSlot(aObj, SLOT_origin,
                        aOrigin ? STRING_TO_JSVAL(aOrigin) : emptyString);
     JS_SetReservedSlot(aObj, SLOT_source, OBJECT_TO_JSVAL(aSource));
   }
 
   static JSBool
-  Construct(JSContext* aCx, uintN aArgc, jsval* aVp)
+  Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL, JSMSG_WRONG_CONSTRUCTOR,
                          sClass.name);
     return false;
   }
 
   static void
   Finalize(JSContext* aCx, JSObject* aObj)
@@ -582,17 +582,17 @@ private:
       return true;
     }
 
     *aVp = JS_GetReservedSlot(aObj, slot);
     return true;
   }
 
   static JSBool
-  InitMessageEvent(JSContext* aCx, uintN aArgc, jsval* aVp)
+  InitMessageEvent(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     MessageEvent* event = GetInstancePrivate(aCx, obj, sFunctions[0].name);
     if (!event) {
@@ -733,17 +733,17 @@ private:
     Event::InitEventCommon(aObj, aEvent, aType, aBubbles, aCancelable,
                            aIsTrusted);
     JS_SetReservedSlot(aObj, SLOT_message, STRING_TO_JSVAL(aMessage));
     JS_SetReservedSlot(aObj, SLOT_filename, STRING_TO_JSVAL(aFilename));
     JS_SetReservedSlot(aObj, SLOT_lineno, INT_TO_JSVAL(aLineNumber));
   }
 
   static JSBool
-  Construct(JSContext* aCx, uintN aArgc, jsval* aVp)
+  Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL, JSMSG_WRONG_CONSTRUCTOR,
                          sClass.name);
     return false;
   }
 
   static void
   Finalize(JSContext* aCx, JSObject* aObj)
@@ -767,17 +767,17 @@ private:
       return false;
     }
 
     *aVp = JS_GetReservedSlot(aObj, slot);
     return true;
   }
 
   static JSBool
-  InitErrorEvent(JSContext* aCx, uintN aArgc, jsval* aVp)
+  InitErrorEvent(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     ErrorEvent* event = GetInstancePrivate(aCx, obj, sFunctions[0].name);
     if (!event) {
@@ -914,17 +914,17 @@ private:
                            aIsTrusted);
     JS_SetReservedSlot(aObj, SLOT_lengthComputable,
                        aLengthComputable ? JSVAL_TRUE : JSVAL_FALSE);
     JS_SetReservedSlot(aObj, SLOT_loaded, DOUBLE_TO_JSVAL(aLoaded));
     JS_SetReservedSlot(aObj, SLOT_total, DOUBLE_TO_JSVAL(aTotal));
   }
 
   static JSBool
-  Construct(JSContext* aCx, uintN aArgc, jsval* aVp)
+  Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL, JSMSG_WRONG_CONSTRUCTOR,
                          sClass.name);
     return false;
   }
 
   static void
   Finalize(JSContext* aCx, JSObject* aObj)
@@ -948,17 +948,17 @@ private:
       return false;
     }
 
     *aVp = JS_GetReservedSlot(aObj, slot);
     return true;
   }
 
   static JSBool
-  InitProgressEvent(JSContext* aCx, uintN aArgc, jsval* aVp)
+  InitProgressEvent(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     ProgressEvent* event = GetInstancePrivate(aCx, obj, sFunctions[0].name);
     if (!event) {
--- a/dom/workers/Exceptions.cpp
+++ b/dom/workers/Exceptions.cpp
@@ -84,46 +84,46 @@ public:
     if (proto && !JS_DefineProperties(aCx, proto, sStaticProperties)) {
       return NULL;
     }
 
     return proto;
   }
 
   static JSObject*
-  Create(JSContext* aCx, intN aCode);
+  Create(JSContext* aCx, int aCode);
 
 private:
   DOMException()
   {
     MOZ_COUNT_CTOR(mozilla::dom::workers::exceptions::DOMException);
   }
 
   ~DOMException()
   {
     MOZ_COUNT_DTOR(mozilla::dom::workers::exceptions::DOMException);
   }
 
   static JSBool
-  Construct(JSContext* aCx, uintN aArgc, jsval* aVp)
+  Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL, JSMSG_WRONG_CONSTRUCTOR,
                          sClass.name);
     return false;
   }
 
   static void
   Finalize(JSContext* aCx, JSObject* aObj)
   {
     JS_ASSERT(JS_GetClass(aObj) == &sClass);
     delete GetJSPrivateSafeish<DOMException>(aObj);
   }
 
   static JSBool
-  ToString(JSContext* aCx, uintN aArgc, jsval* aVp)
+  ToString(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     JSClass* classPtr = JS_GetClass(obj);
     if (classPtr != &sClass) {
@@ -237,17 +237,17 @@ JSPropertySpec DOMException::sStaticProp
 
 #undef EXCEPTION_ENTRY
 
   { 0, 0, 0, NULL, NULL }
 };
 
 // static
 JSObject*
-DOMException::Create(JSContext* aCx, intN aCode)
+DOMException::Create(JSContext* aCx, int aCode)
 {
   JSObject* obj = JS_NewObject(aCx, &sClass, NULL, NULL);
   if (!obj) {
     return NULL;
   }
 
   size_t foundIndex = size_t(-1);
   for (size_t index = 0; index < ArrayLength(sStaticProperties) - 1; index++) {
@@ -292,31 +292,31 @@ public:
   static JSObject*
   InitClass(JSContext* aCx, JSObject* aObj)
   {
     return JS_InitClass(aCx, aObj, NULL, &sClass, Construct, 0, sProperties,
                         NULL, sStaticProperties, NULL);
   }
 
   static JSObject*
-  Create(JSContext* aCx, intN aCode);
+  Create(JSContext* aCx, int aCode);
 
 private:
   FileException()
   {
     MOZ_COUNT_CTOR(mozilla::dom::workers::exceptions::FileException);
   }
 
   ~FileException()
   {
     MOZ_COUNT_DTOR(mozilla::dom::workers::exceptions::FileException);
   }
 
   static JSBool
-  Construct(JSContext* aCx, uintN aArgc, jsval* aVp)
+  Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL, JSMSG_WRONG_CONSTRUCTOR,
                          sClass.name);
     return false;
   }
 
   static void
   Finalize(JSContext* aCx, JSObject* aObj)
@@ -381,17 +381,17 @@ JSPropertySpec FileException::sStaticPro
 
 #undef EXCEPTION_ENTRY
 
   { 0, 0, 0, NULL, NULL }
 };
 
 // static
 JSObject*
-FileException::Create(JSContext* aCx, intN aCode)
+FileException::Create(JSContext* aCx, int aCode)
 {
   JSObject* obj = JS_NewObject(aCx, &sClass, NULL, NULL);
   if (!obj) {
     return NULL;
   }
 
   size_t foundIndex = size_t(-1);
   for (size_t index = 0; index < ArrayLength(sStaticProperties) - 1; index++) {
@@ -426,26 +426,26 @@ namespace exceptions {
 bool
 InitClasses(JSContext* aCx, JSObject* aGlobal)
 {
   return DOMException::InitClass(aCx, aGlobal) &&
          FileException::InitClass(aCx, aGlobal);
 }
 
 void
-ThrowDOMExceptionForCode(JSContext* aCx, intN aCode)
+ThrowDOMExceptionForCode(JSContext* aCx, int aCode)
 {
   JSObject* exception = DOMException::Create(aCx, aCode);
   JS_ASSERT(exception);
 
   JS_SetPendingException(aCx, OBJECT_TO_JSVAL(exception));
 }
 
 void
-ThrowFileExceptionForCode(JSContext* aCx, intN aCode)
+ThrowFileExceptionForCode(JSContext* aCx, int aCode)
 {
   JSObject* exception = FileException::Create(aCx, aCode);
   JS_ASSERT(exception);
 
   JS_SetPendingException(aCx, OBJECT_TO_JSVAL(exception));
 }
 
 } // namespace exceptions
--- a/dom/workers/Exceptions.h
+++ b/dom/workers/Exceptions.h
@@ -84,18 +84,18 @@
 BEGIN_WORKERS_NAMESPACE
 
 namespace exceptions {
 
 bool
 InitClasses(JSContext* aCx, JSObject* aGlobal);
 
 void
-ThrowDOMExceptionForCode(JSContext* aCx, intN aCode);
+ThrowDOMExceptionForCode(JSContext* aCx, int aCode);
 
 void
-ThrowFileExceptionForCode(JSContext* aCx, intN aCode);
+ThrowFileExceptionForCode(JSContext* aCx, int aCode);
 
 } // namespace exceptions
 
 END_WORKERS_NAMESPACE
 
 #endif // mozilla_dom_workers_exceptions_h__
--- a/dom/workers/File.cpp
+++ b/dom/workers/File.cpp
@@ -106,17 +106,17 @@ private:
 
     JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL,
                          JSMSG_INCOMPATIBLE_PROTO, sClass.name, aFunctionName,
                          JS_GetClass(aObj)->name);
     return NULL;
   }
 
   static JSBool
-  Construct(JSContext* aCx, uintN aArgc, jsval* aVp)
+  Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL, JSMSG_WRONG_CONSTRUCTOR,
                          sClass.name);
     return false;
   }
 
   static void
   Finalize(JSContext* aCx, JSObject* aObj)
@@ -166,17 +166,17 @@ private:
     }
 
     *aVp = STRING_TO_JSVAL(jsType);
 
     return true;
   }
 
   static JSBool
-  Slice(JSContext* aCx, uintN aArgc, jsval* aVp)
+  Slice(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     nsIDOMBlob* blob = GetInstancePrivate(aCx, obj, "slice");
     if (!blob) {
@@ -296,17 +296,17 @@ private:
 
     JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL,
                          JSMSG_INCOMPATIBLE_PROTO, sClass.name, aFunctionName,
                          JS_GetClass(aObj)->name);
     return NULL;
   }
 
   static JSBool
-  Construct(JSContext* aCx, uintN aArgc, jsval* aVp)
+  Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL, JSMSG_WRONG_CONSTRUCTOR,
                          sClass.name);
     return false;
   }
 
   static void
   Finalize(JSContext* aCx, JSObject* aObj)
--- a/dom/workers/FileReaderSync.cpp
+++ b/dom/workers/FileReaderSync.cpp
@@ -64,17 +64,17 @@ namespace {
 
 inline bool
 EnsureSucceededOrThrow(JSContext* aCx, nsresult rv)
 {
   if (NS_SUCCEEDED(rv)) {
     return true;
   }
 
-  intN code = rv == NS_ERROR_FILE_NOT_FOUND ?
+  int code = rv == NS_ERROR_FILE_NOT_FOUND ?
               FILE_NOT_FOUND_ERR :
               FILE_NOT_READABLE_ERR;
   ThrowFileExceptionForCode(aCx, code);
   return false;
 }
 
 inline nsIDOMBlob*
 GetDOMBlobFromJSObject(JSContext* aCx, JSObject* aObj) {
@@ -134,17 +134,17 @@ private:
 
     JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL,
                          JSMSG_INCOMPATIBLE_PROTO, sClass.name, aFunctionName,
                          JS_GetClass(aObj)->name);
     return NULL;
   }
 
   static JSBool
-  Construct(JSContext* aCx, uintN aArgc, jsval* aVp)
+  Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_NewObject(aCx, &sClass, NULL, NULL);
     if (!obj) {
       return false;
     }
 
     FileReaderSyncPrivate* fileReader = new FileReaderSyncPrivate();
     NS_ADDREF(fileReader);
@@ -160,17 +160,17 @@ private:
   {
     JS_ASSERT(JS_GetClass(aObj) == &sClass);
     FileReaderSyncPrivate* fileReader =
       GetJSPrivateSafeish<FileReaderSyncPrivate>(aObj);
     NS_IF_RELEASE(fileReader);
   }
 
   static JSBool
-  ReadAsArrayBuffer(JSContext* aCx, uintN aArgc, jsval* aVp)
+  ReadAsArrayBuffer(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     FileReaderSyncPrivate* fileReader =
       GetInstancePrivate(aCx, obj, "readAsArrayBuffer");
@@ -207,17 +207,17 @@ private:
       return false;
     }
 
     JS_SET_RVAL(aCx, aVp, OBJECT_TO_JSVAL(jsArrayBuffer));
     return true;
   }
 
   static JSBool
-  ReadAsDataURL(JSContext* aCx, uintN aArgc, jsval* aVp)
+  ReadAsDataURL(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     FileReaderSyncPrivate* fileReader =
       GetInstancePrivate(aCx, obj, "readAsDataURL");
@@ -247,17 +247,17 @@ private:
       return false;
     }
 
     JS_SET_RVAL(aCx, aVp, STRING_TO_JSVAL(jsBlobText));
     return true;
   }
 
   static JSBool
-  ReadAsBinaryString(JSContext* aCx, uintN aArgc, jsval* aVp)
+  ReadAsBinaryString(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     FileReaderSyncPrivate* fileReader =
       GetInstancePrivate(aCx, obj, "readAsBinaryString");
@@ -287,17 +287,17 @@ private:
       return false;
     }
 
     JS_SET_RVAL(aCx, aVp, STRING_TO_JSVAL(jsBlobText));
     return true;
   }
 
   static JSBool
-  ReadAsText(JSContext* aCx, uintN aArgc, jsval* aVp)
+  ReadAsText(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     FileReaderSyncPrivate* fileReader =
       GetInstancePrivate(aCx, obj, "readAsText");
--- a/dom/workers/Location.cpp
+++ b/dom/workers/Location.cpp
@@ -119,32 +119,32 @@ private:
   }
 
   ~Location()
   {
     MOZ_COUNT_DTOR(mozilla::dom::workers::Location);
   }
 
   static JSBool
-  Construct(JSContext* aCx, uintN aArgc, jsval* aVp)
+  Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL, JSMSG_WRONG_CONSTRUCTOR,
                          sClass.name);
     return false;
   }
 
   static void
   Finalize(JSContext* aCx, JSObject* aObj)
   {
     JS_ASSERT(JS_GetClass(aObj) == &sClass);
     delete static_cast<Location*>(JS_GetPrivate(aObj));
   }
 
   static JSBool
-  ToString(JSContext* aCx, uintN aArgc, jsval* aVp)
+  ToString(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     JSClass* classPtr = JS_GetClass(obj);
     if (classPtr != &sClass) {
--- a/dom/workers/Navigator.cpp
+++ b/dom/workers/Navigator.cpp
@@ -130,17 +130,17 @@ private:
   }
 
   ~Navigator()
   {
     MOZ_COUNT_DTOR(mozilla::dom::workers::Navigator);
   }
 
   static JSBool
-  Construct(JSContext* aCx, uintN aArgc, jsval* aVp)
+  Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL, JSMSG_WRONG_CONSTRUCTOR,
                          sClass.name);
     return false;
   }
 
   static void
   Finalize(JSContext* aCx, JSObject* aObj)
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -384,17 +384,17 @@ public:
 };
 
 } /* anonymous namespace */
 
 BEGIN_WORKERS_NAMESPACE
 
 // Entry point for the DOM.
 JSBool
-ResolveWorkerClasses(JSContext* aCx, JSObject* aObj, jsid aId, uintN aFlags,
+ResolveWorkerClasses(JSContext* aCx, JSObject* aObj, jsid aId, unsigned aFlags,
                      JSObject** aObjp)
 {
   AssertIsOnMainThread();
 
   // Don't care about assignments or declarations, bail now.
   if (aFlags & (JSRESOLVE_ASSIGNING | JSRESOLVE_DECLARING)) {
     *aObjp = nsnull;
     return true;
--- a/dom/workers/ScriptLoader.cpp
+++ b/dom/workers/ScriptLoader.cpp
@@ -727,17 +727,17 @@ LoadWorkerScript(JSContext* aCx)
 
   ScriptLoadInfo* info = loadInfos.AppendElement();
   info->mURL = worker->ScriptURL();
 
   return LoadAllScripts(aCx, worker, loadInfos, true);
 }
 
 bool
-Load(JSContext* aCx, uintN aURLCount, jsval* aURLs)
+Load(JSContext* aCx, unsigned aURLCount, jsval* aURLs)
 {
   WorkerPrivate* worker = GetWorkerPrivateFromContext(aCx);
   NS_ASSERTION(worker, "This should never be null!");
 
   if (!aURLCount) {
     return true;
   }
 
@@ -745,17 +745,17 @@ Load(JSContext* aCx, uintN aURLCount, js
     JS_ReportError(aCx, "Cannot load more than %d scripts at one time!",
                    MAX_CONCURRENT_SCRIPTS);
     return false;
   }
 
   nsTArray<ScriptLoadInfo> loadInfos;
   loadInfos.SetLength(PRUint32(aURLCount));
 
-  for (uintN index = 0; index < aURLCount; index++) {
+  for (unsigned index = 0; index < aURLCount; index++) {
     JSString* str = JS_ValueToString(aCx, aURLs[index]);
     if (!str) {
       return false;
     }
 
     size_t length;
     const jschar* buffer = JS_GetStringCharsAndLength(aCx, str, &length);
     if (!buffer) {
--- a/dom/workers/ScriptLoader.h
+++ b/dom/workers/ScriptLoader.h
@@ -44,15 +44,15 @@
 #include "jsapi.h"
 
 BEGIN_WORKERS_NAMESPACE
 
 namespace scriptloader {
 
 bool LoadWorkerScript(JSContext* aCx);
 
-bool Load(JSContext* aCx, uintN aURLCount, jsval* aURLs);
+bool Load(JSContext* aCx, unsigned aURLCount, jsval* aURLs);
 
 } // namespace scriptloader
 
 END_WORKERS_NAMESPACE
 
 #endif /* mozilla_dom_workers_scriptloader_h__ */
--- a/dom/workers/Worker.cpp
+++ b/dom/workers/Worker.cpp
@@ -134,17 +134,17 @@ public:
     SetJSPrivateSafeish(aObj, NULL);
   }
 
   static WorkerPrivate*
   GetInstancePrivate(JSContext* aCx, JSObject* aObj, const char* aFunctionName);
 
 protected:
   static JSBool
-  ConstructInternal(JSContext* aCx, uintN aArgc, jsval* aVp,
+  ConstructInternal(JSContext* aCx, unsigned aArgc, jsval* aVp,
                     bool aIsChromeWorker)
   {
     if (!aArgc) {
       JS_ReportError(aCx, "Constructor requires at least one argument!");
       return false;
     }
 
     JSString* scriptURL = JS_ValueToString(aCx, JS_ARGV(aCx, aVp)[0]);
@@ -228,17 +228,17 @@ private:
     if (!worker) {
       return !JS_IsExceptionPending(aCx);
     }
 
     return worker->SetEventListenerOnEventTarget(aCx, name + 2, aVp);
   }
 
   static JSBool
-  Construct(JSContext* aCx, uintN aArgc, jsval* aVp)
+  Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     return ConstructInternal(aCx, aArgc, aVp, false);
   }
 
   static void
   Finalize(JSContext* aCx, JSObject* aObj)
   {
     JS_ASSERT(JS_GetClass(aObj) == &sClass);
@@ -254,34 +254,34 @@ private:
     JS_ASSERT(JS_GetClass(aObj) == &sClass);
     WorkerPrivate* worker = GetJSPrivateSafeish<WorkerPrivate>(aObj);
     if (worker) {
       worker->TraceInstance(aTrc);
     }
   }
 
   static JSBool
-  Terminate(JSContext* aCx, uintN aArgc, jsval* aVp)
+  Terminate(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     const char*& name = sFunctions[0].name;
     WorkerPrivate* worker = GetInstancePrivate(aCx, obj, name);
     if (!worker) {
       return !JS_IsExceptionPending(aCx);
     }
 
     return worker->Terminate(aCx);
   }
 
   static JSBool
-  PostMessage(JSContext* aCx, uintN aArgc, jsval* aVp)
+  PostMessage(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     const char*& name = sFunctions[1].name;
     WorkerPrivate* worker = GetInstancePrivate(aCx, obj, name);
@@ -382,17 +382,17 @@ private:
         return GetJSPrivateSafeish<WorkerPrivate>(aObj);
       }
     }
 
     return Worker::GetInstancePrivate(aCx, aObj, aFunctionName);
   }
 
   static JSBool
-  Construct(JSContext* aCx, uintN aArgc, jsval* aVp)
+  Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     return ConstructInternal(aCx, aArgc, aVp, true);
   }
 
   static void
   Finalize(JSContext* aCx, JSObject* aObj)
   {
     JS_ASSERT(JS_GetClass(aObj) == &sClass);
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -3474,17 +3474,17 @@ WorkerPrivate::ReportError(JSContext* aC
                                         columnNumber, flags, errorNumber, 0)) {
     JS_ReportPendingException(aCx);
   }
 
   mErrorHandlerRecursionCount--;
 }
 
 bool
-WorkerPrivate::SetTimeout(JSContext* aCx, uintN aArgc, jsval* aVp,
+WorkerPrivate::SetTimeout(JSContext* aCx, unsigned aArgc, jsval* aVp,
                           bool aIsInterval)
 {
   AssertIsOnWorkerThread();
   NS_ASSERTION(aArgc, "Huh?!");
 
   const PRUint32 timerId = mNextTimeoutId++;
 
   Status currentStatus;
@@ -3536,17 +3536,17 @@ WorkerPrivate::SetTimeout(JSContext* aCx
     double intervalMS = 0;
     if (!JS_ValueToNumber(aCx, argv[1], &intervalMS)) {
       return false;
     }
     newInfo->mInterval = TimeDuration::FromMilliseconds(intervalMS);
 
     if (aArgc > 2 && JSVAL_IS_OBJECT(newInfo->mTimeoutVal)) {
       nsTArray<jsval> extraArgVals(aArgc - 2);
-      for (uintN index = 2; index < aArgc; index++) {
+      for (unsigned index = 2; index < aArgc; index++) {
         extraArgVals.AppendElement(argv[index]);
       }
       newInfo->mExtraArgVals.SwapElements(extraArgVals);
     }
   }
 
   newInfo->mTargetTime = TimeStamp::Now() + newInfo->mInterval;
 
--- a/dom/workers/WorkerPrivate.h
+++ b/dom/workers/WorkerPrivate.h
@@ -650,17 +650,17 @@ public:
 
   bool
   NotifyInternal(JSContext* aCx, Status aStatus);
 
   void
   ReportError(JSContext* aCx, const char* aMessage, JSErrorReport* aReport);
 
   bool
-  SetTimeout(JSContext* aCx, uintN aArgc, jsval* aVp, bool aIsInterval);
+  SetTimeout(JSContext* aCx, unsigned aArgc, jsval* aVp, bool aIsInterval);
 
   bool
   ClearTimeout(JSContext* aCx, uint32 aId);
 
   bool
   RunExpiredTimeouts(JSContext* aCx);
 
   bool
--- a/dom/workers/WorkerScope.cpp
+++ b/dom/workers/WorkerScope.cpp
@@ -190,17 +190,17 @@ private:
 
     return scope->SetEventListenerOnEventTarget(aCx, name + 2, aVp);
   }
 
   static WorkerGlobalScope*
   GetInstancePrivate(JSContext* aCx, JSObject* aObj, const char* aFunctionName);
 
   static JSBool
-  Construct(JSContext* aCx, uintN aArgc, jsval* aVp)
+  Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL, JSMSG_WRONG_CONSTRUCTOR,
                          sClass.name);
     return false;
   }
 
   static JSBool
   GetSelf(JSContext* aCx, JSObject* aObj, jsid aIdval, jsval* aVp)
@@ -260,17 +260,17 @@ private:
       scope->mSlots[SLOT_location] = OBJECT_TO_JSVAL(location);
     }
 
     *aVp = scope->mSlots[SLOT_location];
     return true;
   }
 
   static JSBool
-  UnwrapErrorEvent(JSContext* aCx, uintN aArgc, jsval* aVp)
+  UnwrapErrorEvent(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JS_ASSERT(JSVAL_IS_OBJECT(JS_CALLEE(aCx, aVp)));
     JS_ASSERT(aArgc == 1);
     JS_ASSERT(JSVAL_IS_OBJECT(JS_ARGV(aCx, aVp)[0]));
 
     JSObject* wrapper = JSVAL_TO_OBJECT(JS_CALLEE(aCx, aVp));
     JS_ASSERT(JS_ObjectIsFunction(aCx, wrapper));
 
@@ -378,33 +378,33 @@ private:
       scope->mSlots[SLOT_navigator] = OBJECT_TO_JSVAL(navigator);
     }
 
     *aVp = scope->mSlots[SLOT_navigator];
     return true;
   }
 
   static JSBool
-  Close(JSContext* aCx, uintN aArgc, jsval* aVp)
+  Close(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     WorkerGlobalScope* scope = GetInstancePrivate(aCx, obj, sFunctions[0].name);
     if (!scope) {
       return false;
     }
 
     return scope->mWorker->CloseInternal(aCx);
   }
 
   static JSBool
-  ImportScripts(JSContext* aCx, uintN aArgc, jsval* aVp)
+  ImportScripts(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     WorkerGlobalScope* scope = GetInstancePrivate(aCx, obj, sFunctions[1].name);
     if (!scope) {
@@ -414,17 +414,17 @@ private:
     if (aArgc && !scriptloader::Load(aCx, aArgc, JS_ARGV(aCx, aVp))) {
       return false;
     }
 
     return true;
   }
 
   static JSBool
-  SetTimeout(JSContext* aCx, uintN aArgc, jsval* aVp)
+  SetTimeout(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     WorkerGlobalScope* scope = GetInstancePrivate(aCx, obj, sFunctions[2].name);
     if (!scope) {
@@ -435,17 +435,17 @@ private:
     if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "v", &dummy)) {
       return false;
     }
 
     return scope->mWorker->SetTimeout(aCx, aArgc, aVp, false);
   }
 
   static JSBool
-  ClearTimeout(JSContext* aCx, uintN aArgc, jsval* aVp)
+  ClearTimeout(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     WorkerGlobalScope* scope = GetInstancePrivate(aCx, obj, sFunctions[3].name);
     if (!scope) {
@@ -456,17 +456,17 @@ private:
     if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "u", &id)) {
       return false;
     }
 
     return scope->mWorker->ClearTimeout(aCx, id);
   }
 
   static JSBool
-  SetInterval(JSContext* aCx, uintN aArgc, jsval* aVp)
+  SetInterval(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     WorkerGlobalScope* scope = GetInstancePrivate(aCx, obj, sFunctions[4].name);
     if (!scope) {
@@ -477,17 +477,17 @@ private:
     if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "v", &dummy)) {
       return false;
     }
 
     return scope->mWorker->SetTimeout(aCx, aArgc, aVp, true);
   }
 
   static JSBool
-  ClearInterval(JSContext* aCx, uintN aArgc, jsval* aVp)
+  ClearInterval(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     WorkerGlobalScope* scope = GetInstancePrivate(aCx, obj, sFunctions[5].name);
     if (!scope) {
@@ -498,17 +498,17 @@ private:
     if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "u", &id)) {
       return false;
     }
 
     return scope->mWorker->ClearTimeout(aCx, id);
   }
 
   static JSBool
-  Dump(JSContext* aCx, uintN aArgc, jsval* aVp)
+  Dump(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     if (!GetInstancePrivate(aCx, obj, sFunctions[6].name)) {
       return false;
@@ -531,17 +531,17 @@ private:
       fputs(buffer.ptr(), stderr);
       fflush(stderr);
     }
 
     return true;
   }
 
   static JSBool
-  AtoB(JSContext* aCx, uintN aArgc, jsval* aVp)
+  AtoB(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     if (!GetInstancePrivate(aCx, obj, sFunctions[7].name)) {
       return false;
@@ -557,17 +557,17 @@ private:
       return false;
     }
 
     JS_SET_RVAL(aCx, aVp, result);
     return true;
   }
 
   static JSBool
-  BtoA(JSContext* aCx, uintN aArgc, jsval* aVp)
+  BtoA(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     if (!GetInstancePrivate(aCx, obj, sFunctions[8].name)) {
       return false;
@@ -726,25 +726,25 @@ private:
 
     JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL,
                          JSMSG_INCOMPATIBLE_PROTO, sClass.name, aFunctionName,
                          classPtr->name);
     return NULL;
   }
 
   static JSBool
-  Construct(JSContext* aCx, uintN aArgc, jsval* aVp)
+  Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL, JSMSG_WRONG_CONSTRUCTOR,
                          sClass.name);
     return false;
   }
 
   static JSBool
-  Resolve(JSContext* aCx, JSObject* aObj, jsid aId, uintN aFlags,
+  Resolve(JSContext* aCx, JSObject* aObj, jsid aId, unsigned aFlags,
           JSObject** aObjp)
   {
     JSBool resolved;
     if (!JS_ResolveStandardClass(aCx, aObj, aId, &resolved)) {
       return false;
     }
 
     *aObjp = resolved ? aObj : NULL;
@@ -770,17 +770,17 @@ private:
     DedicatedWorkerGlobalScope* scope =
       GetJSPrivateSafeish<DedicatedWorkerGlobalScope>(aObj);
     if (scope) {
       scope->TraceInstance(aTrc);
     }
   }
 
   static JSBool
-  PostMessage(JSContext* aCx, uintN aArgc, jsval* aVp)
+  PostMessage(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     const char*& name = sFunctions[0].name;
     DedicatedWorkerGlobalScope* scope = GetInstancePrivate(aCx, obj, name);
--- a/dom/workers/Workers.h
+++ b/dom/workers/Workers.h
@@ -68,17 +68,17 @@ AssertIsOnMainThread();
 #else
 inline void
 AssertIsOnMainThread()
 { }
 #endif
 
 // All of these are implemented in RuntimeService.cpp
 JSBool
-ResolveWorkerClasses(JSContext* aCx, JSObject* aObj, jsid aId, uintN aFlags,
+ResolveWorkerClasses(JSContext* aCx, JSObject* aObj, jsid aId, unsigned aFlags,
                      JSObject** aObjp);
 
 void
 CancelWorkersForWindow(JSContext* aCx, nsPIDOMWindow* aWindow);
 
 void
 SuspendWorkersForWindow(JSContext* aCx, nsPIDOMWindow* aWindow);
 
--- a/dom/workers/XMLHttpRequest.cpp
+++ b/dom/workers/XMLHttpRequest.cpp
@@ -151,17 +151,17 @@ private:
 
     JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL,
                          JSMSG_INCOMPATIBLE_PROTO, sClass.name, aFunctionName,
                          JS_GetClass(aObj)->name);
     return NULL;
   }
 
   static JSBool
-  Construct(JSContext* aCx, uintN aArgc, jsval* aVp)
+  Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL, JSMSG_WRONG_CONSTRUCTOR,
                          sClass.name);
     return false;
   }
 
   static void
   Finalize(JSContext* aCx, JSObject* aObj)
@@ -368,17 +368,17 @@ private:
 
     JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL,
                          JSMSG_INCOMPATIBLE_PROTO, sClass.name, aFunctionName,
                          JS_GetClass(aObj)->name);
     return NULL;
   }
 
   static JSBool
-  Construct(JSContext* aCx, uintN aArgc, jsval* aVp)
+  Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_NewObject(aCx, &sClass, NULL, NULL);
     if (!obj) {
       return false;
     }
 
     JSString* textStr = JS_NewStringCopyN(aCx, "text", 4);
     if (!textStr) {
@@ -560,34 +560,34 @@ private:
     if (!priv) {
       return false;
     }
 
     return priv->SetEventListenerOnEventTarget(aCx, name + 2, aVp);
   }
 
   static JSBool
-  Abort(JSContext* aCx, uintN aArgc, jsval* aVp)
+  Abort(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     XMLHttpRequestPrivate* priv =
       GetInstancePrivate(aCx, obj, sFunctions[0].name);
     if (!priv) {
       return false;
     }
 
     return priv->Abort(aCx);
   }
 
   static JSBool
-  GetAllResponseHeaders(JSContext* aCx, uintN aArgc, jsval* aVp)
+  GetAllResponseHeaders(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     XMLHttpRequestPrivate* priv =
       GetInstancePrivate(aCx, obj, sFunctions[1].name);
@@ -600,17 +600,17 @@ private:
       return false;
     }
 
     JS_SET_RVAL(aCx, aVp, STRING_TO_JSVAL(responseHeaders));
     return true;
   }
 
   static JSBool
-  GetResponseHeader(JSContext* aCx, uintN aArgc, jsval* aVp)
+  GetResponseHeader(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     XMLHttpRequestPrivate* priv =
       GetInstancePrivate(aCx, obj, sFunctions[2].name);
@@ -639,17 +639,17 @@ private:
       return false;
     }
   
     JS_SET_RVAL(aCx, aVp, STRING_TO_JSVAL(value));
     return true;
   }
 
   static JSBool
-  Open(JSContext* aCx, uintN aArgc, jsval* aVp)
+  Open(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     XMLHttpRequestPrivate* priv =
       GetInstancePrivate(aCx, obj, sFunctions[3].name);
@@ -665,17 +665,17 @@ private:
                              &url, &async, &user, &password)) {
       return false;
     }
 
     return priv->Open(aCx, method, url, async, user, password);
   }
 
   static JSBool
-  Send(JSContext* aCx, uintN aArgc, jsval* aVp)
+  Send(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     XMLHttpRequestPrivate* priv =
       GetInstancePrivate(aCx, obj, sFunctions[4].name);
@@ -684,17 +684,17 @@ private:
     }
 
     jsval body = aArgc ? JS_ARGV(aCx, aVp)[0] : JSVAL_VOID;
 
     return priv->Send(aCx, !!aArgc, body);
   }
 
   static JSBool
-  SendAsBinary(JSContext* aCx, uintN aArgc, jsval* aVp)
+  SendAsBinary(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     XMLHttpRequestPrivate* priv =
       GetInstancePrivate(aCx, obj, sFunctions[5].name);
@@ -717,17 +717,17 @@ private:
         return false;
       }
     }
 
     return priv->SendAsBinary(aCx, body);
   }
 
   static JSBool
-  SetRequestHeader(JSContext* aCx, uintN aArgc, jsval* aVp)
+  SetRequestHeader(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     XMLHttpRequestPrivate* priv =
       GetInstancePrivate(aCx, obj, sFunctions[6].name);
@@ -740,17 +740,17 @@ private:
                              &value)) {
       return false;
     }
 
     return priv->SetRequestHeader(aCx, header, value);
   }
 
   static JSBool
-  OverrideMimeType(JSContext* aCx, uintN aArgc, jsval* aVp)
+  OverrideMimeType(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     XMLHttpRequestPrivate* priv =
       GetInstancePrivate(aCx, obj, sFunctions[7].name);
--- a/dom/workers/XMLHttpRequestPrivate.cpp
+++ b/dom/workers/XMLHttpRequestPrivate.cpp
@@ -188,17 +188,17 @@ END_WORKERS_NAMESPACE
 USING_WORKERS_NAMESPACE
 
 using mozilla::dom::workers::xhr::XMLHttpRequestPrivate;
 using mozilla::dom::workers::xhr::Proxy;
 using mozilla::dom::workers::exceptions::ThrowDOMExceptionForCode;
 
 namespace {
 
-inline intN
+inline int
 GetDOMExceptionCodeFromResult(nsresult aResult)
 {
   if (NS_SUCCEEDED(aResult)) {
     return 0;
   }
 
   if (NS_ERROR_GET_MODULE(aResult) == NS_ERROR_MODULE_DOM) {
     return NS_ERROR_GET_CODE(aResult);
@@ -719,21 +719,21 @@ protected:
   WorkerPrivate* mWorkerPrivate;
   nsRefPtr<Proxy> mProxy;
   PRUint32 mSyncQueueKey;
 
 private:
   class ResponseRunnable : public MainThreadProxyRunnable
   {
     PRUint32 mSyncQueueKey;
-    intN mErrorCode;
+    int mErrorCode;
 
   public:
     ResponseRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy,
-                     PRUint32 aSyncQueueKey, intN aErrorCode)
+                     PRUint32 aSyncQueueKey, int aErrorCode)
     : MainThreadProxyRunnable(aWorkerPrivate, SkipWhenClearing, aProxy),
       mSyncQueueKey(aSyncQueueKey), mErrorCode(aErrorCode)
     {
       NS_ASSERTION(aProxy, "Don't hand me a null proxy!");
     }
 
     bool
     WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
@@ -778,28 +778,28 @@ public:
 
     if (!mWorkerPrivate->RunSyncLoop(aCx, mSyncQueueKey)) {
       return false;
     }
 
     return true;
   }
 
-  virtual intN
+  virtual int
   MainThreadRun() = 0;
 
   NS_IMETHOD
   Run()
   {
     AssertIsOnMainThread();
 
     PRUint32 oldSyncQueueKey = mProxy->mSyncEventResponseSyncQueueKey;
     mProxy->mSyncEventResponseSyncQueueKey = mSyncQueueKey;
 
-    intN rv = MainThreadRun();
+    int rv = MainThreadRun();
 
     nsRefPtr<ResponseRunnable> response =
       new ResponseRunnable(mWorkerPrivate, mProxy, mSyncQueueKey, rv);
     if (!response->Dispatch(nsnull)) {
       NS_WARNING("Failed to dispatch response!");
     }
 
     mProxy->mSyncEventResponseSyncQueueKey = oldSyncQueueKey;
@@ -813,34 +813,34 @@ class SetMultipartRunnable : public Work
   bool mValue;
 
 public:
   SetMultipartRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy,
                        bool aValue)
   : WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy), mValue(aValue)
   { }
 
-  intN
+  int
   MainThreadRun()
   {
     return GetDOMExceptionCodeFromResult(mProxy->mXHR->SetMultipart(mValue));
   }
 };
 
 class SetBackgroundRequestRunnable : public WorkerThreadProxySyncRunnable
 {
   bool mValue;
 
 public:
   SetBackgroundRequestRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy,
                                bool aValue)
   : WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy), mValue(aValue)
   { }
 
-  intN
+  int
   MainThreadRun()
   {
     nsresult rv = mProxy->mXHR->SetMozBackgroundRequest(mValue);
     return GetDOMExceptionCodeFromResult(rv);
   }
 };
 
 class SetWithCredentialsRunnable : public WorkerThreadProxySyncRunnable
@@ -848,17 +848,17 @@ class SetWithCredentialsRunnable : publi
   bool mValue;
 
 public:
   SetWithCredentialsRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy,
                              bool aValue)
   : WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy), mValue(aValue)
   { }
 
-  intN
+  int
   MainThreadRun()
   {
     nsresult rv = mProxy->mXHR->SetWithCredentials(mValue);
     return GetDOMExceptionCodeFromResult(rv);
   }
 };
 
 class SetResponseTypeRunnable : public WorkerThreadProxySyncRunnable
@@ -867,17 +867,17 @@ class SetResponseTypeRunnable : public W
 
 public:
   SetResponseTypeRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy,
                           const nsAString& aResponseType)
   : WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy),
     mResponseType(aResponseType)
   { }
 
-  intN
+  int
   MainThreadRun()
   {
     nsresult rv = mProxy->mXHR->SetResponseType(mResponseType);
     mResponseType.Truncate();
     if (NS_SUCCEEDED(rv)) {
       rv = mProxy->mXHR->GetResponseType(mResponseType);
     }
     return GetDOMExceptionCodeFromResult(rv);
@@ -891,17 +891,17 @@ public:
 
 class AbortRunnable : public WorkerThreadProxySyncRunnable
 {
 public:
   AbortRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy)
   : WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy)
   { }
 
-  intN
+  int
   MainThreadRun()
   {
     mProxy->mInnerChannelId++;
 
     WorkerPrivate* oldWorker = mProxy->mWorkerPrivate;
     mProxy->mWorkerPrivate = mWorkerPrivate;
 
     nsresult rv = mProxy->mXHR->Abort();
@@ -920,17 +920,17 @@ class GetAllResponseHeadersRunnable : pu
 
 public:
   GetAllResponseHeadersRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy,
                                 nsString& aResponseHeaders)
   : WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy),
     mResponseHeaders(aResponseHeaders)
   { }
 
-  intN
+  int
   MainThreadRun()
   {
     nsresult rv =
       mProxy->mXHR->GetAllResponseHeaders(mResponseHeaders);
     return GetDOMExceptionCodeFromResult(rv);
   }
 };
 
@@ -941,17 +941,17 @@ class GetResponseHeaderRunnable : public
 
 public:
   GetResponseHeaderRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy,
                             const nsCString& aHeader, nsCString& aValue)
   : WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy), mHeader(aHeader),
     mValue(aValue)
   { }
 
-  intN
+  int
   MainThreadRun()
   {
     nsresult rv = mProxy->mXHR->GetResponseHeader(mHeader, mValue);
     return GetDOMExceptionCodeFromResult(rv);
   }
 };
 
 class OpenRunnable : public WorkerThreadProxySyncRunnable
@@ -969,29 +969,29 @@ public:
                const nsCString& aMethod, const nsCString& aURL,
                const nsString& aUser, const nsString& aPassword,
                bool aMultipart, bool aBackgroundRequest, bool aWithCredentials)
   : WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy), mMethod(aMethod),
     mURL(aURL), mUser(aUser), mPassword(aPassword), mMultipart(aMultipart),
     mBackgroundRequest(aBackgroundRequest), mWithCredentials(aWithCredentials)
   { }
 
-  intN
+  int
   MainThreadRun()
   {
     WorkerPrivate* oldWorker = mProxy->mWorkerPrivate;
     mProxy->mWorkerPrivate = mWorkerPrivate;
 
-    intN retval = MainThreadRunInternal();
+    int retval = MainThreadRunInternal();
 
     mProxy->mWorkerPrivate = oldWorker;
     return retval;
   }
 
-  intN
+  int
   MainThreadRunInternal()
   {
     if (!mProxy->Init()) {
       return INVALID_STATE_ERR;
     }
 
     nsresult rv;
 
@@ -1038,34 +1038,34 @@ public:
                JSAutoStructuredCloneBuffer& aBody, PRUint32 aSyncQueueKey,
                bool aHasUploadListeners)
   : WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy),
     mSyncQueueKey(aSyncQueueKey), mHasUploadListeners(aHasUploadListeners)
   {
     mBody.swap(aBody);
   }
 
-  intN
+  int
   MainThreadRun()
   {
     NS_ASSERTION(!mProxy->mWorkerPrivate, "Should be null!");
 
     mProxy->mWorkerPrivate = mWorkerPrivate;
 
     NS_ASSERTION(mProxy->mSyncQueueKey == PR_UINT32_MAX, "Should be unset!");
     mProxy->mSyncQueueKey = mSyncQueueKey;
 
     nsCOMPtr<nsIVariant> variant;
     if (mBody.data()) {
       nsIXPConnect* xpc = nsContentUtils::XPConnect();
       NS_ASSERTION(xpc, "This should never be null!");
 
       RuntimeService::AutoSafeJSContext cx;
 
-      intN error = 0;
+      int error = 0;
 
       jsval body;
       if (mBody.read(cx, &body)) {
         if (NS_FAILED(xpc->JSValToVariant(cx, &body,
                                           getter_AddRefs(variant)))) {
           error = INVALID_STATE_ERR;
         }
       }
@@ -1109,17 +1109,17 @@ class SendAsBinaryRunnable : public Work
 public:
   SendAsBinaryRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy,
                        const nsString& aBody, PRUint32 aSyncQueueKey,
                        bool aHasUploadListeners)
   : WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy), mBody(aBody),
     mSyncQueueKey(aSyncQueueKey), mHasUploadListeners(aHasUploadListeners)
   { }
 
-  intN
+  int
   MainThreadRun()
   {
     NS_ASSERTION(!mProxy->mWorkerPrivate, "Should be null!");
 
     mProxy->mWorkerPrivate = mWorkerPrivate;
 
     NS_ASSERTION(mProxy->mSyncQueueKey == PR_UINT32_MAX, "Should be unset!");
     mProxy->mSyncQueueKey = mSyncQueueKey;
@@ -1151,17 +1151,17 @@ class SetRequestHeaderRunnable : public 
 
 public:
   SetRequestHeaderRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy,
                            const nsCString& aHeader, const nsCString& aValue)
   : WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy), mHeader(aHeader),
     mValue(aValue)
   { }
 
-  intN
+  int
   MainThreadRun()
   {
     nsresult rv = mProxy->mXHR->SetRequestHeader(mHeader, mValue);
     return GetDOMExceptionCodeFromResult(rv);
   }
 };
 
 class OverrideMimeTypeRunnable : public WorkerThreadProxySyncRunnable
@@ -1169,17 +1169,17 @@ class OverrideMimeTypeRunnable : public 
   nsCString mMimeType;
 
 public:
   OverrideMimeTypeRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy,
                            const nsCString& aMimeType)
   : WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy), mMimeType(aMimeType)
   { }
 
-  intN
+  int
   MainThreadRun()
   {
     nsresult rv = mProxy->mXHR->OverrideMimeType(mMimeType);
     return GetDOMExceptionCodeFromResult(rv);
   }
 };
 
 class AutoUnpinXHR {
--- a/gfx/skia/src/xml/SkJS.cpp
+++ b/gfx/skia/src/xml/SkJS.cpp
@@ -79,17 +79,17 @@ global_enumerate(JSContext *cx, JSObject
 #ifdef LAZY_STANDARD_CLASSES
     return JS_EnumerateStandardClasses(cx, obj);
 #else
     return JS_TRUE;
 #endif
 }
 
 static JSBool
-global_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, JSObject **objp)
+global_resolve(JSContext *cx, JSObject *obj, jsval id, unsigned flags, JSObject **objp)
 {
 #ifdef LAZY_STANDARD_CLASSES
     if ((flags & JSRESOLVE_ASSIGNING) == 0) {
         JSBool resolved;
 
         if (!JS_ResolveStandardClass(cx, obj, id, &resolved))
             return JS_FALSE;
         if (resolved) {
--- a/gfx/skia/src/xml/SkJSDisplayable.cpp
+++ b/gfx/skia/src/xml/SkJSDisplayable.cpp
@@ -59,24 +59,24 @@ class SkJSDisplayable {
 public:
     SkJSDisplayable() : fDisplayable(NULL) {}
     ~SkJSDisplayable() { delete fDisplayable; }
     static void Destructor(JSContext *cx, JSObject *obj);
     static JSBool GetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
     static JSBool SetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
     static SkCanvas* gCanvas;
     static SkPaint* gPaint;
-    static JSBool Draw(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
+    static JSBool Draw(JSContext *cx, JSObject *obj, unsigned argc, jsval *argv, jsval *rval);
     SkDisplayable* fDisplayable;
 };
 
 SkCanvas* SkJSDisplayable::gCanvas;
 SkPaint* SkJSDisplayable::gPaint;
 
-JSBool SkJSDisplayable::Draw(JSContext *cx, JSObject *obj, uintN argc,
+JSBool SkJSDisplayable::Draw(JSContext *cx, JSObject *obj, unsigned argc,
                                     jsval *argv, jsval *rval)
 {
     SkJSDisplayable *p = (SkJSDisplayable*) JS_GetPrivate(cx, obj);
     SkASSERT(p->fDisplayable->isDrawable());
     SkDrawable* drawable = (SkDrawable*) p->fDisplayable;
     SkAnimateMaker maker(NULL, gCanvas, gPaint);
     drawable->draw(maker);
     return JS_TRUE;
@@ -88,17 +88,17 @@ JSFunctionSpec SkJSDisplayable_methods[]
     { "draw", SkJSDisplayable::Draw, 1, 0, 0 },
     { 0 }
 };
 
 static JSPropertySpec* gDisplayableProperties[kNumberOfTypes];
 static JSClass gDisplayableClasses[kNumberOfTypes];
 
 #define JS_INIT(_prefix, _class) \
-static JSBool _class##Constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { \
+static JSBool _class##Constructor(JSContext *cx, JSObject *obj, unsigned argc, jsval *argv, jsval *rval) { \
     SkJSDisplayable* jsDisplayable = new SkJSDisplayable(); \
     jsDisplayable->fDisplayable = new _prefix##_class(); \
     JS_SetPrivate(cx, obj, (void*) jsDisplayable); \
     return JS_TRUE; \
 } \
     \
 static JSObject* _class##Init(JSContext *cx, JSObject *obj, JSObject *proto) { \
     JSObject *newProtoObj = JS_InitClass(cx, obj, proto, &gDisplayableClasses[SkType_##_class], \
--- a/gfx/src/nsFontMetrics.cpp
+++ b/gfx/src/nsFontMetrics.cpp
@@ -295,45 +295,50 @@ nsFontMetrics::GetWidth(const char* aStr
     if (aLength == 0)
         return 0;
 
     if (aLength == 1 && aString[0] == ' ')
         return SpaceWidth();
 
     StubPropertyProvider provider;
     AutoTextRun textRun(this, aContext, aString, aLength);
-    return NSToCoordRound(textRun->GetAdvanceWidth(0, aLength, &provider));
+    return textRun.get() ?
+        NSToCoordRound(textRun->GetAdvanceWidth(0, aLength, &provider)) : 0;
 }
 
 nscoord
 nsFontMetrics::GetWidth(const PRUnichar* aString, PRUint32 aLength,
                         nsRenderingContext *aContext)
 {
     if (aLength == 0)
         return 0;
 
     if (aLength == 1 && aString[0] == ' ')
         return SpaceWidth();
 
     StubPropertyProvider provider;
     AutoTextRun textRun(this, aContext, aString, aLength);
-    return NSToCoordRound(textRun->GetAdvanceWidth(0, aLength, &provider));
+    return textRun.get() ?
+        NSToCoordRound(textRun->GetAdvanceWidth(0, aLength, &provider)) : 0;
 }
 
 // Draw a string using this font handle on the surface passed in.
 void
 nsFontMetrics::DrawString(const char *aString, PRUint32 aLength,
                           nscoord aX, nscoord aY,
                           nsRenderingContext *aContext)
 {
     if (aLength == 0)
         return;
 
     StubPropertyProvider provider;
     AutoTextRun textRun(this, aContext, aString, aLength);
+    if (!textRun.get()) {
+        return;
+    }
     gfxPoint pt(aX, aY);
     if (mTextRunRTL) {
         pt.x += textRun->GetAdvanceWidth(0, aLength, &provider);
     }
     textRun->Draw(aContext->ThebesContext(), pt, gfxFont::GLYPH_FILL, 0, aLength,
                   &provider, nsnull, nsnull);
 }
 
@@ -343,16 +348,19 @@ nsFontMetrics::DrawString(const PRUnicha
                           nsRenderingContext *aContext,
                           nsRenderingContext *aTextRunConstructionContext)
 {
     if (aLength == 0)
         return;
 
     StubPropertyProvider provider;
     AutoTextRun textRun(this, aTextRunConstructionContext, aString, aLength);
+    if (!textRun.get()) {
+        return;
+    }
     gfxPoint pt(aX, aY);
     if (mTextRunRTL) {
         pt.x += textRun->GetAdvanceWidth(0, aLength, &provider);
     }
     textRun->Draw(aContext->ThebesContext(), pt, gfxFont::GLYPH_FILL, 0, aLength,
                   &provider, nsnull, nsnull);
 }
 
@@ -360,21 +368,23 @@ nsBoundingMetrics
 nsFontMetrics::GetBoundingMetrics(const PRUnichar *aString, PRUint32 aLength,
                                   nsRenderingContext *aContext)
 {
     if (aLength == 0)
         return nsBoundingMetrics();
 
     StubPropertyProvider provider;
     AutoTextRun textRun(this, aContext, aString, aLength);
-    gfxTextRun::Metrics theMetrics =
-        textRun->MeasureText(0, aLength,
-                             gfxFont::TIGHT_HINTED_OUTLINE_EXTENTS,
-                             aContext->ThebesContext(), &provider);
+    nsBoundingMetrics m;
+    if (textRun.get()) {
+        gfxTextRun::Metrics theMetrics =
+            textRun->MeasureText(0, aLength,
+                                 gfxFont::TIGHT_HINTED_OUTLINE_EXTENTS,
+                                 aContext->ThebesContext(), &provider);
 
-    nsBoundingMetrics m;
-    m.leftBearing  = NSToCoordFloor( theMetrics.mBoundingBox.X());
-    m.rightBearing = NSToCoordCeil(  theMetrics.mBoundingBox.XMost());
-    m.ascent       = NSToCoordCeil( -theMetrics.mBoundingBox.Y());
-    m.descent      = NSToCoordCeil(  theMetrics.mBoundingBox.YMost());
-    m.width        = NSToCoordRound( theMetrics.mAdvanceWidth);
+        m.leftBearing  = NSToCoordFloor( theMetrics.mBoundingBox.X());
+        m.rightBearing = NSToCoordCeil(  theMetrics.mBoundingBox.XMost());
+        m.ascent       = NSToCoordCeil( -theMetrics.mBoundingBox.Y());
+        m.descent      = NSToCoordCeil(  theMetrics.mBoundingBox.YMost());
+        m.width        = NSToCoordRound( theMetrics.mAdvanceWidth);
+    }
     return m;
 }
--- a/gfx/thebes/gfxFont.cpp
+++ b/gfx/thebes/gfxFont.cpp
@@ -1872,26 +1872,16 @@ gfxFont::Measure(gfxTextRun *aTextRun,
                                   // over-stressing platform shapers
 
 #define BACKTRACK_LIMIT  1024 // If we can't find a space or a cluster start
                               // within 1K chars, just chop arbitrarily.
                               // Limiting backtrack here avoids pathological
                               // behavior on long runs with no whitespace.
 
 static bool
-IsClusterExtender(PRUint32 aUSV)
-{
-    PRUint8 category = GetGeneralCategory(aUSV);
-    return ((category >= HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK &&
-             category <= HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) ||
-            (aUSV >= 0x200c && aUSV <= 0x200d) || // ZWJ, ZWNJ
-            (aUSV >= 0xff9e && aUSV <= 0xff9f));  // katakana sound marks
-}
-
-static bool
 IsBoundarySpace(PRUnichar aChar, PRUnichar aNextChar)
 {
     return (aChar == ' ' || aChar == 0x00A0) && !IsClusterExtender(aNextChar);
 }
 
 static inline PRUint32
 HashMix(PRUint32 aHash, PRUnichar aCh)
 {
@@ -3792,105 +3782,35 @@ gfxFontStyle::ComputeWeight() const
 // anything but still need to set cluster info.
 /*static*/ void
 gfxShapedWord::SetupClusterBoundaries(CompressedGlyph *aGlyphs,
                                       const PRUnichar *aString, PRUint32 aLength)
 {
     gfxTextRun::CompressedGlyph extendCluster;
     extendCluster.SetComplex(false, true, 0);
 
-    HSType hangulState = HST_NONE;
-
-    for (PRUint32 i = 0; i < aLength; ++i) {
-        bool surrogatePair = false;
-        PRUint32 ch = aString[i];
-        if (NS_IS_HIGH_SURROGATE(ch) &&
-            i < aLength - 1 && NS_IS_LOW_SURROGATE(aString[i+1]))
-        {
-            ch = SURROGATE_TO_UCS4(ch, aString[i+1]);
-            surrogatePair = true;
+    ClusterIterator iter(aString, aLength);
+
+    // the ClusterIterator won't be able to tell us if the string
+    // _begins_ with a cluster-extender, so we handle that here
+    if (aLength && IsClusterExtender(*aString)) {
+        *aGlyphs = extendCluster;
+    }
+
+    while (!iter.AtEnd()) {
+        // advance iter to the next cluster-start (or end of text)
+        iter.Next();
+        // step past the first char of the cluster
+        aString++;
+        aGlyphs++;
+        // mark all the rest as cluster-continuations
+        while (aString < iter) {
+            *aGlyphs++ = extendCluster;
+            aString++;
         }
-
-        PRUint8 category = GetGeneralCategory(ch);
-        HSType hangulType = HST_NONE;
-
-        // combining marks extend the cluster
-        if (IsClusterExtender(ch)) {
-            aGlyphs[i] = extendCluster;
-        } else if (category == HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER) {
-            // handle special cases in Letter_Other category
-#if 0
-            // Currently disabled. This would follow the UAX#29 specification
-            // for extended grapheme clusters, but this is not favored by
-            // Thai users, at least for editing behavior.
-            // See discussion of equivalent Pango issue in bug 474068 and
-            // upstream at https://bugzilla.gnome.org/show_bug.cgi?id=576156.
-
-            if ((ch & ~0xff) == 0x0e00) {
-                // specific Thai & Lao (U+0Exx) chars that extend the cluster
-                if ( ch == 0x0e30 ||
-                    (ch >= 0x0e32 && ch <= 0x0e33) ||
-                     ch == 0x0e45 ||
-                     ch == 0x0eb0 ||
-                    (ch >= 0x0eb2 && ch <= 0x0eb3))
-                {
-                    if (i > 0) {
-                        aTextRun->SetGlyphs(i, extendCluster, nsnull);
-                    }
-                }
-                else if ((ch >= 0x0e40 && ch <= 0x0e44) ||
-                         (ch >= 0x0ec0 && ch <= 0x0ec4))
-                {
-                    // characters that are prepended to the following cluster
-                    if (i < length - 1) {
-                        aTextRun->SetGlyphs(i+1, extendCluster, nsnull);
-                    }
-                }
-            } else
-#endif
-            if ((ch & ~0xff) == 0x1100 ||
-                (ch >= 0xa960 && ch <= 0xa97f) ||
-                (ch >= 0xac00 && ch <= 0xd7ff))
-            {
-                // no break within Hangul syllables
-                hangulType = GetHangulSyllableType(ch);
-                switch (hangulType) {
-                case HST_L:
-                case HST_LV:
-                case HST_LVT:
-                    if (hangulState == HST_L) {
-                        aGlyphs[i] = extendCluster;
-                    }
-                    break;
-                case HST_V:
-                    if ( (hangulState != HST_NONE) &&
-                        !(hangulState & HST_T))
-                    {
-                        aGlyphs[i] = extendCluster;
-                    }
-                    break;
-                case HST_T:
-                    if (hangulState & (HST_V |
-                                       HST_T))
-                    {
-                        aGlyphs[i] = extendCluster;
-                    }
-                    break;
-                default:
-                    break;
-                }
-            }
-        }
-
-        if (surrogatePair) {
-            ++i;
-            aGlyphs[i] = extendCluster;
-        }
-
-        hangulState = hangulType;
     }
 }
 
 gfxShapedWord::DetailedGlyph *
 gfxShapedWord::AllocateDetailedGlyphs(PRUint32 aIndex, PRUint32 aCount)
 {
     NS_ASSERTION(aIndex < Length(), "Index out of range");
 
--- a/gfx/thebes/gfxGDIFontList.cpp
+++ b/gfx/thebes/gfxGDIFontList.cpp
@@ -98,16 +98,18 @@ BuildKeyNameFromFontName(nsAString &aNam
     if (aName.Length() >= LF_FACESIZE)
         aName.Truncate(LF_FACESIZE - 1);
     ToLowerCase(aName);
 }
 
 // Implementation of gfxPlatformFontList for Win32 GDI,
 // using GDI font enumeration APIs to get the list of fonts
 
+static HMODULE fontlib;
+
 class WinUserFontData : public gfxUserFontData {
 public:
     WinUserFontData(HANDLE aFontRef, bool aIsEmbedded)
         : mFontRef(aFontRef), mIsEmbedded(aIsEmbedded)
     { }
 
     virtual ~WinUserFontData()
     {
@@ -558,16 +560,22 @@ GDIFontFamily::FindStyleVariations()
  *
  * gfxGDIFontList
  *
  */
 
 gfxGDIFontList::gfxGDIFontList()
 {
     mFontSubstitutes.Init(50);
+
+    // Make sure the t2embed library is available because it may be
+    // disabled to work around security vulnerabilities.
+    if (!fontlib) {
+        fontlib = LoadLibraryW(L"t2embed.dll");
+    }
 }
 
 static void
 RemoveCharsetFromFontSubstitute(nsAString &aName)
 {
     PRInt32 comma = aName.FindChar(PRUnichar(','));
     if (comma >= 0)
         aName.Truncate(comma);
@@ -847,16 +855,20 @@ gfxGDIFontList::MakePlatformFont(const g
     struct FontDataDeleter {
         FontDataDeleter(const PRUint8 *aFontData)
             : mFontData(aFontData) { }
         ~FontDataDeleter() { NS_Free((void*)mFontData); }
         const PRUint8 *mFontData;
     };
     FontDataDeleter autoDelete(aFontData);
 
+    // if the t2embed library isn't available, bail
+    if (!fontlib)
+        return nsnull;
+
     bool hasVertical;
     bool isCFF = gfxFontUtils::IsCffFont(aFontData, hasVertical);
 
     nsresult rv;
     HANDLE fontRef = nsnull;
     bool isEmbedded = false;
 
     nsAutoString uniqueName;
--- a/gfx/thebes/gfxGraphiteShaper.cpp
+++ b/gfx/thebes/gfxGraphiteShaper.cpp
@@ -35,17 +35,16 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "prtypes.h"
 #include "prmem.h"
 #include "nsString.h"
 #include "nsBidiUtils.h"
 #include "nsMathUtils.h"
-#include "nsHashSets.h"
 
 #include "gfxTypes.h"
 
 #include "gfxContext.h"
 #include "gfxPlatform.h"
 #include "gfxGraphiteShaper.h"
 #include "gfxFontUtils.h"
 
--- a/intl/unicharutil/public/nsUnicodeProperties.h
+++ b/intl/unicharutil/public/nsUnicodeProperties.h
@@ -60,16 +60,22 @@ inline nsIUGenCategory::nsUGenCategory G
 }
 
 PRUint8 GetEastAsianWidth(PRUint32 aCh);
 
 PRInt32 GetScriptCode(PRUint32 aCh);
 
 PRUint32 GetScriptTagForCode(PRInt32 aScriptCode);
 
+bool IsClusterExtender(PRUint32 aCh, PRUint8 aCategory);
+
+inline bool IsClusterExtender(PRUint32 aCh) {
+    return IsClusterExtender(aCh, GetGeneralCategory(aCh));
+}
+
 enum HSType {
     HST_NONE = 0x00,
     HST_L    = 0x01,
     HST_V    = 0x02,
     HST_T    = 0x04,
     HST_LV   = 0x03,
     HST_LVT  = 0x07
 };
@@ -83,13 +89,38 @@ enum ShapingType {
     SHAPING_HANGUL    = 0x0008,
     SHAPING_MONGOLIAN = 0x0010,
     SHAPING_INDIC     = 0x0020,
     SHAPING_THAI      = 0x0040
 };
 
 PRInt32 ScriptShapingType(PRInt32 aScriptCode);
 
+// A simple iterator for a string of PRUnichar codepoints that advances
+// by Unicode grapheme clusters
+class ClusterIterator
+{
+public:
+    ClusterIterator(const PRUnichar* aText, PRUint32 aLength)
+        : mText(aText), mLimit(aText + aLength), mPos(aText)
+    { }
+
+    operator const PRUnichar* () const {
+        return mPos;
+    }
+
+    bool AtEnd() const {
+        return mPos >= mLimit;
+    }
+
+    void Next();
+
+private:
+    const PRUnichar* mText;
+    const PRUnichar* mLimit;
+    const PRUnichar* mPos;
+};
+
 } // end namespace unicode
 
 } // end namespace mozilla
 
 #endif /* NS_UNICODEPROPERTIES_H */
--- a/intl/unicharutil/src/nsUnicodeProperties.cpp
+++ b/intl/unicharutil/src/nsUnicodeProperties.cpp
@@ -36,16 +36,17 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsUnicodeProperties.h"
 #include "nsUnicodeScriptCodes.h"
 #include "nsUnicodePropertyData.cpp"
 
 #include "mozilla/Util.h"
 #include "nsMemory.h"
+#include "nsCharTraits.h"
 
 #include "harfbuzz/hb-unicode.h"
 
 #define UNICODE_BMP_LIMIT 0x10000
 #define UNICODE_LIMIT     0x110000
 
 namespace mozilla {
 
@@ -209,16 +210,25 @@ GetHangulSyllableType(PRUint32 aCh)
     // all Hangul chars are in plane 0
     if (aCh < UNICODE_BMP_LIMIT) {
         return HSType(sHangulValues[sHangulPages[0][aCh >> kHangulCharBits]]
                                    [aCh & ((1 << kHangulCharBits) - 1)]);
     }
     return HST_NONE;
 }
 
+bool
+IsClusterExtender(PRUint32 aCh, PRUint8 aCategory)
+{
+    return ((aCategory >= HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK &&
+             aCategory <= HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) ||
+            (aCh >= 0x200c && aCh <= 0x200d) || // ZWJ, ZWNJ
+            (aCh >= 0xff9e && aCh <= 0xff9f));  // katakana sound marks
+}
+
 // TODO: replace this with a properties file or similar;
 // expect this to evolve as harfbuzz shaping support matures.
 //
 // The "shaping type" of each script run, as returned by this
 // function, is compared to the bits set in the
 // gfx.font_rendering.harfbuzz.scripts
 // preference to decide whether to use the harfbuzz shaper.
 //
@@ -267,11 +277,79 @@ ScriptShapingType(PRInt32 aScriptCode)
     case MOZ_SCRIPT_MYANMAR:
     case MOZ_SCRIPT_PHAGS_PA:
     case MOZ_SCRIPT_BATAK:
     case MOZ_SCRIPT_BRAHMI:
         return SHAPING_INDIC; // scripts that require Indic or other "special" shaping
     }
 }
 
+void
+ClusterIterator::Next()
+{
+    if (AtEnd()) {
+        NS_WARNING("ClusterIterator has already reached the end");
+        return;
+    }
+
+    PRUint32 ch = *mPos++;
+
+    // Handle conjoining Jamo that make Hangul syllables
+    if ((ch & ~0xff) == 0x1100 ||
+        (ch >= 0xa960 && ch <= 0xa97f) ||
+        (ch >= 0xac00 && ch <= 0xd7ff)) {
+        HSType hangulState = GetHangulSyllableType(ch);
+        while (mPos < mLimit) {
+            ch = *mPos;
+            HSType hangulType = GetHangulSyllableType(ch);
+            switch (hangulType) {
+            case HST_L:
+            case HST_LV:
+            case HST_LVT:
+                if (hangulState == HST_L) {
+                    hangulState = hangulType;
+                    mPos++;
+                    continue;
+                }
+                break;
+            case HST_V:
+                if ((hangulState != HST_NONE) && !(hangulState & HST_T)) {
+                    hangulState = hangulType;
+                    mPos++;
+                    continue;
+                }
+                break;
+            case HST_T:
+                if (hangulState & (HST_V | HST_T)) {
+                    hangulState = hangulType;
+                    mPos++;
+                    continue;
+                }
+                break;
+            default:
+                break;
+            }
+            break;
+        }
+    }
+
+    while (mPos < mLimit) {
+        ch = *mPos;
+
+        // Check for surrogate pairs; note that isolated surrogates will just
+        // be treated as generic (non-cluster-extending) characters here,
+        // which is fine for cluster-iterating purposes
+        if (NS_IS_LOW_SURROGATE(ch) &&
+            NS_IS_HIGH_SURROGATE(*(mPos - 1))) {
+            ch = SURROGATE_TO_UCS4(*(mPos - 1), *mPos);
+            mPos++;
+        }
+
+        if (!IsClusterExtender(ch)) {
+            break;
+        }
+        mPos++;
+    }
+}
+
 } // end namespace unicode
 
 } // end namespace mozilla
--- a/ipc/ril/Ril.cpp
+++ b/ipc/ril/Ril.cpp
@@ -228,31 +228,31 @@ RilClient::OnFileCanReadWithoutBlocking(
     //   - mIncoming isn't completely read, but there's no more
     //     data available on the socket
     //     If so, break;
 
     MOZ_ASSERT(fd == mSocket.mFd);
     while (true) {
         if (!mIncoming) {
             mIncoming = new RilRawData();
-            int ret = read(fd, mIncoming->mData, 1024);
+            int ret = read(fd, mIncoming->mData, RilRawData.MAX_DATA_SIZE);
             if (ret <= 0) {
                 LOG("Cannot read from network, error %d\n", ret);
                 // At this point, assume that we can't actually access
                 // the socket anymore, and start a reconnect loop.
                 mIncoming.forget();
                 mReadWatcher.StopWatchingFileDescriptor();
                 mWriteWatcher.StopWatchingFileDescriptor();
                 close(mSocket.mFd);
                 mIOLoop->PostTask(FROM_HERE, new RilReconnectTask());
                 return;
             }
             mIncoming->mSize = ret;
             sConsumer->MessageReceived(mIncoming.forget());
-            if (ret < 1024) {
+            if (ret < RilRawData.MAX_DATA_SIZE) {
                 return;
             }
         }
     }
 }
 
 void
 RilClient::OnFileCanWriteWithoutBlocking(int fd)
--- a/ipc/testshell/TestShellParent.cpp
+++ b/ipc/testshell/TestShellParent.cpp
@@ -132,17 +132,17 @@ TestShellCommandParent::RunCallback(cons
     NS_ERROR("Failed to enter compartment!");
     return false;
   }
 
   JSString* str = JS_NewUCStringCopyN(mCx, aResponse.get(), aResponse.Length());
   NS_ENSURE_TRUE(str, JS_FALSE);
 
   jsval argv[] = { STRING_TO_JSVAL(str) };
-  uintN argc = ArrayLength(argv);
+  unsigned argc = ArrayLength(argv);
 
   jsval rval;
   JSBool ok = JS_CallFunctionValue(mCx, global, mCallback, argc, argv, &rval);
   NS_ENSURE_TRUE(ok, JS_FALSE);
 
   return JS_TRUE;
 }
 
--- a/ipc/testshell/XPCShellEnvironment.cpp
+++ b/ipc/testshell/XPCShellEnvironment.cpp
@@ -225,34 +225,34 @@ ScriptErrorReporter(JSContext *cx,
     }
     JS_free(cx, prefix);
 }
 
 JSContextCallback gOldContextCallback = NULL;
 
 static JSBool
 ContextCallback(JSContext *cx,
-                uintN contextOp)
+                unsigned contextOp)
 {
     if (gOldContextCallback && !gOldContextCallback(cx, contextOp))
         return JS_FALSE;
 
     if (contextOp == JSCONTEXT_NEW) {
         JS_SetErrorReporter(cx, ScriptErrorReporter);
         JS_SetVersion(cx, JSVERSION_LATEST);
     }
     return JS_TRUE;
 }
 
 static JSBool
 Print(JSContext *cx,
-      uintN argc,
+      unsigned argc,
       jsval *vp)
 {
-    uintN i, n;
+    unsigned i, n;
     JSString *str;
 
     jsval *argv = JS_ARGV(cx, vp);
     for (i = n = 0; i < argc; i++) {
         str = JS_ValueToString(cx, argv[i]);
         if (!str)
             return JS_FALSE;
         JSAutoByteString bytes(cx, str);
@@ -279,17 +279,17 @@ GetLine(char *bufp,
     if (!fgets(line, sizeof line, file))
         return JS_FALSE;
     strcpy(bufp, line);
     return JS_TRUE;
 }
 
 static JSBool
 Dump(JSContext *cx,
-     uintN argc,
+     unsigned argc,
      jsval *vp)
 {
     JS_SET_RVAL(cx, vp, JSVAL_VOID);
 
     JSString *str;
     if (!argc)
         return JS_TRUE;
 
@@ -302,20 +302,20 @@ Dump(JSContext *cx,
 
     fputs(bytes.ptr(), stdout);
     fflush(stdout);
     return JS_TRUE;
 }
 
 static JSBool
 Load(JSContext *cx,
-     uintN argc,
+     unsigned argc,
      jsval *vp)
 {
-    uintN i;
+    unsigned i;
     JSString *str;
     JSScript *script;
     jsval result;
     FILE *file;
 
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
@@ -346,52 +346,52 @@ Load(JSContext *cx,
         }
     }
     JS_SET_RVAL(cx, vp, JSVAL_VOID);
     return JS_TRUE;
 }
 
 static JSBool
 Version(JSContext *cx,
-        uintN argc,
+        unsigned argc,
         jsval *vp)
 {
     jsval *argv = JS_ARGV(cx, vp);
     if (argc > 0 && JSVAL_IS_INT(argv[0]))
         JS_SET_RVAL(cx, vp, INT_TO_JSVAL(JS_SetVersion(cx, JSVersion(JSVAL_TO_INT(argv[0])))));
     else
         JS_SET_RVAL(cx, vp, INT_TO_JSVAL(JS_GetVersion(cx)));
     return JS_TRUE;
 }
 
 static JSBool
-BuildDate(JSContext *cx, uintN argc, jsval *vp)
+BuildDate(JSContext *cx, unsigned argc, jsval *vp)
 {
     fprintf(stdout, "built on %s at %s\n", __DATE__, __TIME__);
     return JS_TRUE;
 }
 
 static JSBool
 Quit(JSContext *cx,
-     uintN argc,
+     unsigned argc,
      jsval *vp)
 {
     int exitCode = 0;
     JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "/ i", &exitCode);
 
     XPCShellEnvironment* env = Environment(cx);
     env->SetExitCode(exitCode);
     env->SetIsQuitting();
 
     return JS_FALSE;
 }
 
 static JSBool
 DumpXPC(JSContext *cx,
-        uintN argc,
+        unsigned argc,
         jsval *vp)
 {
     int32_t depth = 2;
 
     if (argc > 0) {
         if (!JS_ValueToInt32(cx, JS_ARGV(cx, vp)[0], &depth))
             return JS_FALSE;
     }
@@ -400,32 +400,32 @@ DumpXPC(JSContext *cx,
     if(xpc)
         xpc->DebugDump(int16_t(depth));
     JS_SET_RVAL(cx, vp, JSVAL_VOID);
     return JS_TRUE;
 }
 
 static JSBool
 GC(JSContext *cx,
-   uintN argc,
+   unsigned argc,
    jsval *vp)
 {
     JS_GC(cx);
 #ifdef JS_GCMETER
     JSRuntime *rt = JS_GetRuntime(cx);
     js_DumpGCStats(rt, stdout);
 #endif
     JS_SET_RVAL(cx, vp, JSVAL_VOID);
     return JS_TRUE;
 }
 
 #ifdef JS_GC_ZEAL
 static JSBool
 GCZeal(JSContext *cx, 
-       uintN argc,
+       unsigned argc,
        jsval *vp)
 {
   jsval* argv = JS_ARGV(cx, vp);
 
   uint32_t zeal;
   if (!JS_ValueToECMAUint32(cx, argv[0], &zeal))
     return JS_FALSE;
 
@@ -433,17 +433,17 @@ GCZeal(JSContext *cx,
   return JS_TRUE;
 }
 #endif
 
 #ifdef DEBUG
 
 static JSBool
 DumpHeap(JSContext *cx,
-         uintN argc,
+         unsigned argc,
          jsval *vp)
 {
     JSAutoByteString fileName;
     void* startThing = NULL;
     JSGCTraceKind startTraceKind = JSTRACE_OBJECT;
     void *thingToFind = NULL;
     size_t maxDepth = (size_t)-1;
     void *thingToIgnore = NULL;
@@ -519,17 +519,17 @@ DumpHeap(JSContext *cx,
             (unsigned)(vp - argv));
     return JS_FALSE;
 }
 
 #endif /* DEBUG */
 
 static JSBool
 Clear(JSContext *cx,
-      uintN argc,
+      unsigned argc,
       jsval *vp)
 {
     jsval *argv = JS_ARGV(cx, vp);
     if (argc > 0 && !JSVAL_IS_PRIMITIVE(argv[0])) {
         JS_ClearScope(cx, JSVAL_TO_OBJECT(argv[0]));
     } else {
         JS_ReportError(cx, "'clear' requires an object");
         return JS_FALSE;
--- a/js/ipc/ObjectWrapperParent.cpp
+++ b/js/ipc/ObjectWrapperParent.cpp
@@ -48,33 +48,33 @@
 #include "jsfriendapi.h"
 
 using namespace mozilla::jsipc;
 
 namespace {
 
     // Only need one reserved slot because the ObjectWrapperParent* is
     // stored in the private slot.
-    static const uintN sFlagsSlot = 0;
-    static const uintN sNumSlots = 1;
-    static const uintN CPOW_FLAG_RESOLVING = 1 << 0;
+    static const unsigned sFlagsSlot = 0;
+    static const unsigned sNumSlots = 1;
+    static const unsigned CPOW_FLAG_RESOLVING = 1 << 0;
 
     class AutoResolveFlag
     {
         JSObject* mObj;
-        uintN mOldFlags;
+        unsigned mOldFlags;
         JS_DECL_USE_GUARD_OBJECT_NOTIFIER
 
-        static uintN GetFlags(JSObject* obj) {
+        static unsigned GetFlags(JSObject* obj) {
             jsval v = JS_GetReservedSlot(obj, sFlagsSlot);
             return JSVAL_TO_INT(v);
         }
 
-        static uintN SetFlags(JSObject* obj, uintN flags) {
-            uintN oldFlags = GetFlags(obj);
+        static unsigned SetFlags(JSObject* obj, unsigned flags) {
+            unsigned oldFlags = GetFlags(obj);
             if (oldFlags != flags)
                 JS_SetReservedSlot(obj, sFlagsSlot, INT_TO_JSVAL(flags));
             return oldFlags;
         }
 
     public:
 
         AutoResolveFlag(JSObject* obj
@@ -572,17 +572,17 @@ ObjectWrapperParent::CPOW_NewEnumerate(J
     }
 
     NS_NOTREACHED("Unknown enum_op value in CPOW_NewEnumerate");
     return JS_FALSE;
 }
 
 /*static*/ JSBool
 ObjectWrapperParent::CPOW_NewResolve(JSContext *cx, JSObject *obj, jsid id,
-                                     uintN flags, JSObject **objp)
+                                     unsigned flags, JSObject **objp)
 {
     CPOW_LOG(("Calling CPOW_NewResolve (%s)...",
               JSVAL_TO_CSTR(cx, id)));
 
     ObjectWrapperParent* self = Unwrap(obj);
     if (!self)
         return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_NewResolve");
 
@@ -634,17 +634,17 @@ ObjectWrapperParent::CPOW_Finalize(JSCon
     ObjectWrapperParent* self = Unwrap(obj);
     if (self) {
         self->mObj = NULL;
         unused << ObjectWrapperParent::Send__delete__(self);
     }
 }
 
 /*static*/ JSBool
-ObjectWrapperParent::CPOW_Call(JSContext* cx, uintN argc, jsval* vp)
+ObjectWrapperParent::CPOW_Call(JSContext* cx, unsigned argc, jsval* vp)
 {
     CPOW_LOG(("Calling CPOW_Call..."));
 
     JSObject* thisobj = JS_THIS_OBJECT(cx, vp);
     if (!thisobj)
         return JS_FALSE;
 
     ObjectWrapperParent* function =
@@ -660,43 +660,43 @@ ObjectWrapperParent::CPOW_Call(JSContext
         // TODO First make sure we're really replacing the global object?
         ContextWrapperParent* manager =
             static_cast<ContextWrapperParent*>(function->Manager());
         receiver = manager->GetGlobalObjectWrapper();
     }
 
     InfallibleTArray<JSVariant> in_argv(argc);
     jsval* argv = JS_ARGV(cx, vp);
-    for (uintN i = 0; i < argc; i++)
+    for (unsigned i = 0; i < argc; i++)
         if (!jsval_to_JSVariant(cx, argv[i], in_argv.AppendElement()))
             return JS_FALSE;
 
     JSVariant out_rval;
 
     return (function->Manager()->RequestRunToCompletion() &&
             function->CallCall(receiver, in_argv,
                                aco.StatusPtr(), &out_rval) &&
             aco.Ok() &&
             jsval_from_JSVariant(cx, out_rval, vp));
 }
 
 /*static*/ JSBool
-ObjectWrapperParent::CPOW_Construct(JSContext* cx, uintN argc, jsval* vp)
+ObjectWrapperParent::CPOW_Construct(JSContext* cx, unsigned argc, jsval* vp)
 {
     CPOW_LOG(("Calling CPOW_Construct..."));
     
     ObjectWrapperParent* constructor = Unwrap(JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)));
     if (!constructor)
         return with_error(cx, JS_FALSE, "Could not unwrap CPOW constructor function");
 
     AutoCheckOperation aco(cx, constructor);
 
     InfallibleTArray<JSVariant> in_argv(argc);
     jsval* argv = JS_ARGV(cx, vp);
-    for (uintN i = 0; i < argc; i++)
+    for (unsigned i = 0; i < argc; i++)
         if (!jsval_to_JSVariant(cx, argv[i], in_argv.AppendElement()))
             return JS_FALSE;
 
     PObjectWrapperParent* out_powp;
 
     return (constructor->Manager()->RequestRunToCompletion() &&
             constructor->CallConstruct(in_argv, aco.StatusPtr(), &out_powp) &&
             aco.Ok() &&
--- a/js/ipc/